[Spice-devel] [PATCH libcacard 07/45] simpletlv: Allow clonning of the SimpleTLV structures with test
Jonathon Jongsma
jjongsma at redhat.com
Wed Aug 1 14:52:27 UTC 2018
just a minor typo in the summary: clonning -> cloning
On Tue, 2018-07-31 at 16:50 +0200, Jakub Jelen wrote:
> * This function creates a deep copy of the whole structure.
> * The new structure is dynamically allocated and needs to be freed.
>
> Signed-off-by: Jakub Jelen <jjelen at redhat.com>
> Reviewed-by: Robert Relyea <rrelyea at redhat.com>
> ---
> src/simpletlv.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> src/simpletlv.h | 9 +++++++++
> tests/simpletlv.c | 28 ++++++++++++++++++++++++++++
> 3 files changed, 79 insertions(+)
>
> diff --git a/src/simpletlv.c b/src/simpletlv.c
> index 5cea04b..2a9a6a7 100644
> --- a/src/simpletlv.c
> +++ b/src/simpletlv.c
> @@ -278,4 +278,46 @@ simpletlv_free(struct simpletlv_member *tlv,
> size_t tlvlen)
> }
> free(tlv);
> }
> +
> +struct simpletlv_member *
> +simpletlv_clone(struct simpletlv_member *tlv, size_t tlvlen)
> +{
> + size_t i = 0, j;
> + struct simpletlv_member *new = NULL;
> +
> + new = malloc(sizeof(struct simpletlv_member)*tlvlen);
> + if (!new)
> + goto failure;
> +
> + for (i = 0; i < tlvlen; i++) {
> + new[i].type = tlv[i].type;
> + new[i].tag = tlv[i].tag;
> + new[i].length = tlv[i].length;
> + if (tlv[i].type == SIMPLETLV_TYPE_COMPOUND) {
> + new[i].value.child = simpletlv_clone(
> + tlv[i].value.child, tlv[i].length);
> + if (new[i].value.child == NULL)
> + goto failure;
> + } else {
> + new[i].value.value = malloc(
> + sizeof(unsigned char)*tlv[i].length);
> + if (new[i].value.value == NULL)
> + goto failure;
> + memcpy(new[i].value.value, tlv[i].value.value,
> + tlv[i].length);
> + }
> + }
> + return new;
> +
> +failure:
> + for (j = 0; j < i; i++) {
> + if (tlv[i].type == SIMPLETLV_TYPE_COMPOUND) {
> + simpletlv_free(new[i].value.child, new[i].length);
> + } else {
> + free(new[i].value.value);
> + }
> + }
> + free(new);
> + return NULL;
> +}
> /* vim: set ts=4 sw=4 tw=0 noet expandtab: */
> diff --git a/src/simpletlv.h b/src/simpletlv.h
> index dcb795b..e1cb5a2 100644
> --- a/src/simpletlv.h
> +++ b/src/simpletlv.h
> @@ -115,4 +115,13 @@ int
> simpletlv_read_tag(unsigned char **buf, size_t buflen,
> unsigned char *tag_out, size_t *taglen);
>
> +
> +/* create a deep copy of the SimpleTLV structure
> + *
> + * The calling function is responsible for freeing the structure and
> + * all its children by calling simpletlv_free().
> + */
> +struct simpletlv_member *
> +simpletlv_clone(struct simpletlv_member *tlv, size_t tlvlen);
> +
> #endif
> diff --git a/tests/simpletlv.c b/tests/simpletlv.c
> index 3bd22ae..2be78db 100644
> --- a/tests/simpletlv.c
> +++ b/tests/simpletlv.c
> @@ -220,6 +220,7 @@ static void test_encode_skipped(void)
> {0x30, 2, {/*.value = simple_value2*/}, SIMPLETLV_TYPE_NONE}
> };
> unsigned char encoded[] = "\x25\x02\x12\x14";
> +
> simple[0].value.value = simple_value;
> simple[1].value.value = simple_value2;
>
> @@ -242,6 +243,32 @@ static void test_encode_skipped(void)
> g_free(result);
> }
>
> +static void test_clone_simple(void)
> +{
> + unsigned char *result = NULL;
> + size_t result_len = 0;
> + unsigned char simple_value[] = "\x14\x18";
> + unsigned char simple_value2[] = "\x64\x24\x44";
> + static struct simpletlv_member simple[2] = {
> + {0x13, 2, {/*.value = simple_value*/}, SIMPLETLV_TYPE_LEAF},
> + {0xDD, 3, {/*.value = simple_value2*/}, SIMPLETLV_TYPE_LEAF}
> + };
> + unsigned char encoded[] =
> "\x13\x02\x14\x18\xDD\x03\x64\x24\x44";
> + struct simpletlv_member *clone;
> +
> + simple[0].value.value = simple_value;
> + simple[1].value.value = simple_value2;
> +
> + clone = simpletlv_clone(simple, 2);
> + g_assert_nonnull(clone);
> +
> + result = NULL;
> + result_len = simpletlv_encode(clone, 2, &result, 0, NULL);
> + g_assert_cmpmem(result, result_len, encoded, 9);
> + g_free(result);
> + simpletlv_free(clone, 2);
> +}
> +
> int main(int argc, char *argv[])
> {
> int ret;
> @@ -256,6 +283,7 @@ int main(int argc, char *argv[])
> g_test_add_func("/simpletlv/encode/simple", test_encode_simple);
> g_test_add_func("/simpletlv/encode/nested", test_encode_nested);
> g_test_add_func("/simpletlv/encode/skipped",
> test_encode_skipped);
> + g_test_add_func("/simpletlv/clone/simple", test_clone_simple);
>
> ret = g_test_run();
>
More information about the Spice-devel
mailing list