Optimize code structure of json-parser.

This commit is contained in:
Xie Han
2023-11-26 01:39:19 +08:00
parent 8fa0e05b40
commit 273134f0ff

View File

@@ -70,28 +70,6 @@ struct __json_element
typedef struct __json_member json_member_t;
typedef struct __json_element json_element_t;
static void __insert_json_member(json_member_t *memb, struct list_head *pos,
json_object_t *obj)
{
struct rb_node **p = &obj->root.rb_node;
struct rb_node *parent = NULL;
json_member_t *entry;
while (*p)
{
parent = *p;
entry = rb_entry(*p, json_member_t, rb);
if (strcmp(memb->name, entry->name) < 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
rb_link_node(&memb->rb, parent, p);
rb_insert_color(&memb->rb, &obj->root);
list_add(&memb->list, pos);
}
static int __json_string_length(const char *cursor)
{
int len = 0;
@@ -140,7 +118,7 @@ static int __parse_json_hex4(const char *cursor, const char **end,
*code = (*code << 4) + hex;
cursor++;
}
}
*end = cursor;
return 0;
@@ -175,7 +153,7 @@ static int __parse_json_unicode(const char *cursor, const char **end,
if (ret < 0)
return ret;
if (next < 0xdc00 || next > 0xdfff)
if (next < 0xdc00 || next > 0xdfff)
return -2;
code = (((code & 0x3ff) << 10) | (next & 0x3ff)) + 0x10000;
@@ -192,9 +170,9 @@ static int __parse_json_unicode(const char *cursor, const char **end,
utf8[1] = 0x80 | (code & 0x3f);
return 2;
}
else if (code <= 0xffff)
else if (code <= 0xffff)
{
utf8[0] = 0xe0 | (code >> 12);
utf8[0] = 0xe0 | (code >> 12);
utf8[1] = 0x80 | ((code >> 6) & 0x3f);
utf8[2] = 0x80 | (code & 0x3f);
return 3;
@@ -466,13 +444,152 @@ static int __parse_json_number(const char *cursor, const char **end,
return 0;
}
static void __insert_json_member(json_member_t *memb, struct list_head *pos,
json_object_t *obj)
{
struct rb_node **p = &obj->root.rb_node;
struct rb_node *parent = NULL;
json_member_t *entry;
while (*p)
{
parent = *p;
entry = rb_entry(*p, json_member_t, rb);
if (strcmp(memb->name, entry->name) < 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
rb_link_node(&memb->rb, parent, p);
rb_insert_color(&memb->rb, &obj->root);
list_add(&memb->list, pos);
}
static int __parse_json_value(const char *cursor, const char **end,
int depth, json_value_t *val);
static void __destroy_json_value(json_value_t *val);
static int __parse_json_member(const char *cursor, const char **end,
int depth, json_member_t *memb)
{
int ret;
ret = __parse_json_string(cursor, &cursor, memb->name);
if (ret < 0)
return ret;
while (isspace(*cursor))
cursor++;
if (*cursor != ':')
return -2;
cursor++;
while (isspace(*cursor))
cursor++;
ret = __parse_json_value(cursor, &cursor, depth, &memb->value);
if (ret < 0)
return ret;
*end = cursor;
return 0;
}
static int __parse_json_members(const char *cursor, const char **end,
int depth, json_object_t *obj)
{
json_member_t *memb;
int cnt = 0;
int ret;
while (isspace(*cursor))
cursor++;
if (*cursor == '}')
{
*end = cursor + 1;
return 0;
}
while (1)
{
if (*cursor != '\"')
return -2;
cursor++;
ret = __json_string_length(cursor);
if (ret < 0)
return ret;
memb = (json_member_t *)malloc(offsetof(json_member_t, name) + ret + 1);
if (!memb)
return -1;
ret = __parse_json_member(cursor, &cursor, depth, memb);
if (ret < 0)
{
free(memb);
return ret;
}
__insert_json_member(memb, obj->head.prev, obj);
cnt++;
while (isspace(*cursor))
cursor++;
if (*cursor == ',')
{
cursor++;
while (isspace(*cursor))
cursor++;
}
else if (*cursor == '}')
break;
else
return -2;
}
*end = cursor + 1;
return cnt;
}
static void __destroy_json_members(json_object_t *obj)
{
struct list_head *pos, *tmp;
json_member_t *memb;
list_for_each_safe(pos, tmp, &obj->head)
{
memb = list_entry(pos, json_member_t, list);
__destroy_json_value(&memb->value);
free(memb);
}
}
static int __parse_json_object(const char *cursor, const char **end,
int depth, json_object_t *obj);
int depth, json_object_t *obj)
{
int ret;
if (depth == JSON_DEPTH_LIMIT)
return -3;
INIT_LIST_HEAD(&obj->head);
obj->root.rb_node = NULL;
ret = __parse_json_members(cursor, end, depth + 1, obj);
if (ret < 0)
{
__destroy_json_members(obj);
return ret;
}
obj->size = ret;
return 0;
}
static int __parse_json_elements(const char *cursor, const char **end,
int depth, json_array_t *arr)
@@ -652,105 +769,6 @@ static int __parse_json_value(const char *cursor, const char **end,
return 0;
}
static int __parse_json_member(const char *cursor, const char **end,
int depth, json_member_t *memb)
{
int ret;
ret = __parse_json_string(cursor, &cursor, memb->name);
if (ret < 0)
return ret;
while (isspace(*cursor))
cursor++;
if (*cursor != ':')
return -2;
cursor++;
while (isspace(*cursor))
cursor++;
ret = __parse_json_value(cursor, &cursor, depth, &memb->value);
if (ret < 0)
return ret;
*end = cursor;
return 0;
}
static int __parse_json_members(const char *cursor, const char **end,
int depth, json_object_t *obj)
{
json_member_t *memb;
int cnt = 0;
int ret;
while (isspace(*cursor))
cursor++;
if (*cursor == '}')
{
*end = cursor + 1;
return 0;
}
while (1)
{
if (*cursor != '\"')
return -2;
cursor++;
ret = __json_string_length(cursor);
if (ret < 0)
return ret;
memb = (json_member_t *)malloc(offsetof(json_member_t, name) + ret + 1);
if (!memb)
return -1;
ret = __parse_json_member(cursor, &cursor, depth, memb);
if (ret < 0)
{
free(memb);
return ret;
}
__insert_json_member(memb, obj->head.prev, obj);
cnt++;
while (isspace(*cursor))
cursor++;
if (*cursor == ',')
{
cursor++;
while (isspace(*cursor))
cursor++;
}
else if (*cursor == '}')
break;
else
return -2;
}
*end = cursor + 1;
return cnt;
}
static void __destroy_json_members(json_object_t *obj)
{
struct list_head *pos, *tmp;
json_member_t *memb;
list_for_each_safe(pos, tmp, &obj->head)
{
memb = list_entry(pos, json_member_t, list);
__destroy_json_value(&memb->value);
free(memb);
}
}
static void __destroy_json_value(json_value_t *val)
{
switch (val->type)
@@ -769,27 +787,6 @@ static void __destroy_json_value(json_value_t *val)
}
}
static int __parse_json_object(const char *cursor, const char **end,
int depth, json_object_t *obj)
{
int ret;
if (depth == JSON_DEPTH_LIMIT)
return -3;
INIT_LIST_HEAD(&obj->head);
obj->root.rb_node = NULL;
ret = __parse_json_members(cursor, end, depth + 1, obj);
if (ret < 0)
{
__destroy_json_members(obj);
return ret;
}
obj->size = ret;
return 0;
}
static void __move_json_value(json_value_t *src, json_value_t *dest)
{
switch (src->type)