mirror of
https://github.com/sogou/workflow.git
synced 2026-02-08 01:33:17 +08:00
Optimize code structure of json-parser.
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user