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@xxxxxxxxxx> > Reviewed-by: Robert Relyea <rrelyea@xxxxxxxxxx> > --- > 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(); > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel