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; }
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; }
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; }