int JSON::parseArray(const tiny_string &jsonstring, int pos, ASObject** parent, const multiname& key, IFunction *reviver) { int len = jsonstring.numChars(); pos++; // ignore '[' ASObject* subobj = Class<Array>::getInstanceS(); if (*parent == NULL) *parent = subobj; else (*parent)->setVariableByMultiname(key,subobj,ASObject::CONST_NOT_ALLOWED); multiname name(NULL); name.name_type=multiname::NAME_INT; name.name_i = 0; name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute = false; bool done = false; bool needdata = false; while (!done && pos < len) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; char c = jsonstring.charAt(pos); switch(c) { case ']': done = true; pos++; break; case ',': name.name_i++; needdata = true; pos++; break; default: pos = parse(jsonstring,pos,&subobj,name, reviver); needdata = false; break; } } if (!done || needdata) throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseObject(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key, IFunction *reviver) { int len = jsonstring.numChars(); pos++; // ignore '{' or ',' ASObject* subobj = Class<ASObject>::getInstanceS(); if (*parent == NULL) *parent = subobj; else (*parent)->setVariableByMultiname(key,subobj,ASObject::CONST_NOT_ALLOWED); multiname name(NULL); name.name_type=multiname::NAME_STRING; name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute = false; bool done = false; bool bfirst = true; bool needkey = true; bool needvalue = false; while (!done && pos < len) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; char c = jsonstring.charAt(pos); switch(c) { case '}': if (!bfirst && (needkey || needvalue)) throwError<SyntaxError>(kJSONInvalidParseInput); done = true; pos++; break; case '\"': { tiny_string keyname; pos = parseString(jsonstring,pos,NULL,name,&keyname); name.name_s_id=getSys()->getUniqueStringId(keyname); needkey = false; needvalue = true; } break; case ',': if (needkey || needvalue) throwError<SyntaxError>(kJSONInvalidParseInput); pos++; name.name_s_id=0; needkey = true; break; case ':': pos++; pos = parse(jsonstring,pos,&subobj,name,reviver); needvalue = false; break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } bfirst=false; } if (!done) throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseString(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key, tiny_string* result) { pos++; // ignore starting quotes int len = jsonstring.numChars(); if (pos >= len) throwError<SyntaxError>(kJSONInvalidParseInput); tiny_string sub = jsonstring.substr(pos,len-pos); tiny_string res; bool done = false; for (CharIterator it=sub.begin(); it!=sub.end(); it++) { pos++; if (*it == '\"') { done = true; break; } else if(*it == '\\') { it++; pos++; if(it == sub.end()) break; if(*it == '\"') res += '\"'; else if(*it == '\\') res += '\\'; else if(*it == '/') res += '/'; else if(*it == 'b') res += '\b'; else if(*it == 'f') res += '\f'; else if(*it == 'n') res += '\n'; else if(*it == 'r') res += '\r'; else if(*it == 't') res += '\t'; else if(*it == 'u') { tiny_string strhex; for (int i = 0; i < 4; i++) { it++; pos++; if (it==sub.end()) throwError<SyntaxError>(kJSONInvalidParseInput); switch(*it) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': strhex += *it; break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } if (it==sub.end()) throwError<SyntaxError>(kJSONInvalidParseInput); } int64_t hexnum; if (Integer::fromStringFlashCompatible(strhex.raw_buf(),hexnum,16)) { if (hexnum < 0x20 && hexnum != 0xf) throwError<SyntaxError>(kJSONInvalidParseInput); res += tiny_string::fromChar(hexnum); } else break; } else throwError<SyntaxError>(kJSONInvalidParseInput); } else if (*it < 0x20) { throwError<SyntaxError>(kJSONInvalidParseInput); } else { res += *it; } } if (!done) throwError<SyntaxError>(kJSONInvalidParseInput); if (parent != NULL) { if (*parent == NULL) *parent = Class<ASString>::getInstanceS(res); else (*parent)->setVariableByMultiname(key,Class<ASString>::getInstanceS(res),ASObject::CONST_NOT_ALLOWED); } if (result) *result =res; return pos; }