diff --git a/src/libs/libJson2.cpp b/src/libs/libJson2.cpp index 6b4b5fb98..d3645d760 100644 --- a/src/libs/libJson2.cpp +++ b/src/libs/libJson2.cpp @@ -4,6 +4,7 @@ #include "libs/libs.h" #include "loader/symbolDatabase.h" +#include #include #include #include @@ -60,6 +61,9 @@ struct JsonValue { uint32_t type; }; +static_assert(sizeof(JsonArray) == 8); +static_assert(sizeof(JsonValue) == 32 && offsetof(JsonValue, type) == 28); + struct JsonInitParameter2 { void* allocator; void* user_data; @@ -142,6 +146,7 @@ static void JsonValueInit(JsonValue* self) { } static void JsonValueClear(JsonValue* self); +static void JsonValueCopy(JsonValue* dst, const JsonValue* src); static JsonValue* JsonValueNew() { auto* value = new JsonValue; @@ -167,6 +172,28 @@ static JsonObject* JsonObjectNew() { return object; } +static std::vector* JsonArrayCopy(const JsonArray* src, JsonValue* parent) { + auto* impl = new std::vector; + for (const auto* value: *JsonArrayImpl(src)) { + auto* copy = JsonValueNew(); + JsonValueCopy(copy, value); + copy->parent = parent; + impl->push_back(copy); + } + return impl; +} + +static std::map* JsonObjectCopy(const JsonObject* src, JsonValue* parent) { + auto* impl = new std::map; + for (const auto& [key, value]: *JsonObjectImpl(src)) { + auto* copy = JsonValueNew(); + JsonValueCopy(copy, value); + copy->parent = parent; + impl->emplace(key, copy); + } + return impl; +} + static void JsonValueSetEmptyType(JsonValue* self, uint32_t type) { if (self == nullptr) { return; @@ -194,7 +221,7 @@ static void JsonStringDelete(JsonString* self) { } } -static void JsonArrayDelete(JsonArray* self) { +static void JsonArrayDestroy(JsonArray* self) { if (self != nullptr) { if (self->impl != nullptr) { for (auto* value: *self->impl) { @@ -202,11 +229,11 @@ static void JsonArrayDelete(JsonArray* self) { } } delete self->impl; - delete self; + self->impl = nullptr; } } -static void JsonObjectDelete(JsonObject* self) { +static void JsonObjectDestroy(JsonObject* self) { if (self != nullptr) { if (self->impl != nullptr) { for (auto& item: *self->impl) { @@ -214,7 +241,7 @@ static void JsonObjectDelete(JsonObject* self) { } } delete self->impl; - delete self; + self->impl = nullptr; } } @@ -225,8 +252,14 @@ static void JsonValueClear(JsonValue* self) { switch (self->type) { case JsonValueTypeString: JsonStringDelete(self->string); break; - case JsonValueTypeArray: JsonArrayDelete(self->array); break; - case JsonValueTypeObject: JsonObjectDelete(self->object); break; + case JsonValueTypeArray: + JsonArrayDestroy(self->array); + delete self->array; + break; + case JsonValueTypeObject: + JsonObjectDestroy(self->object); + delete self->object; + break; default: break; } @@ -249,26 +282,8 @@ static void JsonValueCopy(JsonValue* dst, const JsonValue* src) { case JsonValueTypeUInteger: dst->uinteger = src->uinteger; break; case JsonValueTypeReal: dst->real = src->real; break; case JsonValueTypeString: dst->string = JsonStringNew(*JsonStringImpl(src->string)); break; - case JsonValueTypeArray: { - dst->array = JsonArrayNew(); - for (auto* value: *JsonArrayImpl(src->array)) { - auto* copy = JsonValueNew(); - JsonValueCopy(copy, value); - copy->parent = dst; - dst->array->impl->push_back(copy); - } - break; - } - case JsonValueTypeObject: { - dst->object = JsonObjectNew(); - for (const auto& item: *JsonObjectImpl(src->object)) { - auto* copy = JsonValueNew(); - JsonValueCopy(copy, item.second); - copy->parent = dst; - (*dst->object->impl)[item.first] = copy; - } - break; - } + case JsonValueTypeArray: dst->array = new JsonArray {JsonArrayCopy(src->array, dst)}; break; + case JsonValueTypeObject: dst->object = new JsonObject {JsonObjectCopy(src->object, dst)}; break; default: dst->uinteger = 0; break; } } @@ -579,16 +594,34 @@ static JsonValue* KYTY_SYSV_ABI JsonValueObjectCtor(JsonValue* self, const JsonO JsonValueInit(self); if (self != nullptr) { self->type = JsonValueTypeObject; - self->object = JsonObjectNew(); - for (const auto& item: *JsonObjectImpl(value)) { - auto* copy = JsonValueNew(); - JsonValueCopy(copy, item.second); - (*self->object->impl)[item.first] = copy; - } + self->object = new JsonObject {JsonObjectCopy(value, self)}; } return self; } +static JsonValue* KYTY_SYSV_ABI JsonValueArrayCtor(JsonValue* self, const JsonArray* value) { + PRINT_NAME(); + + JsonValueInit(self); + if (self != nullptr) { + self->type = JsonValueTypeArray; + self->array = new JsonArray {JsonArrayCopy(value, self)}; + } + return self; +} + +static void KYTY_SYSV_ABI JsonValueSetObject(JsonValue* self, const JsonObject* value) { + PRINT_NAME(); + + if (self != nullptr) { + // The source may be this value's object or one of its descendants. + auto* object = new JsonObject {JsonObjectCopy(value, self)}; + JsonValueClear(self); + self->type = JsonValueTypeObject; + self->object = object; + } +} + static void KYTY_SYSV_ABI JsonValueDtor(void* self) { PRINT_NAME(); @@ -825,6 +858,21 @@ static size_t KYTY_SYSV_ABI JsonStringLength(const JsonString* self) { return JsonStringImpl(self)->length(); } +static JsonArray* KYTY_SYSV_ABI JsonArrayCtor(JsonArray* self) { + PRINT_NAME(); + + if (self != nullptr) { + self->impl = new std::vector; + } + return self; +} + +static void KYTY_SYSV_ABI JsonArrayDtor(JsonArray* self) { + PRINT_NAME(); + + JsonArrayDestroy(self); +} + static JsonArray* KYTY_SYSV_ABI JsonArrayPushBack(JsonArray* self, const JsonValue* value) { PRINT_NAME(); @@ -863,12 +911,7 @@ static JsonObject* KYTY_SYSV_ABI JsonObjectCopyCtor(JsonObject* self, const Json PRINT_NAME(); if (self != nullptr) { - self->impl = new std::map; - for (const auto& item: *JsonObjectImpl(src)) { - auto* copy = JsonValueNew(); - JsonValueCopy(copy, item.second); - (*self->impl)[item.first] = copy; - } + self->impl = JsonObjectCopy(src, nullptr); } return self; } @@ -876,23 +919,17 @@ static JsonObject* KYTY_SYSV_ABI JsonObjectCopyCtor(JsonObject* self, const Json static void KYTY_SYSV_ABI JsonObjectDtor(JsonObject* self) { PRINT_NAME(); - if (self != nullptr) { - if (self->impl != nullptr) { - for (auto& item: *self->impl) { - JsonValueDelete(item.second); - } - self->impl->clear(); - } - delete self->impl; - self->impl = nullptr; - } + JsonObjectDestroy(self); } static JsonObject* KYTY_SYSV_ABI JsonObjectAssign(JsonObject* self, const JsonObject* src) { PRINT_NAME(); - JsonObjectDtor(self); - JsonObjectCopyCtor(self, src); + if (self != nullptr) { + auto* impl = JsonObjectCopy(src, nullptr); + JsonObjectDestroy(self); + self->impl = impl; + } return self; } @@ -992,6 +1029,10 @@ LIB_DEFINE(InitNet_1_Json2) { LIB_FUNC("5JmzZt8twAo", LibJson2::JsonObjectDtor); LIB_FUNC("nM5XqdeXFPw", LibJson2::JsonValueReferArray); LIB_FUNC("-NxEk7XLkDY", LibJson2::JsonValueReferObject); + LIB_FUNC("JP-PtKMiI1E", LibJson2::JsonArrayCtor); + LIB_FUNC("HJ8GpRT1aiw", LibJson2::JsonArrayDtor); + LIB_FUNC("iZeYfOxtMRg", LibJson2::JsonValueArrayCtor); + LIB_FUNC("dFCphqnd+a4", LibJson2::JsonValueSetObject); LIB_FUNC("zQtLRTqceMY", LibJson2::JsonArrayPushBack); LIB_FUNC("0lLK8+kDqmE", LibJson2::JsonValueIntCtor); LIB_FUNC("urOpESTBZmo", LibJson2::JsonObjectAssign);