2010-06-17 Zoltan Varga <vargaz@gmail.com>
[mono.git] / support / x-struct-str.c
blobb71a9cca1f0a153b54f5b7007b49927fcb98692e
1 /*
2 * A helper routine to copy the strings between differing structures.
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <limits.h>
9 #include "mph.h"
11 #define MAX_OFFSETS 10
13 #define OFFSET_SHIFT 1
15 #define lstr_at(p, n) (*(char**)(((char*)(p))+(n >> OFFSET_SHIFT)))
17 #define str_at(p, n) ( \
18 (((n) & MPH_STRING_OFFSET_MASK) == MPH_STRING_OFFSET_ARRAY) \
19 ? (char*)(p) + (n >> OFFSET_SHIFT) \
20 : lstr_at(p, n) \
23 char* MPH_INTERNAL
24 _mph_copy_structure_strings (
25 void *to, const mph_string_offset_t *to_offsets,
26 const void *from, const mph_string_offset_t *from_offsets,
27 size_t num_strings)
29 int i;
30 size_t buflen;
31 int len[MAX_OFFSETS];
32 char *buf, *cur = NULL;
34 g_assert (num_strings < MAX_OFFSETS);
36 for (i = 0; i < num_strings; ++i) {
37 lstr_at (to, to_offsets[i]) = NULL;
40 buflen = num_strings;
41 for (i = 0; i < num_strings; ++i) {
42 const char* s = str_at(from, from_offsets[i]);
43 len [i] = s ? strlen (s) : 0;
44 if (len[i] < INT_MAX - buflen)
45 buflen += len[i];
46 else
47 len[i] = -1;
50 cur = buf = malloc (buflen);
51 if (buf == NULL) {
52 return NULL;
55 for (i = 0; i < num_strings; ++i) {
56 if (len[i] > 0) {
57 lstr_at (to, to_offsets[i]) =
58 strcpy (cur, str_at (from, from_offsets[i]));
59 cur += (len[i] +1);
63 return buf;
66 #ifdef TEST
69 * To run the tests:
70 * $ gcc -DTEST -I.. `pkg-config --cflags --libs glib-2.0` x-struct-str.c
71 * $ ./a.out
74 #include <stdio.h>
76 struct foo {
77 char *a;
78 int b;
79 char *c;
80 char d[10];
83 struct bar {
84 int b;
85 char *a;
86 double d;
87 char *c;
88 char *e;
91 int
92 main ()
94 /* test copying foo to bar */
95 struct foo f = {"hello", 42, "world", "!!"};
96 struct bar b;
97 mph_string_offset_t foo_offsets[] = {
98 MPH_STRING_OFFSET(struct foo, a, MPH_STRING_OFFSET_PTR),
99 MPH_STRING_OFFSET(struct foo, c, MPH_STRING_OFFSET_PTR),
100 MPH_STRING_OFFSET(struct foo, d, MPH_STRING_OFFSET_ARRAY)
102 mph_string_offset_t bar_offsets[] = {
103 MPH_STRING_OFFSET(struct bar, a, MPH_STRING_OFFSET_PTR),
104 MPH_STRING_OFFSET(struct bar, c, MPH_STRING_OFFSET_PTR),
105 MPH_STRING_OFFSET(struct bar, e, MPH_STRING_OFFSET_PTR)
107 char *buf;
109 buf = _mph_copy_structure_strings (&b, bar_offsets,
110 &f, foo_offsets, 3);
111 printf ("b.a=%s\n", b.a);
112 printf ("b.c=%s\n", b.c);
113 printf ("b.e=%s\n", b.e);
115 f.c = NULL;
116 buf = _mph_copy_structure_strings (&b, bar_offsets,
117 &f, foo_offsets, 3);
118 printf ("b.a=%s\n", b.a);
119 printf ("b.c=%s\n", b.c);
120 printf ("b.e=%s\n", b.e);
122 return 0;
124 #endif