aboutsummaryrefslogtreecommitdiff
path: root/stdlib/arrays.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-11-29 18:09:12 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-11-29 18:09:12 -0500
commitf66f8ad7119207b99f00ea2ea389550ee65db5b3 (patch)
tree5b5a7c887b311e3de2f2cb293b1228598c5b9eb1 /stdlib/arrays.c
parent4b5e4cd1f21582f5e5fa682ab4e4bff252963468 (diff)
Add serialization and deserialization
Diffstat (limited to 'stdlib/arrays.c')
-rw-r--r--stdlib/arrays.c43
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