diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h index 187a55c..a4ed028 100644 --- a/include/cn-cbor/cn-cbor.h +++ b/include/cn-cbor/cn-cbor.h @@ -425,6 +425,22 @@ bool cn_cbor_array_append(cn_cbor* cb_array, cn_cbor* cb_value, cn_cbor_errback *errp); +/** + * Remove an item from a CBOR array. + * + * The removed node is automatically freed on succes. + * + * @param[in] cb_array The array from which to remove + * @param[in] cb_value The value to remove + * @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined) + * @param[out] errp Error + * @return True on success + */ +bool cn_cbor_array_remove(cn_cbor* cb_array, + cn_cbor* cb_value + CBOR_CONTEXT, + cn_cbor_errback *errp); + #ifdef __cplusplus } #endif diff --git a/src/cn-create.c b/src/cn-create.c index 4ddce3b..dd402fc 100644 --- a/src/cn-create.c +++ b/src/cn-create.c @@ -205,6 +205,47 @@ bool cn_cbor_array_append(cn_cbor* cb_array, return true; } +bool cn_cbor_array_remove(cn_cbor* cb_array, + cn_cbor* cb_value + CBOR_CONTEXT, + cn_cbor_errback *errp) +{ + //Make sure input is an array. + if(!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY || + cb_value->parent != cb_array) + { + if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;} + return false; + } + + cn_cbor *p = cb_array->first_child; + if (p == cb_value) { + cb_array->first_child = cb_value->next; + p = NULL; + } else { + while (p) { + if (p->next == cb_value) { + break; + } + p = p->next; + } + } + if (cb_array->last_child == cb_value) { + cb_array->last_child = p; + if (p) { + p->next = NULL; + } + } + if (p && p->next) { + p->next = p->next->next; + } + cb_array->length--; + cb_value->next = NULL; + cb_value->parent = NULL; + cn_cbor_free(cb_value CBOR_CONTEXT_PARAM); + return true; +} + #ifdef __cplusplus } #endif diff --git a/test/cbor_test.c b/test/cbor_test.c index eafea5d..251c923 100644 --- a/test/cbor_test.c +++ b/test/cbor_test.c @@ -419,6 +419,28 @@ CTEST(cbor, array) cn_cbor_array_append(a, cn_cbor_string_create("five", CONTEXT_NULL_COMMA &err), &err); ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR); ASSERT_EQUAL(a->length, 2); + + cn_cbor_array_append(a, cn_cbor_string_create("six", CONTEXT_NULL_COMMA &err), &err); + ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR); + ASSERT_EQUAL(a->length, 3); + + cn_cbor *e = cn_cbor_index(a, 1); + ASSERT_NOT_NULL(e); + cn_cbor_array_remove(a, e, &err); + ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR); + ASSERT_EQUAL(a->length, 2); + + e = cn_cbor_index(a, 1); + ASSERT_NOT_NULL(e); + cn_cbor_array_remove(a, e, &err); + ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR); + ASSERT_EQUAL(a->length, 1); + + e = cn_cbor_index(a, 0); + ASSERT_NOT_NULL(e); + cn_cbor_array_remove(a, e, &err); + ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR); + ASSERT_EQUAL(a->length, 0); } CTEST(cbor, array_errors) @@ -429,6 +451,11 @@ CTEST(cbor, array_errors) ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER); cn_cbor_array_append(ci, NULL, &err); ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER); + + cn_cbor *e = cn_cbor_string_create("six", CONTEXT_NULL_COMMA &err); + cn_cbor *a = cn_cbor_array_create(CONTEXT_NULL_COMMA &err); + cn_cbor_array_remove(a, e, &err); + ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER); } CTEST(cbor, create_encode)