X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=support%2Fx-struct-str.c;h=5124af71fc948720d20fb6be1a350e0974615bc2;hb=edbc5c2334e10836479d1cc528c68d4ad5b47440;hp=68925ed2cf87d2841509099e0457a0b73c836acd;hpb=00e065484e866f3a0349c882f804c4a79a13ee5c;p=mono.git diff --git a/support/x-struct-str.c b/support/x-struct-str.c index 68925ed2cf8..5124af71fc9 100644 --- a/support/x-struct-str.c +++ b/support/x-struct-str.c @@ -10,12 +10,20 @@ #define MAX_OFFSETS 10 -#define str_at(p, n) (*(char**)(((char*)p)+n)) +#define OFFSET_SHIFT 1 -char* MPH_INTERNAL +#define lstr_at(p, n) (*(char**)(((char*)(p))+(n >> OFFSET_SHIFT))) + +#define str_at(p, n) ( \ + (((n) & MPH_STRING_OFFSET_MASK) == MPH_STRING_OFFSET_ARRAY) \ + ? (char*)(p) + (n >> OFFSET_SHIFT) \ + : lstr_at(p, n) \ +) + +char* _mph_copy_structure_strings ( - void *to, const size_t *to_offsets, - const void *from, const size_t *from_offsets, + void *to, const mph_string_offset_t *to_offsets, + const void *from, const mph_string_offset_t *from_offsets, size_t num_strings) { int i; @@ -26,12 +34,13 @@ _mph_copy_structure_strings ( g_assert (num_strings < MAX_OFFSETS); for (i = 0; i < num_strings; ++i) { - str_at (to, to_offsets[i]) = NULL; + lstr_at (to, to_offsets[i]) = NULL; } buflen = num_strings; for (i = 0; i < num_strings; ++i) { - len[i] = strlen (str_at(from, from_offsets[i])); + const char* s = str_at(from, from_offsets[i]); + len [i] = s ? strlen (s) : 0; if (len[i] < INT_MAX - buflen) buflen += len[i]; else @@ -45,7 +54,7 @@ _mph_copy_structure_strings ( for (i = 0; i < num_strings; ++i) { if (len[i] > 0) { - str_at (to, to_offsets[i]) = + lstr_at (to, to_offsets[i]) = strcpy (cur, str_at (from, from_offsets[i])); cur += (len[i] +1); } @@ -56,12 +65,19 @@ _mph_copy_structure_strings ( #ifdef TEST +/* + * To run the tests: + * $ gcc -DTEST -I.. `pkg-config --cflags --libs glib-2.0` x-struct-str.c + * $ ./a.out + */ + #include struct foo { char *a; int b; char *c; + char d[10]; }; struct bar { @@ -69,22 +85,39 @@ struct bar { char *a; double d; char *c; + char *e; }; int main () { /* test copying foo to bar */ - struct foo f = {"hello", 42, "world"}; + struct foo f = {"hello", 42, "world", "!!"}; struct bar b; - size_t foo_offsets[] = {offsetof(struct foo, a), offsetof(struct foo, c)}; - size_t bar_offsets[] = {offsetof(struct bar, a), offsetof(struct bar, c)}; + mph_string_offset_t foo_offsets[] = { + MPH_STRING_OFFSET(struct foo, a, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET(struct foo, c, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET(struct foo, d, MPH_STRING_OFFSET_ARRAY) + }; + mph_string_offset_t bar_offsets[] = { + MPH_STRING_OFFSET(struct bar, a, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET(struct bar, c, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET(struct bar, e, MPH_STRING_OFFSET_PTR) + }; char *buf; buf = _mph_copy_structure_strings (&b, bar_offsets, - &f, foo_offsets, 2); + &f, foo_offsets, 3); + printf ("b.a=%s\n", b.a); + printf ("b.c=%s\n", b.c); + printf ("b.e=%s\n", b.e); + + f.c = NULL; + buf = _mph_copy_structure_strings (&b, bar_offsets, + &f, foo_offsets, 3); printf ("b.a=%s\n", b.a); printf ("b.c=%s\n", b.c); + printf ("b.e=%s\n", b.e); return 0; }