11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
22PROMEKI_NAMESPACE_BEGIN
38template <
size_t NumBytes>
class ByteArray {
39 PROMEKI_SHARED_FINAL(ByteArray)
41 using Ptr = SharedPtr<ByteArray>;
42 using DataType = Array<uint8_t, NumBytes>;
48 ByteArray(
const DataType &val) : d(val) {}
51 ByteArray(DataType &&val) noexcept : d(std::move(val)) {}
54 explicit ByteArray(
const uint8_t *src) { std::memcpy(d.data(), src, NumBytes); }
60 constexpr size_t size()
const {
return NumBytes; }
63 uint8_t &operator[](
size_t index) {
return d[index]; }
66 const uint8_t &operator[](
size_t index)
const {
return d[index]; }
69 uint8_t *data() {
return d.data(); }
72 const uint8_t *data()
const {
return d.data(); }
76 for (
size_t i = 0; i < NumBytes; i++) {
77 if (d[i] != 0)
return false;
83 friend bool operator==(
const ByteArray &lhs,
const ByteArray &rhs) {
return lhs.d == rhs.d; }
86 friend bool operator!=(
const ByteArray &lhs,
const ByteArray &rhs) {
return lhs.d != rhs.d; }
92 String toHexString()
const {
93 static const char digits[] =
"0123456789abcdef";
95 for (
size_t i = 0; i < NumBytes; i++) {
96 ret += digits[d[i] >> 4];
97 ret += digits[d[i] & 0x0F];
108 static ByteArray fromHexString(
const char *str, Error *err =
nullptr) {
110 if (str ==
nullptr) {
111 if (err !=
nullptr) *err = Error::Invalid;
114 for (
size_t i = 0; i < NumBytes; i++) {
115 int hi = hexCharToVal(str[i * 2]);
116 int lo = hexCharToVal(str[i * 2 + 1]);
117 if (hi < 0 || lo < 0) {
118 if (err !=
nullptr) *err = Error::Invalid;
121 ret.d[i] =
static_cast<uint8_t
>((hi << 4) | lo);
123 if (err !=
nullptr) *err = Error::Ok;
133 static ByteArray fromHexString(
const String &str, Error *err =
nullptr) {
134 return fromHexString(str.cstr(), err);
140 static int hexCharToVal(
char c) {
141 if (c >=
'0' && c <=
'9')
return c -
'0';
142 if (c >=
'a' && c <=
'f')
return c -
'a' + 10;
143 if (c >=
'A' && c <=
'F')
return c -
'A' + 10;