📄 script_enc.c
字号:
} GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "recieved", id); gf_list_add(sc_enc->identifiers, strdup(id)); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, id);}void SFE_Arguments(ScriptEnc *sc_enc){ while (1) { if (!SFE_NextToken(sc_enc)) return; if (sc_enc->token_code == TOK_RIGHT_CURVE) break; else if (sc_enc->token_code == TOK_COMMA) continue; GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL); SFE_PutIdentifier(sc_enc, sc_enc->token); } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL);}void SFE_StatementBlock(ScriptEnc *sc_enc);void SFE_Statement(ScriptEnc *sc_enc);void SFE_PutInteger(ScriptEnc *sc_enc, char *str){ u32 nbBits, val = 0; if (sc_enc->emul) return; if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) { val = strtoul(sc_enc->token, (char **) NULL, 16); } else if (str[0]=='0' && isdigit(str[1])) { val = strtoul(str, (char **) NULL, 8); } else if (isdigit(str[0])) { val = strtoul(str, (char **) NULL, 10); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str)); sc_enc->err = GF_BAD_PARAM; return; } nbBits = gf_get_bit_size(val); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 5, "nbBitsInteger", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token);}u32 SFE_LoadExpression(ScriptEnc *sc_enc, u32 *expr_sep){ Bool is_var = 0; u32 close_code, open_code; u32 count = 0; u32 nbExpr = 1; u32 nbIndir = 0; expr_sep[0] = 0; sc_enc->expr_toks_len = 0; while ( (sc_enc->token_code != TOK_SEMICOLON) && (sc_enc->token_code != TOK_RIGHT_CURVE) ) { switch (sc_enc->token_code) { case TOK_CONDTEST: nbIndir ++; break; case TOK_CONDSEP: if (nbIndir > 0) nbIndir--; /*'case'*/ else { goto break_loop; } break; case TOK_IDENTIFIER: case TOK_NUMBER: case TOK_STRING: case TOK_BOOLEAN: gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); break; case TOK_FUNCTION: goto break_loop; } if (sc_enc->token_code==TOK_VAR) is_var = 1; if (!is_var || (sc_enc->token_code!=TOK_COMMA)) { sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code; sc_enc->expr_toks_len++; } open_code = sc_enc->token_code; close_code = 0; if (sc_enc->token_code == TOK_LEFT_CURVE) close_code = TOK_RIGHT_CURVE; else if (sc_enc->token_code == TOK_LEFT_BRACKET) close_code = TOK_RIGHT_BRACKET; else if (sc_enc->token_code == TOK_LEFT_BRACE) close_code = TOK_RIGHT_BRACE; /*other expr*/ if ((sc_enc->token_code == TOK_COMMA) && (sc_enc->expr_toks[0] != TOK_VAR) ){ expr_sep[nbExpr++] = sc_enc->expr_toks_len - 1; } /*sub-expr*/ else if (close_code) { count++; do { SFE_NextToken(sc_enc); if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) || (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) { gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); } sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code; sc_enc->expr_toks_len++; if (sc_enc->token_code == open_code) count++; else if (sc_enc->token_code == close_code) count--; } while ( (sc_enc->token_code != close_code) || count); } SFE_NextToken(sc_enc); }break_loop: if (sc_enc->err) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: end of compoundExpression not found\n")); return 0; } expr_sep[nbExpr] = sc_enc->expr_toks_len; if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) || (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) { gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); } if ((sc_enc->token_code != TOK_CONDSEP) && (sc_enc->token_code != TOK_RIGHT_BRACE) && (sc_enc->expr_toks[0] != TOK_VAR)) { sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code; sc_enc->expr_toks_len++; } return nbExpr;}u32 MoveToToken(ScriptEnc *sc_enc, u32 endTok, u32 cur, u32 end);u32 SFE_ScanExpression(ScriptEnc *sc_enc, u32 start, u32 end, u32 *expr_sep){ u32 curTok; u32 n = start; u32 nbExpr = 1; expr_sep[0] = start; while (n<end) { curTok = sc_enc->expr_toks[n++]; if (curTok == TOK_LEFT_CURVE) { n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n-1, end); n++; } else if (curTok == TOK_LEFT_BRACKET) { n = MoveToToken(sc_enc, TOK_RIGHT_BRACKET, n-1, end); n++; } else if (curTok == TOK_COMMA) { expr_sep[nbExpr++] = n-1; } } expr_sep[nbExpr] = end; return nbExpr;}u32 SFE_Expression(ScriptEnc *sc_enc, u32 start, u32 end, Bool memberAccess);void SFE_CompoundExpression(ScriptEnc *sc_enc, u32 start, u32 end, u32 isPar){ u32 nbExp, i; /*filled by indexes of ',' expressions in the expr_tok buffer*/ u32 expr_sep[MAX_NUM_EXPR]; if (sc_enc->err) return; if (end==0) { /*load expressions , eg "a ? ((a>b) ? 1 : 0) : 0" */ nbExp = SFE_LoadExpression(sc_enc, expr_sep); } else { /*load sub-expression from loaded expression set*/ nbExp = SFE_ScanExpression(sc_enc, start, end, expr_sep); } SFE_Expression(sc_enc, expr_sep[0], expr_sep[1], 0); for (i=1; i<nbExp; i++) { SFE_WRITE_INT(sc_enc, 1, 1, isPar ? "hasParam" : "hasExpression", NULL); SFE_Expression(sc_enc, expr_sep[i]+1, expr_sep[i+1], 0); } SFE_WRITE_INT(sc_enc, 0, 1, isPar ? "hasParam" : "hasExpression", NULL);}void SFE_OptionalExpression(ScriptEnc *sc_enc){ if (sc_enc->token_code != TOK_SEMICOLON) { SFE_WRITE_INT(sc_enc, 1, 1, "hasCompoundExpression", NULL); SFE_CompoundExpression(sc_enc, 0, 0, 0); } else { SFE_WRITE_INT(sc_enc, 0, 1, "hasCompoundExpression", NULL); }}void SFE_IfStatement(ScriptEnc *sc_enc){ char *buf_bck; u32 tok_bck; SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_NextToken(sc_enc); SFE_CompoundExpression(sc_enc, 0, 0, 0); SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE); SFE_StatementBlock(sc_enc); buf_bck = sc_enc->cur_buf; tok_bck = sc_enc->token_code; SFE_NextToken(sc_enc); if (sc_enc->token_code == TOK_ELSE) { SFE_WRITE_INT(sc_enc, 1, 1, "hasELSEStatement", NULL); SFE_StatementBlock(sc_enc); } else { SFE_WRITE_INT(sc_enc, 0, 1, "hasELSEStatement", NULL); sc_enc->cur_buf = buf_bck; sc_enc->token_code = tok_bck; }}void SFE_ForStatement(ScriptEnc *sc_enc){ SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_NextToken(sc_enc); SFE_OptionalExpression(sc_enc); SFE_CheckToken(sc_enc, TOK_SEMICOLON); SFE_NextToken(sc_enc); SFE_OptionalExpression(sc_enc); SFE_CheckToken(sc_enc, TOK_SEMICOLON); SFE_NextToken(sc_enc); SFE_OptionalExpression(sc_enc); SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE); SFE_StatementBlock(sc_enc);}void SFE_WhileStatement(ScriptEnc *sc_enc){ SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_NextToken(sc_enc); SFE_CompoundExpression(sc_enc, 0, 0, 0); SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE); SFE_StatementBlock(sc_enc);}void SFE_ReturnStatement(ScriptEnc *sc_enc){ SFE_NextToken(sc_enc); if (sc_enc->token_code != TOK_SEMICOLON) { SFE_WRITE_INT(sc_enc, 1, 1, "returnValue", NULL); SFE_CompoundExpression(sc_enc, 0, 0, 0); } else { SFE_WRITE_INT(sc_enc, 0, 1, "returnValue", NULL); }}void SFE_CaseBlock(ScriptEnc *sc_enc){ SFE_WRITE_INT(sc_enc, 1, 1, "isCompoundStatement", NULL); SFE_NextToken(sc_enc); if (sc_enc->token_code == TOK_LEFT_BRACE) { SFE_NextToken(sc_enc); while (sc_enc->token_code != TOK_RIGHT_BRACE) { SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL); SFE_Statement(sc_enc); SFE_NextToken(sc_enc); } SFE_NextToken(sc_enc); } while ((sc_enc->token_code != TOK_CASE) && (sc_enc->token_code != TOK_DEFAULT) && (sc_enc->token_code != TOK_RIGHT_BRACE)) { SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL); SFE_Statement(sc_enc); SFE_NextToken(sc_enc); } SFE_WRITE_INT(sc_enc, 0, 1, "hasStatement", NULL);}u32 SFE_PutCaseInteger(ScriptEnc *sc_enc, char *str, u32 nbBits){ u32 val = 0; if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) { val = strtoul(sc_enc->token, (char **) NULL, 16); } else if (str[0]=='0' && isdigit(str[1])) { val = strtoul(str, (char **) NULL, 8); } else if (isdigit(str[0])) { val = strtoul(str, (char **) NULL, 10); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str)); sc_enc->err = GF_BAD_PARAM; return 0; } if (!sc_enc->emul) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token); } else { nbBits = gf_get_bit_size(val); } return nbBits;}void SFE_SwitchStatement(ScriptEnc *sc_enc){ u32 nbBits, maxBits = 0; Bool prev_emu; char *buf_bck; u32 tok_bck; SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_NextToken(sc_enc); SFE_CompoundExpression(sc_enc, 0, 0, 0); SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_BRACE); /*first pass in emul*/ buf_bck = sc_enc->cur_buf; tok_bck = sc_enc->token_code; prev_emu = sc_enc->emul; sc_enc->emul = 1; SFE_NextToken(sc_enc); while (sc_enc->token_code == TOK_CASE) { SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_NUMBER); nbBits = SFE_PutCaseInteger(sc_enc, sc_enc->token, 0); if (maxBits<nbBits) maxBits = nbBits; SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_CONDSEP); SFE_CaseBlock(sc_enc); SFE_WRITE_INT(sc_enc, (sc_enc->token_code == TOK_CASE) ? 1 : 0, 1, "hasMoreCases", NULL); } /*second pass in parent mode*/ sc_enc->cur_buf = buf_bck; sc_enc->token_code = tok_bck; sc_enc->emul = prev_emu; maxBits ++; SFE_WRITE_INT(sc_enc, maxBits, 5, "caseNbBits", NULL); SFE_NextToken(sc_enc); while (sc_enc->token_code == TOK_CASE) { SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_NUMBER); SFE_PutCaseInteger(sc_enc, sc_enc->token, maxBits); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_CONDSEP); SFE_CaseBlock(sc_enc); SFE_WRITE_INT(sc_enc, (sc_enc->token_code == TOK_CASE) ? 1 : 0, 1, "hasMoreCases", NULL); } if (sc_enc->token_code == TOK_DEFAULT) { SFE_WRITE_INT(sc_enc, 1, 1, "hasDefault", NULL); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_CONDSEP); SFE_CaseBlock(sc_enc); } else { SFE_WRITE_INT(sc_enc, 0, 1, "hasDefault", NULL); } SFE_CheckToken(sc_enc, TOK_RIGHT_BRACE);}void SFE_Statement(ScriptEnc *sc_enc){ switch (sc_enc->token_code) { case TOK_IF: SFE_WRITE_INT(sc_enc, ST_IF, NUMBITS_STATEMENT, "statementType", "if"); SFE_IfStatement(sc_enc); break; case TOK_FOR: SFE_WRITE_INT(sc_enc, ST_FOR, NUMBITS_STATEMENT, "statementType", "for"); SFE_ForStatement(sc_enc); break; case TOK_WHILE: SFE_WRITE_INT(sc_enc, ST_WHILE, NUMBITS_STATEMENT, "statementType", "while"); SFE_WhileStatement(sc_enc); break; case TOK_RETURN: SFE_WRITE_INT(sc_enc, ST_RETURN, NUMBITS_STATEMENT, "statementType", "return"); SFE_ReturnStatement(sc_enc); break; case TOK_BREAK: SFE_WRITE_INT(sc_enc, ST_BREAK, NUMBITS_STATEMENT, "statementType", "break"); SFE_NextToken(sc_enc); break; case TOK_CONTINUE: SFE_WRITE_INT(sc_enc, ST_CONTINUE, NUMBITS_STATEMENT, "statementType", "continue"); SFE_NextToken(sc_enc); break; case TOK_SWITCH: SFE_WRITE_INT(sc_enc, ST_SWITCH, NUMBITS_STATEMENT, "statementType", "while"); SFE_SwitchStatement(sc_enc); break; default: SFE_WRITE_INT(sc_enc, ST_COMPOUND_EXPR, NUMBITS_STATEMENT, "statementType", "compoundExpr"); SFE_CompoundExpression(sc_enc, 0, 0, 0); break; }}void SFE_Statements(ScriptEnc *sc_enc){ while (1) { if (!SFE_NextToken(sc_enc)) return; if (sc_enc->token_code == TOK_RIGHT_BRACE) break; SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL); SFE_Statement(sc_enc); } SFE_WRITE_INT(sc_enc, 0, 1, "hasStatement", NULL);}void SFE_StatementBlock(ScriptEnc *sc_enc){ if (!SFE_NextToken(sc_enc)) return; if (sc_enc->token_code == TOK_LEFT_BRACE) { SFE_WRITE_INT(sc_enc, 1, 1, "isCompoundStatement", NULL); SFE_Statements(sc_enc); } else { SFE_WRITE_INT(sc_enc, 0, 1, "isCompoundStatement", NULL); SFE_Statement(sc_enc); }}void SFE_Function(ScriptEnc *sc_enc){ char szName[1000]; SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_FUNCTION); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_IDENTIFIER); strcpy(szName, sc_enc->token); SFE_PutIdentifier(sc_enc, sc_enc->token); SFE_NextToken(sc_enc); SFE_CheckToken(sc_enc, TOK_LEFT_CURVE); SFE_Arguments(sc_enc); SFE_StatementBlock(sc_enc); if (sc_enc->err) GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Error while parsing function %s\n", szName));}GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n){ char *ptr; ScriptEnc sc_enc; if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM; memset(&sc_enc, 0, sizeof(ScriptEnc)); sc_enc.codec = codec; sc_enc.script = n; sc_enc.bs = bs; sc_enc.identifiers = gf_list_new(); sc_enc.id_buf = gf_list_new(); sc_enc.err = GF_OK; if (codec->is_encoding_command) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Script::isList", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); } else { EncScriptFields(&sc_enc); } /*reserevd*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "reserved", NULL); if (script_field) { sc_enc.cur_buf = (char *)script_field->script_text; } else if (((M_Script*)n)->url.count) { sc_enc.cur_buf = (char *)((M_Script*)n)->url.vals[0].script_text; } if (sc_enc.cur_buf) { if (!strnicmp(sc_enc.cur_buf, "javascript:", 11) || !strnicmp(sc_enc.cur_buf, "vrmlscript:", 11) || !strnicmp(sc_enc.cur_buf, "ECMAScript:", 11) ) { sc_enc.cur_buf += 11; } else if (!strnicmp(sc_enc.cur_buf, "mpeg4script:", 12) ) { sc_enc.cur_buf += 12; } } /*encode functions*/ while (sc_enc.cur_buf && sc_enc.cur_buf[0] && (sc_enc.cur_buf[0]!='}')) { if (strchr("\r\n\t ", sc_enc.cur_buf[0]) ) { sc_enc.cur_buf++; continue; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasFunction", NULL); SFE_Function(&sc_enc); if (sc_enc.err) break; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasFunction", NULL); //clean up while (gf_list_count(sc_enc.identifiers)) { ptr = (char *)gf_list_get(sc_enc.identifiers, 0); gf_list_rem(sc_enc.identifiers, 0); free(ptr); } gf_list_del(sc_enc.identifiers); /*in case of error this is needed*/ while (gf_list_count(sc_enc.id_buf)) { ptr = (char *)gf_list_get(sc_enc.id_buf, 0); gf_list_rem(sc_enc.id_buf, 0); free(ptr); } gf_list_del(sc_enc.id_buf); return sc_enc.err;}void SFE_PutReal(ScriptEnc *sc_enc, char *str){ u32 i, length = strlen(str); for (i=0; i<length; i++) { s32 c = str[i]; if (c >= '0' && c <= '9') { SFE_WRITE_INT(sc_enc, c-'0', 4, "floatChar", "Digital"); } else if (c == '.') { SFE_WRITE_INT(sc_enc, 10, 4, "floatChar", "Decimal Point"); } else if (c == 'e' || c == 'E') { SFE_WRITE_INT(sc_enc, 11, 4, "floatChar", "Exponential");} else if (c == '-') {SFE_WRITE_INT(sc_enc, 12, 4, "floatChar", "Sign");} else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not a real number\n", str)); sc_enc->err = GF_BAD_PARAM; return; } } SFE_WRITE_INT(sc_enc, 15, 4, "floatChar", "End Symbol");}void SFE_PutNumber(ScriptEnc *sc_enc, char *str) { if (strpbrk(str,".eE-") == 0) { SFE_WRITE_INT(sc_enc, 1, 1, "isInteger", "integer"); SFE_PutInteger(sc_enc, str); } else { SFE_WRITE_INT(sc_enc, 0, 1, "isInteger", "real"); SFE_PutReal(sc_enc, str); }}void SFE_PutBoolean(ScriptEnc *sc_enc, char *str){ u32 v = 1; if (!stricmp(str, "false") || !strcmp(str, "0")) v = 0; SFE_WRITE_INT(sc_enc, v, 1, "value", "bolean");}#define CHECK_TOK(x) \ if (curTok != x) { \ GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Token %s read, %s expected\n", tok_names[curTok], tok_names[x])); \ sc_enc->err = GF_BAD_PARAM; \ } \u32 TOK_To_ET(u32 tok){ switch(tok) { case TOK_INCREMENT: return ET_INCREMENT; case TOK_DECREMENT: return ET_DECREMENT; case TOK_NOT: return ET_NOT; case TOK_ONESCOMP: return ET_ONESCOMP; case TOK_MULTIPLY : return ET_MULTIPLY; case TOK_DIVIDE : return ET_DIVIDE; case TOK_MOD : return ET_MOD; case TOK_PLUS : return ET_PLUS; case TOK_MINUS : return ET_MINUS; case TOK_LSHIFT : return ET_LSHIFT; case TOK_RSHIFT : return ET_RSHIFT; case TOK_RSHIFTFILL : return ET_RSHIFTFILL; case TOK_LT : return ET_LT; case TOK_LE : return ET_LE; case TOK_GT : return ET_GT; case TOK_GE : return ET_GE; case TOK_EQ : return ET_EQ; case TOK_NE : return ET_NE; case TOK_AND : return ET_AND; case TOK_XOR : return ET_XOR; case TOK_OR : return ET_OR; case TOK_LAND : return ET_LAND; case TOK_LOR : return ET_LOR; case TOK_CONDTEST : return ET_CONDTEST;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -