diff --git a/src/cbor/common.c b/src/cbor/common.c index 9c1239d5..47764277 100644 --- a/src/cbor/common.c +++ b/src/cbor/common.c @@ -158,3 +158,101 @@ cbor_item_t *cbor_move(cbor_item_t *item) { item->refcount--; return item; } + +bool cbor_equal(cbor_item_t *item1, cbor_item_t *item2) { + size_t i; + cbor_item_t * cur_item1, * cur_item2; + bool ret; + + if (item1 != NULL && item2 != NULL) { + if (item1->type != item2->type) { + return false; + } else { + switch (item1->type) { + case CBOR_TYPE_UINT: + case CBOR_TYPE_NEGINT: + if (cbor_int_get_width(item1) != cbor_int_get_width(item2)) { + return false; + } else { + if (cbor_int_get_width(item1) == CBOR_INT_8) + return !memcmp(item1->data, item2->data, sizeof(uint8_t))?true:false; + else if (cbor_int_get_width(item1) == CBOR_INT_16) + return !memcmp(item1->data, item2->data, sizeof(uint16_t))?true:false; + else if (cbor_int_get_width(item1) == CBOR_INT_32) + return !memcmp(item1->data, item2->data, sizeof(uint32_t))?true:false; + else if (cbor_int_get_width(item1) == CBOR_INT_64) + return !memcmp(item1->data, item2->data, sizeof(uint64_t))?true:false; + else + return false; + } + break; + case CBOR_TYPE_BYTESTRING: + if (cbor_bytestring_length(item1) != cbor_bytestring_length(item2)) + return false; + else + return !memcmp(item1->data, item2->data, cbor_bytestring_length(item1))?true:false; + break; + case CBOR_TYPE_STRING: + if (cbor_string_length(item1) != cbor_string_length(item2)) + return false; + else + return !memcmp(item1->data, item2->data, cbor_string_length(item1))?true:false; + break; + case CBOR_TYPE_ARRAY: + if (cbor_array_size(item1) != cbor_array_size(item2)) { + return false; + } else { + ret = true; + for (i=0; i #include #include +#include +#include // TODO REMOVE ME #include "cbor/configuration.h" #include "data.h" @@ -285,6 +287,16 @@ size_t cbor_refcount(const cbor_item_t *item); */ cbor_item_t *cbor_move(cbor_item_t *item); +/** Compares two items + * + * Compares the type, metadata and value of item1 and item2 + * + * @param item1[borrow] the first item + * @param item2[borrow] the second item + * @return the true if item1 and item2 are equal, false otherwise + */ +bool cbor_equal(cbor_item_t *item1, cbor_item_t *item2); + #ifdef __cplusplus } #endif diff --git a/src/cbor/maps.c b/src/cbor/maps.c index 6b04c5ee..dc07a5d5 100644 --- a/src/cbor/maps.c +++ b/src/cbor/maps.c @@ -123,3 +123,20 @@ struct cbor_pair *cbor_map_handle(const cbor_item_t *item) { assert(cbor_isa_map(item)); return (struct cbor_pair *)item->data; } + +struct cbor_item_t *cbor_map_get(const cbor_item_t *item, const cbor_item_t * key) { + size_t i; + struct cbor_pair pair; + cbor_item_t * value = NULL; + assert(cbor_isa_map(item)); + + for (i=0; i + * 2019 Nicolas Mora + * + * libcbor is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include + +#include + +#include "assertions.h" +#include "cbor.h" + +cbor_item_t *item1, *item2; + +static void test_equal_uint(void **state) { + item1 = cbor_build_uint8(10); + item2 = cbor_build_uint8(10); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_uint8(10); + item2 = cbor_build_uint8(8); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_uint8(10); + item2 = cbor_build_uint16(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_uint8(10); + item2 = cbor_build_negint8(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_uint8(10); + item2 = cbor_build_bytestring("test", 4); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_negint(void **state) { + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint8(10); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint8(8); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint16(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_uint8(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_bytestring("test", 4); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_bytestring(void **state) { + item1 = cbor_build_bytestring("test", 4); + item2 = cbor_build_bytestring("test", 4); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_bytestring("test", 4); + item2 = cbor_build_bytestring("tes", 3); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_bytestring("test", 4); + item2 = cbor_build_bytestring("tset", 4); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_bytestring("test", 4); + item2 = cbor_build_negint8(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_string(void **state) { + item1 = cbor_build_string("test"); + item2 = cbor_build_string("test"); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_string("test"); + item2 = cbor_build_string("tes"); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_string("test"); + item2 = cbor_build_string("tset"); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_string("test"); + item2 = cbor_build_negint8(10); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_array(void **state) { + cbor_item_t *element; + + item1 = cbor_new_definite_array(3); + item2 = cbor_new_definite_array(3); + + element = cbor_build_string("test1"); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_string("test1"); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_negint8(10); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_negint8(10); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_bytestring("test", 4); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_bytestring("test", 4); + cbor_array_push(item2, element); + cbor_decref(&element); + + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_definite_array(3); + item2 = cbor_new_definite_array(3); + + element = cbor_build_negint8(10); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_string("test1"); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_string("test1"); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_negint8(10); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_bytestring("test", 4); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_bytestring("test", 4); + cbor_array_push(item2, element); + cbor_decref(&element); + + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_definite_array(3); + item2 = cbor_new_definite_array(2); + + element = cbor_build_string("test1"); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_string("test1"); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_negint8(10); + cbor_array_push(item1, element); + cbor_decref(&element); + + element = cbor_build_negint8(10); + cbor_array_push(item2, element); + cbor_decref(&element); + + element = cbor_build_bytestring("test", 4); + cbor_array_push(item1, element); + cbor_decref(&element); + + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_map(void **state) { + struct cbor_pair pair; + + item1 = cbor_new_definite_map(3); + item2 = cbor_new_definite_map(3); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_definite_map(3); + item2 = cbor_new_definite_map(3); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_definite_map(3); + item2 = cbor_new_definite_map(3); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_string("test"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_definite_map(3); + item2 = cbor_new_definite_map(3); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item1, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(item2, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +static void test_equal_tag(void **state) { + cbor_item_t *tag1, *tag2; + + tag1 = cbor_new_tag(8); + tag2 = cbor_new_tag(8); + + assert_true(cbor_equal(tag1, tag2) == true); + cbor_decref(&tag1); + cbor_decref(&tag2); + + tag1 = cbor_new_tag(6); + tag2 = cbor_new_tag(8); + + assert_true(cbor_equal(tag1, tag2) == false); + cbor_decref(&tag1); + cbor_decref(&tag2); + + tag1 = cbor_new_tag(6); + tag2 = cbor_build_bytestring("test", 4); + + assert_true(cbor_equal(tag1, tag2) == false); + cbor_decref(&tag1); + cbor_decref(&tag2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint8(10); + tag1 = cbor_new_tag(8); + tag2 = cbor_new_tag(8); + cbor_tag_set_item(tag1, item1); + cbor_tag_set_item(tag2, item2); + assert_true(cbor_equal(tag1, tag2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + cbor_decref(&tag1); + cbor_decref(&tag2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint8(10); + tag1 = cbor_new_tag(8); + tag2 = cbor_new_tag(6); + cbor_tag_set_item(tag1, item1); + cbor_tag_set_item(tag2, item2); + assert_true(cbor_equal(tag1, tag2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + cbor_decref(&tag1); + cbor_decref(&tag2); + + item1 = cbor_build_negint8(10); + item2 = cbor_build_negint8(8); + tag1 = cbor_new_tag(8); + tag2 = cbor_new_tag(8); + cbor_tag_set_item(tag1, item1); + cbor_tag_set_item(tag2, item2); + assert_true(cbor_equal(tag1, tag2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + cbor_decref(&tag1); + cbor_decref(&tag2); +} + +static void test_equal_float_ctrl(void **state) { + item1 = cbor_build_bool(true); + item2 = cbor_build_bool(true); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_float2(8); + item2 = cbor_build_float2(8); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_float8(1234567890); + item2 = cbor_build_float8(1234567890); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_null(); + item2 = cbor_new_null(); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_undef(); + item2 = cbor_new_undef(); + assert_true(cbor_equal(item1, item2) == true); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_float2(8); + item2 = cbor_build_float8(8); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_new_undef(); + item2 = cbor_new_null(); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); + + item1 = cbor_build_float2(8); + item2 = cbor_build_bytestring("test", 4); + assert_true(cbor_equal(item1, item2) == false); + cbor_decref(&item1); + cbor_decref(&item2); +} + +int main(void) { + const struct CMUnitTest tests[] = { + + cmocka_unit_test(test_equal_uint), + cmocka_unit_test(test_equal_negint), + cmocka_unit_test(test_equal_bytestring), + cmocka_unit_test(test_equal_string), + cmocka_unit_test(test_equal_array), + cmocka_unit_test(test_equal_map), + cmocka_unit_test(test_equal_tag), + cmocka_unit_test(test_equal_float_ctrl)}; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/type_5_test.c b/test/type_5_test.c index eae0cf20..f260e61f 100644 --- a/test/type_5_test.c +++ b/test/type_5_test.c @@ -177,6 +177,71 @@ static void test_streamed_streamed_kv_map(void **state) { assert_null(map); } +static void test_get(void **state) { + struct cbor_pair pair; + cbor_item_t *key, *value, *control; + + map = cbor_new_definite_map(3); + + pair.key = cbor_build_string("key1"); + pair.value = cbor_build_string("value1"); + assert_true(cbor_map_add(map, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_negint8(10); + pair.value = cbor_build_string("value2"); + assert_true(cbor_map_add(map, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + pair.key = cbor_build_uint8(4); + pair.value = cbor_build_bytestring("test", 4); + assert_true(cbor_map_add(map, pair) == true); + cbor_decref(&pair.key); + cbor_decref(&pair.value); + + key = cbor_build_string("key1"); + value = cbor_map_get(map, key); + control = cbor_build_string("value1"); + assert_non_null(value); + assert_true(cbor_equal(value, control) == true); + cbor_decref(&key); + cbor_decref(&value); + cbor_decref(&control); + + key = cbor_build_negint8(10); + value = cbor_map_get(map, key); + control = cbor_build_string("value2"); + assert_non_null(value); + assert_true(cbor_equal(value, control) == true); + cbor_decref(&key); + cbor_decref(&value); + cbor_decref(&control); + + key = cbor_new_null(); + value = cbor_map_get(map, key); + assert_null(value); + cbor_decref(&key); + + key = cbor_build_bytestring("test", 4); + value = cbor_map_get(map, key); + assert_null(value); + cbor_decref(&key); + + key = cbor_build_negint8(4); + value = cbor_map_get(map, key); + assert_null(value); + cbor_decref(&key); + + key = cbor_build_string("key"); + value = cbor_map_get(map, key); + assert_null(value); + cbor_decref(&key); + + cbor_decref(&map); +} + int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_empty_map), @@ -185,6 +250,7 @@ int main(void) { cmocka_unit_test(test_def_nested_map), cmocka_unit_test(test_streamed_key_map), cmocka_unit_test(test_streamed_kv_map), - cmocka_unit_test(test_streamed_streamed_kv_map)}; + cmocka_unit_test(test_streamed_streamed_kv_map), + cmocka_unit_test(test_get)}; return cmocka_run_group_tests(tests, NULL, NULL); }