22#include "pw_bytes/array.h"
23#include "pw_bytes/bit.h"
24#include "pw_bytes/span.h"
25#include "pw_span/span.h"
42 std::conditional_t<sizeof(T) == 8, uint64_t, void>>>> {
43 static_assert(std::is_integral_v<T>);
50constexpr void CopyLittleEndian(uint8_t value, U* dest) {
51 dest[0] =
static_cast<U
>(value);
55constexpr void CopyLittleEndian(uint16_t value, U* dest) {
56 dest[0] =
static_cast<U
>(value & 0x00FF);
57 dest[1] =
static_cast<U
>((value & 0xFF00) >> 8);
61constexpr void CopyLittleEndian(uint32_t value, U* dest) {
62 dest[0] =
static_cast<U
>((value & 0x000000FF) >> 0 * 8);
63 dest[1] =
static_cast<U
>((value & 0x0000FF00) >> 1 * 8);
64 dest[2] =
static_cast<U
>((value & 0x00FF0000) >> 2 * 8);
65 dest[3] =
static_cast<U
>((value & 0xFF000000) >> 3 * 8);
69constexpr void CopyLittleEndian(uint64_t value, U* dest) {
70 dest[0] =
static_cast<U
>((value & 0x00000000000000FF) >> 0 * 8);
71 dest[1] =
static_cast<U
>((value & 0x000000000000FF00) >> 1 * 8);
72 dest[2] =
static_cast<U
>((value & 0x0000000000FF0000) >> 2 * 8);
73 dest[3] =
static_cast<U
>((value & 0x00000000FF000000) >> 3 * 8);
74 dest[4] =
static_cast<U
>((value & 0x000000FF00000000) >> 4 * 8);
75 dest[5] =
static_cast<U
>((value & 0x0000FF0000000000) >> 5 * 8);
76 dest[6] =
static_cast<U
>((value & 0x00FF000000000000) >> 6 * 8);
77 dest[7] =
static_cast<U
>((value & 0xFF00000000000000) >> 7 * 8);
80template <
typename T,
typename U>
81constexpr void CopyLittleEndian(T value, U* dest) {
82 CopyLittleEndian(
static_cast<EquivalentUint<T>
>(value), dest);
86constexpr T ReverseBytes(T value) {
87 EquivalentUint<T> unsigned_int =
static_cast<EquivalentUint<T>
>(value);
89 if constexpr (
sizeof(unsigned_int) == 1) {
90 return static_cast<T
>(unsigned_int);
91 }
else if constexpr (
sizeof(unsigned_int) == 2) {
92 return static_cast<T
>(((unsigned_int & 0x00FF) << 8) |
93 ((unsigned_int & 0xFF00) >> 8));
94 }
else if constexpr (
sizeof(unsigned_int) == 4) {
95 return static_cast<T
>(((unsigned_int & 0x000000FF) << 3 * 8) |
96 ((unsigned_int & 0x0000FF00) << 1 * 8) |
97 ((unsigned_int & 0x00FF0000) >> 1 * 8) |
98 ((unsigned_int & 0xFF000000) >> 3 * 8));
100 static_assert(
sizeof(unsigned_int) == 8);
101 return static_cast<T
>(((unsigned_int & 0x00000000000000FF) << 7 * 8) |
102 ((unsigned_int & 0x000000000000FF00) << 5 * 8) |
103 ((unsigned_int & 0x0000000000FF0000) << 3 * 8) |
104 ((unsigned_int & 0x00000000FF000000) << 1 * 8) |
105 ((unsigned_int & 0x000000FF00000000) >> 1 * 8) |
106 ((unsigned_int & 0x0000FF0000000000) >> 3 * 8) |
107 ((unsigned_int & 0x00FF000000000000) >> 5 * 8) |
108 ((unsigned_int & 0xFF00000000000000) >> 7 * 8));
125 return from == to ? value : internal::ReverseBytes(value);
133 return ConvertOrder(endian::native, to_endianness, value);
139 return ConvertOrder(from_endianness, endian::native, value);
145template <
typename T,
typename U>
147 static_assert(std::is_same_v<U, std::byte> || std::is_same_v<U, char> ||
148 std::is_same_v<U, unsigned char> ||
149 std::is_same_v<U, signed char>,
150 "pw::bytes::CopyInOrder can only copy to a byte type");
157 std::array<std::byte,
sizeof(T)> bytes{};
171 std::memcpy(&value, buffer,
sizeof(value));
184T
ReadInOrder(endian order,
const void* buffer,
size_t max_bytes_to_read) {
186 std::memcpy(&value, buffer, std::min(
sizeof(value), max_bytes_to_read));
194 typename = std::enable_if_t<kBufferSize != dynamic_extent &&
195 sizeof(B) ==
sizeof(std::byte)>>
197 static_assert(kBufferSize >=
sizeof(T));
198 return ReadInOrder<T>(order, buffer.data());
202template <
typename T,
typename B,
size_t kBufferSize>
203T
ReadInOrder(endian order,
const std::array<B, kBufferSize>& buffer) {
204 return ReadInOrder<T>(order,
span(buffer));
208template <
typename T,
typename B,
size_t kBufferSize>
210 return ReadInOrder<T>(order,
span(buffer));
219 if (buffer.size() <
sizeof(T)) {
223 value = ReadInOrder<T>(order, buffer.data());
Definition: span_impl.h:235
constexpr T ConvertOrderTo(endian to_endianness, T value)
Definition: endian.h:132
constexpr T ConvertOrder(endian from, endian to, T value)
Definition: endian.h:124
constexpr T ConvertOrderFrom(endian from_endianness, T value)
Converts a value from the specified byte order to the native byte order.
Definition: endian.h:138
constexpr void CopyInOrder(endian order, T value, U *dest)
Definition: endian.h:146
T ReadInOrder(endian order, const void *buffer)
Definition: endian.h:169
Binary data manipulation utilities.
Definition: array.h:25