| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * A helper routine to copy the strings between differing structures.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include "mph.h"
- #define MAX_OFFSETS 10
- #define OFFSET_SHIFT 1
- #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_INTERNAL
- _mph_copy_structure_strings (
- 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;
- size_t buflen;
- int len[MAX_OFFSETS];
- char *buf, *cur = NULL;
- g_assert (num_strings < MAX_OFFSETS);
- for (i = 0; i < num_strings; ++i) {
- 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]));
- if (len[i] < INT_MAX - buflen)
- buflen += len[i];
- else
- len[i] = -1;
- }
- cur = buf = malloc (buflen);
- if (buf == NULL) {
- return NULL;
- }
- for (i = 0; i < num_strings; ++i) {
- if (len[i] > 0) {
- lstr_at (to, to_offsets[i]) =
- strcpy (cur, str_at (from, from_offsets[i]));
- cur += (len[i] +1);
- }
- }
- return buf;
- }
- #ifdef TEST
- #include <stdio.h>
- struct foo {
- char *a;
- int b;
- char *c;
- char d[10];
- };
- struct bar {
- int b;
- char *a;
- double d;
- char *c;
- char *e;
- };
- int
- main ()
- {
- /* test copying foo to bar */
- struct foo f = {"hello", 42, "world", "!!"};
- struct bar b;
- 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, 3);
- printf ("b.a=%s\n", b.a);
- printf ("b.c=%s\n", b.c);
- printf ("b.e=%s\n", b.e);
- return 0;
- }
- #endif
|