From 23b4688c444f3a083c479946dc0cca6d1076fc65 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 22 Dec 2023 18:09:31 +0100 Subject: [PATCH] util/ByteOrder: move Packed* classes to separate headers --- src/decoder/plugins/DsdiffDecoderPlugin.cxx | 2 +- src/decoder/plugins/DsfDecoderPlugin.cxx | 2 +- src/output/plugins/snapcast/Client.cxx | 2 + src/output/plugins/snapcast/Protocol.hxx | 7 +- src/tag/ApeLoader.cxx | 2 +- src/tag/Id3Picture.cxx | 2 +- src/util/ByteOrder.hxx | 296 -------------------- src/util/PackedBigEndian.hxx | 149 ++++++++++ src/util/PackedLittleEndian.hxx | 163 +++++++++++ 9 files changed, 320 insertions(+), 305 deletions(-) create mode 100644 src/util/PackedBigEndian.hxx create mode 100644 src/util/PackedLittleEndian.hxx diff --git a/src/decoder/plugins/DsdiffDecoderPlugin.cxx b/src/decoder/plugins/DsdiffDecoderPlugin.cxx index e325185cd..72c0917fd 100644 --- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx +++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx @@ -16,7 +16,7 @@ #include "input/InputStream.hxx" #include "pcm/CheckAudioFormat.hxx" #include "util/BitReverse.hxx" -#include "util/ByteOrder.hxx" +#include "util/PackedBigEndian.hxx" #include "tag/Handler.hxx" #include "DsdLib.hxx" diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx index 6c83fcefe..d99af62df 100644 --- a/src/decoder/plugins/DsfDecoderPlugin.cxx +++ b/src/decoder/plugins/DsfDecoderPlugin.cxx @@ -17,7 +17,7 @@ #include "input/InputStream.hxx" #include "pcm/CheckAudioFormat.hxx" #include "util/BitReverse.hxx" -#include "util/ByteOrder.hxx" +#include "util/PackedLittleEndian.hxx" #include "DsdLib.hxx" #include "tag/Handler.hxx" diff --git a/src/output/plugins/snapcast/Client.cxx b/src/output/plugins/snapcast/Client.cxx index 1b9d72822..a3ed85659 100644 --- a/src/output/plugins/snapcast/Client.cxx +++ b/src/output/plugins/snapcast/Client.cxx @@ -9,6 +9,8 @@ #include "event/Loop.hxx" #include "net/SocketError.hxx" #include "net/UniqueSocketDescriptor.hxx" +#include "util/PackedBigEndian.hxx" +#include "util/PackedLittleEndian.hxx" #include "util/SpanCast.hxx" #include "Log.hxx" diff --git a/src/output/plugins/snapcast/Protocol.hxx b/src/output/plugins/snapcast/Protocol.hxx index fd6cc3b54..3e662cfe7 100644 --- a/src/output/plugins/snapcast/Protocol.hxx +++ b/src/output/plugins/snapcast/Protocol.hxx @@ -1,10 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef MPD_OUTPUT_SNAPCAST_PROTOCOL_HXX -#define MPD_OUTPUT_SNAPCAST_PROTOCOL_HXX +#pragma once -#include "util/ByteOrder.hxx" +#include "util/PackedLittleEndian.hxx" // see https://github.com/badaix/snapcast/blob/master/doc/binary_protocol.md @@ -55,5 +54,3 @@ struct SnapcastWireChunk { struct SnapcastTime { SnapcastTimestamp latency; }; - -#endif diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx index 3b7037161..71725c07d 100644 --- a/src/tag/ApeLoader.cxx +++ b/src/tag/ApeLoader.cxx @@ -2,8 +2,8 @@ // Copyright The Music Player Daemon Project #include "ApeLoader.hxx" -#include "util/ByteOrder.hxx" #include "input/InputStream.hxx" +#include "util/PackedLittleEndian.hxx" #include #include diff --git a/src/tag/Id3Picture.cxx b/src/tag/Id3Picture.cxx index 86b95d38d..ad9bd3415 100644 --- a/src/tag/Id3Picture.cxx +++ b/src/tag/Id3Picture.cxx @@ -3,7 +3,7 @@ #include "Id3Picture.hxx" #include "Handler.hxx" -#include "util/ByteOrder.hxx" +#include "util/PackedBigEndian.hxx" #include #include diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index 868079a9f..78bcc21df 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -224,299 +224,3 @@ FromLE16S(uint16_t value) noexcept /* assuming two's complement representation */ return static_cast(FromLE16(value)); } - -/** - * A packed big-endian 16 bit integer. - */ -class PackedBE16 { - uint8_t hi, lo; - -public: - PackedBE16() = default; - - constexpr PackedBE16(uint16_t src) noexcept - :hi(uint8_t(src >> 8)), - lo(uint8_t(src)) {} - - /** - * Construct an instance from an integer which is already - * big-endian. - */ - static constexpr auto FromBE(uint16_t src) noexcept { - union { - uint16_t in; - PackedBE16 out; - } u{src}; - return u.out; - } - - constexpr operator uint16_t() const noexcept { - return (uint16_t(hi) << 8) | uint16_t(lo); - } - - /** - * Reads the raw, big-endian value. - */ - constexpr uint16_t raw() const noexcept { - uint16_t x = *this; - if (IsLittleEndian()) - x = ByteSwap16(x); - return x; - } -}; - -static_assert(sizeof(PackedBE16) == sizeof(uint16_t), "Wrong size"); -static_assert(alignof(PackedBE16) == 1, "Wrong alignment"); - -/** - * A packed big-endian 32 bit integer. - */ -class PackedBE32 { - uint8_t a, b, c, d; - -public: - PackedBE32() = default; - - constexpr PackedBE32(uint32_t src) noexcept - :a(uint8_t(src >> 24)), - b(uint8_t(src >> 16)), - c(uint8_t(src >> 8)), - d(uint8_t(src)) {} - - /** - * Construct an instance from an integer which is already - * big-endian. - */ - static constexpr auto FromBE(uint32_t src) noexcept { - union { - uint32_t in; - PackedBE32 out; - } u{src}; - return u.out; - } - - constexpr operator uint32_t() const noexcept { - return (uint32_t(a) << 24) | (uint32_t(b) << 16) | - (uint32_t(c) << 8) | uint32_t(d); - } - - /** - * Reads the raw, big-endian value. - */ - constexpr uint32_t raw() const noexcept { - uint32_t x = *this; - if (IsLittleEndian()) - x = ByteSwap32(x); - return x; - } -}; - -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. - */ -class PackedLE16 { - uint8_t lo, hi; - -public: - PackedLE16() = default; - - constexpr PackedLE16(uint16_t src) noexcept - :lo(uint8_t(src)), - hi(uint8_t(src >> 8)) {} - - /** - * Construct an instance from an integer which is already - * little-endian. - */ - static constexpr auto FromLE(uint16_t src) noexcept { - union { - uint16_t in; - PackedLE16 out; - } u{src}; - return u.out; - } - - constexpr operator uint16_t() const noexcept { - return (uint16_t(hi) << 8) | uint16_t(lo); - } - - PackedLE16 &operator=(uint16_t new_value) noexcept { - lo = uint8_t(new_value); - hi = uint8_t(new_value >> 8); - return *this; - } - - /** - * Reads the raw, little-endian value. - */ - constexpr uint16_t raw() const noexcept { - uint16_t x = *this; - if (IsBigEndian()) - x = ByteSwap16(x); - return x; - } -}; - -static_assert(sizeof(PackedLE16) == sizeof(uint16_t), "Wrong size"); -static_assert(alignof(PackedLE16) == 1, "Wrong alignment"); - -/** - * A packed little-endian 32 bit integer. - */ -class PackedLE32 { - uint8_t a, b, c, d; - -public: - PackedLE32() = default; - - constexpr PackedLE32(uint32_t src) noexcept - :a(uint8_t(src)), - b(uint8_t(src >> 8)), - c(uint8_t(src >> 16)), - d(uint8_t(src >> 24)) {} - - /** - * Construct an instance from an integer which is already - * little-endian. - */ - static constexpr auto FromLE(uint32_t src) noexcept { - union { - uint32_t in; - PackedLE32 out; - } u{src}; - return u.out; - } - - constexpr operator uint32_t() const noexcept { - return uint32_t(a) | (uint32_t(b) << 8) | - (uint32_t(c) << 16) | (uint32_t(d) << 24); - } - - PackedLE32 &operator=(uint32_t new_value) noexcept { - a = uint8_t(new_value); - b = uint8_t(new_value >> 8); - c = uint8_t(new_value >> 16); - d = uint8_t(new_value >> 24); - return *this; - } - - /** - * Reads the raw, little-endian value. - */ - constexpr uint32_t raw() const noexcept { - uint32_t x = *this; - if (IsBigEndian()) - x = ByteSwap32(x); - return x; - } -}; - -static_assert(sizeof(PackedLE32) == sizeof(uint32_t), "Wrong size"); -static_assert(alignof(PackedLE32) == 1, "Wrong alignment"); - -/** - * 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"); diff --git a/src/util/PackedBigEndian.hxx b/src/util/PackedBigEndian.hxx new file mode 100644 index 000000000..1933d3ded --- /dev/null +++ b/src/util/PackedBigEndian.hxx @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: BSD-2-Clause +// author: Max Kellermann + +#pragma once + +#include "ByteOrder.hxx" + +#include + +/** + * A packed big-endian 16 bit integer. + */ +class PackedBE16 { + uint8_t hi, lo; + +public: + PackedBE16() = default; + + constexpr PackedBE16(uint16_t src) noexcept + :hi(uint8_t(src >> 8)), + lo(uint8_t(src)) {} + + /** + * Construct an instance from an integer which is already + * big-endian. + */ + static constexpr auto FromBE(uint16_t src) noexcept { + union { + uint16_t in; + PackedBE16 out; + } u{src}; + return u.out; + } + + constexpr operator uint16_t() const noexcept { + return (uint16_t(hi) << 8) | uint16_t(lo); + } + + /** + * Reads the raw, big-endian value. + */ + constexpr uint16_t raw() const noexcept { + uint16_t x = *this; + if (IsLittleEndian()) + x = ByteSwap16(x); + return x; + } +}; + +static_assert(sizeof(PackedBE16) == sizeof(uint16_t), "Wrong size"); +static_assert(alignof(PackedBE16) == 1, "Wrong alignment"); + +/** + * A packed big-endian 32 bit integer. + */ +class PackedBE32 { + uint8_t a, b, c, d; + +public: + PackedBE32() = default; + + constexpr PackedBE32(uint32_t src) noexcept + :a(uint8_t(src >> 24)), + b(uint8_t(src >> 16)), + c(uint8_t(src >> 8)), + d(uint8_t(src)) {} + + /** + * Construct an instance from an integer which is already + * big-endian. + */ + static constexpr auto FromBE(uint32_t src) noexcept { + union { + uint32_t in; + PackedBE32 out; + } u{src}; + return u.out; + } + + constexpr operator uint32_t() const noexcept { + return (uint32_t(a) << 24) | (uint32_t(b) << 16) | + (uint32_t(c) << 8) | uint32_t(d); + } + + /** + * Reads the raw, big-endian value. + */ + constexpr uint32_t raw() const noexcept { + uint32_t x = *this; + if (IsLittleEndian()) + x = ByteSwap32(x); + return x; + } +}; + +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"); diff --git a/src/util/PackedLittleEndian.hxx b/src/util/PackedLittleEndian.hxx new file mode 100644 index 000000000..8242a453e --- /dev/null +++ b/src/util/PackedLittleEndian.hxx @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: BSD-2-Clause +// author: Max Kellermann + +#pragma once + +#include "ByteOrder.hxx" + +#include + +/** + * A packed little-endian 16 bit integer. + */ +class PackedLE16 { + uint8_t lo, hi; + +public: + PackedLE16() = default; + + constexpr PackedLE16(uint16_t src) noexcept + :lo(uint8_t(src)), + hi(uint8_t(src >> 8)) {} + + /** + * Construct an instance from an integer which is already + * little-endian. + */ + static constexpr auto FromLE(uint16_t src) noexcept { + union { + uint16_t in; + PackedLE16 out; + } u{src}; + return u.out; + } + + constexpr operator uint16_t() const noexcept { + return (uint16_t(hi) << 8) | uint16_t(lo); + } + + PackedLE16 &operator=(uint16_t new_value) noexcept { + lo = uint8_t(new_value); + hi = uint8_t(new_value >> 8); + return *this; + } + + /** + * Reads the raw, little-endian value. + */ + constexpr uint16_t raw() const noexcept { + uint16_t x = *this; + if (IsBigEndian()) + x = ByteSwap16(x); + return x; + } +}; + +static_assert(sizeof(PackedLE16) == sizeof(uint16_t), "Wrong size"); +static_assert(alignof(PackedLE16) == 1, "Wrong alignment"); + +/** + * A packed little-endian 32 bit integer. + */ +class PackedLE32 { + uint8_t a, b, c, d; + +public: + PackedLE32() = default; + + constexpr PackedLE32(uint32_t src) noexcept + :a(uint8_t(src)), + b(uint8_t(src >> 8)), + c(uint8_t(src >> 16)), + d(uint8_t(src >> 24)) {} + + /** + * Construct an instance from an integer which is already + * little-endian. + */ + static constexpr auto FromLE(uint32_t src) noexcept { + union { + uint32_t in; + PackedLE32 out; + } u{src}; + return u.out; + } + + constexpr operator uint32_t() const noexcept { + return uint32_t(a) | (uint32_t(b) << 8) | + (uint32_t(c) << 16) | (uint32_t(d) << 24); + } + + PackedLE32 &operator=(uint32_t new_value) noexcept { + a = uint8_t(new_value); + b = uint8_t(new_value >> 8); + c = uint8_t(new_value >> 16); + d = uint8_t(new_value >> 24); + return *this; + } + + /** + * Reads the raw, little-endian value. + */ + constexpr uint32_t raw() const noexcept { + uint32_t x = *this; + if (IsBigEndian()) + x = ByteSwap32(x); + return x; + } +}; + +static_assert(sizeof(PackedLE32) == sizeof(uint32_t), "Wrong size"); +static_assert(alignof(PackedLE32) == 1, "Wrong alignment"); + +/** + * 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");