From 81afb47cd063b48cdafede4f1f39ccdcad02c52a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 17 May 2022 09:26:14 +0200 Subject: [PATCH] util/ByteOrder: add class PackedBE64 --- src/util/ByteOrder.hxx | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index ec1bf00fe..c13c3acbb 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -351,6 +351,58 @@ public: static_assert(sizeof(PackedBE32) == sizeof(uint32_t), "Wrong size"); static_assert(alignof(PackedBE32) == 1, "Wrong alignment"); +/** + * A packed big-endian 64 bit integer. + */ +class PackedBE64 { + uint8_t a, b, c, d, e, f, g, h; + +public: + PackedBE64() = default; + + constexpr PackedBE64(uint64_t src) noexcept + :a(uint8_t(src >> 56)), + b(uint8_t(src >> 48)), + c(uint8_t(src >> 40)), + d(uint8_t(src >> 32)), + e(uint8_t(src >> 24)), + f(uint8_t(src >> 16)), + g(uint8_t(src >> 8)), + h(uint8_t(src)) {} + + /** + * Construct an instance from an integer which is already + * big-endian. + */ + static constexpr auto FromBE(uint64_t src) noexcept { + union { + uint64_t in; + PackedBE64 out; + } u{src}; + return u.out; + } + + constexpr operator uint64_t() const noexcept { + return (uint64_t(a) << 56) | (uint64_t(b) << 48) | + (uint64_t(c) << 40) | (uint64_t(d) << 32) | + (uint64_t(e) << 24) | (uint64_t(f) << 16) | + (uint64_t(g) << 8) | uint64_t(h); + } + + /** + * Reads the raw, big-endian value. + */ + constexpr uint64_t raw() const noexcept { + uint64_t x = *this; + if (IsLittleEndian()) + x = ByteSwap64(x); + return x; + } +}; + +static_assert(sizeof(PackedBE64) == sizeof(uint64_t), "Wrong size"); +static_assert(alignof(PackedBE64) == 1, "Wrong alignment"); + /** * A packed little-endian 16 bit integer. */