libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
bytearray.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cstdint>
14#include <cstddef>
15#include <cstring>
16#include <promeki/array.h>
17#include <promeki/namespace.h>
18#include <promeki/string.h>
19#include <promeki/error.h>
20#include <promeki/sharedptr.h>
21
22PROMEKI_NAMESPACE_BEGIN
23
38template <size_t NumBytes> class ByteArray {
39 PROMEKI_SHARED_FINAL(ByteArray)
40 public:
41 using Ptr = SharedPtr<ByteArray>;
42 using DataType = Array<uint8_t, NumBytes>;
43
45 ByteArray() : d{} {}
46
48 ByteArray(const DataType &val) : d(val) {}
49
51 ByteArray(DataType &&val) noexcept : d(std::move(val)) {}
52
54 explicit ByteArray(const uint8_t *src) { std::memcpy(d.data(), src, NumBytes); }
55
57 ~ByteArray() {}
58
60 constexpr size_t size() const { return NumBytes; }
61
63 uint8_t &operator[](size_t index) { return d[index]; }
64
66 const uint8_t &operator[](size_t index) const { return d[index]; }
67
69 uint8_t *data() { return d.data(); }
70
72 const uint8_t *data() const { return d.data(); }
73
75 bool isZero() const {
76 for (size_t i = 0; i < NumBytes; i++) {
77 if (d[i] != 0) return false;
78 }
79 return true;
80 }
81
83 friend bool operator==(const ByteArray &lhs, const ByteArray &rhs) { return lhs.d == rhs.d; }
84
86 friend bool operator!=(const ByteArray &lhs, const ByteArray &rhs) { return lhs.d != rhs.d; }
87
92 String toHexString() const {
93 static const char digits[] = "0123456789abcdef";
94 String ret;
95 for (size_t i = 0; i < NumBytes; i++) {
96 ret += digits[d[i] >> 4];
97 ret += digits[d[i] & 0x0F];
98 }
99 return ret;
100 }
101
108 static ByteArray fromHexString(const char *str, Error *err = nullptr) {
109 ByteArray ret;
110 if (str == nullptr) {
111 if (err != nullptr) *err = Error::Invalid;
112 return ret;
113 }
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;
119 return ByteArray();
120 }
121 ret.d[i] = static_cast<uint8_t>((hi << 4) | lo);
122 }
123 if (err != nullptr) *err = Error::Ok;
124 return ret;
125 }
126
133 static ByteArray fromHexString(const String &str, Error *err = nullptr) {
134 return fromHexString(str.cstr(), err);
135 }
136
137 private:
138 DataType d;
139
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;
144 return -1;
145 }
146};
147
148PROMEKI_NAMESPACE_END
149
150#endif // PROMEKI_ENABLE_CORE