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; }
void JSON::parseAll(const tiny_string &jsonstring, ASObject** parent , const multiname& key, IFunction *reviver) { int len = jsonstring.numBytes(); int pos = 0; while (pos < len) { if (*parent && (*parent)->isPrimitive()) throwError<SyntaxError>(kJSONInvalidParseInput); pos = parse(jsonstring, pos, parent , key, reviver); while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; } }
int JSON::parseNull(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key) { int len = jsonstring.numBytes(); if (len >= pos+4) { if (jsonstring.charAt(pos) == 'n' && jsonstring.charAt(pos + 1) == 'u' && jsonstring.charAt(pos + 2) == 'l' && jsonstring.charAt(pos + 3) == 'l') { pos += 4; if (*parent == NULL) *parent = getSys()->getNullRef(); else (*parent)->setVariableByMultiname(key,getSys()->getNullRef(),ASObject::CONST_NOT_ALLOWED); } else throwError<SyntaxError>(kJSONInvalidParseInput); } else throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseTrue(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key) { int len = jsonstring.numBytes(); if (len >= pos+4) { if (jsonstring.charAt(pos) == 't' && jsonstring.charAt(pos + 1) == 'r' && jsonstring.charAt(pos + 2) == 'u' && jsonstring.charAt(pos + 3) == 'e') { pos += 4; if (*parent == NULL) *parent = abstract_b(true); else (*parent)->setVariableByMultiname(key,abstract_b(true),ASObject::CONST_NOT_ALLOWED); } else throwError<SyntaxError>(kJSONInvalidParseInput); } else throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseNumber(const tiny_string &jsonstring, int pos, ASObject** parent, const multiname& key) { int len = jsonstring.numBytes(); tiny_string res; bool done = false; while (!done && pos < len) { char c = jsonstring.charAt(pos); switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': case '+': case '.': case 'E': case 'e': res += c; pos++; break; default: done = true; break; } } ASString* numstr = Class<ASString>::getInstanceS(res); number_t num = numstr->toNumber(); if (std::isnan(num)) throwError<SyntaxError>(kJSONInvalidParseInput); if (*parent == NULL) *parent = Class<Number>::getInstanceS(num); else { (*parent)->setVariableByMultiname(key,Class<Number>::getInstanceS(num),ASObject::CONST_NOT_ALLOWED); } 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::parse(const tiny_string &jsonstring, int pos, ASObject** parent , const multiname& key, IFunction *reviver) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; int len = jsonstring.numBytes(); if (pos < len) { char c = jsonstring.charAt(pos); switch(c) { case '{': pos = parseObject(jsonstring,pos,parent,key, reviver); break; case '[': pos = parseArray(jsonstring,pos,parent,key, reviver); break; case '"': pos = parseString(jsonstring,pos,parent,key); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': pos = parseNumber(jsonstring,pos,parent,key); break; case 't': pos = parseTrue(jsonstring,pos,parent,key); break; case 'f': pos = parseFalse(jsonstring,pos,parent,key); break; case 'n': pos = parseNull(jsonstring,pos,parent,key); break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } } if (reviver) { bool haskey = key.name_type!= multiname::NAME_OBJECT; ASObject* params[2]; if (haskey) { params[0] = Class<ASString>::getInstanceS(key.normalizedName()); if ((*parent)->hasPropertyByMultiname(key,true,false)) { params[1] = (*parent)->getVariableByMultiname(key).getPtr(); params[1]->incRef(); } else params[1] = getSys()->getNullRef(); } else { params[0] = Class<ASString>::getInstanceS(""); params[1] = *parent; params[1]->incRef(); } ASObject *funcret=reviver->call(getSys()->getNullRef(), params, 2); if(funcret) { if (haskey) { if (funcret->is<Undefined>()) { (*parent)->deleteVariableByMultiname(key); funcret->decRef(); } else { (*parent)->setVariableByMultiname(key,funcret,ASObject::CONST_NOT_ALLOWED); } } else *parent= funcret; } } return pos; }