• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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