• 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 
_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