From f3ebaf8bdd56c0bee27d547929553dd37986385d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 12 Mar 2023 20:23:58 +0100 Subject: [PATCH] util/ByteOrder: add class PackedLE64 --- src/util/ByteOrder.hxx | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index dae163b73..868079a9f 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -1,8 +1,7 @@ // SPDX-License-Identifier: BSD-2-Clause // author: Max Kellermann -#ifndef BYTE_ORDER_HXX -#define BYTE_ORDER_HXX +#pragma once #include @@ -470,4 +469,54 @@ public: static_assert(sizeof(PackedLE32) == sizeof(uint32_t), "Wrong size"); static_assert(alignof(PackedLE32) == 1, "Wrong alignment"); -#endif +/** + * A packed little-endian 64 bit integer. + */ +class PackedLE64 { + uint8_t a, b, c, d, e, f, g, h; + +public: + PackedLE64() = default; + + constexpr PackedLE64(uint64_t src) noexcept + :a(uint8_t(src)), + b(uint8_t(src >> 8)), + c(uint8_t(src >> 16)), + d(uint8_t(src >> 24)), + e(uint8_t(src >> 32)), + f(uint8_t(src >> 40)), + g(uint8_t(src >> 48)), + h(uint8_t(src >> 56)) {} + + /** + * Construct an instance from an integer which is already + * little-endian. + */ + static constexpr auto FromLE(uint64_t src) noexcept { + union { + uint64_t in; + PackedLE64 out; + } u{src}; + return u.out; + } + + constexpr operator uint64_t() const noexcept { + return uint64_t(a) | (uint64_t(b) << 8) | + (uint64_t(c) << 16) | (uint64_t(d) << 24) | + (uint64_t(e) << 32) | (uint64_t(f) << 40) | + (uint64_t(g) << 48) | (uint64_t(h) << 56); + } + + /** + * Reads the raw, big-endian value. + */ + constexpr uint64_t raw() const noexcept { + uint64_t x = *this; + if (IsBigEndian()) + x = ByteSwap64(x); + return x; + } +}; + +static_assert(sizeof(PackedLE64) == sizeof(uint64_t), "Wrong size"); +static_assert(alignof(PackedLE64) == 1, "Wrong alignment");