| #include "cn-cbor/cn-cbor.h" |
| #include <stdlib.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 false; } |
| |
| #ifdef USE_CBOR_CONTEXT |
| #define CBOR_CONTEXT_PARAM , context |
| |
| #define CN_CALLOC(ctx) ((ctx) && (ctx)->calloc_func) ? \ |
| (ctx)->calloc_func(1, sizeof(cn_cbor), (ctx)->context) : \ |
| calloc(1, sizeof(cn_cbor)); |
| |
| #define CN_CALLOC_CONTEXT() CN_CALLOC(context) |
| #else |
| #define CBOR_CONTEXT_PARAM |
| #define CN_CALLOC(ctx) calloc(1, sizeof(cn_cbor)); |
| #define CN_CALLOC_CONTEXT() CN_CALLOC(context) |
| #endif |
| |
| |
| /*** |
| * Replace the i-th element in the array. |
| * Extend the array if necessary so it has enough elements. |
| * |
| * @param[in] cn_cbor * Array to use |
| * @param[in] const cn_cbor * New item to be placed in the array |
| * @param[in] int Zero based index to be used |
| * @param[in] context * Context based allocation structure |
| * @param[in,out] cn_cbor_errback * CBOR error return on failure |
| * returns bool Did we succeed? |
| */ |
| |
| bool cn_cbor_array_replace(cn_cbor * cb_array, cn_cbor * cb_value, int index, CBOR_CONTEXT_COMMA cn_cbor_errback *errp) |
| { |
| int i; |
| cn_cbor * cb_temp; |
| cn_cbor * cb_temp2; |
| |
| if (!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY) { |
| if (errp != NULL) errp->err = CN_CBOR_ERR_INVALID_PARAMETER; |
| return false; |
| } |
| |
| if (index == 0) { |
| if (cb_array->length > 0) { |
| cb_temp = cb_array->first_child; |
| |
| cb_value->parent = cb_array; |
| cb_value->next = cb_temp->next; |
| if (cb_array->last_child == cb_temp) { |
| cb_array->last_child = cb_value; |
| } |
| cb_array->first_child = cb_value; |
| cb_temp->parent = NULL; |
| cb_temp->next = NULL; |
| cn_cbor_free(cb_temp CBOR_CONTEXT_PARAM); |
| return true; |
| } |
| return cn_cbor_array_append(cb_array, cb_value, errp); |
| } |
| |
| if (cb_array->first_child == NULL) { |
| INIT_CB(cb_temp2); |
| cb_array->first_child = cb_array->last_child = cb_temp2; |
| cb_temp2->parent = cb_array; |
| cb_array->length = 1; |
| cb_temp2->type = CN_CBOR_INVALID; |
| } |
| |
| cb_temp = cb_array->first_child; |
| for (i = 1; i < index; i++) { |
| if (cb_temp->next == NULL) { |
| INIT_CB(cb_temp2); |
| cb_temp2->type = CN_CBOR_INVALID; |
| cb_temp->next = cb_temp2; |
| cb_temp2->parent = cb_array; |
| cb_array->last_child = cb_temp2; |
| cb_array->length += 1; |
| } |
| |
| cb_temp = cb_temp->next; |
| } |
| |
| if (cb_temp->next == NULL) { |
| cb_temp->next = cb_value; |
| cb_value->parent = cb_array; |
| cb_array->last_child = cb_value; |
| cb_array->length += 1; |
| return true; |
| } |
| |
| cb_temp2 = cb_temp->next; |
| cb_value->next = cb_temp2->next; |
| cb_temp->next = cb_value; |
| cb_value->parent = cb_array; |
| if (cb_array->last_child == cb_temp2) { |
| cb_array->last_child = cb_value; |
| } |
| |
| cb_temp2->next = NULL; |
| cb_temp2->parent = NULL; |
| cn_cbor_free(cb_temp2 CBOR_CONTEXT_PARAM); |
| |
| return true; |
| } |