| #ifndef CN_CREATE_C |
| #define CN_CREATE_C |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include "dll-export.h" |
| #include "cn-cbor/cn-cbor.h" |
| #include "cbor.h" |
| |
| #define INIT_CB(v) \ |
| if (errp) { \ |
| errp->err = CN_CBOR_NO_ERROR; \ |
| } \ |
| (v) = CN_CALLOC_CONTEXT(); \ |
| if (!(v)) { \ |
| if (errp) { \ |
| errp->err = CN_CBOR_ERR_OUT_OF_MEMORY; \ |
| } \ |
| return NULL; \ |
| } |
| |
| MYLIB_EXPORT |
| cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_MAP; |
| ret->flags |= CN_CBOR_FL_COUNT; |
| |
| return ret; |
| } |
| |
| MYLIB_EXPORT |
| cn_cbor* cn_cbor_data_create(const uint8_t* data, int len CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_BYTES; |
| ret->length = len; |
| ret->v.str = (const char*)data; // TODO: add v.ustr to the union? |
| |
| return ret; |
| } |
| |
| MYLIB_EXPORT |
| cn_cbor* cn_cbor_string_create(const char* data CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_TEXT; |
| ret->length = strlen(data); |
| ret->v.str = data; |
| |
| return ret; |
| } |
| |
| MYLIB_EXPORT |
| cn_cbor* cn_cbor_int_create(int64_t value CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| if (value < 0) { |
| ret->type = CN_CBOR_INT; |
| ret->v.sint = value; |
| } |
| else { |
| ret->type = CN_CBOR_UINT; |
| ret->v.uint = value; |
| } |
| |
| return ret; |
| } |
| |
| #ifndef CBOR_NO_FLOAT |
| cn_cbor* cn_cbor_float_create(float value CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_FLOAT; |
| ret->v.f = value; |
| |
| return ret; |
| } |
| |
| cn_cbor* cn_cbor_double_create(double value CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_DOUBLE; |
| ret->v.dbl = value; |
| |
| return ret; |
| } |
| #endif /* CBOR_NO_FLOAT */ |
| |
| static bool _append_kv(cn_cbor* cb_map, cn_cbor* key, cn_cbor* val) |
| { |
| // Connect key and value and insert them into the map. |
| key->parent = cb_map; |
| key->next = val; |
| val->parent = cb_map; |
| val->next = NULL; |
| |
| if (cb_map->last_child) { |
| cb_map->last_child->next = key; |
| } |
| else { |
| cb_map->first_child = key; |
| } |
| cb_map->last_child = val; |
| cb_map->length += 2; |
| return true; |
| } |
| |
| MYLIB_EXPORT |
| bool cn_cbor_map_put(cn_cbor* cb_map, cn_cbor* cb_key, cn_cbor* cb_value, cn_cbor_errback* errp) |
| { |
| // Make sure input is a map. Otherwise |
| if (!cb_map || !cb_key || !cb_value || cb_map->type != CN_CBOR_MAP) { |
| if (errp) { |
| errp->err = CN_CBOR_ERR_INVALID_PARAMETER; |
| } |
| return false; |
| } |
| |
| return _append_kv(cb_map, cb_key, cb_value); |
| } |
| |
| MYLIB_EXPORT |
| bool cn_cbor_mapput_int(cn_cbor* cb_map, int64_t key, cn_cbor* cb_value CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* cb_key; |
| |
| // Make sure input is a map. Otherwise |
| if (!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP) { |
| if (errp) { |
| errp->err = CN_CBOR_ERR_INVALID_PARAMETER; |
| } |
| return false; |
| } |
| |
| cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp); |
| if (!cb_key) { |
| return false; |
| } |
| return _append_kv(cb_map, cb_key, cb_value); |
| } |
| |
| MYLIB_EXPORT |
| bool cn_cbor_mapput_string(cn_cbor* cb_map, const char* key, cn_cbor* cb_value CBOR_CONTEXT, cn_cbor_errback* errp) |
| { |
| cn_cbor* cb_key; |
| |
| // Make sure input is a map. Otherwise |
| if (!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP) { |
| if (errp) { |
| errp->err = CN_CBOR_ERR_INVALID_PARAMETER; |
| } |
| return false; |
| } |
| |
| cb_key = cn_cbor_string_create(key CBOR_CONTEXT_PARAM, errp); |
| if (!cb_key) { |
| return false; |
| } |
| return _append_kv(cb_map, cb_key, cb_value); |
| } |
| |
| MYLIB_EXPORT |
| cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback* errp) |
| { |
| cn_cbor* ret; |
| INIT_CB(ret); |
| |
| ret->type = CN_CBOR_ARRAY; |
| ret->flags |= CN_CBOR_FL_COUNT; |
| |
| return ret; |
| } |
| |
| MYLIB_EXPORT |
| bool cn_cbor_array_append(cn_cbor* cb_array, cn_cbor* cb_value, cn_cbor_errback* errp) |
| { |
| // Make sure input is an array. |
| if (!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY) { |
| if (errp) { |
| errp->err = CN_CBOR_ERR_INVALID_PARAMETER; |
| } |
| return false; |
| } |
| |
| cb_value->parent = cb_array; |
| cb_value->next = NULL; |
| if (cb_array->last_child) { |
| cb_array->last_child->next = cb_value; |
| } |
| else { |
| cb_array->first_child = cb_value; |
| } |
| cb_array->last_child = cb_value; |
| cb_array->length++; |
| return true; |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* CN_CBOR_C */ |