struct ref {
TAILQ_ENTRY(ref) next;
void *pointer;
+ int dummy; /* To renumerate pointers */
};
TAILQ_HEAD(ref_l, ref);
size_t len;
struct marshal_subinfo *current;
struct marshal_serialized *new = NULL, *serialized = NULL;
+ int dummy = 1;
log_debug("marshal", "start serialization of %s", mi->name);
TAILQ_FOREACH(cref, refs, next) {
if (unserialized == cref->pointer)
return 0;
+ /* dummy should be higher than any existing dummy */
+ if (cref->dummy >= dummy) dummy = cref->dummy + 1;
}
/* Handle special cases. */
len = -1;
goto marshal_error;
}
- serialized->orig = unserialized;
+ /* We don't use the original pointer but a dummy one. */
+ serialized->orig = (unsigned char*)NULL + dummy;
/* Append the new reference */
if (!(cref = calloc(1, sizeof(struct ref)))) {
goto marshal_error;
}
cref->pointer = unserialized;
+ cref->dummy = dummy;
TAILQ_INSERT_TAIL(refs, cref, next);
/* First, serialize the main structure */
free(serialized);
return -1;
}
+ /* We want to put the renumerated pointer instead of the real one. */
+ if (current->kind == pointer && !skip) {
+ TAILQ_FOREACH(cref, refs, next) {
+ if (source == cref->pointer) {
+ void *fakepointer = (unsigned char*)NULL + cref->dummy;
+ memcpy((unsigned char *)serialized->object + current->offset,
+ &fakepointer, sizeof(void *));
+ break;
+ }
+ }
+ }
if (sublen == 0) continue; /* This was already serialized */
/* Append the result */
new = realloc(serialized, len + sublen);
}
END_TEST
+START_TEST(test_equality) {
+ struct struct_simple source_simple1 = {
+ .a1 = 451,
+ .a2 = 451424,
+ .a3 = 'o',
+ .a4 = 74,
+ .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
+ };
+ struct struct_simpleentry entry1 = {
+ .g1 = 47,
+ .g2 = &source_simple1,
+ };
+
+ struct struct_simple source_simple2;
+ struct struct_simpleentry entry2;
+
+ void *buffer1, *buffer2;
+ memcpy(&source_simple2, &source_simple1, sizeof(source_simple1));
+ memcpy(&entry2, &entry1, sizeof(entry1));
+ entry2.g2 = &source_simple2;
+ ssize_t len1 = marshal_serialize(struct_simpleentry, &entry1, &buffer1);
+ ssize_t len2 = marshal_serialize(struct_simpleentry, &entry2, &buffer2);
+ fail_unless(len1 > 0, "Unable to serialize");
+ fail_unless(len2 > 0, "Unable to serialize");
+ ck_assert_int_eq(len1, len2);
+ fail_unless(!memcmp(buffer1, buffer2, len1), "Same content should give the same serialization");
+ free(buffer1); free(buffer2);
+}
+END_TEST
+
Suite *
marshal_suite(void)
{
tcase_add_test(tc_marshal, test_string);
tcase_add_test(tc_marshal, test_fixed_string);
tcase_add_test(tc_marshal, test_ignore);
+ tcase_add_test(tc_marshal, test_equality);
suite_add_tcase(s, tc_marshal);
return s;