📄 script_enc.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. * *//* script encoder is IM1 version*/#include "script.h"#include <gpac/internal/scenegraph_dev.h>typedef struct { GF_Node *script; GF_BifsEncoder *codec; GF_BitStream *bs; GF_List *identifiers; GF_Err err; char *cur_buf; char token[500]; u32 token_code; u32 cur_line; Bool emul; char expr_toks[500]; u32 expr_toks_len; GF_List *id_buf;} ScriptEnc;#define SFE_WRITE_INT(sc_enc, val, nbBits, str1, str2) \ if (!sc_enc->emul) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, str1, str2); \static GF_Err EncScriptFields(ScriptEnc *sc_enc){ u32 nbFields, nbBits, eType, nbBitsProto, i; Bool use_list; GF_Err e; GF_FieldInfo info; nbFields = gf_node_get_num_fields_in_mode(sc_enc->script, GF_SG_FIELD_CODING_ALL) - 3; use_list = 1; nbBits = gf_get_bit_size(nbFields); if (nbFields+1 > 4 + gf_get_bit_size(nbFields)) use_list = 0; if (!nbFields) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "Script::isList", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL); return GF_OK; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, use_list ? 1 : 0, 1, "Script::isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 4, "nbBits", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbFields, nbBits, "count", NULL); } nbBitsProto = 0; if (sc_enc->codec->encoding_proto) nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(sc_enc->codec->encoding_proto) - 1); for (i=0; i<nbFields; i++) { if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "end", NULL); gf_node_get_field(sc_enc->script, i+3, &info); switch (info.eventType) { case GF_SG_EVENT_IN: eType = GF_SG_SCRIPT_TYPE_EVENT_IN; break; case GF_SG_EVENT_OUT: eType = GF_SG_SCRIPT_TYPE_EVENT_OUT; break; default: eType = GF_SG_SCRIPT_TYPE_FIELD; break; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, eType, 2, "eventType", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, info.fieldType, 6, "fieldType", NULL); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, (char *) info.name); /*this is an identifier for script*/ gf_list_add(sc_enc->identifiers, strdup(info.name)); if (sc_enc->codec->encoding_proto) { GF_Route *isedField = gf_bifs_enc_is_field_ised(sc_enc->codec, sc_enc->script, i+3); if (isedField) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "isedField", NULL); if (isedField->ToNode == sc_enc->script) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "isedField", NULL); } /*default value*/ if (eType == GF_SG_SCRIPT_TYPE_FIELD) { GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, (info.far_ptr) ? 1 : 0, 1, "hasInitialValue", NULL); if (info.far_ptr) { e = gf_bifs_enc_field(sc_enc->codec, sc_enc->bs, sc_enc->script, &info); if (e) return e; } } } if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL); return GF_OK;}enum { TOK_FUNCTION, TOK_IF, TOK_ELSE, TOK_FOR, TOK_WHILE, TOK_RETURN, TOK_BREAK, TOK_CONTINUE, TOK_NEW, TOK_SWITCH, TOK_CASE, TOK_DEFAULT, TOK_VAR, NUMBER_OF_KEYWORD, TOK_LEFT_BRACE = NUMBER_OF_KEYWORD, TOK_RIGHT_BRACE, TOK_LEFT_CURVE, TOK_RIGHT_CURVE, TOK_LEFT_BRACKET, TOK_RIGHT_BRACKET, TOK_PERIOD, TOK_NOT, TOK_ONESCOMP, TOK_NEGATIVE, TOK_INCREMENT, TOK_DECREMENT, TOK_MULTIPLY, TOK_DIVIDE, TOK_MOD, TOK_PLUS, TOK_MINUS, TOK_LSHIFT, TOK_RSHIFT, TOK_RSHIFTFILL, TOK_LT, TOK_LE, TOK_GT, TOK_GE, TOK_EQ, TOK_NE, TOK_AND, TOK_XOR, TOK_OR, TOK_LAND, TOK_LOR, TOK_CONDTEST, TOK_ASSIGN, TOK_PLUSEQ, TOK_MINUSEQ, TOK_MULTIPLYEQ, TOK_DIVIDEEQ, TOK_MODEQ, TOK_LSHIFTEQ, TOK_RSHIFTEQ, TOK_RSHIFTFILLEQ, TOK_ANDEQ, TOK_XOREQ, TOK_OREQ, TOK_COMMA, TOK_SEMICOLON, TOK_CONDSEP, TOK_IDENTIFIER, TOK_STRING, TOK_NUMBER, TOK_EOF, TOK_BOOLEAN };const char *tok_names[] ={ "function", "if", "else", "for", "while", "return", "break", "continue", "new", "switch", "case", "default", "var", "{", "}", "(", ")", "[", "]", ".", "!", "~", "-", "++", "--", "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||", "?", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", ",", ";", ":", "identifier", "string", "number", "boolean", "end of script"};const char* sc_keywords [] ={ "function", "if", "else", "for", "while", "return", "break", "continue", "new", "switch", "case", "default", "var"};Bool SFE_GetNumber(ScriptEnc *sc_enc){ u32 i = 0; Bool exp = 0; while ( isdigit(sc_enc->cur_buf[i]) || (toupper(sc_enc->cur_buf[i])=='X') || ((toupper(sc_enc->cur_buf[i]) >='A') && (toupper(sc_enc->cur_buf[i])<='F')) || (sc_enc->cur_buf[i]=='.') || (tolower(sc_enc->cur_buf[i])=='e') || (exp && (sc_enc->cur_buf[i] == '-')) ) { sc_enc->token[i] = sc_enc->cur_buf[i]; if (tolower(sc_enc->cur_buf[i])=='e') exp = 1; i++; if (!sc_enc->cur_buf[i]) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Invalid number syntax (%s)\n", sc_enc->cur_buf)); sc_enc->err = GF_BAD_PARAM; return 0; } } sc_enc->token[i] = 0; sc_enc->cur_buf += i; sc_enc->token_code = TOK_NUMBER; return 1;}Bool SFE_NextToken(ScriptEnc *sc_enc){ u32 i; if (sc_enc->err) return 0; while (strchr(" \t\r\n", sc_enc->cur_buf[0])) { if (sc_enc->cur_buf[0]=='\n') sc_enc->cur_line ++; sc_enc->cur_buf++; } if ((sc_enc->cur_buf[0] == '/') && (sc_enc->cur_buf[1] == '*')) { sc_enc->cur_buf += 2; while ((sc_enc->cur_buf[0] != '*') || (sc_enc->cur_buf[1] != '/')) { sc_enc->cur_buf++; if (!sc_enc->cur_buf[0] || !sc_enc->cur_buf[1]) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: cannot find closing comment */\n")); sc_enc->err = GF_BAD_PARAM; return 0; } } sc_enc->cur_buf+=2; return SFE_NextToken(sc_enc); } i = 0; /*get a name*/ if (isalpha(sc_enc->cur_buf[i]) || (sc_enc->cur_buf[i]=='_')) { while (isalnum(sc_enc->cur_buf[i]) || (sc_enc->cur_buf[i]=='_')) { sc_enc->token[i] = sc_enc->cur_buf[i]; i++; } sc_enc->token[i] = 0; sc_enc->cur_buf += i; sc_enc->token_code = TOK_IDENTIFIER; /*check keyword*/ for (i=0; i<NUMBER_OF_KEYWORD; i++) { if (!strcmp(sc_enc->token, sc_keywords[i])) { sc_enc->token_code = i; return 1; } } if (!stricmp(sc_enc->token, "TRUE") || !stricmp(sc_enc->token, "FALSE") ) { sc_enc->token_code = TOK_BOOLEAN; } return 1; } /*get a number*/ if (isdigit(sc_enc->cur_buf[i])) return SFE_GetNumber(sc_enc); /*get a string*/ if ((sc_enc->cur_buf[i]=='\'') || (sc_enc->cur_buf[i]=='\"') || ((sc_enc->cur_buf[i]=='\\') && (sc_enc->cur_buf[i+1]=='\"')) ) { char end; Bool skip_last = 0; end = sc_enc->cur_buf[i]; if (sc_enc->cur_buf[i]=='\\') { skip_last = 1; sc_enc->cur_buf++; } while (sc_enc->cur_buf[i+1] != end) { sc_enc->token[i] = sc_enc->cur_buf[i+1]; i++; } sc_enc->token[i] = 0; sc_enc->cur_buf += i+2; if (skip_last) sc_enc->cur_buf++; sc_enc->token_code = TOK_STRING; return 1; } /*all other codes*/ switch (sc_enc->cur_buf[i]) { case '.': if (isdigit(sc_enc->cur_buf[i+1])) { SFE_GetNumber(sc_enc); return 1; } else { sc_enc->token_code = TOK_PERIOD; } break; case '!': if (sc_enc->cur_buf[i+1] == '=') { sc_enc->token_code = TOK_NE; sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_NOT; } break; case '=': if (sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_EQ; sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_ASSIGN; } break; case '+': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_PLUSEQ; sc_enc->cur_buf ++; } else if(sc_enc->cur_buf[i+1]=='+') { sc_enc->token_code = TOK_INCREMENT; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_PLUS; } break; case '-': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_MINUSEQ; sc_enc->cur_buf++; } else if(sc_enc->cur_buf[i+1] == '-') { sc_enc->token_code = TOK_DECREMENT; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_MINUS; } break; case '*': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_MULTIPLYEQ; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_MULTIPLY; } break; case '/': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_DIVIDEEQ; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_DIVIDE; } break; case '%': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_MODEQ; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_MOD; } break; case '&': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_ANDEQ; sc_enc->cur_buf++; } else if(sc_enc->cur_buf[i+1]=='&') { sc_enc->token_code = TOK_LAND; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_AND; } break; case '|': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_OREQ; sc_enc->cur_buf++; } else if(sc_enc->cur_buf[i+1]=='|') { sc_enc->token_code = TOK_LOR; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_OR; } break; case '^': if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_XOREQ; sc_enc->cur_buf++; } else { sc_enc->token_code = TOK_XOR; } break; case '<': if (sc_enc->cur_buf[i+1]=='<') { if(sc_enc->cur_buf[i+2]=='=') { sc_enc->token_code = TOK_LSHIFTEQ; sc_enc->cur_buf += 1; } else { sc_enc->token_code = TOK_LSHIFT; } sc_enc->cur_buf += 1; } else if(sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_LE; sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_LT; } break; case '>': if (sc_enc->cur_buf[i+1]=='>') { if (sc_enc->cur_buf[i+2]=='=') { sc_enc->token_code = TOK_RSHIFTEQ; sc_enc->cur_buf ++; } else if(sc_enc->cur_buf[i+2]=='>') { if(sc_enc->cur_buf[i+3]=='=') { sc_enc->token_code = TOK_RSHIFTFILLEQ; sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_RSHIFTFILL; } sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_RSHIFT; } sc_enc->cur_buf ++; } else if (sc_enc->cur_buf[i+1]=='=') { sc_enc->token_code = TOK_GE; sc_enc->cur_buf ++; } else { sc_enc->token_code = TOK_GT; } break; case '?': sc_enc->token_code = TOK_CONDTEST; break; case ':': sc_enc->token_code = TOK_CONDSEP; break; case '~': sc_enc->token_code = TOK_ONESCOMP; break; case ',': sc_enc->token_code = TOK_COMMA; break; case ';': sc_enc->token_code = TOK_SEMICOLON; break; case '{': sc_enc->token_code = TOK_LEFT_BRACE; break; case '}': sc_enc->token_code = TOK_RIGHT_BRACE; break; case '(': sc_enc->token_code = TOK_LEFT_CURVE; break; case ')': sc_enc->token_code = TOK_RIGHT_CURVE; break; case '[': sc_enc->token_code = TOK_LEFT_BRACKET; break; case ']': sc_enc->token_code = TOK_RIGHT_BRACKET; break; default: GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Unrecognized symbol %c\n", sc_enc->cur_buf[i])); sc_enc->err = GF_BAD_PARAM; return 0; } sc_enc->cur_buf ++; return 1;}Bool SFE_CheckToken(ScriptEnc *sc_enc, u32 token){ if (sc_enc->token_code != token) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Bad token (expecting \"%s\" got \"%s\")\n", tok_names[token] , tok_names[sc_enc->token_code])); return 0; } return 1;}void SFE_PutIdentifier(ScriptEnc *sc_enc, char *id) { u32 i; u32 nbBits, length; char *str; if (sc_enc->emul) return; i=0; while ((str = (char *)gf_list_enum(sc_enc->identifiers, &i))) { if (strcmp(str, id)) continue; nbBits = 0; length = gf_list_count(sc_enc->identifiers) - 1; while (length > 0) { length >>= 1; nbBits ++; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "recieved", str); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, i-1, nbBits, "identifierCode", str); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -