From 4ce704f9c227dce649b5852bdfb83920b962f61a Mon Sep 17 00:00:00 2001 From: Sainan Date: Mon, 25 Nov 2024 14:12:58 +0100 Subject: [PATCH] Add ioBase::i64_dyn_v2 --- soup/Reader.cpp | 17 +++++++++++++++++ soup/Reader.hpp | 3 +++ soup/Writer.cpp | 15 +++++++++++++++ soup/Writer.hpp | 3 +++ 4 files changed, 38 insertions(+) diff --git a/soup/Reader.cpp b/soup/Reader.cpp index fe2b0697..1810d37e 100644 --- a/soup/Reader.cpp +++ b/soup/Reader.cpp @@ -73,4 +73,21 @@ NAMESPACE_SOUP return true; } + + bool Reader::i64_dyn_v2(int64_t& v) noexcept + { + uint64_t u; + SOUP_RETHROW_FALSE(u64_dyn_v2(u)); + const bool neg = (u >> 6) & 1; // check bit 6 + u = ((u >> 1) & ~0x3f) | (u & 0x3f); // remove bit 6 + if (neg) + { + v = (u * -1) - 1; + } + else + { + v = u; + } + return true; + } } diff --git a/soup/Reader.hpp b/soup/Reader.hpp index 0e1d5280..48164c69 100644 --- a/soup/Reader.hpp +++ b/soup/Reader.hpp @@ -41,6 +41,9 @@ NAMESPACE_SOUP // An unsigned 64-bit integer encoded in 1..9 bytes. This is a slightly more efficient version of u64_dyn, e.g. 0x4000..0x407f are encoded in 2 bytes instead of 3. bool u64_dyn_v2(uint64_t& v) noexcept; + // A signed 64-bit integer encoded in 1..9 bytes. (Specialisation of u64_dyn_v2. This revision also simplifies how negative integers are handled.) + bool i64_dyn_v2(int64_t& v) noexcept; + // An integer where every byte's most significant bit is used to indicate if another byte follows, most significant byte first. template bool om(Int& v) noexcept diff --git a/soup/Writer.cpp b/soup/Writer.cpp index c84e1c10..37c75743 100644 --- a/soup/Writer.cpp +++ b/soup/Writer.cpp @@ -73,6 +73,21 @@ NAMESPACE_SOUP return ret; } + bool Writer::i64_dyn_v2(const int64_t& v) noexcept + { + uint64_t u; + bool neg = (v < 0); + if (neg) + { + u = (v * -1) - 1; + } + else + { + u = v; + } + return u64_dyn_v2(((uint64_t)neg << 6) | ((u & ~0x3f) << 1) | (u & 0x3f)); + } + bool Writer::mysql_lenenc(const uint64_t& v) noexcept { if (v < 0xFB) diff --git a/soup/Writer.hpp b/soup/Writer.hpp index 5fe36bbb..06781f22 100644 --- a/soup/Writer.hpp +++ b/soup/Writer.hpp @@ -31,6 +31,9 @@ NAMESPACE_SOUP // An unsigned 64-bit integer encoded in 1..9 bytes. This is a slightly more efficient version of u64_dyn, e.g. 0x4000..0x407f are encoded in 2 bytes instead of 3. bool u64_dyn_v2(const uint64_t& v) noexcept; + // A signed 64-bit integer encoded in 1..9 bytes. (Specialisation of u64_dyn_v2. This revision also simplifies how negative integers are handled.) + bool i64_dyn_v2(const int64_t& v) noexcept; + // An integer where every byte's most significant bit is used to indicate if another byte follows, most significant byte first. template bool om(const Int& v) noexcept