json2: add array and object value lifecycles

This commit is contained in:
nmzik
2026-09-06 14:48:49 +04:00
parent 533176f9ff
commit 9c6f6fa624
+91 -50
View File
@@ -4,6 +4,7 @@
#include "libs/libs.h"
#include "loader/symbolDatabase.h"
#include <cstddef>
#include <cstring>
#include <map>
#include <nlohmann/json.hpp>
@@ -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<JsonValue*>* JsonArrayCopy(const JsonArray* src, JsonValue* parent) {
auto* impl = new std::vector<JsonValue*>;
for (const auto* value: *JsonArrayImpl(src)) {
auto* copy = JsonValueNew();
JsonValueCopy(copy, value);
copy->parent = parent;
impl->push_back(copy);
}
return impl;
}
static std::map<std::string, JsonValue*>* JsonObjectCopy(const JsonObject* src, JsonValue* parent) {
auto* impl = new std::map<std::string, JsonValue*>;
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<JsonValue*>;
}
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<std::string, JsonValue*>;
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);