From 447edf7e4916b4ae6ea4c8691eb43c85abbf8a7a Mon Sep 17 00:00:00 2001 From: Xie Han <63350856@qq.com> Date: Thu, 21 Dec 2023 22:49:43 +0800 Subject: [PATCH 1/4] update json-parser. --- json_parser.c | 373 ++++++++++++++++++++++++++------------------------ list.h | 180 ++++++++++++------------ 2 files changed, 285 insertions(+), 268 deletions(-) diff --git a/json_parser.c b/json_parser.c index 3f876c9..4b0e089 100644 --- a/json_parser.c +++ b/json_parser.c @@ -52,28 +52,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; @@ -122,7 +100,7 @@ static int __parse_json_hex4(const char *cursor, const char **end, *code = (*code << 4) + hex; cursor++; - } + } *end = cursor; return 0; @@ -157,7 +135,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; @@ -174,9 +152,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; @@ -252,7 +230,7 @@ static int __parse_json_string(const char *cursor, const char **end, return 0; } -static double __power_of_10[309] = { +static const double __power_of_10[309] = { 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, @@ -332,13 +310,15 @@ static double __evaluate_json_number(const char *integer, if (*integer != '0') { - figures++; mant = *integer - '0'; - while (isdigit(*++integer) && figures < 18) + integer++; + figures++; + while (isdigit(*integer) && figures < 18) { - figures++; mant *= 10; mant += *integer - '0'; + integer++; + figures++; } while (isdigit(*integer)) @@ -358,12 +338,28 @@ static double __evaluate_json_number(const char *integer, while (isdigit(*fraction) && figures < 18) { - figures++; mant *= 10; mant += *fraction - '0'; - exp--; fraction++; + figures++; + } + + if (exp != 0 && figures != 0) + { + while (exp > 0 && figures < 18) + { + mant *= 10; + exp--; + figures++; + } + + while (exp < 0 && mant % 10 == 0) + { + mant /= 10; + exp++; + figures--; + } } num = mant; @@ -378,7 +374,7 @@ static double __evaluate_json_number(const char *integer, else if (exp > -324 - figures) { num /= __power_of_10[-exp - 308]; - num /= 1.0e308; + num /= __power_of_10[308]; } else num = 0.0; @@ -404,22 +400,26 @@ static int __parse_json_number(const char *cursor, const char **end, if (*cursor == '0' && isdigit(cursor[1])) return -2; - while (isdigit(*++cursor)) - ; + cursor++; + while (isdigit(*cursor)) + cursor++; if (*cursor == '.') { - fraction = ++cursor; + cursor++; + fraction = cursor; if (!isdigit(*cursor)) return -2; - while (isdigit(*++cursor)) - ; + cursor++; + while (isdigit(*cursor)) + cursor++; } if (*cursor == 'E' || *cursor == 'e') { - sign = (*++cursor == '-'); + cursor++; + sign = (*cursor == '-'); if (sign || *cursor == '+') cursor++; @@ -427,15 +427,17 @@ static int __parse_json_number(const char *cursor, const char **end, return -2; exp = *cursor - '0'; - while (isdigit(*++cursor)) + cursor++; + while (isdigit(*cursor) && exp < 2000000) { - if (exp < 2000000) - { - exp *= 10; - exp += *cursor - '0'; - } + exp *= 10; + exp += *cursor - '0'; + cursor++; } + while (isdigit(*cursor)) + cursor++; + if (sign) exp = -exp; } @@ -448,13 +450,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) @@ -634,105 +775,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) @@ -751,27 +793,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) @@ -848,7 +869,6 @@ static int __set_json_value(int type, va_list ap, json_value_t *val) json_value_t *json_value_parse(const char *doc) { json_value_t *val; - int ret; val = (json_value_t *)malloc(sizeof (json_value_t)); if (!val) @@ -857,26 +877,19 @@ json_value_t *json_value_parse(const char *doc) while (isspace(*doc)) doc++; - ret = __parse_json_value(doc, &doc, 0, val); - if (ret >= 0) + if (__parse_json_value(doc, &doc, 0, val) >= 0) { while (isspace(*doc)) doc++; - if (*doc) - { - __destroy_json_value(val); - ret = -2; - } - } + if (*doc == '\0') + return val; - if (ret < 0) - { - free(val); - return NULL; + __destroy_json_value(val); } - return val; + free(val); + return NULL; } json_value_t *json_value_create(int type, ...) diff --git a/list.h b/list.h index 2552b62..02f69d7 100644 --- a/list.h +++ b/list.h @@ -2,7 +2,7 @@ #define _LINUX_LIST_H /* - * Simple doubly linked list implementation. + * Circular doubly linked list implementation. * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as @@ -20,6 +20,13 @@ struct list_head { #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) +/** + * INIT_LIST_HEAD - Initialize a list_head structure + * @list: list_head structure to be initialized. + * + * Initializes the list_head to point to itself. If it is a list header, + * the result is an empty list. + */ static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; @@ -32,41 +39,41 @@ static inline void INIT_LIST_HEAD(struct list_head *list) * This is only for internal list manipulation where we know * the prev/next entries already! */ -static inline void __list_add(struct list_head *node, - struct list_head *prev, - struct list_head *next) +static inline void __list_add(struct list_head *entry, + struct list_head *prev, + struct list_head *next) { - next->prev = node; - node->next = next; - node->prev = prev; - prev->next = node; + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; } /** * list_add - add a new entry - * @new: new entry to be added + * @entry: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ -static inline void list_add(struct list_head *node, struct list_head *head) +static inline void list_add(struct list_head *entry, struct list_head *head) { - __list_add(node, head, head->next); + __list_add(entry, head, head->next); } /** * list_add_tail - add a new entry - * @new: new entry to be added + * @entry: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ -static inline void list_add_tail(struct list_head *node, - struct list_head *head) +static inline void list_add_tail(struct list_head *entry, + struct list_head *head) { - __list_add(node, head->prev, head); + __list_add(entry, head->prev, head); } /* @@ -85,7 +92,8 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) /** * list_del - deletes entry from list. * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. */ static inline void list_del(struct list_head *entry) { @@ -94,25 +102,25 @@ static inline void list_del(struct list_head *entry) /** * list_move - delete from one list and add as another's head - * @list: the entry to move + * @entry: the entry to move * @head: the head that will precede our entry */ -static inline void list_move(struct list_head *list, struct list_head *head) +static inline void list_move(struct list_head *entry, struct list_head *head) { - __list_del(list->prev, list->next); - list_add(list, head); + __list_del(entry->prev, entry->next); + list_add(entry, head); } /** * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move + * @entry: the entry to move * @head: the head that will follow our entry */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) +static inline void list_move_tail(struct list_head *entry, + struct list_head *head) { - __list_del(list->prev, list->next); - list_add_tail(list, head); + __list_del(entry->prev, entry->next); + list_add_tail(entry, head); } /** @@ -124,18 +132,18 @@ static inline int list_empty(const struct list_head *head) return head->next == head; } -static inline void __list_splice(struct list_head *list, - struct list_head *head) +static inline void __list_splice(const struct list_head *list, + struct list_head *prev, + struct list_head *next) { struct list_head *first = list->next; struct list_head *last = list->prev; - struct list_head *at = head->next; - first->prev = head; - head->next = first; + first->prev = prev; + prev->next = first; - last->next = at; - at->prev = last; + last->next = next; + next->prev = last; } /** @@ -143,10 +151,11 @@ static inline void __list_splice(struct list_head *list, * @list: the new list to add. * @head: the place to add it in the first list. */ -static inline void list_splice(struct list_head *list, struct list_head *head) +static inline void list_splice(const struct list_head *list, + struct list_head *head) { if (!list_empty(list)) - __list_splice(list, head); + __list_splice(list, head, head->next); } /** @@ -157,10 +166,10 @@ static inline void list_splice(struct list_head *list, struct list_head *head) * The list at @list is reinitialised */ static inline void list_splice_init(struct list_head *list, - struct list_head *head) + struct list_head *head) { if (!list_empty(list)) { - __list_splice(list, head); + __list_splice(list, head, head->next); INIT_LIST_HEAD(list); } } @@ -175,7 +184,7 @@ static inline void list_splice_init(struct list_head *list, ((type *)((char *)(ptr)-(size_t)(&((type *)0)->member))) /** - * list_for_each - iterate over a list + * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ @@ -183,7 +192,7 @@ static inline void list_splice_init(struct list_head *list, for (pos = (head)->next; pos != (head); pos = pos->next) /** - * list_for_each_prev - iterate over a list backwards + * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ @@ -191,28 +200,28 @@ static inline void list_splice_init(struct list_head *list, for (pos = (head)->prev; pos != (head); pos = pos->prev) /** - * list_for_each_safe - iterate over a list safe against removal of list entry + * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop counter. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) + pos = n, n = pos->next) /** - * list_for_each_entry - iterate over list of given type + * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof (*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof (*pos), member)) + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof (*pos), member)) -/** - * Single-linked list. Added by Xie Han . +/* + * Singly linked list implementation. */ struct slist_node { @@ -223,7 +232,7 @@ struct slist_head { struct slist_node first, *last; }; -#define SLIST_HEAD_INIT(name) { { (struct slist_node *)0 }, &(name).first } +#define SLIST_HEAD_INIT(name) { { (struct slist_node *)0 }, &(name).first } #define SLIST_HEAD(name) \ struct slist_head name = SLIST_HEAD_INIT(name) @@ -234,77 +243,72 @@ static inline void INIT_SLIST_HEAD(struct slist_head *list) list->last = &list->first; } -static inline void slist_add_head(struct slist_node *node, - struct slist_head *list) +static inline void slist_add_after(struct slist_node *entry, + struct slist_node *prev, + struct slist_head *list) { - node->next = list->first.next; - list->first.next = node; - if (!node->next) - list->last = node; + entry->next = prev->next; + prev->next = entry; + if (!entry->next) + list->last = entry; } -static inline void slist_add_tail(struct slist_node *node, - struct slist_head *list) +static inline void slist_add_head(struct slist_node *entry, + struct slist_head *list) { - node->next = (struct slist_node *)0; - list->last->next = node; - list->last = node; + slist_add_after(entry, &list->first, list); } -static inline void slist_add_after(struct slist_node *node, - struct slist_node *prev, - struct slist_head *list) +static inline void slist_add_tail(struct slist_node *entry, + struct slist_head *list) { - node->next = prev->next; - prev->next = node; - if (!node->next) - list->last = node; -} - -static inline void slist_del_head(struct slist_head *list) -{ - list->first.next = list->first.next->next; - if (!list->first.next) - list->last = &list->first; + entry->next = (struct slist_node *)0; + list->last->next = entry; + list->last = entry; } static inline void slist_del_after(struct slist_node *prev, - struct slist_head *list) + struct slist_head *list) { prev->next = prev->next->next; if (!prev->next) list->last = prev; } -static inline int slist_empty(struct slist_head *list) +static inline void slist_del_head(struct slist_head *list) +{ + slist_del_after(&list->first, list); +} + +static inline int slist_empty(const struct slist_head *list) { return !list->first.next; } -static inline void __slist_splice(struct slist_head *list, - struct slist_node *at, - struct slist_head *head) +static inline void __slist_splice(const struct slist_head *list, + struct slist_node *prev, + struct slist_head *head) { - list->last->next = at->next; - at->next = list->first.next; + list->last->next = prev->next; + prev->next = list->first.next; if (!list->last->next) head->last = list->last; } -static inline void slist_splice(struct slist_head *list, - struct slist_node *at, - struct slist_head *head) +static inline void slist_splice(const struct slist_head *list, + struct slist_node *prev, + struct slist_head *head) { if (!slist_empty(list)) - __slist_splice(list, at, head); + __slist_splice(list, prev, head); } static inline void slist_splice_init(struct slist_head *list, - struct slist_node *at, - struct slist_head *head) + struct slist_node *prev, + struct slist_head *head) { if (!slist_empty(list)) { - __slist_splice(list, at, head); + __slist_splice(list, prev, head); INIT_SLIST_HEAD(list); } } @@ -317,11 +321,11 @@ static inline void slist_splice_init(struct slist_head *list, #define slist_for_each_safe(pos, prev, head) \ for (prev = &(head)->first, pos = prev->next; pos; \ - prev = prev->next == pos ? pos : prev, pos = prev->next) + prev = prev->next == pos ? pos : prev, pos = prev->next) #define slist_for_each_entry(pos, head, member) \ for (pos = slist_entry((head)->first.next, typeof (*pos), member); \ - &pos->member != (struct slist_node *)0; \ - pos = slist_entry(pos->member.next, typeof (*pos), member)) + &pos->member != (struct slist_node *)0; \ + pos = slist_entry(pos->member.next, typeof (*pos), member)) #endif From 489a8dcac8d3e56b44ae600484296085e2f44e07 Mon Sep 17 00:00:00 2001 From: Xie Han <63350856@qq.com> Date: Sun, 24 Dec 2023 01:19:46 +0800 Subject: [PATCH 2/4] fix: bug when pushing back a vector. --- Json.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Json.cc b/Json.cc index 2505a7a..ff8f701 100644 --- a/Json.cc +++ b/Json.cc @@ -552,15 +552,18 @@ void Json::normal_push_back(const std::string& key, { json_object_t* obj = json_value_object(parent_); const json_value_t* find = json_object_find(key.c_str(), obj); + const json_value_t* v; if (find == nullptr) { - json_object_append(obj, key.c_str(), JSON_VALUE_NULL); - return; + v = json_object_append(obj, key.c_str(), JSON_VALUE_ARRAY); + } + else + { + v = json_object_insert_before(find, obj, key.c_str(), + JSON_VALUE_ARRAY); + json_value_t* remove_val = json_object_remove(find, obj); + json_value_destroy(remove_val); } - const json_value_t *v = json_object_insert_before(find, obj, key.c_str(), - JSON_VALUE_ARRAY); - json_value_t* remove_val = json_object_remove(find, obj); - json_value_destroy(remove_val); json_array_t* arr = json_value_array(v); for (const auto& str : val) json_array_append(arr, JSON_VALUE_STRING, str.c_str()); From ffb4dbbce3fa52db0afe964d1a3b440fbf1dec00 Mon Sep 17 00:00:00 2001 From: Xie Han <63350856@qq.com> Date: Sun, 24 Dec 2023 03:43:29 +0800 Subject: [PATCH 3/4] feat: enable pushing back a placeholder array. --- Json.cc | 20 ++++++++++++++++++++ Json.h | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/Json.cc b/Json.cc index ff8f701..6c880c6 100644 --- a/Json.cc +++ b/Json.cc @@ -602,6 +602,11 @@ Json Json::copy() const void Json::push_back(bool val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; @@ -613,6 +618,11 @@ void Json::push_back(bool val) void Json::push_back(std::nullptr_t val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; @@ -635,6 +645,11 @@ void Json::push_back(const std::vector& val) void Json::push_back(const char* val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; @@ -645,6 +660,11 @@ void Json::push_back(const char* val) void Json::push_back(const Json& val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; diff --git a/Json.h b/Json.h index 14a06ae..ad1924d 100644 --- a/Json.h +++ b/Json.h @@ -345,6 +345,11 @@ class Json bool>::type = true> void push_back(T val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; @@ -359,6 +364,11 @@ class Json bool>::type = true> void push_back(const T& val) { + if (is_placeholder()) + { + *this = Json::Array{{val}}; + return; + } if (!can_arr_push_back()) { return; From 0c1a6e78f9833fe5cb7051657492674518e3d41d Mon Sep 17 00:00:00 2001 From: Xie Han <63350856@qq.com> Date: Sun, 24 Dec 2023 04:26:46 +0800 Subject: [PATCH 4/4] feat: enable pushing a placeholder object. --- Json.cc | 36 ++++++++++++++++++++++++++++++++++++ Json.h | 11 +++++++++++ 2 files changed, 47 insertions(+) diff --git a/Json.cc b/Json.cc index 6c880c6..0f8892e 100644 --- a/Json.cc +++ b/Json.cc @@ -101,6 +101,17 @@ Json::Json(const std::string& str, bool parse_flag) : parent_(nullptr) allocated_ = node_ == nullptr ? false : true; } +Json::Json(const std::vector& val) + : node_(json_value_create(JSON_VALUE_ARRAY)), + parent_(nullptr), allocated_(true) +{ + json_array_t* arr = json_value_array(node_); + for (const auto& str : val) + { + json_array_append(arr, JSON_VALUE_STRING, str.c_str()); + } +} + Json::~Json() { destroy_node(&node_); @@ -378,6 +389,11 @@ bool Json::can_obj_push_back() void Json::push_back(const std::string& key, bool val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -389,6 +405,11 @@ void Json::push_back(const std::string& key, bool val) void Json::push_back(const std::string& key, std::nullptr_t val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -404,6 +425,11 @@ void Json::push_back(const std::string& key, const std::string& val) void Json::push_back(const std::string& key, const char* val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -414,6 +440,11 @@ void Json::push_back(const std::string& key, const char* val) void Json::push_back(const std::string& key, const std::vector& val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -430,6 +461,11 @@ void Json::push_back(const std::string& key, const std::vector& val void Json::push_back(const std::string& key, const Json& val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; diff --git a/Json.h b/Json.h index ad1924d..3d53523 100644 --- a/Json.h +++ b/Json.h @@ -204,6 +204,11 @@ class Json bool>::type = true> void push_back(const std::string& key, const T& val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -219,6 +224,11 @@ class Json bool>::type = true> void push_back(const std::string& key, const T& val) { + if (is_placeholder()) + { + *this = Json::Object{{key, val}}; + return; + } if (!can_obj_push_back()) { return; @@ -722,6 +732,7 @@ class Json Json(double val); Json(int val); Json(bool val); + Json(const std::vector& val); // For parse Json(const std::string& str, bool parse_flag);