util/ByteOrder: move Packed* classes to separate headers
This commit is contained in:
parent
c4d8888972
commit
23b4688c44
|
@ -16,7 +16,7 @@
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "pcm/CheckAudioFormat.hxx"
|
#include "pcm/CheckAudioFormat.hxx"
|
||||||
#include "util/BitReverse.hxx"
|
#include "util/BitReverse.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/PackedBigEndian.hxx"
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
#include "DsdLib.hxx"
|
#include "DsdLib.hxx"
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "pcm/CheckAudioFormat.hxx"
|
#include "pcm/CheckAudioFormat.hxx"
|
||||||
#include "util/BitReverse.hxx"
|
#include "util/BitReverse.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/PackedLittleEndian.hxx"
|
||||||
#include "DsdLib.hxx"
|
#include "DsdLib.hxx"
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "event/Loop.hxx"
|
#include "event/Loop.hxx"
|
||||||
#include "net/SocketError.hxx"
|
#include "net/SocketError.hxx"
|
||||||
#include "net/UniqueSocketDescriptor.hxx"
|
#include "net/UniqueSocketDescriptor.hxx"
|
||||||
|
#include "util/PackedBigEndian.hxx"
|
||||||
|
#include "util/PackedLittleEndian.hxx"
|
||||||
#include "util/SpanCast.hxx"
|
#include "util/SpanCast.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
// Copyright The Music Player Daemon Project
|
// Copyright The Music Player Daemon Project
|
||||||
|
|
||||||
#ifndef MPD_OUTPUT_SNAPCAST_PROTOCOL_HXX
|
#pragma once
|
||||||
#define MPD_OUTPUT_SNAPCAST_PROTOCOL_HXX
|
|
||||||
|
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/PackedLittleEndian.hxx"
|
||||||
|
|
||||||
// see https://github.com/badaix/snapcast/blob/master/doc/binary_protocol.md
|
// see https://github.com/badaix/snapcast/blob/master/doc/binary_protocol.md
|
||||||
|
|
||||||
|
@ -55,5 +54,3 @@ struct SnapcastWireChunk {
|
||||||
struct SnapcastTime {
|
struct SnapcastTime {
|
||||||
SnapcastTimestamp latency;
|
SnapcastTimestamp latency;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Copyright The Music Player Daemon Project
|
// Copyright The Music Player Daemon Project
|
||||||
|
|
||||||
#include "ApeLoader.hxx"
|
#include "ApeLoader.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
|
#include "util/PackedLittleEndian.hxx"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "Id3Picture.hxx"
|
#include "Id3Picture.hxx"
|
||||||
#include "Handler.hxx"
|
#include "Handler.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/PackedBigEndian.hxx"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -224,299 +224,3 @@ FromLE16S(uint16_t value) noexcept
|
||||||
/* assuming two's complement representation */
|
/* assuming two's complement representation */
|
||||||
return static_cast<int16_t>(FromLE16(value));
|
return static_cast<int16_t>(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");
|
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ByteOrder.hxx"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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");
|
|
@ -0,0 +1,163 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ByteOrder.hxx"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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");
|
Loading…
Reference in New Issue