result_t ParseJsonObject(v8::Local<v8::Value> &retVal) { v8::Local<v8::Object> json_object = v8::Object::New(isolate->m_isolate); result_t hr; AdvanceSkipWhitespace(); if (c0_ != '}') { do { if (c0_ != '"') return ReportUnexpectedCharacter(); v8::Local<v8::Value> key; v8::Local<v8::Value> value; hr = ParseJsonString(key); if (hr < 0) return hr; if (c0_ != ':') return ReportUnexpectedCharacter(); AdvanceSkipWhitespace(); hr = ParseJsonValue(value); if (hr < 0) return hr; json_object->Set(key, value); } while (MatchSkipWhiteSpace(',')); if (c0_ != '}') return ReportUnexpectedCharacter(); } AdvanceSkipWhitespace(); v8::Local<v8::Value> type = json_object->Get(isolate->NewFromUtf8("type")); v8::Local<v8::Value> data = json_object->Get(isolate->NewFromUtf8("data")); if (!type.IsEmpty() && !data.IsEmpty()) { v8::String::Utf8Value str(type); if (*str) { int32_t i; for (i = 0; s_from[i].name; i++) if (!qstrcmp(*str, s_from[i].name)) { s_from[i].from(isolate, data, json_object); break; } } } retVal = json_object; return 0; }
result_t ParseJsonValue(v8::Local<v8::Value> &retVal) { if (c0_ == '"') return ParseJsonString(retVal); if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(retVal); if (c0_ == '{') return ParseJsonObject(retVal); if (c0_ == '[') return ParseJsonArray(retVal); if (c0_ == 'f') { if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { AdvanceSkipWhitespace(); retVal = v8::False(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } if (c0_ == 't') { if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && AdvanceGetChar() == 'e') { AdvanceSkipWhitespace(); retVal = v8::True(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } if (c0_ == 'n') { if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && AdvanceGetChar() == 'l') { AdvanceSkipWhitespace(); retVal = v8::Null(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } return ReportUnexpectedCharacter(); }
result_t ParseJsonArray(v8::Local<v8::Value> &retVal) { v8::Local<v8::Array> elements = v8::Array::New(isolate->m_isolate); int32_t cnt = 0; result_t hr; AdvanceSkipWhitespace(); if (c0_ != ']') { do { v8::Local<v8::Value> element; hr = ParseJsonValue(element); if (hr < 0) return hr; elements->Set(cnt ++, element); } while (MatchSkipWhiteSpace(',')); if (c0_ != ']') return ReportUnexpectedCharacter(); } AdvanceSkipWhitespace(); retVal = elements; return 0; }
result_t ParseJsonObject(v8::Local<v8::Value> &retVal) { v8::Local<v8::Object> json_object = v8::Object::New(isolate->m_isolate); result_t hr; AdvanceSkipWhitespace(); if (c0_ != '}') { do { if (c0_ != '"') return ReportUnexpectedCharacter(); v8::Local<v8::Value> key; v8::Local<v8::Value> value; hr = ParseJsonString(key); if (hr < 0) return hr; if (c0_ != ':') return ReportUnexpectedCharacter(); AdvanceSkipWhitespace(); hr = ParseJsonValue(value); if (hr < 0) return hr; json_object->Set(key, value); } while (MatchSkipWhiteSpace(',')); if (c0_ != '}') return ReportUnexpectedCharacter(); } AdvanceSkipWhitespace(); retVal = json_object; return 0; }
result_t ParseJsonString(v8::Local<v8::Value> &retVal) { wstring str; Advance(); while (c0_ != '"') { if (c0_ >= 0 && c0_ < 0x20) return ReportUnexpectedCharacter(); if (c0_ != '\\') { int32_t beg_pos = position_; while (c0_ != '"' && c0_ != '\\') { Advance(); if (c0_ >= 0 && c0_ < 0x20) return ReportUnexpectedCharacter(); } str.append(utf8to16String(source_ + beg_pos, position_ - beg_pos)); } else { Advance(); switch (c0_) { case '"': case '\\': case '/': str.append(1, c0_); break; case 'b': str.append(1, '\x08'); break; case 'f': str.append(1, '\x0c'); break; case 'n': str.append(1, '\x0a'); break; case 'r': str.append(1, '\x0d'); break; case 't': str.append(1, '\x09'); break; case 'u': { uint16_t value = 0; for (int32_t i = 0; i < 4; i++) { Advance(); if (!qisxdigit(c0_)) return ReportUnexpectedCharacter(); value = value * 16 + qhex(c0_); } str.append(1, value); break; } default: return ReportUnexpectedCharacter(); } Advance(); } } AdvanceSkipWhitespace(); retVal = v8::String::NewFromTwoByte(isolate->m_isolate, (const uint16_t*)str.c_str(), v8::String::kNormalString, (int32_t) str.length()); return 0; }
result_t ParseJsonNumber(v8::Local<v8::Value> &retVal) { bool negative = false; int32_t beg_pos = position_; if (c0_ == '-') { Advance(); negative = true; } if (c0_ == '0') { Advance(); if (IsDecimalDigit(c0_)) return ReportUnexpectedCharacter(); } else { int32_t i = 0; int32_t digits = 0; if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter(); do { i = i * 10 + c0_ - '0'; digits++; Advance(); } while (IsDecimalDigit(c0_)); if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { SkipWhitespace(); retVal = v8::Int32::New(isolate->m_isolate, negative ? -i : i); return 0; } } if (c0_ == '.') { Advance(); if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter(); do { Advance(); } while (IsDecimalDigit(c0_)); } if (AsciiAlphaToLower(c0_) == 'e') { Advance(); if (c0_ == '-' || c0_ == '+') Advance(); if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter(); do { Advance(); } while (IsDecimalDigit(c0_)); } int32_t length = position_ - beg_pos; double number; std::string chars(source_ + beg_pos, length); number = atof(chars.c_str()); SkipWhitespace(); retVal = v8::Number::New(isolate->m_isolate, number); return 0; }