From: Vincent Bernat Date: Sat, 21 Jan 2012 22:21:07 +0000 (+0100) Subject: marshal: add a way to ignore a pointer (setting it to NULL) X-Git-Tag: 0.6.0~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=305e061cbc5e8828e52068a68ea925da27bb7cb0;p=thirdparty%2Flldpd.git marshal: add a way to ignore a pointer (setting it to NULL) --- diff --git a/src/marshal.c b/src/marshal.c index 8a7131fa..303069a6 100644 --- a/src/marshal.c +++ b/src/marshal.c @@ -33,6 +33,11 @@ struct marshal_info marshal_info__fstring = { .size = 0, .pointers = {{ .mi = NULL }}, }; +struct marshal_info marshal_info__ignore = { + .name = "ignored", + .size = 0, + .pointers = {{ .mi = NULL }}, +}; /* List of already seen pointers */ struct ref { @@ -100,6 +105,7 @@ _marshal_serialize(struct marshal_info *mi, void *unserialized, void **input, size_t sublen; void *source; void *target; + if (current->kind == ignore) continue; if (current->kind == pointer) { source = *(void **)((unsigned char *)unserialized + current->offset); if (source == NULL) continue; @@ -245,6 +251,10 @@ _marshal_unserialize(struct marshal_info *mi, void *buffer, size_t len, void **o for (current = mi->pointers; current->mi; current++) { size_t sublen; void *new = (unsigned char *)*output + current->offset; + if (current->kind == ignore) { + *(void **)((unsigned char *)*output + current->offset) = 0; + continue; + } if (current->kind == pointer) { if (*(void **)new == NULL) continue; diff --git a/src/marshal.h b/src/marshal.h index cac9e682..74640306 100644 --- a/src/marshal.h +++ b/src/marshal.h @@ -21,6 +21,7 @@ struct marshal_info; enum marshal_subinfo_kind { pointer, substruct, + ignore, }; #define MARSHAL_INFO_POINTER 1 #define MARSHAL_INFO_SUB 2 @@ -38,6 +39,7 @@ struct marshal_info { /* Special case for strings */ extern struct marshal_info marshal_info__string; extern struct marshal_info marshal_info__fstring; +extern struct marshal_info marshal_info__ignore; /* Declare a new marshal_info struct named after the type we want to marshal. The marshalled type has to be a structure. */ @@ -58,6 +60,7 @@ extern struct marshal_info marshal_info__fstring; .offset2 = offsetof(struct type, len), \ .kind = pointer, \ .mi = &marshal_info__fstring }, +#define MARSHAL_IGNORE(type, member) MARSHAL_ADD(ignore, type, _ignore, member) #define MARSHAL_TQE(type, field) \ MARSHAL_POINTER(type, type, field.tqe_next) \ MARSHAL_POINTER(type, type, field.tqe_prev) diff --git a/tests/check_marshal.c b/tests/check_marshal.c index 5d4102c3..0ed35ce8 100644 --- a/tests/check_marshal.c +++ b/tests/check_marshal.c @@ -611,6 +611,7 @@ START_TEST(test_string) { free(destination); } END_TEST + struct struct_fixedstring { int s1; char *s2; @@ -635,7 +636,7 @@ START_TEST(test_fixed_string) { len = marshal_serialize(struct_fixedstring, &source, &buffer); fail_unless(len > 0, "Unable to serialize"); - memset(&source, 0, sizeof(struct struct_string)); + memset(&source, 0, sizeof(struct struct_fixedstring)); len2 = marshal_unserialize(struct_fixedstring, buffer, len, &destination); fail_unless(len2 > 0, "Unable to deserialize"); free(buffer); @@ -654,6 +655,39 @@ START_TEST(test_fixed_string) { } END_TEST +struct struct_ignore { + int t1; + void *t2; + int t3; +}; +MARSHAL_BEGIN(struct_ignore) +MARSHAL_IGNORE(struct_ignore, t2) +MARSHAL_END; + +START_TEST(test_ignore) { + struct struct_ignore source = { + .t1 = 4544, + .t2 = (void *)"String 2 Bla", + .t3 = 11111, + }; + struct struct_ignore *destination; + void *buffer; + size_t len, len2; + + len = marshal_serialize(struct_ignore, &source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_ignore)); + len2 = marshal_unserialize(struct_ignore, buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->t1, 4544); + ck_assert_int_eq(destination->t2, NULL); + ck_assert_int_eq(destination->t3, 11111); + free(destination); +} +END_TEST + Suite * marshal_suite(void) { @@ -672,6 +706,7 @@ marshal_suite(void) tcase_add_test(tc_marshal, test_embedded_list); tcase_add_test(tc_marshal, test_string); tcase_add_test(tc_marshal, test_fixed_string); + tcase_add_test(tc_marshal, test_ignore); suite_add_tcase(s, tc_marshal); return s;