libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
eui64.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 <cstring>
15#include <format>
16#include <promeki/namespace.h>
17#include <promeki/string.h>
18#include <promeki/result.h>
19#include <promeki/array.h>
20#include <promeki/enums.h>
21#include <promeki/datatype.h>
22
23PROMEKI_NAMESPACE_BEGIN
24
25class MacAddress;
26class TextStream;
27class DataStream;
28
60class EUI64 {
61 public:
62 PROMEKI_DATATYPE(EUI64, DataTypeEUI64, 1)
63
64
65 Error writeToStream(DataStream &s) const;
67 template <uint32_t V> static Result<EUI64> readFromStream(DataStream &s);
68
70 using DataFormat = Array<uint8_t, 8>;
71
85 static Result<EUI64> fromString(const String &str);
86
97 static EUI64 fromMacAddress(const MacAddress &mac);
98
100 EUI64() : _addr{} {}
101
106 explicit EUI64(const DataFormat &bytes) : _addr(bytes) {}
107
111 EUI64(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h)
112 : _addr{DataFormat{a, b, c, d, e, f, g, h}} {}
113
115 bool isNull() const { return _addr.isZero(); }
116
121 const DataFormat &data() const { return _addr; }
122
127 const uint8_t *raw() const { return _addr.data(); }
128
134 uint8_t octet(int index) const {
135 if (index < 0 || index > 7) return 0;
136 return _addr[index];
137 }
138
146 bool hasMacAddress() const { return _addr[3] == 0xFF && _addr[4] == 0xFE; }
147
158 MacAddress toMacAddress() const;
159
164 String toString() const;
165
171 String toString(const EUI64Format &fmt) const;
172
174 bool operator==(const EUI64 &other) const { return _addr == other._addr; }
176 bool operator!=(const EUI64 &other) const { return _addr != other._addr; }
178 bool operator<(const EUI64 &other) const {
179 return std::memcmp(_addr.data(), other._addr.data(), 8) < 0;
180 }
181
182 private:
183 DataFormat _addr;
184};
185
187TextStream &operator<<(TextStream &stream, const EUI64 &addr);
188
189PROMEKI_NAMESPACE_END
190
206template <> struct std::formatter<promeki::EUI64> {
207 int _spec = 0; // 0=hyphen, 1=colon, 2=ipv6
208
209 constexpr auto parse(std::format_parse_context &ctx) {
210 auto it = ctx.begin();
211 if (it != ctx.end() && *it != '}') {
212 if (*it == 'h') {
213 _spec = 0;
214 ++it;
215 } else if (*it == 'o') {
216 _spec = 1;
217 ++it;
218 } else if (*it == 'v') {
219 _spec = 2;
220 ++it;
221 }
222 }
223 return it;
224 }
225
226 template <typename FormatContext> auto format(const promeki::EUI64 &v, FormatContext &ctx) const {
227 promeki::EUI64Format fmt(_spec);
228 promeki::String s = v.toString(fmt);
229 return std::format_to(ctx.out(), "{}", std::string_view(s.cstr(), s.byteCount()));
230 }
231};
232
233#endif // PROMEKI_ENABLE_CORE