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
76 #ifndef CBOR_NO_FLOAT
cn_cbor_float_create(float value CBOR_CONTEXT,cn_cbor_errback * errp)77 cn_cbor* cn_cbor_float_create(float value
78 CBOR_CONTEXT,
79 cn_cbor_errback *errp)
80 {
81 cn_cbor* ret;
82 INIT_CB(ret);
83
84 ret->type = CN_CBOR_FLOAT;
85 ret->v.f = value;
86
87 return ret;
88 }
89
cn_cbor_double_create(double value CBOR_CONTEXT,cn_cbor_errback * errp)90 cn_cbor* cn_cbor_double_create(double value
91 CBOR_CONTEXT,
92 cn_cbor_errback *errp)
93 {
94 cn_cbor* ret;
95 INIT_CB(ret);
96
97 ret->type = CN_CBOR_DOUBLE;
98 ret->v.dbl = value;
99
100 return ret;
101 }
102 #endif /* CBOR_NO_FLOAT */
103
_append_kv(cn_cbor * cb_map,cn_cbor * key,cn_cbor * val)104 static bool _append_kv(cn_cbor *cb_map, cn_cbor *key, cn_cbor *val)
105 {
106 //Connect key and value and insert them into the map.
107 key->parent = cb_map;
108 key->next = val;
109 val->parent = cb_map;
110 val->next = NULL;
111
112 if(cb_map->last_child) {
113 cb_map->last_child->next = key;
114 } else {
115 cb_map->first_child = key;
116 }
117 cb_map->last_child = val;
118 cb_map->length += 2;
119 return true;
120 }
121
cn_cbor_map_put(cn_cbor * cb_map,cn_cbor * cb_key,cn_cbor * cb_value,cn_cbor_errback * errp)122 bool cn_cbor_map_put(cn_cbor* cb_map,
123 cn_cbor *cb_key, cn_cbor *cb_value,
124 cn_cbor_errback *errp)
125 {
126 //Make sure input is a map. Otherwise
127 if(!cb_map || !cb_key || !cb_value || cb_map->type != CN_CBOR_MAP)
128 {
129 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
130 return false;
131 }
132
133 return _append_kv(cb_map, cb_key, cb_value);
134 }
135
cn_cbor_mapput_int(cn_cbor * cb_map,int64_t key,cn_cbor * cb_value CBOR_CONTEXT,cn_cbor_errback * errp)136 bool cn_cbor_mapput_int(cn_cbor* cb_map,
137 int64_t key, cn_cbor* cb_value
138 CBOR_CONTEXT,
139 cn_cbor_errback *errp)
140 {
141 cn_cbor* cb_key;
142
143 //Make sure input is a map. Otherwise
144 if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
145 {
146 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
147 return false;
148 }
149
150 cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp);
151 if (!cb_key) { return false; }
152 return _append_kv(cb_map, cb_key, cb_value);
153 }
154
cn_cbor_mapput_string(cn_cbor * cb_map,const char * key,cn_cbor * cb_value CBOR_CONTEXT,cn_cbor_errback * errp)155 bool cn_cbor_mapput_string(cn_cbor* cb_map,
156 const char* key, cn_cbor* cb_value
157 CBOR_CONTEXT,
158 cn_cbor_errback *errp)
159 {
160 cn_cbor* cb_key;
161
162 //Make sure input is a map. Otherwise
163 if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
164 {
165 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
166 return false;
167 }
168
169 cb_key = cn_cbor_string_create(key CBOR_CONTEXT_PARAM, errp);
170 if (!cb_key) { return false; }
171 return _append_kv(cb_map, cb_key, cb_value);
172 }
173
cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback * errp)174 cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
175 {
176 cn_cbor* ret;
177 INIT_CB(ret);
178
179 ret->type = CN_CBOR_ARRAY;
180 ret->flags |= CN_CBOR_FL_COUNT;
181
182 return ret;
183 }
184
cn_cbor_array_append(cn_cbor * cb_array,cn_cbor * cb_value,cn_cbor_errback * errp)185 bool cn_cbor_array_append(cn_cbor* cb_array,
186 cn_cbor* cb_value,
187 cn_cbor_errback *errp)
188 {
189 //Make sure input is an array.
190 if(!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY)
191 {
192 if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
193 return false;
194 }
195
196 cb_value->parent = cb_array;
197 cb_value->next = NULL;
198 if(cb_array->last_child) {
199 cb_array->last_child->next = cb_value;
200 } else {
201 cb_array->first_child = cb_value;
202 }
203 cb_array->last_child = cb_value;
204 cb_array->length++;
205 return true;
206 }
207
208 #ifdef __cplusplus
209 }
210 #endif
211
212 #endif /* CN_CBOR_C */
213