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/optionals.c | |
| parent | 4b5e4cd1f21582f5e5fa682ab4e4bff252963468 (diff) | |
Add serialization and deserialization
Diffstat (limited to 'stdlib/optionals.c')
| -rw-r--r-- | stdlib/optionals.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/stdlib/optionals.c b/stdlib/optionals.c index 810f6172..38cd4700 100644 --- a/stdlib/optionals.c +++ b/stdlib/optionals.c @@ -13,7 +13,7 @@ #include "threads.h" #include "util.h" -public PUREFUNC bool is_null(const void *obj, const TypeInfo_t *non_optional_type) +public PUREFUNC bool is_none(const void *obj, const TypeInfo_t *non_optional_type) { if (non_optional_type->metamethods.is_none) return non_optional_type->metamethods.is_none(obj, non_optional_type); @@ -23,14 +23,14 @@ public PUREFUNC bool is_null(const void *obj, const TypeInfo_t *non_optional_typ PUREFUNC public uint64_t Optional$hash(const void *obj, const TypeInfo_t *type) { - return is_null(obj, type->OptionalInfo.type) ? 0 : generic_hash(obj, type->OptionalInfo.type); + return is_none(obj, type->OptionalInfo.type) ? 0 : generic_hash(obj, type->OptionalInfo.type); } PUREFUNC public int32_t Optional$compare(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return 0; - bool x_is_null = is_null(x, type->OptionalInfo.type); - bool y_is_null = is_null(y, type->OptionalInfo.type); + bool x_is_null = is_none(x, type->OptionalInfo.type); + bool y_is_null = is_none(y, type->OptionalInfo.type); if (x_is_null && y_is_null) return 0; else if (x_is_null != y_is_null) return (int32_t)y_is_null - (int32_t)x_is_null; else return generic_compare(x, y, type->OptionalInfo.type); @@ -40,8 +40,8 @@ PUREFUNC public bool Optional$equal(const void *x, const void *y, const TypeInfo { if (x == y) return true; - bool x_is_null = is_null(x, type->OptionalInfo.type); - bool y_is_null = is_null(y, type->OptionalInfo.type); + bool x_is_null = is_none(x, type->OptionalInfo.type); + bool y_is_null = is_none(y, type->OptionalInfo.type); if (x_is_null && y_is_null) return true; else if (x_is_null != y_is_null) return false; else return generic_equal(x, y, type->OptionalInfo.type); @@ -52,9 +52,42 @@ public Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t if (!obj) return Text$concat(generic_as_text(obj, colorize, type->OptionalInfo.type), Text("?")); - if (is_null(obj, type->OptionalInfo.type)) + if (is_none(obj, type->OptionalInfo.type)) return colorize ? Text("\x1b[31mNONE\x1b[m") : Text("NONE"); return generic_as_text(obj, colorize, type->OptionalInfo.type); } +public void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +{ + bool has_value = !is_none(obj, type->OptionalInfo.type); + fputc((int)has_value, out); + if (has_value) + _serialize(obj, out, pointers, type->OptionalInfo.type); +} + +public void Optional$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type) +{ + bool has_value = (bool)fgetc(in); + const TypeInfo_t *nonnull = type->OptionalInfo.type; + if (has_value) { + memset(outval, 0, (size_t)type->size); + _deserialize(in, outval, pointers, nonnull); + } else { + if (nonnull->tag == TextInfo) + *(Text_t*)outval = (Text_t){.length=-1}; + else if (nonnull->tag == ArrayInfo) + *(Array_t*)outval = (Array_t){.length=-1}; + else if (nonnull->tag == TableInfo) + *(Table_t*)outval = (Table_t){.entries={.length=-1}}; + else if (nonnull == &Num$info) + *(double*)outval = NAN; + else if (nonnull == &Num32$info) + *(float*)outval = NAN; + else if (nonnull->tag == StructInfo || (nonnull->tag == OpaqueInfo && type->size > nonnull->size)) + memset(outval + type->size, -1, (size_t)(type->size - nonnull->size)); + else + memset(outval, 0, (size_t)type->size); + } +} + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 |
