1 #ifndef CN_CREATE_C
2 #define CN_CREATE_C
3
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7
8 #include <string.h>
9 #include <stdlib.h>
10
11 #include "cn-cbor/cn-cbor.h"
12 #include "cbor.h"
13
14 #define INIT_CB(v) \
15 if (errp) {errp->err = CN_CBOR_NO_ERROR;} \
16 (v) = CN_CALLOC_CONTEXT(); \
17 if (!(v)) { if (errp) {errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;} return NULL; }
18
cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback * errp)19 cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
20 {
21 cn_cbor* ret;
22 INIT_CB(ret);
23
24 ret->type = CN_CBOR_MAP;
25 ret->flags |= CN_CBOR_FL_COUNT;
26
27 return ret;
28 }
29
cn_cbor_data_create(const uint8_t * data,int len CBOR_CONTEXT,cn_cbor_errback * errp)30 cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
31 CBOR_CONTEXT,
32 cn_cbor_errback *errp)
33 {
34 cn_cbor* ret;
35 INIT_CB(ret);
36
37 ret->type = CN_CBOR_BYTES;
38 ret->length = len;
39 ret->v.str = (const char*) data; // TODO: add v.ustr to the union?
40
41 return ret;
42 }
43
cn_cbor_string_create(const char * data CBOR_CONTEXT,cn_cbor_errback * errp)44 cn_cbor* cn_cbor_string_create(const char* data
45 CBOR_CONTEXT,
46 cn_cbor_errback *errp)
47 {
48 cn_cbor* ret;
49 INIT_CB(ret);
50
51 ret->type = CN_CBOR_TEXT;
52 ret->length = strlen(data);
53 ret->v.str = data;
54
55 return ret;
56 }
57
cn_cbor_int_create(int64_t value CBOR_CONTEXT,cn_cbor_errback * errp)58 cn_cbor* cn_cbor_int_create(int64_t value
59 CBOR_CONTEXT,
60 cn_cbor_errback *errp)
61 {
62 cn_cbor* ret;
63 INIT_CB(ret);
64
65 if (value<0) {
66 ret->type = CN_CBOR_INT;
67 ret->v.sint = value;
68 } else {
69 ret->type = CN_CBOR_UINT;
70 ret->v.uint = value;
71 }
72
73 return ret;
74 }
75
_append_kv(cn_cbor * cb_map,cn_cbor * key,cn_cbor * val)76 static bool _append_kv(cn_cbor *cb_map, cn_cbor *key, cn_cbor *val)
77 {
78 //Connect key and value and insert them into the map.
79 key->parent = cb_map;
80 key->next = val;
81 val->parent = cb_map;
82 val->next = NULL;
83
84 if(cb_map->last_child) {
85 cb_map->last_child->next = key;
86 } else {
87 cb_map->first_child = key;
88 }
89 cb_map->last_child = val;
90 cb_map->length += 2;
91 return true;
92 }
93
cn_cbor_map_put(cn_cbor * cb_map,cn_cbor * cb_key,cn_cbor * cb_value,cn_cbor_errback * errp)94 bool cn_cbor_map_put(cn_cbor* cb_map,
95 cn_cbor *cb_key, cn_cbor *cb_value,
96 cn_cbor_errback *errp)
97 {
98 //Make sure input is a map. Otherwise
99 if(!cb_map || !cb_key || !cb_value || cb_map->type != CN_CBOR_MAP)
100 {
101 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
102 return false;
103 }
104
105 return _append_kv(cb_map, cb_key, cb_value);
106 }
107
cn_cbor_mapput_int(cn_cbor * cb_map,int64_t key,cn_cbor * cb_value CBOR_CONTEXT,cn_cbor_errback * errp)108 bool cn_cbor_mapput_int(cn_cbor* cb_map,
109 int64_t key, cn_cbor* cb_value
110 CBOR_CONTEXT,
111 cn_cbor_errback *errp)
112 {
113 cn_cbor* cb_key;
114
115 //Make sure input is a map. Otherwise
116 if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
117 {
118 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
119 return false;
120 }
121
122 cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp);
123 if (!cb_key) { return false; }
124 return _append_kv(cb_map, cb_key, cb_value);
125 }
126
cn_cbor_mapput_string(cn_cbor * cb_map,const char * key,cn_cbor * cb_value CBOR_CONTEXT,cn_cbor_errback * errp)127 bool cn_cbor_mapput_string(cn_cbor* cb_map,
128 const char* key, cn_cbor* cb_value
129 CBOR_CONTEXT,
130 cn_cbor_errback *errp)
131 {
132 cn_cbor* cb_key;
133
134 //Make sure input is a map. Otherwise
135 if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
136 {
137 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
138 return false;
139 }
140
141 cb_key = cn_cbor_string_create(key CBOR_CONTEXT_PARAM, errp);
142 if (!cb_key) { return false; }
143 return _append_kv(cb_map, cb_key, cb_value);
144 }
145
cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback * errp)146 cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
147 {
148 cn_cbor* ret;
149 INIT_CB(ret);
150
151 ret->type = CN_CBOR_ARRAY;
152 ret->flags |= CN_CBOR_FL_COUNT;
153
154 return ret;
155 }
156
cn_cbor_array_append(cn_cbor * cb_array,cn_cbor * cb_value,cn_cbor_errback * errp)157 bool cn_cbor_array_append(cn_cbor* cb_array,
158 cn_cbor* cb_value,
159 cn_cbor_errback *errp)
160 {
161 //Make sure input is an array.
162 if(!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY)
163 {
164 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
165 return false;
166 }
167
168 cb_value->parent = cb_array;
169 cb_value->next = NULL;
170 if(cb_array->last_child) {
171 cb_array->last_child->next = cb_value;
172 } else {
173 cb_array->first_child = cb_value;
174 }
175 cb_array->last_child = cb_value;
176 cb_array->length++;
177 return true;
178 }
179
180 #ifdef __cplusplus
181 }
182 #endif
183
184 #endif /* CN_CBOR_C */
185