]> mj.ucw.cz Git - libucw.git/blob - ucw-json/json.c
JSON: Skeleton, memory representation, parser
[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 #undef LOCAL_DEBUG
11
12 #include <ucw/lib.h>
13 #include <ucw/gary.h>
14 #include <ucw/mempool.h>
15 #include <ucw-json/json.h>
16
17 struct json_context *json_new(void)
18 {
19   struct mempool *mp = mp_new(4096);
20   struct json_context *js = mp_alloc_zero(mp, sizeof(*js));
21   js->pool = mp;
22   mp_save(mp, &js->init_state);
23   return js;
24 }
25
26 void json_delete(struct json_context *js)
27 {
28   mp_delete(js->pool);
29 }
30
31 void json_reset(struct json_context *js)
32 {
33   mp_restore(js->pool, &js->init_state);
34 }
35
36
37 struct json_node *json_new_node(struct json_context *js, enum json_node_type type)
38 {
39   struct json_node *n = mp_alloc_fast(js->pool, sizeof(*n));
40   n->type = type;
41   return n;
42 }
43
44 struct json_node *json_new_array(struct json_context *js)
45 {
46   struct json_node *n = json_new_node(js, JSON_ARRAY);
47   GARY_INIT_SPACE_ALLOC(n->elements, 4, mp_get_allocator(js->pool));
48   return n;
49 }
50
51 void json_array_append(struct json_node *array, struct json_node *elt)
52 {
53   ASSERT(array->type == JSON_ARRAY);
54   *GARY_PUSH(array->elements) = elt;
55 }
56
57 struct json_node *json_new_object(struct json_context *js)
58 {
59   struct json_node *n = json_new_node(js, JSON_OBJECT);
60   GARY_INIT_SPACE_ALLOC(n->pairs, 4, mp_get_allocator(js->pool));
61   return n;
62 }
63
64 void json_object_set(struct json_node *n, const char *key, struct json_node *value)
65 {
66   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
67     if (!strcmp(n->pairs[i].key, key))
68       {
69         if (value)
70           n->pairs[i].value = value;
71         else
72           {
73             n->pairs[i] = n->pairs[GARY_SIZE(n->pairs) - 1];
74             GARY_POP(n->pairs);
75           }
76         return;
77       }
78
79   if (value)
80     {
81       struct json_pair *p = GARY_PUSH(n->pairs);
82       p->key = key;
83       p->value = value;
84     }
85 }
86
87 struct json_node *json_object_get(struct json_node *n, const char *key)
88 {
89   for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
90     if (!strcmp(n->pairs[i].key, key))
91       return n->pairs[i].value;
92   return NULL;
93 }