Skip to content

Commit

Permalink
Add json_value_copy().
Browse files Browse the repository at this point in the history
  • Loading branch information
Barenboim committed May 20, 2024
1 parent 9d2ff27 commit 2082c17
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 23 deletions.
165 changes: 142 additions & 23 deletions src/util/json_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,32 @@ static void __destroy_json_value(json_value_t *val)
}
}

json_value_t *json_value_parse(const char *cursor)
{
json_value_t *val;

val = (json_value_t *)malloc(sizeof (json_value_t));
if (!val)
return NULL;

while (isspace(*cursor))
cursor++;

if (__parse_json_value(cursor, &cursor, 0, val) >= 0)
{
while (isspace(*cursor))
cursor++;

if (*cursor == '\0')
return val;

__destroy_json_value(val);
}

free(val);
return NULL;
}

static void __move_json_value(json_value_t *src, json_value_t *dest)
{
switch (src->type)
Expand Down Expand Up @@ -879,52 +905,145 @@ static int __set_json_value(int type, va_list ap, json_value_t *val)
return 0;
}

json_value_t *json_value_parse(const char *cursor)
json_value_t *json_value_create(int type, ...)
{
json_value_t *val;
va_list ap;
int ret;

val = (json_value_t *)malloc(sizeof (json_value_t));
if (!val)
return NULL;

while (isspace(*cursor))
cursor++;
va_start(ap, type);
ret = __set_json_value(type, ap, val);
va_end(ap);
if (ret < 0)
{
free(val);
return NULL;
}

if (__parse_json_value(cursor, &cursor, 0, val) >= 0)
return val;
}

static int __copy_json_value(const json_value_t *src, json_value_t *dest);

static int __copy_json_members(const json_object_t *src, json_object_t *dest)
{
struct list_head *pos;
json_member_t *entry;
json_member_t *memb;
int len;

list_for_each(pos, &src->head)
{
while (isspace(*cursor))
cursor++;
entry = list_entry(pos, json_member_t, list);
len = strlen(entry->name);
memb = (json_member_t *)malloc(offsetof(json_member_t, name) + len + 1);
if (!memb)
return -1;

if (*cursor == '\0')
return val;
if (__copy_json_value(&entry->value, &memb->value) < 0)
{
free(memb);
return -1;
}

__destroy_json_value(val);
memcpy(memb->name, entry->name, len + 1);
__insert_json_member(memb, dest->head.prev, dest);
}

free(val);
return NULL;
return src->size;
}

json_value_t *json_value_create(int type, ...)
static int __copy_json_elements(const json_array_t *src, json_array_t *dest)
{
json_value_t *val;
va_list ap;
int ret;
struct list_head *pos;
json_element_t *entry;
json_element_t *elem;

val = (json_value_t *)malloc(sizeof (json_value_t));
if (!val)
list_for_each(pos, &src->head)
{
elem = (json_element_t *)malloc(sizeof (json_element_t));
if (!elem)
return -1;

entry = list_entry(pos, json_element_t, list);
if (__copy_json_value(&entry->value, &elem->value) < 0)
{
free(elem);
return -1;
}

list_add_tail(&elem->list, &dest->head);
}

return src->size;
}

static int __copy_json_value(const json_value_t *src, json_value_t *dest)
{
int len;

switch (src->type)
{
case JSON_VALUE_STRING:
len = strlen(src->value.string);
dest->value.string = (char *)malloc(len + 1);
if (!dest->value.string)
return -1;

memcpy(dest->value.string, src->value.string, len + 1);
break;

case JSON_VALUE_NUMBER:
dest->value.number = src->value.number;
break;

case JSON_VALUE_OBJECT:
INIT_LIST_HEAD(&dest->value.object.head);
dest->value.object.root.rb_node = NULL;
if (__copy_json_members(&src->value.object, &dest->value.object) < 0)
{
__destroy_json_members(&dest->value.object);
return -1;
}

dest->value.object.size = src->value.object.size;
break;

case JSON_VALUE_ARRAY:
INIT_LIST_HEAD(&dest->value.array.head);
if (__copy_json_elements(&src->value.array, &dest->value.array) < 0)
{
__destroy_json_elements(&dest->value.array);
return -1;
}

dest->value.array.size = src->value.array.size;
break;
}

dest->type = src->type;
return 0;
}

json_value_t *json_value_copy(const json_value_t *val)
{
json_value_t *copy;

copy = (json_value_t *)malloc(sizeof (json_value_t));
if (!copy)
return NULL;

va_start(ap, type);
ret = __set_json_value(type, ap, val);
va_end(ap);
if (ret < 0)
if (__copy_json_value(val, copy) < 0)
{
free(val);
free(copy);
return NULL;
}

return val;
return copy;
}

void json_value_destroy(json_value_t *val)
Expand Down
1 change: 1 addition & 0 deletions src/util/json_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C"

json_value_t *json_value_parse(const char *text);
json_value_t *json_value_create(int type, ...);
json_value_t *json_value_copy(const json_value_t *val);
void json_value_destroy(json_value_t *val);

int json_value_type(const json_value_t *val);
Expand Down

0 comments on commit 2082c17

Please sign in to comment.