From 54b9bb6f25b703cded0a8552a8dfed1d53673b8f Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Fri, 23 Jun 2023 22:34:38 +0200 Subject: [PATCH] Repair machineword reads --- .../cpp/preserves_binary_reader.hpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/implementations/cpp/preserves_binary_reader.hpp b/implementations/cpp/preserves_binary_reader.hpp index 4176e2c..5ca5bb4 100644 --- a/implementations/cpp/preserves_binary_reader.hpp +++ b/implementations/cpp/preserves_binary_reader.hpp @@ -61,14 +61,18 @@ namespace Preserves { return d; } - boost::optional next_unsigned(size_t n) { + boost::optional> next_machineword(size_t n, bool always_unsigned) { uint8_t buf[n]; if (!next_chunk(buf, n)) return boost::none; - uint64_t v = 0; - for (size_t j = 0; j < n; j++) { - v = (v << 8) | buf[j]; + if ((buf[0] & 0x80) && !always_unsigned) { + int64_t v = -1; + for (size_t j = 0; j < n; j++) v = (v << 8) | buf[j]; + return Value::from_int(v); + } else { + uint64_t v = 0; + for (size_t j = 0; j < n; j++) v = (v << 8) | buf[j]; + return Value::from_int(v); } - return v; } boost::optional> next_bignum(size_t n) { @@ -115,12 +119,13 @@ namespace Preserves { } case BinaryTag::MediumInteger_lo ... BinaryTag::MediumInteger_hi: { int n = int(tag) - int(BinaryTag::MediumInteger_lo) + 1; - if (n < 9) { - return next_unsigned(n).map([](uint64_t v) { return Value::from_int(int64_t(v)); }); - } + if (n < 9) return next_machineword(n, false); if (n == 9) { // We can handle this with uint64_t if it's unsigned and the first byte is 0. - if (i.get() == 0) return next_unsigned(8).map(Value::from_unsigned); + if (i.peek() == 0) { + i.get(); + return next_machineword(8, true); + } } return next_bignum(n); }