System/Libraries/Json: Fundamental (breaking) changes to API
Going forward, the following methods will require a mem_task to be provided: Clone, CreateArray, CreateObject, Parse, Stringify. For JsonArray, append/insert/prepend will take arguments in the form ((index,) value, type). A JsonItem will automatically be created which encapsulates this value and type. If type is not specified, the following will be done to determine the type: - Cast value to JsonElement* and check if the signature matches. If it does, assign type as value(JsonElement*)->type; or - If value > 0x1000, assign type as JSON_STRING; or - Otherwise, assign type as JSON_BOOLEAN.
This commit is contained in:
parent
b4e6abc79f
commit
90af0edcbb
1 changed files with 185 additions and 191 deletions
|
@ -34,8 +34,7 @@
|
|||
#define JSON_STATE_ARRAY_BOOLEAN 207
|
||||
#define JSON_STATE_ARRAY_NULL 208
|
||||
|
||||
#define JSON_PARSER_FIFO_SIZE 16384
|
||||
#define JSON_STRINGIFY_BUF_SIZE 1048576
|
||||
#define JSON_PARSER_FIFO_SIZE 32768
|
||||
|
||||
#define JSON_WRAPPER_MAGIC_NUMBER 0xDEADC0DEDEADC0DE
|
||||
|
||||
|
@ -45,6 +44,8 @@ class @json_stringify_string
|
|||
{
|
||||
I64 length;
|
||||
U8* value;
|
||||
I64 capacity;
|
||||
CTask* mem_task;
|
||||
}
|
||||
|
||||
class @json_element
|
||||
|
@ -67,6 +68,7 @@ class @json_object : @json_element
|
|||
{
|
||||
I64 length;
|
||||
@json_key* keys;
|
||||
CTask* mem_task;
|
||||
};
|
||||
|
||||
class @json_array : @json_element
|
||||
|
@ -74,6 +76,7 @@ class @json_array : @json_element
|
|||
I64 length;
|
||||
@json_item* items;
|
||||
@json_item* last_item;
|
||||
CTask* mem_task;
|
||||
};
|
||||
|
||||
extern class @json_callable_object;
|
||||
|
@ -83,9 +86,9 @@ class @json_callable_array : @json_array
|
|||
U64 (*@)(I64 index, Bool return_item = FALSE);
|
||||
@json_callable_array* (*a)(I64 index, Bool return_item = FALSE);
|
||||
@json_callable_object* (*o)(I64 index, Bool return_item = FALSE);
|
||||
U0 (*append)(@json_item* append_item);
|
||||
U0 (*insert)(@json_item* insert_item, I64 index);
|
||||
U0 (*prepend)(@json_item* prepend_item);
|
||||
U0 (*append)(U64 value, I64 type = NULL);
|
||||
U0 (*insert)(I64 index, U64 value, I64 type = NULL);
|
||||
U0 (*prepend)(U64 value, I64 type = NULL);
|
||||
U0 (*remove)(I64 index);
|
||||
};
|
||||
|
||||
|
@ -106,6 +109,7 @@ class @json_parser
|
|||
I64 pos;
|
||||
I64 state;
|
||||
Bool debug;
|
||||
CTask* mem_task;
|
||||
};
|
||||
|
||||
#define JsonArray @json_callable_array
|
||||
|
@ -156,12 +160,35 @@ U0 @json_debug_parser_state(@json_parser* parser)
|
|||
}
|
||||
}
|
||||
|
||||
U0 @json_append_item(@json_array* arr, @json_item* append_item)
|
||||
@json_item* @json_create_item(U64 value, I64 type = NULL, CTask* mem_task)
|
||||
{
|
||||
if (!arr || !append_item)
|
||||
@json_item* item = CAlloc(sizeof(@json_item), mem_task);
|
||||
item->sig = JSON_SIG;
|
||||
item->type = type;
|
||||
if (!item->type) {
|
||||
if (value(@json_element*)->sig == JSON_SIG) {
|
||||
item->type = value(@json_element*)->type;
|
||||
} else if (value > 0x1000) {
|
||||
item->type = JSON_STRING;
|
||||
} else {
|
||||
item->type = JSON_BOOLEAN;
|
||||
value = value != 0;
|
||||
}
|
||||
}
|
||||
if (item->type == JSON_STRING)
|
||||
item->value = StrNew(value, mem_task);
|
||||
else
|
||||
item->value = value;
|
||||
return item;
|
||||
}
|
||||
|
||||
U0 @json_append_item(@json_array* arr, U64 value, I64 type = NULL)
|
||||
{
|
||||
if (!arr)
|
||||
return;
|
||||
if (arr->type != JSON_ARRAY)
|
||||
return;
|
||||
@json_item* append_item = @json_create_item(value, type, arr->mem_task);
|
||||
@json_item* item = arr->last_item;
|
||||
if (!item) {
|
||||
append_item->prev = NULL;
|
||||
|
@ -177,11 +204,11 @@ U0 @json_append_item(@json_array* arr, @json_item* append_item)
|
|||
arr->length++;
|
||||
}
|
||||
|
||||
U8* @json_string_from_fifo(CFifoU8* f)
|
||||
U8* @json_string_from_fifo(CFifoU8* f, CTask* mem_task)
|
||||
{
|
||||
U8 ch;
|
||||
I64 i = 0;
|
||||
U8* str = CAlloc(FifoU8Cnt(f) + 1, slon_mem_task);
|
||||
U8* str = CAlloc(FifoU8Cnt(f) + 1, mem_task);
|
||||
while (FifoU8Cnt(f)) {
|
||||
FifoU8Rem(f, &ch);
|
||||
str[i] = ch;
|
||||
|
@ -271,14 +298,14 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_OBJECT_NUMBER:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(key->value);
|
||||
key->value = Str2F64(key->value);
|
||||
@json_insert_key(obj, key);
|
||||
return;
|
||||
break;
|
||||
case JSON_STATE_OBJECT_BOOLEAN:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(key->value);
|
||||
if (StrCmp("true", key->value) && StrCmp("false", key->value)) {
|
||||
PrintErr("@json_parse_object: Illegal boolean value at position %d",
|
||||
|
@ -294,7 +321,7 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
return;
|
||||
break;
|
||||
case JSON_STATE_OBJECT_NULL:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(key->value);
|
||||
if (StrCmp("null", key->value)) {
|
||||
PrintErr("@json_parse_object: Illegal null value at position %d",
|
||||
|
@ -319,13 +346,13 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_OBJECT_NUMBER:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
key->value = Str2F64(key->value);
|
||||
@json_insert_key(obj, key);
|
||||
parser->state = JSON_STATE_OBJECT;
|
||||
break;
|
||||
case JSON_STATE_OBJECT_BOOLEAN:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(key->value);
|
||||
if (StrCmp("true", key->value) && StrCmp("false", key->value)) {
|
||||
PrintErr("@json_parse_object: Illegal boolean value at position %d",
|
||||
|
@ -341,7 +368,7 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
parser->state = JSON_STATE_OBJECT;
|
||||
break;
|
||||
case JSON_STATE_OBJECT_NULL:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(key->value);
|
||||
if (StrCmp("null", key->value)) {
|
||||
PrintErr("@json_parse_object: Illegal null value at position %d",
|
||||
|
@ -400,7 +427,7 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
case '"':
|
||||
switch (parser->state) {
|
||||
case JSON_STATE_OBJECT_STRING:
|
||||
key->value = @json_string_from_fifo(parser->consumed);
|
||||
key->value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_insert_key(obj, key);
|
||||
parser->state = JSON_STATE_OBJECT_NEXT;
|
||||
break;
|
||||
|
@ -409,11 +436,11 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
parser->state = JSON_STATE_OBJECT_STRING;
|
||||
break;
|
||||
case JSON_STATE_OBJECT_KEY:
|
||||
key->name = @json_string_from_fifo(parser->consumed);
|
||||
key->name = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
parser->state = JSON_STATE_OBJECT_SEPARATOR;
|
||||
break;
|
||||
case JSON_STATE_OBJECT:
|
||||
key = CAlloc(sizeof(@json_key), slon_mem_task);
|
||||
key = CAlloc(sizeof(@json_key), parser->mem_task);
|
||||
key->sig = JSON_SIG;
|
||||
parser->state = JSON_STATE_OBJECT_KEY;
|
||||
break;
|
||||
|
@ -485,7 +512,7 @@ U0 @json_parse_object(@json_parser* parser, @json_object* obj)
|
|||
|
||||
U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
||||
{
|
||||
@json_item* item = NULL;
|
||||
U64 value = NULL;
|
||||
while (1) {
|
||||
if (parser->state == JSON_STATE_ARRAY) {
|
||||
switch (parser->stream[parser->pos]) {
|
||||
|
@ -498,8 +525,6 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
return;
|
||||
break;
|
||||
}
|
||||
item = CAlloc(sizeof(@json_item), slon_mem_task);
|
||||
item->sig = JSON_SIG;
|
||||
parser->state = JSON_STATE_ARRAY_TYPE;
|
||||
}
|
||||
switch (parser->stream[parser->pos]) {
|
||||
|
@ -519,38 +544,38 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_NUMBER:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_rstrip(item->value);
|
||||
item->value = Str2F64(item->value);
|
||||
@json_append_item(arr, item);
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(value);
|
||||
value = Str2F64(value);
|
||||
@json_append_item(arr, value, JSON_NUMBER);
|
||||
return;
|
||||
break;
|
||||
case JSON_STATE_ARRAY_BOOLEAN:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_rstrip(item->value);
|
||||
if (StrCmp("true", item->value) && StrCmp("false", item->value)) {
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(value);
|
||||
if (StrCmp("true", value) && StrCmp("false", value)) {
|
||||
PrintErr("@json_parse_array: Illegal boolean value at position %d",
|
||||
parser->pos);
|
||||
while (1)
|
||||
Sleep(1);
|
||||
}
|
||||
if (!StrCmp("true", item->value))
|
||||
item->value = TRUE;
|
||||
if (!StrCmp("true", value))
|
||||
value = TRUE;
|
||||
else
|
||||
item->value = FALSE;
|
||||
@json_append_item(arr, item);
|
||||
value = FALSE;
|
||||
@json_append_item(arr, value, JSON_BOOLEAN);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_NULL:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_rstrip(item->value);
|
||||
if (StrCmp("null", item->value)) {
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(value);
|
||||
if (StrCmp("null", value)) {
|
||||
PrintErr("@json_parse_array: Illegal null value at position %d",
|
||||
parser->pos);
|
||||
while (1)
|
||||
Sleep(1);
|
||||
}
|
||||
item->value = NULL;
|
||||
@json_append_item(arr, item);
|
||||
value = NULL;
|
||||
@json_append_item(arr, value, JSON_NULL);
|
||||
break;
|
||||
case JSON_STATE_ARRAY:
|
||||
case JSON_STATE_ARRAY_NEXT:
|
||||
|
@ -564,38 +589,38 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_NUMBER:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
item->value = Str2F64(item->value);
|
||||
@json_append_item(arr, item);
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
value = Str2F64(value);
|
||||
@json_append_item(arr, value, JSON_NUMBER);
|
||||
parser->state = JSON_STATE_ARRAY;
|
||||
break;
|
||||
case JSON_STATE_ARRAY_BOOLEAN:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_rstrip(item->value);
|
||||
if (StrCmp("true", item->value) && StrCmp("false", item->value)) {
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(value);
|
||||
if (StrCmp("true", value) && StrCmp("false", value)) {
|
||||
PrintErr("@json_parse_array: Illegal boolean value at position %d",
|
||||
parser->pos);
|
||||
while (1)
|
||||
Sleep(1);
|
||||
}
|
||||
if (!StrCmp("true", item->value))
|
||||
item->value = TRUE;
|
||||
if (!StrCmp("true", value))
|
||||
value = TRUE;
|
||||
else
|
||||
item->value = FALSE;
|
||||
@json_append_item(arr, item);
|
||||
value = FALSE;
|
||||
@json_append_item(arr, value, JSON_BOOLEAN);
|
||||
parser->state = JSON_STATE_ARRAY;
|
||||
break;
|
||||
case JSON_STATE_ARRAY_NULL:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_rstrip(item->value);
|
||||
if (StrCmp("null", item->value)) {
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_rstrip(value);
|
||||
if (StrCmp("null", value)) {
|
||||
PrintErr("@json_parse_array: Illegal null value at position %d",
|
||||
parser->pos);
|
||||
while (1)
|
||||
Sleep(1);
|
||||
}
|
||||
item->value = NULL;
|
||||
@json_append_item(arr, item);
|
||||
value = NULL;
|
||||
@json_append_item(arr, value, JSON_NULL);
|
||||
parser->state = JSON_STATE_ARRAY;
|
||||
break;
|
||||
case JSON_STATE_ARRAY_NEXT:
|
||||
|
@ -609,9 +634,8 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_TYPE:
|
||||
item->type = JSON_ARRAY;
|
||||
item->value = @json_parse_object_or_array(parser);
|
||||
@json_append_item(arr, item);
|
||||
value = @json_parse_object_or_array(parser);
|
||||
@json_append_item(arr, value, JSON_ARRAY);
|
||||
parser->state = JSON_STATE_ARRAY_NEXT;
|
||||
break;
|
||||
}
|
||||
|
@ -622,9 +646,8 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_TYPE:
|
||||
item->type = JSON_OBJECT;
|
||||
item->value = @json_parse_object_or_array(parser);
|
||||
@json_append_item(arr, item);
|
||||
value = @json_parse_object_or_array(parser);
|
||||
@json_append_item(arr, value, JSON_OBJECT);
|
||||
parser->state = JSON_STATE_ARRAY_NEXT;
|
||||
break;
|
||||
}
|
||||
|
@ -632,12 +655,11 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
case '"':
|
||||
switch (parser->state) {
|
||||
case JSON_STATE_ARRAY_STRING:
|
||||
item->value = @json_string_from_fifo(parser->consumed);
|
||||
@json_append_item(arr, item);
|
||||
value = @json_string_from_fifo(parser->consumed, parser->mem_task);
|
||||
@json_append_item(arr, value, JSON_STRING);
|
||||
parser->state = JSON_STATE_ARRAY_NEXT;
|
||||
break;
|
||||
case JSON_STATE_ARRAY_TYPE:
|
||||
item->type = JSON_STRING;
|
||||
parser->state = JSON_STATE_ARRAY_STRING;
|
||||
break;
|
||||
}
|
||||
|
@ -651,7 +673,6 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_TYPE:
|
||||
item->type = JSON_NUMBER;
|
||||
parser->state = JSON_STATE_ARRAY_NUMBER;
|
||||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
|
@ -664,7 +685,6 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_ARRAY_TYPE:
|
||||
item->type = JSON_BOOLEAN;
|
||||
parser->state = JSON_STATE_ARRAY_BOOLEAN;
|
||||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
|
@ -676,7 +696,6 @@ U0 @json_parse_array(@json_parser* parser, @json_array* arr)
|
|||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
case JSON_STATE_OBJECT_TYPE:
|
||||
item->type = JSON_NULL;
|
||||
parser->state = JSON_STATE_ARRAY_NULL;
|
||||
FifoU8Ins(parser->consumed, parser->stream[parser->pos]);
|
||||
break;
|
||||
|
@ -707,7 +726,7 @@ extern @json_callable_object* @json_create_callable_object(@json_object* obj);
|
|||
|
||||
@json_element* @json_parse_object_or_array(@json_parser* parser)
|
||||
{
|
||||
@json_element* el = CAlloc(sizeof(@json_element) * 2, slon_mem_task);
|
||||
@json_element* el = CAlloc(sizeof(@json_array), parser->mem_task);
|
||||
el->sig = JSON_SIG;
|
||||
while (1) {
|
||||
switch (parser->stream[parser->pos]) {
|
||||
|
@ -721,6 +740,7 @@ extern @json_callable_object* @json_create_callable_object(@json_object* obj);
|
|||
break;
|
||||
case '{':
|
||||
el->type = JSON_OBJECT;
|
||||
el(@json_object*)->mem_task = parser->mem_task;
|
||||
parser->pos++;
|
||||
parser->state = JSON_STATE_OBJECT;
|
||||
@json_parse_object(parser, el);
|
||||
|
@ -728,6 +748,7 @@ extern @json_callable_object* @json_create_callable_object(@json_object* obj);
|
|||
break;
|
||||
case '[':
|
||||
el->type = JSON_ARRAY;
|
||||
el(@json_array*)->mem_task = parser->mem_task;
|
||||
parser->pos++;
|
||||
parser->state = JSON_STATE_ARRAY;
|
||||
@json_parse_array(parser, el);
|
||||
|
@ -745,45 +766,46 @@ extern @json_callable_object* @json_create_callable_object(@json_object* obj);
|
|||
}
|
||||
}
|
||||
|
||||
@json_element* @json_parse(U8* str)
|
||||
@json_element* @json_parse(U8* str, CTask* mem_task)
|
||||
{
|
||||
@json_parser* parser = CAlloc(sizeof(@json_parser), slon_mem_task);
|
||||
parser->consumed = FifoU8New(JSON_PARSER_FIFO_SIZE, slon_mem_task);
|
||||
// parser->debug = TRUE;
|
||||
if (!str || !mem_task) {
|
||||
return NULL;
|
||||
}
|
||||
@json_parser* parser = CAlloc(sizeof(@json_parser), mem_task);
|
||||
parser->mem_task = mem_task;
|
||||
parser->consumed = FifoU8New(JSON_PARSER_FIFO_SIZE, parser->mem_task);
|
||||
parser->stream = str;
|
||||
@json_element* root = @json_parse_object_or_array(parser);
|
||||
FifoU8Flush(parser->consumed);
|
||||
FifoU8Del(parser->consumed);
|
||||
Free(parser);
|
||||
return root;
|
||||
return @json_parse_object_or_array(parser);
|
||||
}
|
||||
|
||||
U0 @json_prepend_item(@json_array* arr, @json_item* prepend_item)
|
||||
U0 @json_prepend_item(@json_array* arr, U64 value, I64 type)
|
||||
{
|
||||
if (!arr || !prepend_item)
|
||||
if (!arr)
|
||||
return;
|
||||
if (arr->type != JSON_ARRAY)
|
||||
return;
|
||||
@json_item* prepend_item = @json_create_item(value, type, arr->mem_task);
|
||||
@json_item* items = arr->items;
|
||||
arr->items = prepend_item;
|
||||
arr->items->next = items;
|
||||
arr->length++;
|
||||
}
|
||||
|
||||
U0 @json_insert_item(@json_array* arr, @json_item* insert_item, I64 index)
|
||||
U0 @json_insert_item(@json_array* arr, I64 index, U64 value, I64 type)
|
||||
{
|
||||
if (!arr || !insert_item)
|
||||
if (!arr)
|
||||
return;
|
||||
if (arr->type != JSON_ARRAY)
|
||||
return;
|
||||
if (index <= 0) {
|
||||
@json_prepend_item(arr, insert_item);
|
||||
@json_prepend_item(arr, value, type);
|
||||
return;
|
||||
}
|
||||
if (index >= arr->length) {
|
||||
@json_append_item(arr, insert_item);
|
||||
@json_append_item(arr, value, type);
|
||||
return;
|
||||
}
|
||||
@json_item* insert_item = @json_create_item(value, type, arr->mem_task);
|
||||
@json_item* insert_at_item = arr->items;
|
||||
@json_item* insert_after_item = NULL;
|
||||
I64 i;
|
||||
|
@ -797,6 +819,16 @@ U0 @json_insert_item(@json_array* arr, @json_item* insert_item, I64 index)
|
|||
arr->length++;
|
||||
}
|
||||
|
||||
U0 @json_stringify_check_capacity(@json_stringify_string* str)
|
||||
{
|
||||
if (str->length >= str->capacity) {
|
||||
str->capacity *= 2;
|
||||
U8* new_value = CAlloc(str->capacity * 2, str->mem_task);
|
||||
MemCpy(new_value, str->value, str->length);
|
||||
str->value = new_value;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @json_stringify_append_char(@json_stringify_string* str, U8 char)
|
||||
{
|
||||
// FIXME: unicode
|
||||
|
@ -830,6 +862,7 @@ U0 @json_stringify_append_char(@json_stringify_string* str, U8 char)
|
|||
break;
|
||||
}
|
||||
str->value[str->length] = NULL;
|
||||
@json_stringify_check_capacity(str);
|
||||
}
|
||||
|
||||
U0 @json_stringify_append_char_escape_quotes(@json_stringify_string* str, U8 char)
|
||||
|
@ -869,6 +902,7 @@ U0 @json_stringify_append_char_escape_quotes(@json_stringify_string* str, U8 cha
|
|||
break;
|
||||
}
|
||||
str->value[str->length] = NULL;
|
||||
@json_stringify_check_capacity(str);
|
||||
}
|
||||
|
||||
U0 @json_stringify_append_str(@json_stringify_string* str, U8* str2)
|
||||
|
@ -884,6 +918,7 @@ U0 @json_stringify_append_str(@json_stringify_string* str, U8* str2)
|
|||
@json_stringify_append_char_escape_quotes(str, *str2);
|
||||
}
|
||||
str2++;
|
||||
@json_stringify_check_capacity(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1004,15 +1039,17 @@ U0 @json_stringify_object_or_array(@json_stringify_string* str, @json_element* e
|
|||
}
|
||||
}
|
||||
|
||||
U8* @json_stringify(@json_element* el, I64 buf_size = JSON_STRINGIFY_BUF_SIZE)
|
||||
U8* @json_stringify(@json_element* el, CTask* mem_task)
|
||||
{
|
||||
// U8* str = CAlloc(buf_size, slon_mem_task);
|
||||
@json_stringify_string* str = CAlloc(sizeof(@json_stringify_string), slon_mem_task);
|
||||
U8* value = CAlloc(buf_size, slon_mem_task);
|
||||
str->value = value;
|
||||
if (!el || !mem_task) {
|
||||
return NULL;
|
||||
}
|
||||
@json_stringify_string* str = CAlloc(sizeof(@json_stringify_string), mem_task);
|
||||
str->mem_task = mem_task;
|
||||
str->capacity = 256;
|
||||
str->value = CAlloc(str->capacity * 2, str->mem_task);
|
||||
@json_stringify_object_or_array(str, el);
|
||||
Free(str);
|
||||
return value;
|
||||
return str->value;
|
||||
}
|
||||
|
||||
U64 @json_get(@json_object* obj, U8* key, Bool return_key = FALSE)
|
||||
|
@ -1049,12 +1086,12 @@ U0 @json_set(@json_object* obj, U8* key, U64 value, I64 type = JSON_SAME)
|
|||
}
|
||||
iter_key = iter_key->next;
|
||||
}
|
||||
@json_key* new_key = CAlloc(sizeof(@json_key), slon_mem_task);
|
||||
@json_key* new_key = CAlloc(sizeof(@json_key), obj->mem_task);
|
||||
new_key->sig = JSON_SIG;
|
||||
new_key->name = StrNew(key, slon_mem_task);
|
||||
new_key->name = StrNew(key, obj->mem_task);
|
||||
new_key->type = type;
|
||||
if (new_key->type == JSON_STRING)
|
||||
new_key->value = StrNew(value, slon_mem_task);
|
||||
new_key->value = StrNew(value, obj->mem_task);
|
||||
else
|
||||
new_key->value = value;
|
||||
@json_insert_key(obj, new_key);
|
||||
|
@ -1077,7 +1114,6 @@ U0 @json_unset(@json_object* obj, U8* key)
|
|||
prev_key->next = next_key;
|
||||
if (next_key)
|
||||
next_key->prev = prev_key;
|
||||
// FIXME: Delete the unset key
|
||||
return;
|
||||
}
|
||||
iter_key = iter_key->next;
|
||||
|
@ -1101,15 +1137,13 @@ U0 @json_callable_object_unset_wrapper_function(U8* key)
|
|||
|
||||
@json_callable_object* @json_create_callable_object(@json_object* obj)
|
||||
{
|
||||
// Alloc callable object and copy instance
|
||||
@json_callable_object* cobj = CAlloc(sizeof(@json_callable_object), slon_mem_task);
|
||||
cobj->sig = JSON_SIG;
|
||||
@json_callable_object* cobj = CAlloc(sizeof(@json_callable_object), obj->mem_task);
|
||||
MemCpy(cobj, obj, sizeof(@json_object));
|
||||
|
||||
// Create a copy of function and patch Get
|
||||
U64 a;
|
||||
I64 code_size = MSize(&@json_callable_object_get_wrapper_function);
|
||||
cobj->@ = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
cobj->@ = CAlloc(code_size, obj->mem_task->code_heap);
|
||||
MemCpy(cobj->@, &@json_callable_object_get_wrapper_function, code_size);
|
||||
|
||||
a = cobj->@;
|
||||
|
@ -1122,7 +1156,7 @@ U0 @json_callable_object_unset_wrapper_function(U8* key)
|
|||
|
||||
// Create a copy of function and patch Set
|
||||
code_size = MSize(&@json_callable_object_set_wrapper_function);
|
||||
cobj->set = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
cobj->set = CAlloc(code_size, obj->mem_task->code_heap);
|
||||
MemCpy(cobj->set, &@json_callable_object_set_wrapper_function, code_size);
|
||||
|
||||
a = cobj->set;
|
||||
|
@ -1135,7 +1169,7 @@ U0 @json_callable_object_unset_wrapper_function(U8* key)
|
|||
|
||||
// Create a copy of function and patch Unset
|
||||
code_size = MSize(&@json_callable_object_unset_wrapper_function);
|
||||
cobj->unset = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
cobj->unset = CAlloc(code_size, obj->mem_task->code_heap);
|
||||
MemCpy(cobj->unset, &@json_callable_object_unset_wrapper_function, code_size);
|
||||
|
||||
a = cobj->unset;
|
||||
|
@ -1152,26 +1186,18 @@ U0 @json_callable_object_unset_wrapper_function(U8* key)
|
|||
return cobj;
|
||||
}
|
||||
|
||||
@json_callable_object* @json_create_object()
|
||||
@json_callable_object* @json_create_object(CTask* mem_task)
|
||||
{
|
||||
@json_object* obj = CAlloc(sizeof(@json_object), slon_mem_task);
|
||||
if (!mem_task) {
|
||||
return NULL;
|
||||
}
|
||||
@json_object* obj = CAlloc(sizeof(@json_object), mem_task);
|
||||
obj->mem_task = mem_task;
|
||||
obj->sig = JSON_SIG;
|
||||
obj->type = JSON_OBJECT;
|
||||
return @json_create_callable_object(obj);
|
||||
}
|
||||
|
||||
@json_item* @json_create_item(U64 value, I64 type)
|
||||
{
|
||||
@json_item* item = CAlloc(sizeof(@json_item), slon_mem_task);
|
||||
item->sig = JSON_SIG;
|
||||
item->type = type;
|
||||
if (item->type == JSON_STRING)
|
||||
item->value = StrNew(value, slon_mem_task);
|
||||
else
|
||||
item->value = value;
|
||||
return item;
|
||||
}
|
||||
|
||||
U64 @json_array_index(@json_array* arr, I64 index, Bool return_item = FALSE)
|
||||
{
|
||||
if (!arr)
|
||||
|
@ -1227,28 +1253,27 @@ U0 @json_remove_item(@json_array* arr, I64 index)
|
|||
prev_item->next = next_item;
|
||||
if (next_item)
|
||||
next_item->prev = prev_item;
|
||||
@json_remove_item_final : Free(item);
|
||||
--arr->length;
|
||||
@json_remove_item_final : --arr->length;
|
||||
}
|
||||
|
||||
U64 @json_callable_array_index_wrapper_function(I64 index, Bool return_item = FALSE)
|
||||
{
|
||||
return @json_get(JSON_WRAPPER_MAGIC_NUMBER, index, return_item);
|
||||
return @json_array_index(JSON_WRAPPER_MAGIC_NUMBER, index, return_item);
|
||||
}
|
||||
|
||||
U0 @json_callable_array_append_wrapper_function(@json_item* append_item)
|
||||
U0 @json_callable_array_append_wrapper_function(U64 value, I64 type = NULL)
|
||||
{
|
||||
@json_append_item(JSON_WRAPPER_MAGIC_NUMBER, append_item);
|
||||
@json_append_item(JSON_WRAPPER_MAGIC_NUMBER, value, type);
|
||||
}
|
||||
|
||||
U0 @json_callable_array_insert_wrapper_function(@json_item* insert_item, I64 index)
|
||||
U0 @json_callable_array_insert_wrapper_function(I64 index, U64 value, I64 type = NULL)
|
||||
{
|
||||
@json_insert_item(JSON_WRAPPER_MAGIC_NUMBER, insert_item, index);
|
||||
@json_insert_item(JSON_WRAPPER_MAGIC_NUMBER, index, value, type);
|
||||
}
|
||||
|
||||
U0 @json_callable_array_prepend_wrapper_function(@json_item* prepend_item)
|
||||
U0 @json_callable_array_prepend_wrapper_function(U64 value, I64 type = NULL)
|
||||
{
|
||||
@json_prepend_item(JSON_WRAPPER_MAGIC_NUMBER, prepend_item);
|
||||
@json_prepend_item(JSON_WRAPPER_MAGIC_NUMBER, value, type);
|
||||
}
|
||||
|
||||
U0 @json_callable_array_remove_wrapper_function(I64 index)
|
||||
|
@ -1259,14 +1284,13 @@ U0 @json_callable_array_remove_wrapper_function(I64 index)
|
|||
@json_callable_array* @json_create_callable_array(@json_array* arr)
|
||||
{
|
||||
// Alloc callable object and copy instance
|
||||
@json_callable_array* carr = CAlloc(sizeof(@json_callable_array), slon_mem_task);
|
||||
carr->sig = JSON_SIG;
|
||||
@json_callable_array* carr = CAlloc(sizeof(@json_callable_array), arr->mem_task);
|
||||
MemCpy(carr, arr, sizeof(@json_array));
|
||||
|
||||
// Create a copy of function and patch Index
|
||||
U64 a;
|
||||
I64 code_size = MSize(&@json_callable_array_index_wrapper_function);
|
||||
carr->@ = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
carr->@ = CAlloc(code_size, arr->mem_task->code_heap);
|
||||
MemCpy(carr->@, &@json_callable_array_index_wrapper_function, code_size);
|
||||
|
||||
a = carr->@;
|
||||
|
@ -1282,46 +1306,46 @@ U0 @json_callable_array_remove_wrapper_function(I64 index)
|
|||
|
||||
// Create a copy of function and patch Append
|
||||
code_size = MSize(&@json_callable_array_append_wrapper_function);
|
||||
carr->append = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
carr->append = CAlloc(code_size, arr->mem_task->code_heap);
|
||||
MemCpy(carr->append, &@json_callable_array_append_wrapper_function, code_size);
|
||||
|
||||
a = carr->append;
|
||||
a += 0x0c;
|
||||
a += 0x12;
|
||||
MemSetI64(a, carr, 1);
|
||||
|
||||
a = carr->append;
|
||||
a += 0x15;
|
||||
a += 0x1b;
|
||||
@patch_call_rel32(a, &@json_append_item);
|
||||
|
||||
// Create a copy of function and patch Prepend
|
||||
code_size = MSize(&@json_callable_array_prepend_wrapper_function);
|
||||
carr->prepend = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
carr->prepend = CAlloc(code_size, arr->mem_task->code_heap);
|
||||
MemCpy(carr->prepend, &@json_callable_array_prepend_wrapper_function, code_size);
|
||||
|
||||
a = carr->prepend;
|
||||
a += 0x0c;
|
||||
a += 0x12;
|
||||
MemSetI64(a, carr, 1);
|
||||
|
||||
a = carr->prepend;
|
||||
a += 0x15;
|
||||
a += 0x1b;
|
||||
@patch_call_rel32(a, &@json_prepend_item);
|
||||
|
||||
// Create a copy of function and patch Insert
|
||||
code_size = MSize(&@json_callable_array_insert_wrapper_function);
|
||||
carr->insert = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
carr->insert = CAlloc(code_size, arr->mem_task->code_heap);
|
||||
MemCpy(carr->insert, &@json_callable_array_insert_wrapper_function, code_size);
|
||||
|
||||
a = carr->insert;
|
||||
a += 0x12;
|
||||
a += 0x1a;
|
||||
MemSetI64(a, carr, 1);
|
||||
|
||||
a = carr->insert;
|
||||
a += 0x1b;
|
||||
a += 0x23;
|
||||
@patch_call_rel32(a, &@json_insert_item);
|
||||
|
||||
// Create a copy of function and patch Remove
|
||||
code_size = MSize(&@json_callable_array_remove_wrapper_function);
|
||||
carr->remove = CAlloc(code_size, slon_mem_task->code_heap);
|
||||
carr->remove = CAlloc(code_size, arr->mem_task->code_heap);
|
||||
MemCpy(carr->remove, &@json_callable_array_remove_wrapper_function, code_size);
|
||||
|
||||
a = carr->remove;
|
||||
|
@ -1335,97 +1359,67 @@ U0 @json_callable_array_remove_wrapper_function(I64 index)
|
|||
return carr;
|
||||
}
|
||||
|
||||
@json_array* @json_create_array()
|
||||
@json_array* @json_create_array(CTask* mem_task)
|
||||
{
|
||||
@json_array* arr = CAlloc(sizeof(@json_array), slon_mem_task);
|
||||
if (!mem_task) {
|
||||
return NULL;
|
||||
}
|
||||
@json_array* arr = CAlloc(sizeof(@json_array), mem_task);
|
||||
arr->mem_task = mem_task;
|
||||
arr->sig = JSON_SIG;
|
||||
arr->type = JSON_ARRAY;
|
||||
return @json_create_callable_array(arr);
|
||||
}
|
||||
|
||||
U64 @json_parse_file(U8* path)
|
||||
U64 @json_parse_file(U8* path, CTask* mem_task)
|
||||
{
|
||||
if (!path || !mem_task || !FileFind(path)) {
|
||||
return NULL;
|
||||
}
|
||||
U64 res = NULL;
|
||||
U8* json_string = FileRead(path);
|
||||
if (json_string) {
|
||||
res = @json_parse(json_string);
|
||||
Free(json_string);
|
||||
res = @json_parse(json_string, mem_task);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 @json_delete(@json_element* el)
|
||||
U0 @json_dump_to_file(U8* path, @json_element* el, CTask* mem_task)
|
||||
{
|
||||
// FIXME: Implement this
|
||||
no_warn el;
|
||||
}
|
||||
|
||||
U0 @json_dump_to_file(U8* path, @json_element* el)
|
||||
{
|
||||
if (!path || !el)
|
||||
if (!path || !el || !mem_task)
|
||||
return;
|
||||
U8* json_string = @json_stringify(el);
|
||||
U8* json_string = @json_stringify(el, mem_task);
|
||||
FileWrite(path, json_string, StrLen(json_string));
|
||||
Free(json_string);
|
||||
}
|
||||
|
||||
@json_element* @json_clone(@json_element* el)
|
||||
@json_element* @json_clone(@json_element* el, CTask* mem_task)
|
||||
{
|
||||
if (!el)
|
||||
if (!el || !mem_task) {
|
||||
return NULL;
|
||||
U8* tmp = @json_stringify(el);
|
||||
if (!tmp)
|
||||
}
|
||||
U8* tmp = @json_stringify(el, mem_task);
|
||||
if (!tmp) {
|
||||
return NULL;
|
||||
@json_element* clone = @json_parse(tmp);
|
||||
Free(tmp);
|
||||
return clone;
|
||||
}
|
||||
return @json_parse(tmp, mem_task);
|
||||
}
|
||||
|
||||
class @json
|
||||
{
|
||||
U0(*AppendItem)
|
||||
(@json_array * arr, @json_item * append_item);
|
||||
U64(*ArrayIndex)
|
||||
(@json_array * arr, I64 index, Bool return_item = FALSE);
|
||||
@json_element* (*Clone)(@json_element* el);
|
||||
@json_object* (*CreateObject)();
|
||||
@json_callable_object* (*CreateCallableObject)(@json_object* obj);
|
||||
@json_item* (*CreateItem)(U64 value, I64 type);
|
||||
@json_array* (*CreateArray)();
|
||||
U0 (*Delete)(@json_element* el);
|
||||
U0 (*DumpToFile)(U8* path, @json_element* el);
|
||||
U0(*InsertItem)
|
||||
(@json_array * arr, @json_item * insert_item, I64 index);
|
||||
@json_element* (*Parse)(U8* str);
|
||||
U64 (*ParseFile)(U8* path);
|
||||
U0(*PrependItem)
|
||||
(@json_array * arr, @json_item * prepend_item);
|
||||
U0(*RemoveItem)
|
||||
(@json_array * arr, I64 index);
|
||||
U64(*Get)
|
||||
(@json_object * obj, U8 * key, Bool return_key = FALSE);
|
||||
U0(*Set)
|
||||
(@json_object * obj, U8 * key, U64 value, I64 type);
|
||||
U8* (*Stringify)(@json_element* el, I64 buf_size = JSON_STRINGIFY_BUF_SIZE);
|
||||
U0(*Unset)
|
||||
(@json_object * obj, U8 * key);
|
||||
@json_element* (*Clone)(@json_element* el, CTask* mem_task);
|
||||
@json_array* (*CreateArray)(CTask* mem_task);
|
||||
@json_object* (*CreateObject)(CTask* mem_task);
|
||||
U0 (*DumpToFile)(U8* path, @json_element* el, CTask* mem_task);
|
||||
@json_element* (*Parse)(U8* str, CTask* mem_task);
|
||||
U64 (*ParseFile)(U8* path, CTask* mem_task);
|
||||
U8* (*Stringify)(@json_element* el, CTask* mem_task);
|
||||
};
|
||||
|
||||
@json Json;
|
||||
Json.AppendItem = &@json_append_item;
|
||||
Json.ArrayIndex = &@json_array_index;
|
||||
Json.Clone = &@json_clone;
|
||||
Json.CreateArray = &@json_create_array;
|
||||
Json.CreateItem = &@json_create_item;
|
||||
Json.CreateObject = &@json_create_object;
|
||||
Json.Delete = &@json_delete;
|
||||
Json.DumpToFile = &@json_dump_to_file;
|
||||
Json.Get = &@json_get;
|
||||
Json.InsertItem = &@json_insert_item;
|
||||
Json.Parse = &@json_parse;
|
||||
Json.ParseFile = &@json_parse_file;
|
||||
Json.PrependItem = &@json_prepend_item;
|
||||
Json.RemoveItem = &@json_remove_item;
|
||||
Json.Set = &@json_set;
|
||||
Json.Stringify = &@json_stringify;
|
||||
Json.Unset = &@json_unset;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue