/* static */ void VJSONGraph::Connect( VJSONGraph** inRetainerGraph, const VJSONValue& inRetainedValue) { if (inRetainedValue.IsObject()) Connect( inRetainerGraph, inRetainedValue.GetObject()->GetGraph()); else if (inRetainedValue.IsArray()) Connect( inRetainerGraph, inRetainedValue.GetArray()->GetGraph()); }
VError VJSONCloner::CloneObject( const VJSONObject *inObject, VJSONValue& outValue) { VError err = VE_OK; if (inObject == NULL) { outValue.SetUndefined(); } else { try { VJSONValue value; std::pair<MapOfValueByObject::iterator,bool> i = fClonedObjects.insert( MapOfValueByObject::value_type( inObject, value)); if (i.second) { // not already cloned err = inObject->Clone( i.first->second, *this); } outValue = i.first->second; } catch(...) { outValue.SetUndefined(); err = vThrowError( VE_MEMORY_FULL); } } return err; }
VError VJSONBinaryWriter::StreamValue(const VJSONValue& inValue, VMemoryBuffer<>& outBuff) { VError err = VE_OK; sBYTE btype = (sBYTE)inValue.GetType(); outBuff.AddData(&btype, 1); switch( inValue.GetType()) { case JSON_null: case JSON_undefined: case JSON_true: case JSON_false: { break; } case JSON_string: { const VInlineString* s = &(inValue.fString); sLONG len = (sLONG)s->GetLength(); outBuff.AddData(&len, 4); if (len > 0) outBuff.AddData(s->GetCPointer(), len * 2); break; } case JSON_date: { outBuff.AddData(&inValue.fTimeStamp, sizeof(sLONG8)); break; } case JSON_number: { outBuff.AddData(&inValue.fNumber, sizeof(Real)); break; } case JSON_array: { err = StreamArray( inValue.GetArray(), outBuff); break; } case JSON_object: { err = StreamObject( inValue.GetObject(), outBuff); break; } default: xbox_assert( false); } return err; }
VError VUUID::GetJSONValue( VJSONValue& outJSONValue) const { if (IsNull()) outJSONValue.SetNull(); else { VString s; GetString(s); outJSONValue.SetString( s); } return VE_OK; }
VError VUUID::FromJSONValue( const VJSONValue& inJSONValue) { if (inJSONValue.IsNull()) SetNull( true); else { VString s; inJSONValue.GetString( s); FromString( s); } return VE_OK; }
VJSONObject* VValueBag::BuildJSONObject(VError& outError) const { // will use stringify until redone in a more elegant way VJSONObject* result = nil; VString jsonstr; outError = GetJSONString(jsonstr); if (outError == VE_OK) { VJSONValue val; outError = val.ParseFromString(jsonstr); if (val.IsObject() && outError == VE_OK) result = RetainRefCountable(val.GetObject()); } return result; }
VError VJSONObject::Clone( VJSONValue& outValue, VJSONCloner& inCloner) const { VError err = VE_OK; EJSONStatus status = EJSON_unhandled; if (fImpl != NULL) { status = fImpl->IJSON_Clone( this, inCloner, outValue, &err); } if (status == EJSON_unhandled) { VJSONObject *clone = new VJSONObject(); if (clone != NULL) { err = CloneProperties( inCloner, clone); } else { err = VE_MEMORY_FULL; } outValue.SetObject( clone); ReleaseRef( &clone); } return err; }
bool VJSFunction::GetResultAsJSONValue( VJSONValue& outResult) const { if (fException != NULL) { outResult.SetUndefined(); return false; } return fResult.GetJSONValue( outResult, &fException); }
VJSONValue VJSONObject::GetProperty( const VString& inName) const { VJSONValue value; EJSONStatus status = EJSON_unhandled; if (fImpl != NULL) { status = fImpl->IJSON_GetProperty( this, inName, value); if (status == EJSON_error) value.SetUndefined(); } if (status == EJSON_unhandled) { MapType::const_iterator i = fMap.find( inName); if (i != fMap.end()) value = i->second.first; } return value; }
VError VJSONArray::Clone( VJSONValue& outValue, VJSONCloner& inCloner) const { VError err = VE_OK; VJSONArray *clone = new VJSONArray; if (clone != NULL) { VectorType clonedVector = fVector; for( VectorType::iterator i = clonedVector.begin() ; (i != clonedVector.end()) && (err == VE_OK) ; ++i) { if (i->IsObject()) { VJSONObject *theOriginalObject = RetainRefCountable( i->GetObject()); err = inCloner.CloneObject( theOriginalObject, *i); VJSONGraph::Connect( &clone->fGraph, *i); ReleaseRefCountable( &theOriginalObject); } else if (i->IsArray()) { VJSONArray *theOriginalArray = RetainRefCountable( i->GetArray()); err = theOriginalArray->Clone( *i, inCloner); VJSONGraph::Connect( &clone->fGraph, *i); ReleaseRefCountable( &theOriginalArray); } } if (err == VE_OK) clone->fVector.swap( clonedVector); } else { err = VE_MEMORY_FULL; } outValue.SetArray( clone); ReleaseRefCountable( &clone); return err; }
bool VJSONObject::SetProperty( const VString& inName, const VJSONValue& inValue) { bool ok = true; try { if (inValue.IsUndefined()) fMap.erase( inName); else { std::pair<MapType::iterator,bool> i = fMap.insert( MapType::value_type( inName, inValue)); if (!i.second) i.first->second = inValue; VJSONGraph::Connect( &fGraph, inValue); } } catch(...) { ok = false; } return ok; }
VError VJSONObject::Clone( VJSONValue& outValue, VJSONCloner& inCloner) const { VError err = VE_OK; VJSONObject *clone = new VJSONObject; if (clone != NULL) { MapType clonedMap = fMap; for( MapType::iterator i = clonedMap.begin() ; (i != clonedMap.end()) && (err == VE_OK) ; ++i) { if (i->second.IsObject()) { VJSONObject *theOriginalObject = RetainRefCountable( i->second.GetObject()); err = inCloner.CloneObject( theOriginalObject, i->second); VJSONGraph::Connect( &clone->fGraph, i->second); ReleaseRefCountable( &theOriginalObject); } else if (i->second.IsArray()) { VJSONArray *theOriginalArray = RetainRefCountable( i->second.GetArray()); err = theOriginalArray->Clone( i->second, inCloner); VJSONGraph::Connect( &clone->fGraph, i->second); ReleaseRefCountable( &theOriginalArray); } } if (err == VE_OK) clone->fMap.swap( clonedMap); } else { err = VE_MEMORY_FULL; } outValue.SetObject( clone); ReleaseRefCountable( &clone); return err; }
bool VJSONObject::SetProperty( const VString& inName, const VJSONValue& inValue) { bool ok; EJSONStatus status = EJSON_unhandled; if (fImpl != NULL) { status = fImpl->IJSON_SetProperty( this, inName, inValue); ok = (status == EJSON_ok); } if (status == EJSON_unhandled) { try { ok = true; if (inValue.IsUndefined()) fMap.erase( inName); else { std::pair<MapType::iterator,bool> i = fMap.insert( MapType::value_type( inName, std::pair<VJSONValue,size_t>(inValue,fMap.size()))); if (!i.second) { i.first->second.first = inValue; } VJSONGraph::Connect( &fGraph, inValue); } } catch(...) { ok = false; } } return ok; }
VError VValue::GetJSONValue(VJSONValue& outJSONValue, bool /*allowDates*/) const { outJSONValue.SetUndefined(); return vThrowError( VE_UNIMPLEMENTED); }
void VJSONValue::test() { const char *sTestJson = "{\"good\":true,\"name\":\"smith\",\"paul\":{\"good\":false,\"name\":\"paul\",\"Nul\":null,\"age\":10.321,\"text\":\"\"\\/\b\f\n\r\t\"},\"age\":42}"; VJSONValue object( JSON_object); object.SetProperty( CVSTR( "name"), VJSONValue( CVSTR( "smith"))); object.SetProperty( CVSTR( "age"), VJSONValue( 42)); object.SetProperty( CVSTR( "good"), VJSONValue::sTrue); for( VJSONPropertyIterator i( object.GetObject()) ; i.IsValid() ; ++i) { VString propertyName = i.GetName(); VJSONValue propertyValue = i.GetValue(); } VJSONValue object_child( JSON_object); object_child.SetProperty( CVSTR( "name"), VJSONValue( CVSTR( "paul"))); object_child.SetProperty( CVSTR( "age"), VJSONValue( 10.321)); object_child.SetProperty( CVSTR( "good"), VJSONValue::sFalse); object_child.SetProperty( CVSTR( "text"), VJSONValue( CVSTR( "\"\\/\b\f\n\r\t"))); object_child.SetProperty( CVSTR( "Nul"), VJSONValue::sNull); object_child.SetProperty( CVSTR( "undef"), VJSONValue::sUndefined); VJSONArray *object_children = new VJSONArray; object_children->Push( object_child); object.SetProperty( CVSTR( "children"), VJSONValue( object_children)); ReleaseRefCountable( &object_children); VString s; VJSONWriter writer( JSON_WithQuotesIfNecessary); VError err = writer.StringifyValue( object, s); DebugMsg( s); DebugMsg( "\n"); VJSONWriter writer2( JSON_WithQuotesIfNecessary | JSON_PrettyFormatting); err = writer2.StringifyValue( object, s); DebugMsg( s); DebugMsg( "\n"); VJSONValue value; VJSONImporter importer(s); err = importer.Parse( value); VString s2; writer2.StringifyValue( value, s2); DebugMsg( s2); DebugMsg( "\n"); xbox_assert( s == s2); { VJSONImporter importer2( CVSTR( "[1,2,3,[4,5],6]")); err = importer2.Parse( value); value.GetString( s2); DebugMsg( s2); DebugMsg( "\n"); } }
VError VJSONWriter::StringifyValue( const VJSONValue& inValue, VString& outString) { VError err = VE_OK; switch( inValue.GetType()) { case JSON_undefined: { outString = VJSONValue::sUndefinedString; break; } case JSON_null: { outString = VJSONValue::sNullString; break; } case JSON_true: { outString = VJSONValue::sTrueString; break; } case JSON_false: { outString = VJSONValue::sFalseString; break; } case JSON_string: { VString s; err = inValue.GetString( s); s.GetJSONString( outString, GetOptions()); break; } case JSON_date: { VTime dd; VString s; inValue.GetTime(dd); dd.GetJSONString(s); if ((GetOptions() & JSON_AllowDates) != 0) { outString = "\"!!" + s + "!!\""; } else outString = "\"" + s + "\""; break; } case JSON_number: { VReal r( inValue.GetNumber()); err = r.GetJSONString( outString, GetOptions()); break; } case JSON_array: { err = StringifyArray( inValue.GetArray(), outString); break; } case JSON_object: { err = StringifyObject( inValue.GetObject(), outString); break; } default: xbox_assert( false); } return err; }
VError VJSONWriter::StringifyValue( const VJSONValue& inValue, VString& outString) { VError err = VE_OK; switch( inValue.GetType()) { case JSON_undefined: { outString = VJSONValue::sUndefinedString; break; } case JSON_null: { outString = VJSONValue::sNullString; break; } case JSON_true: { outString = VJSONValue::sTrueString; break; } case JSON_false: { outString = VJSONValue::sFalseString; break; } case JSON_string: { VString s; err = inValue.GetString( s); s.GetJSONString( outString, GetOptions()); break; } case JSON_number: { VReal r( inValue.GetNumber()); err = r.GetJSONString( outString, GetOptions()); break; } case JSON_array: { err = StringifyArray( inValue.GetArray(), outString); break; } case JSON_object: { err = StringifyObject( inValue.GetObject(), outString); break; } default: xbox_assert( false); } return err; }
VError VJSONBinaryImporter::GetValue(VJSONValue& outVal) { VError err = VE_OK; sBYTE btype = *((uBYTE*)fCurPtr); ++fCurPtr; switch (btype) { case JSON_null: outVal.SetNull(); break; case JSON_undefined: outVal.SetUndefined(); break; case JSON_true: outVal.SetBool(true); break; case JSON_false: outVal.SetBool(false); break; case JSON_string: { VString s; sLONG len = *((sLONG*)fCurPtr); fCurPtr += 4; s.FromBlock(fCurPtr, len * 2, VTC_UTF_16); fCurPtr += (len * 2); outVal.SetString(s); } break; case JSON_date: { VTime dd; sLONG8 ll = *((sLONG8*)fCurPtr); fCurPtr += 8; dd.FromMilliseconds(ll); outVal.SetTime(dd); } break; case JSON_number: { Real rr = *((Real*)fCurPtr); fCurPtr += sizeof(Real); outVal.SetNumber(rr); } break; case JSON_object: { if (*((sWORD*)fCurPtr) == -2) { outVal.SetUndefined(); } else { VJSONObject* obj = new VJSONObject(); sWORD len; do { len = *((sWORD*)fCurPtr); fCurPtr += 2; if (len >= 0) { VString name; name.FromBlock(fCurPtr, (sLONG)len * 2, VTC_UTF_16); fCurPtr += ((sLONG)len * 2); VJSONValue val; err = GetValue(val); obj->SetProperty(name, val); } } while (err == VE_OK && len != -1); outVal.SetObject(obj); QuickReleaseRefCountable(obj); } } break; case JSON_array: { sLONG count = *((sLONG*)fCurPtr); fCurPtr += 4; if (count == -2) { outVal.SetUndefined(); } else { VJSONArray* arr = new VJSONArray(); for (sLONG i = 0; i < count && err == VE_OK; ++i) { VJSONValue val; err = GetValue(val); arr->Push(val); } outVal.SetArray(arr); QuickReleaseRefCountable(arr); } } break; default: xbox_assert(false); break; } return err; }