diff --git a/libc3/data.c b/libc3/data.c
index 2828f5b..d5c9981 100644
--- a/libc3/data.c
+++ b/libc3/data.c
@@ -584,9 +584,7 @@ void * data_init_cast (void *data, const s_sym * const *type,
void * data_init_copy (const s_sym *type, void *data, const void *src)
{
- s_struct s = {0};
const s_struct_type *st;
- s_struct t = {0};
if (type == &g_sym_Array ||
sym_is_array_type(type))
return array_init_copy(data, src);
@@ -656,13 +654,8 @@ void * data_init_copy (const s_sym *type, void *data, const void *src)
return data;
if (! struct_type_find(type, &st))
return NULL;
- if (st) {
- s.type = st;
- s.data = data;
- t.type = st;
- t.data = (void *) src;
- return struct_init_copy(&s, &t);
- }
+ if (st)
+ return struct_type_copy_data(st, data, src);
err_write_1("data_init_copy: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index 9377aed..82fd432 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -13,6 +13,7 @@
#include <string.h>
#include "alloc.h"
#include "assert.h"
+#include "data.h"
#include "env.h"
#include "list.h"
#include "map.h"
@@ -30,6 +31,30 @@ void struct_type_clean (s_struct_type *st)
free(st->offset);
}
+void * struct_type_copy_data (const s_struct_type *st, void *dest,
+ const void *src)
+{
+ uw count;
+ uw i;
+ uw offset;
+ const s_sym *sym;
+ assert(st);
+ assert(dest);
+ assert(src);
+ i = 0;
+ count = st->map.count;
+ while (i < count) {
+ if (! tag_type(st->map.value + i, &sym))
+ return NULL;
+ offset = st->offset[i];
+ if (! data_init_copy(sym, (s8 *) dest + offset,
+ (s8 *) src + offset))
+ return NULL;
+ i++;
+ }
+ return dest;
+}
+
void struct_type_delete (s_struct_type *st)
{
assert(st);
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index 0930e40..42d487c 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -39,8 +39,10 @@ s_struct_type * struct_type_init_copy (s_struct_type *st,
void struct_type_delete (s_struct_type *st);
s_struct_type * struct_type_new (const s_sym *module,
const s_list *spec);
-
/* Observers. */
+void * struct_type_copy_data (const s_struct_type *st,
+ void *dest,
+ const void *src);
bool * struct_type_exists (const s_sym *module,
bool *dest);
const s_struct_type ** struct_type_find (const s_sym *module,