#ifndef CN_CREATE_C #define CN_CREATE_C #ifdef __cplusplus extern "C" { #endif #include <string.h> #include <stdlib.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; } 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; } 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; } 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; } 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; } 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; } 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); } 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); } 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); } 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; } 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 */