internal TinyJsonObject CreateObjectFromJsonHandle(JsonKeyHandle jsonKeyHandle) { TinyJsonObject value = new TinyJsonObject { m_Data = this, Type = JsonKeyType(jsonKeyHandle) }; switch (JsonKeyType(jsonKeyHandle)) { case JsonValueType.Bool: value.m_BoolVal = m_BoolBuffer[LocationInValueBuffer(jsonKeyHandle)]; break; case JsonValueType.Int: value.m_IntVal = m_IntBuffer[LocationInValueBuffer(jsonKeyHandle)]; break; case JsonValueType.Float: value.m_FloatVal = m_FloatBuffer[LocationInValueBuffer(jsonKeyHandle)]; break; case JsonValueType.String: value.m_StringRefHandle = jsonKeyHandle; break; case JsonValueType.Array: value.m_ArrayRefHandle = jsonKeyHandle; break; case JsonValueType.Object: value.m_Data.m_RootObjMap = m_ObjectBuffer[LocationInValueBuffer(jsonKeyHandle)]; break; } return(value); }
/** * When a value is deleted, calling RemoveAtSwapBack() on the value buffer * for the corresponding type invalidates the location index stored in * the JsonValueRef pointing to the previous end of the buffer * * Search for the latter JsonValueRef, and override its location field * with the location contained in the ref pointed to by the handle we are about to free. */ void UpdateStaleReference(JsonKeyHandle refHandleToFree, int indexReferencedByStaleRef) { var refBuffer = m_JsonKeyBuffer; // "delete" old reference m_ValueRefFreeList.Add(refHandleToFree.handle); ((JsonKey *)refBuffer.GetUnsafePtr() + refHandleToFree.handle)->IsFreed = true; // no swapping is needed because no value became stale: if we are deleting the last reference in the buffer // or the element at the end of the buffer if (LocationInValueBuffer(refHandleToFree) == indexReferencedByStaleRef || refBuffer.Length < 2) { return; } // find the stale reference and update its location to be the same as the deleted handle // (since the json type was moved to the deleted handle's location) for (int i = 0; i < refBuffer.Length; i++) { if (!refBuffer[i].IsFreed && refBuffer[i].HasTypeAndLocation(JsonKeyType(refHandleToFree), indexReferencedByStaleRef)) { ((JsonKey *)refBuffer.GetUnsafePtr() + i)->Location = LocationInValueBuffer(refHandleToFree); return; } } JsonValueReferenceNotFoundException(); }
internal void AddOrUpdateString(FixedString128 key, TinyJsonObject value) { JsonKeyHandle jsonRefHandle; if (m_RootObjMap.ContainsKey(key)) { jsonRefHandle = m_RootObjMap[key]; if (JsonKeyType(jsonRefHandle) == JsonValueType.String) { UpdateStringBufferFromObjectBasedOnVariant(value, jsonRefHandle); return; } // remove the old type completely and add a new one as normal RemoveValueFromBuffer(jsonRefHandle); } jsonRefHandle = new JsonKeyHandle(ref this, JsonValueType.String, m_StringBuffer.Length); if (!value.m_StringVal.IsEmpty) { m_StringBuffer.Add(value.m_StringVal[0]); value.m_StringVal.Dispose(); } else { m_StringBuffer.Add(value.m_Data.m_StringBuffer[value.m_Data.LocationInValueBuffer(value.m_StringRefHandle)]); } value.m_StringVal.Dispose(); m_RootObjMap[key] = jsonRefHandle; }
TinyJsonObject(TinyJsonArray array) { this = default; Type = JsonValueType.Array; m_Data = array.m_Data; m_ArrayRefHandle = array.m_ArrayRefHandle; }
/** * Retrieves and converts the deserialized value into its serialized json representation. */ void SerializeValueView(JsonKeyHandle info, ref HeapString buffer) { switch (JsonKeyType(info)) { case JsonValueType.Bool: buffer.Append(m_BoolBuffer.ElementAt(LocationInValueBuffer(info)) ? (FixedString32)"true" : (FixedString32)"false"); break; case JsonValueType.Int: buffer.Append(m_IntBuffer.ElementAt(LocationInValueBuffer(info))); break; case JsonValueType.Float: buffer.Append(m_FloatBuffer.ElementAt(LocationInValueBuffer(info))); break; case JsonValueType.String: buffer.Append((FixedString32)"\""); buffer.Append(m_StringBuffer.ElementAt(LocationInValueBuffer(info))); buffer.Append((FixedString32)"\""); break; case JsonValueType.Array: SerializeArray(m_ArrayBuffer.ElementAt(LocationInValueBuffer(info)), ref buffer); break; case JsonValueType.Object: SerializeObject(ref m_ObjectBuffer.ElementAt(LocationInValueBuffer(info)), ref buffer); break; default: InvalidJsonTypeException(); break; } }
/** * Determine which primitive type the SerializedPrimitiveView is * and add the fully deserialized primitive to the correct buffer. */ JsonKeyHandle DeserializeToPrimitiveBuffer(SerializedPrimitiveView primView) { JsonKeyHandle jsonRefHandle; if (primView.IsBoolean()) { jsonRefHandle = new JsonKeyHandle(ref this, JsonValueType.Bool, m_BoolBuffer.Length); m_BoolBuffer.Add(primView.AsBoolean()); } else if (primView.IsDecimal()) { jsonRefHandle = new JsonKeyHandle(ref this, JsonValueType.Float, m_FloatBuffer.Length); m_FloatBuffer.Add(primView.AsFloat()); } else if (primView.IsIntegral()) { jsonRefHandle = new JsonKeyHandle(ref this, JsonValueType.Int, m_IntBuffer.Length); m_IntBuffer.Add((int)primView.AsInt64()); } else { throw new ArgumentOutOfRangeException("Primitive type not supported"); // todo move to func } return(jsonRefHandle); }
internal JsonKeyHandle CreateNestedArray(out TinyJsonArray array) { var jsonHandle = new JsonKeyHandle(ref this, JsonValueType.Array, m_ArrayBuffer.Length); var arrayValue = new UnsafeList <JsonKeyHandle>(10, m_Allocator); m_ArrayBuffer.Add(arrayValue); array = CreateObjectFromJsonHandle(jsonHandle); return(jsonHandle); }
// A tiny json object of type string can either: // have its data uninitialized, but stringVal initialized with the string // or have its data initialized, and its stringVal is empty but its stringValueRef is initialized to its // location within the data buffer of the object void UpdateStringBufferFromObjectBasedOnVariant(TinyJsonObject value, JsonKeyHandle jsonRefHandle) { if (!value.m_StringVal.IsEmpty) { m_StringBuffer[LocationInValueBuffer(jsonRefHandle)] = value.m_StringVal[0]; value.m_StringVal.Dispose(); } else { m_StringBuffer[LocationInValueBuffer(jsonRefHandle)] = value.m_Data.m_StringBuffer[value.m_Data.LocationInValueBuffer(value.m_StringRefHandle)]; } }
internal JsonKeyHandle CreateNestedObject(out TinyJsonObject value) { var handle = new JsonKeyHandle(ref this, JsonValueType.Object, m_ObjectBuffer.Length); var objMap = new UnsafeHashMap <FixedString128, JsonKeyHandle>(10, m_Allocator); m_ObjectBuffer.Add(objMap); value = new TinyJsonObject { m_Data = this, Type = JsonValueType.Object }; value.m_Data.m_RootObjMap = objMap; return(handle); }
internal void AddOrUpdateInt(FixedString128 key, TinyJsonObject value) { JsonKeyHandle jsonRefHandle; if (m_RootObjMap.ContainsKey(key)) { jsonRefHandle = m_RootObjMap[key]; if (JsonKeyType(jsonRefHandle) == JsonValueType.Int) { // simple value swap if its the same type m_IntBuffer[LocationInValueBuffer(jsonRefHandle)] = value.AsInt(); return; } // remove the old type completely and add a new one as normal RemoveValueFromBuffer(jsonRefHandle); } jsonRefHandle = new JsonKeyHandle(ref this, JsonValueType.Int, m_IntBuffer.Length); m_IntBuffer.Add(value.AsInt()); m_RootObjMap[key] = jsonRefHandle; }
internal TinyJsonArray(JsonKeyHandle refHandle, in TinyJsonData data)
internal void RemoveValueFromBuffer(JsonKeyHandle jsonRefHandle) { // the JsonValueRef location at the end of a type buffer will be invalidated when removing from that buffer // due to calling RemoveAtSwapBack() // so scan through the value refs to find the one pointing to the end of the affected buffer and update // its location int locationInStaleRef; switch (JsonKeyType(jsonRefHandle)) { case JsonValueType.Bool: locationInStaleRef = m_BoolBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_BoolBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); break; case JsonValueType.Int: locationInStaleRef = m_IntBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_IntBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); break; case JsonValueType.Float: locationInStaleRef = m_FloatBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_FloatBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); break; case JsonValueType.String: locationInStaleRef = m_StringBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_StringBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); break; case JsonValueType.Array: // first remove all values in the array var array = m_ArrayBuffer[LocationInValueBuffer(jsonRefHandle)]; for (int i = 0; i < array.Length; i++) { RemoveValueFromBuffer(array[i]); } // before removing the array itself locationInStaleRef = m_ArrayBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_ArrayBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); array.Dispose(); break; case JsonValueType.Object: // first remove all values in the object var unsafeHashMap = m_ObjectBuffer[LocationInValueBuffer(jsonRefHandle)]; foreach (var keyValue in unsafeHashMap) { RemoveValueFromBuffer(keyValue.Value); } // before removing the object itself locationInStaleRef = m_ObjectBuffer.Length - 1; UpdateStaleReference(jsonRefHandle, locationInStaleRef); m_ObjectBuffer.RemoveAtSwapBack(LocationInValueBuffer(jsonRefHandle)); unsafeHashMap.Dispose(); break; default: InvalidJsonTypeException(); return; } }