diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-11-29 18:09:12 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-11-29 18:09:12 -0500 |
| commit | f66f8ad7119207b99f00ea2ea389550ee65db5b3 (patch) | |
| tree | 5b5a7c887b311e3de2f2cb293b1228598c5b9eb1 /stdlib/arrays.c | |
| parent | 4b5e4cd1f21582f5e5fa682ab4e4bff252963468 (diff) | |
Add serialization and deserialization
Diffstat (limited to 'stdlib/arrays.c')
| -rw-r--r-- | stdlib/arrays.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/stdlib/arrays.c b/stdlib/arrays.c index ff219203..8dcc48a9 100644 --- a/stdlib/arrays.c +++ b/stdlib/arrays.c @@ -6,6 +6,7 @@ #include <sys/param.h> #include "arrays.h" +#include "integers.h" #include "metamethods.h" #include "optionals.h" #include "rng.h" @@ -701,4 +702,46 @@ public PUREFUNC bool Array$is_none(const void *obj, const TypeInfo_t*) return ((Array_t*)obj)->length < 0; } +public void Array$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +{ + Array_t arr = *(Array_t*)obj; + int64_t len = arr.length; + Int64$serialize(&len, out, pointers, &Int64$info); + auto item_serialize = type->ArrayInfo.item->metamethods.serialize; + if (item_serialize) { + for (int64_t i = 0; i < len; i++) + item_serialize(arr.data + i*arr.stride, out, pointers, type->ArrayInfo.item); + } else if (arr.stride == type->ArrayInfo.item->size) { + fwrite(arr.data, (size_t)type->ArrayInfo.item->size, (size_t)len, out); + } else { + for (int64_t i = 0; i < len; i++) + fwrite(arr.data + i*arr.stride, (size_t)type->ArrayInfo.item->size, 1, out); + } +} + +public void Array$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t *type) +{ + int64_t len = -1; + Int64$deserialize(in, &len, pointers, &Int64$info); + int64_t padded_size = type->ArrayInfo.item->size; + if (type->ArrayInfo.item->align > 0 && padded_size % type->ArrayInfo.item->align > 0) + padded_size += type->ArrayInfo.item->align - (padded_size % type->ArrayInfo.item->align); + Array_t arr = { + .length=len, + .data=GC_MALLOC((size_t)(len*padded_size)), + .stride=padded_size, + }; + auto item_deserialize = type->ArrayInfo.item->metamethods.deserialize; + if (item_deserialize) { + for (int64_t i = 0; i < len; i++) + item_deserialize(in, arr.data + i*arr.stride, pointers, type->ArrayInfo.item); + } else if (arr.stride == type->ArrayInfo.item->size) { + fread(arr.data, (size_t)type->ArrayInfo.item->size, (size_t)len, in); + } else { + for (int64_t i = 0; i < len; i++) + fread(arr.data + i*arr.stride, (size_t)type->ArrayInfo.item->size, 1, in); + } + *(Array_t*)obj = arr; +} + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
