📄 script_dec.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / BIFS codec sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "script.h"#define BINOP_MINVAL ET_EQtypedef struct { GF_Node *script; GF_BifsDecoder *codec; GF_BitStream *bs; char *string; u32 length; GF_List *identifiers; char *new_line; u32 indent;} ScriptParser;void SFS_Identifier(ScriptParser *parser);void SFS_Arguments(ScriptParser *parser, Bool is_var);void SFS_StatementBlock(ScriptParser *parser, Bool functBody);void SFS_Statement(ScriptParser *parser);void SFS_IfStatement(ScriptParser *parser);void SFS_SwitchStatement(ScriptParser *parser);void SFS_ForStatement(ScriptParser *parser);void SFS_WhileStatement(ScriptParser *parser);void SFS_ReturnStatement(ScriptParser *parser);void SFS_CompoundExpression(ScriptParser *parser);void SFS_OptionalExpression(ScriptParser *parser);void SFS_Expression(ScriptParser *parser);void SFS_NewObject(ScriptParser *parser);void SFS_ArrayDeref(ScriptParser *parser);void SFS_FunctionCall(ScriptParser *parser);void SFS_ObjectMemberAccess(ScriptParser *parser);void SFS_ObjectMethodCall(ScriptParser *parser);void SFS_Params(ScriptParser *parser);void SFS_GetNumber(ScriptParser *parser);void SFS_GetString(ScriptParser *parser);void SFS_GetBoolean(ScriptParser *parser);#define PARSER_STEP_ALLOC 500static void SFS_AddString(ScriptParser *parser, char *str){ char *new_str; if (!str) return; if (strlen(parser->string) + strlen(str) >= parser->length) { parser->length += PARSER_STEP_ALLOC; new_str = (char *)malloc(sizeof(char)*parser->length); strcpy(new_str, parser->string); free(parser->string); parser->string = new_str; } strcat(parser->string, str);}static void SFS_AddInt(ScriptParser *parser, s32 val){ char msg[500]; sprintf(msg, "%d", val); SFS_AddString(parser, msg);}static void SFS_AddChar(ScriptParser *parser, char c){ char msg[2]; sprintf(msg, "%c", c); SFS_AddString(parser, msg);}GF_Err ParseScriptField(ScriptParser *parser){ GF_ScriptField *field; GF_Err e; u32 eventType, fieldType; char name[1000]; GF_FieldInfo info; eventType = gf_bs_read_int(parser->bs, 2); fieldType = gf_bs_read_int(parser->bs, 6); gf_bifs_dec_name(parser->bs, name); field = gf_sg_script_field_new(parser->script, eventType, fieldType, name); if (!field) return GF_NON_COMPLIANT_BITSTREAM; //save the name in the list of identifiers gf_list_add(parser->identifiers, strdup(name)); if (parser->codec->pCurrentProto) { Bool isISfield = gf_bs_read_int(parser->bs, 1); if (isISfield) { u32 numProtoField = gf_sg_proto_get_field_count(parser->codec->pCurrentProto); u32 numBits = gf_get_bit_size(numProtoField - 1); u32 field_all = gf_bs_read_int(parser->bs, numBits); e = gf_sg_script_field_get_info(field, &info); if (e) return e; e = gf_sg_proto_field_set_ised(parser->codec->pCurrentProto, field_all, parser->script, info.fieldIndex); return e; } } /*get default value*/ if (eventType == GF_SG_SCRIPT_TYPE_FIELD) { if (gf_bs_read_int(parser->bs, 1)) { e = gf_sg_script_field_get_info(field, &info); if (e) return e; gf_bifs_dec_field(parser->codec, parser->bs, parser->script, &info); } } return parser->codec->LastError;}static void SFS_IncIndent(ScriptParser *pars) { pars->indent++; }static void SFS_DecIndent(ScriptParser *pars) { pars->indent--; }static void SFS_Space(ScriptParser *pars) { if (pars->new_line) SFS_AddString(pars, " ");}static void SFS_Indent(ScriptParser *pars) { u32 i; if (pars->new_line) { for (i=0; i<pars->indent; i++) SFS_AddString(pars, " "); }}static GFINLINE void SFS_Line(ScriptParser *parser) { if (parser->new_line) { SFS_AddString(parser, parser->new_line); }}GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n){ GF_Err e; u32 i, count, nbBits; char *ptr; ScriptParser parser; Bool has_fields = 0; e = GF_OK; if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM; parser.codec = codec; parser.script = n; parser.bs = bs; parser.length = 500; parser.string = (char *) malloc(sizeof(char)* parser.length); parser.string[0] = 0; parser.identifiers = gf_list_new(); parser.new_line = (char *) (codec->dec_memory_mode ? "\n" : NULL); parser.indent = 0; //first parse fields if (gf_bs_read_int(bs, 1)) { //endFlag while (!gf_bs_read_int(bs, 1)){ e = ParseScriptField(&parser); if (e) goto exit; else has_fields = 1; } } else { nbBits = gf_bs_read_int(bs, 4); count = gf_bs_read_int(bs, nbBits); for (i=0; i<count; i++) { e = ParseScriptField(&parser); if (e) goto exit; else has_fields = 1; } } //reserevd gf_bs_read_int(bs, 1); //then parse SFS_AddString(&parser, "javascript:"); SFS_AddString(&parser, parser.new_line); //hasFunction while (gf_bs_read_int(bs, 1)) { SFS_AddString(&parser, "function "); SFS_Identifier(&parser); SFS_Arguments(&parser, 0); SFS_Space(&parser); SFS_StatementBlock(&parser, 1); SFS_Line(&parser); } SFS_Line(&parser); if (script_field->script_text) free(script_field->script_text); script_field->script_text = (unsigned char *) strdup(parser.string);exit: //clean up while (gf_list_count(parser.identifiers)) { ptr = (char *)gf_list_get(parser.identifiers, 0); free(ptr); gf_list_rem(parser.identifiers, 0); } gf_list_del(parser.identifiers); if (parser.string) free(parser.string); return e;}void SFS_Identifier(ScriptParser *parser){ u32 index; char name[500]; if (parser->codec->LastError) return; //recieved if (gf_bs_read_int(parser->bs, 1)) { index = gf_bs_read_int(parser->bs, gf_get_bit_size(gf_list_count(parser->identifiers) - 1)); SFS_AddString(parser, (char *)gf_list_get(parser->identifiers, index)); } //parse else{ gf_bifs_dec_name(parser->bs, name); gf_list_add(parser->identifiers, strdup(name)); SFS_AddString(parser, name); }}void SFS_Arguments(ScriptParser *parser, Bool is_var){ u32 val; if (parser->codec->LastError) return; if (!is_var) SFS_AddString(parser, "("); val = gf_bs_read_int(parser->bs, 1); while (val) { SFS_Identifier(parser); val = gf_bs_read_int(parser->bs, 1); if (val) SFS_AddString(parser, ","); } if (!is_var) SFS_AddString(parser, ")");}void SFS_StatementBlock(ScriptParser *parser, Bool funcBody){ if (parser->codec->LastError) return; if (gf_bs_read_int(parser->bs, 1)) { SFS_AddString(parser, "{"); SFS_IncIndent(parser); while (gf_bs_read_int(parser->bs, 1)) { SFS_Line(parser); SFS_Indent(parser); SFS_Statement(parser); } SFS_DecIndent(parser); SFS_Line(parser); SFS_Indent(parser); SFS_AddString(parser, "}"); } else if (funcBody) { SFS_AddString(parser, "{"); SFS_Statement(parser); SFS_AddString(parser, "}"); } else { SFS_Statement(parser); }}void SFS_Statement(ScriptParser *parser){ u32 val; if (parser->codec->LastError) return; val = gf_bs_read_int(parser->bs, NUMBITS_STATEMENT); switch (val) { case ST_IF: SFS_IfStatement(parser); break; case ST_FOR: SFS_ForStatement(parser); break; case ST_WHILE: SFS_WhileStatement(parser); break; case ST_RETURN: SFS_ReturnStatement(parser); break; case ST_BREAK: SFS_AddString(parser, "break;"); break; case ST_CONTINUE: SFS_AddString(parser, "continue;"); break; case ST_COMPOUND_EXPR: SFS_CompoundExpression(parser); SFS_AddString(parser, ";"); break; case ST_SWITCH: SFS_SwitchStatement(parser); break; }}void SFS_IfStatement(ScriptParser *parser){ if (parser->codec->LastError) return; SFS_AddString(parser, "if ("); SFS_CompoundExpression(parser); SFS_AddString(parser, ") "); SFS_StatementBlock(parser, 0); //has else if (gf_bs_read_int(parser->bs, 1)) { SFS_Line(parser); SFS_Indent(parser); SFS_AddString(parser, "else "); SFS_StatementBlock(parser, 0); }}void SFS_SwitchStatement(ScriptParser *parser){ u32 numBits, caseValue; if (parser->codec->LastError) return; SFS_AddString(parser, "switch ("); SFS_CompoundExpression(parser); SFS_AddString(parser, ")"); SFS_AddString(parser, "{"); SFS_Line(parser); numBits = gf_bs_read_int(parser->bs, 5); do { SFS_Indent(parser); SFS_AddString(parser, "case "); caseValue = gf_bs_read_int(parser->bs, numBits); SFS_AddInt(parser, caseValue); SFS_AddString(parser, ":"); SFS_Line(parser); SFS_Indent(parser); SFS_StatementBlock(parser, 0); SFS_Line(parser); } while (gf_bs_read_int(parser->bs, 1)); //default if (gf_bs_read_int(parser->bs, 1)) { SFS_AddString(parser, "default:"); SFS_Line(parser); SFS_StatementBlock(parser, 0); } SFS_AddString(parser, "}");}void SFS_ForStatement(ScriptParser *parser){ if (parser->codec->LastError) return; SFS_AddString(parser, "for ("); SFS_OptionalExpression(parser); SFS_AddString(parser, ";"); SFS_OptionalExpression(parser); SFS_AddString(parser, ";"); SFS_OptionalExpression(parser); SFS_AddString(parser, ")"); SFS_StatementBlock(parser, 0);}void SFS_WhileStatement(ScriptParser *parser){ if (parser->codec->LastError) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -