]> mj.ucw.cz Git - libucw.git/blob - ucw-json/json.c
JSON: Tests and bug fixes
[libucw.git] / ucw-json / json.c
1 /*
2  *      UCW JSON Library -- Data Representation
3  *
4  *      (c) 2015 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include <ucw/lib.h>
11 #include <ucw/gary.h>
12 #include <ucw/mempool.h>
13 #include <ucw-json/json.h>
14
15 static void json_init(struct json_context *js)
16 {
17   mp_save(js->pool, &js->init_state);
18 }
19
20 struct json_context *json_new(void)
21 {
22   struct mempool *mp = mp_new(4096);
23   struct json_context *js = mp_alloc_zero(mp, sizeof(*js));
24   js->pool = mp;
25   json_init(js);
26   return js;
27 }
28
29 void json_delete(struct json_context *js)
30 {
31   mp_delete(js->pool);
32 }
33
34 void json_reset(struct json_context *js)
35 {
36   struct mempool *mp = js->pool;
37   mp_restore(mp, &js->init_state);
38   bzero(js, sizeof(*js));
39   js->pool = mp;
40   json_init(js);
41 }
42
43 struct json_node *json_new_node(struct json_context *js, enum json_node_type type)
44 {
45   struct json_node *n = mp_alloc_fast(js->pool, sizeof(*n));
46   n->type = type;
47   return n;
48 }
49
50 struct json_node *json_new_array(struct json_context *js)
51 {
52   struct json_node *n = json_new_node(js, JSON_ARRAY);
53   GARY_INIT_SPACE_ALLOC(n->elements, 4, mp_get_allocator(js->pool));
54   return n;
55 }
56
57 void json_array_append(struct json_node *array, struct json_node *elt)
58 {
59   ASSERT(array->type == JSON_ARRAY);
60   *GARY_PUSH(array->elements) = elt;
61 }
62
63 struct json_node *json_new_object(struct json_context *js)
64 {
65   struct json_node *n = json_new_node(js, JSON_OBJECT);
66   GARY_INIT_SPACE_ALLOC(n->pairs, 4, mp_get_allocator(js->pool));
67   return n;
68 }
69
70 void json_object_set(struct json_node *n, const char *key, struct json_node *value)
71 {
72   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
73     if (!strcmp(n->pairs[i].key, key))
74       {
75         if (value)
76           n->pairs[i].value = value;
77         else
78           {
79             n->pairs[i] = n->pairs[GARY_SIZE(n->pairs) - 1];
80             GARY_POP(n->pairs);
81           }
82         return;
83       }
84
85   if (value)
86     {
87       struct json_pair *p = GARY_PUSH(n->pairs);
88       p->key = key;
89       p->value = value;
90     }
91 }
92
93 struct json_node *json_object_get(struct json_node *n, const char *key)
94 {
95   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
96     if (!strcmp(n->pairs[i].key, key))
97       return n->pairs[i].value;
98   return NULL;
99 }