]> mj.ucw.cz Git - libucw.git/blob - ucw-json/json.c
fbcd5278c389056c0a8ab09a06c84b5df95f84db
[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   js->trivial_token = json_new_node(js, JSON_INVALID);
19 }
20
21 struct json_context *json_new(void)
22 {
23   struct mempool *mp = mp_new(4096);
24   struct json_context *js = mp_alloc_zero(mp, sizeof(*js));
25   js->pool = mp;
26   json_init(js);
27   return js;
28 }
29
30 void json_delete(struct json_context *js)
31 {
32   mp_delete(js->pool);
33 }
34
35 void json_reset(struct json_context *js)
36 {
37   struct mempool *mp = js->pool;
38   mp_restore(mp, &js->init_state);
39   bzero(js, sizeof(*js));
40   js->pool = mp;
41   json_init(js);
42 }
43
44 void json_push(struct json_context *js)
45 {
46   ASSERT(!js->next_token);
47   mp_push(js->pool);
48 }
49
50 void json_pop(struct json_context *js)
51 {
52   ASSERT(!js->next_token);
53   mp_pop(js->pool);
54 }
55
56 struct json_node *json_new_node(struct json_context *js, enum json_node_type type)
57 {
58   struct json_node *n = mp_alloc_fast(js->pool, sizeof(*n));
59   n->type = type;
60   return n;
61 }
62
63 struct json_node *json_new_array(struct json_context *js)
64 {
65   struct json_node *n = json_new_node(js, JSON_ARRAY);
66   GARY_INIT_SPACE_ALLOC(n->elements, 4, mp_get_allocator(js->pool));
67   return n;
68 }
69
70 void json_array_append(struct json_node *array, struct json_node *elt)
71 {
72   ASSERT(array->type == JSON_ARRAY);
73   *GARY_PUSH(array->elements) = elt;
74 }
75
76 struct json_node *json_new_object(struct json_context *js)
77 {
78   struct json_node *n = json_new_node(js, JSON_OBJECT);
79   GARY_INIT_SPACE_ALLOC(n->pairs, 4, mp_get_allocator(js->pool));
80   return n;
81 }
82
83 void json_object_set(struct json_node *n, const char *key, struct json_node *value)
84 {
85   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
86     if (!strcmp(n->pairs[i].key, key))
87       {
88         if (value)
89           n->pairs[i].value = value;
90         else
91           {
92             n->pairs[i] = n->pairs[GARY_SIZE(n->pairs) - 1];
93             GARY_POP(n->pairs);
94           }
95         return;
96       }
97
98   if (value)
99     {
100       struct json_pair *p = GARY_PUSH(n->pairs);
101       p->key = key;
102       p->value = value;
103     }
104 }
105
106 struct json_node *json_object_get(struct json_node *n, const char *key)
107 {
108   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
109     if (!strcmp(n->pairs[i].key, key))
110       return n->pairs[i].value;
111   return NULL;
112 }