New test.
[mono.git] / support / x-struct-str.c
1 /*
2  * A helper routine to copy the strings between differing structures.
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <limits.h>
8
9 #include "mph.h"
10
11 #define MAX_OFFSETS 10
12
13 #define str_at(p, n) (*(char**)(((char*)p)+n))
14
15 char* MPH_INTERNAL
16 _mph_copy_structure_strings (
17         void *to,         const size_t *to_offsets, 
18         const void *from, const size_t *from_offsets, 
19         size_t num_strings)
20 {
21         int i;
22         size_t buflen;
23         int len[MAX_OFFSETS];
24         char *buf, *cur = NULL;
25
26         g_assert (num_strings < MAX_OFFSETS);
27
28         for (i = 0; i < num_strings; ++i) {
29                 str_at (to, to_offsets[i]) = NULL;
30         }
31
32         buflen = num_strings;
33         for (i = 0; i < num_strings; ++i) {
34                 len[i] = strlen (str_at(from, from_offsets[i]));
35                 if (len[i] < INT_MAX - buflen)
36                         buflen += len[i];
37                 else
38                         len[i] = -1;
39         }
40
41         cur = buf = malloc (buflen);
42         if (buf == NULL) {
43                 return NULL;
44         }
45
46         for (i = 0; i < num_strings; ++i) {
47                 if (len[i] > 0) {
48                         str_at (to, to_offsets[i]) = 
49                                 strcpy (cur, str_at (from, from_offsets[i]));
50                         cur += (len[i] +1);
51                 }
52         }
53
54         return buf;
55 }
56
57 #ifdef TEST
58
59 #include <stdio.h>
60
61 struct foo {
62         char *a;
63         int   b;
64         char *c;
65 };
66
67 struct bar {
68         int    b;
69         char  *a;
70         double d;
71         char  *c;
72 };
73
74 int
75 main ()
76 {
77         /* test copying foo to bar */
78         struct foo f = {"hello", 42, "world"};
79         struct bar b;
80         size_t foo_offsets[] = {offsetof(struct foo, a), offsetof(struct foo, c)};
81         size_t bar_offsets[] = {offsetof(struct bar, a), offsetof(struct bar, c)};
82         char *buf;
83
84         buf = _mph_copy_structure_strings (&b, bar_offsets, 
85                         &f, foo_offsets, 2);
86         printf ("b.a=%s\n", b.a);
87         printf ("b.c=%s\n", b.c);
88
89         return 0;
90 }
91 #endif
92