aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-11-29 19:32:47 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-11-29 19:32:47 -0500
commite5e9c8b46c5deb8de9053c5906d0b9f406097816 (patch)
tree6acb2cf6a5a1a7b058be8ad5c6ec38599aa26297
parent725bc9809fb7381241eea218ea08b53708a6c574 (diff)
Make Int serialization more compact
-rw-r--r--README.md1
-rw-r--r--stdlib/integers.c32
2 files changed, 24 insertions, 9 deletions
diff --git a/README.md b/README.md
index b7b89298..ca61a18b 100644
--- a/README.md
+++ b/README.md
@@ -79,6 +79,7 @@ of many language features or the other example programs/modules in
- [Easy interoperability with C](docs/c-interoperability.md)
- Support for [POSIX threads](docs/threads.tm) and thread-safe message passing
queues over [channels](docs/channels.tm).
+- Built-in data serialization and deserialization for datatypes.
## Dependencies
diff --git a/stdlib/integers.c b/stdlib/integers.c
index b40657bc..cd6492ac 100644
--- a/stdlib/integers.c
+++ b/stdlib/integers.c
@@ -369,19 +369,33 @@ static bool Int$is_none(const void *i, const TypeInfo_t*)
return ((Int_t*)i)->small == 0;
}
-static void Int$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*)
+static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t*)
{
- mpz_t n;
- mpz_init_set_int(n, *(Int_t*)obj);
- mpz_out_raw(out, n);
+ Int_t i = *(Int_t*)obj;
+ if (__builtin_expect((i.small & 1), 1)) {
+ fputc(0, out);
+ int64_t i64 = i.small >> 2;
+ Int64$serialize(&i64, out, pointers, &Int64$info);
+ } else {
+ fputc(1, out);
+ mpz_t n;
+ mpz_init_set_int(n, *(Int_t*)obj);
+ mpz_out_raw(out, n);
+ }
}
-static void Int$deserialize(FILE *in, void *obj, Array_t*, const TypeInfo_t*)
+static void Int$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t*)
{
- mpz_t n;
- mpz_init(n);
- mpz_inp_raw(n, in);
- *(Int_t*)obj = Int$from_mpz(n);
+ if (fgetc(in) == 0) {
+ int64_t i = 0;
+ Int64$deserialize(in, &i, pointers, &Int64$info);
+ *(Int_t*)obj = (Int_t){.small=(i<<2) | 1};
+ } else {
+ mpz_t n;
+ mpz_init(n);
+ mpz_inp_raw(n, in);
+ *(Int_t*)obj = Int$from_mpz(n);
+ }
}
public const TypeInfo_t Int$info = {