[ox/std] Add UUID fromString
This commit is contained in:
parent
e19559d7a7
commit
2b821b73ff
4
deps/ox/src/ox/std/optional.hpp
vendored
4
deps/ox/src/ox/std/optional.hpp
vendored
@ -28,7 +28,7 @@ class Optional {
|
|||||||
constexpr Optional() noexcept = default;
|
constexpr Optional() noexcept = default;
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
constexpr Optional(Args &&... args);
|
explicit constexpr Optional(Args &&... args);
|
||||||
|
|
||||||
constexpr Optional(const Optional &other) {
|
constexpr Optional(const Optional &other) {
|
||||||
if (other.m_ptr) {
|
if (other.m_ptr) {
|
||||||
@ -131,7 +131,7 @@ class Optional {
|
|||||||
if (std::is_constant_evaluated()) {
|
if (std::is_constant_evaluated()) {
|
||||||
m_ptr = new U(ox::forward<Args>(args)...);
|
m_ptr = new U(ox::forward<Args>(args)...);
|
||||||
} else {
|
} else {
|
||||||
m_ptr = std::construct_at<U>(reinterpret_cast<T*>(m_data.data()), ox::forward<Args>(args)...);
|
m_ptr = std::construct_at<U>(reinterpret_cast<U*>(m_data.data()), ox::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
return *m_ptr;
|
return *m_ptr;
|
||||||
}
|
}
|
||||||
|
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
@ -19,4 +19,5 @@ add_test("[ox/std] HeapMgr" StdTest malloc)
|
|||||||
add_test("[ox/std] Serialize-Int" StdTest "Serialize-Int")
|
add_test("[ox/std] Serialize-Int" StdTest "Serialize-Int")
|
||||||
add_test("[ox/std] BufferWriter" StdTest "BufferWriter")
|
add_test("[ox/std] BufferWriter" StdTest "BufferWriter")
|
||||||
add_test("[ox/std] StringSplit" StdTest "StringSplit")
|
add_test("[ox/std] StringSplit" StdTest "StringSplit")
|
||||||
|
add_test("[ox/std] FromHex" StdTest "FromHex")
|
||||||
add_test("[ox/std] ToHex" StdTest "ToHex")
|
add_test("[ox/std] ToHex" StdTest "ToHex")
|
||||||
|
27
deps/ox/src/ox/std/test/tests.cpp
vendored
27
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -60,6 +60,8 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
|||||||
oxAssert(s == "AB9C", "BString append broken");
|
oxAssert(s == "AB9C", "BString append broken");
|
||||||
s = "asdf";
|
s = "asdf";
|
||||||
oxAssert(s == "asdf", "String assign broken");
|
oxAssert(s == "asdf", "String assign broken");
|
||||||
|
oxAssert(s != "aoeu", "String assign broken");
|
||||||
|
oxAssert(s.len() == 4, "String assign broken");
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -156,6 +158,29 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"FromHex",
|
||||||
|
[] {
|
||||||
|
oxExpect(ox::detail::fromHex("01").unwrap(), 0x01);
|
||||||
|
oxExpect(ox::detail::fromHex("02").unwrap(), 0x02);
|
||||||
|
oxExpect(ox::detail::fromHex("03").unwrap(), 0x03);
|
||||||
|
oxExpect(ox::detail::fromHex("04").unwrap(), 0x04);
|
||||||
|
oxExpect(ox::detail::fromHex("05").unwrap(), 0x05);
|
||||||
|
oxExpect(ox::detail::fromHex("06").unwrap(), 0x06);
|
||||||
|
oxExpect(ox::detail::fromHex("07").unwrap(), 0x07);
|
||||||
|
oxExpect(ox::detail::fromHex("08").unwrap(), 0x08);
|
||||||
|
oxExpect(ox::detail::fromHex("0d").unwrap(), 0x0d);
|
||||||
|
oxExpect(ox::detail::fromHex("0e").unwrap(), 0x0e);
|
||||||
|
oxExpect(ox::detail::fromHex("0f").unwrap(), 0x0f);
|
||||||
|
oxExpect(ox::detail::fromHex("0F").unwrap(), 0x0f);
|
||||||
|
oxExpect(ox::detail::fromHex("fF").unwrap(), 0xff);
|
||||||
|
oxExpect(ox::detail::fromHex("ff").unwrap(), 0xff);
|
||||||
|
oxExpect(ox::detail::fromHex("a0").unwrap(), 0xa0);
|
||||||
|
oxExpect(ox::detail::fromHex("93").unwrap(), 0x93);
|
||||||
|
oxExpect(ox::detail::fromHex("40").unwrap(), 0x40);
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ToHex",
|
"ToHex",
|
||||||
[] {
|
[] {
|
||||||
@ -168,7 +193,7 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
|||||||
oxExpect(ox::detail::toHex(0x07), "07");
|
oxExpect(ox::detail::toHex(0x07), "07");
|
||||||
oxExpect(ox::detail::toHex(0x08), "08");
|
oxExpect(ox::detail::toHex(0x08), "08");
|
||||||
oxExpect(ox::detail::toHex(0x0d), "0d");
|
oxExpect(ox::detail::toHex(0x0d), "0d");
|
||||||
oxExpect(ox::detail::toHex(0x0e), "03");
|
oxExpect(ox::detail::toHex(0x0e), "0e");
|
||||||
oxExpect(ox::detail::toHex(0x0f), "0f");
|
oxExpect(ox::detail::toHex(0x0f), "0f");
|
||||||
oxExpect(ox::detail::toHex(0x93), "93");
|
oxExpect(ox::detail::toHex(0x93), "93");
|
||||||
oxExpect(ox::detail::toHex(0x40), "40");
|
oxExpect(ox::detail::toHex(0x40), "40");
|
||||||
|
2
deps/ox/src/ox/std/uuid.cpp
vendored
2
deps/ox/src/ox/std/uuid.cpp
vendored
@ -13,7 +13,7 @@ namespace ox {
|
|||||||
bool UUID::s_seeded = false;
|
bool UUID::s_seeded = false;
|
||||||
Random UUID::s_rand;
|
Random UUID::s_rand;
|
||||||
|
|
||||||
void UUID::seed(const RandomSeed &seed) noexcept {
|
void UUID::seedGenerator(const RandomSeed &seed) noexcept {
|
||||||
s_seeded = true;
|
s_seeded = true;
|
||||||
s_rand.seed(seed);
|
s_rand.seed(seed);
|
||||||
}
|
}
|
||||||
|
73
deps/ox/src/ox/std/uuid.hpp
vendored
73
deps/ox/src/ox/std/uuid.hpp
vendored
@ -11,12 +11,56 @@
|
|||||||
#include "array.hpp"
|
#include "array.hpp"
|
||||||
#include "bstring.hpp"
|
#include "bstring.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
|
#include "stringview.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
#include "trace.hpp"
|
#include "trace.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
|
using UUIDStr = ox::BString<36>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto isHexChar(char c) noexcept {
|
||||||
|
return (c >= '0' && c <= '9')
|
||||||
|
|| (c >= 'a' && c <= 'f')
|
||||||
|
|| (c >= 'A' && c <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ox::Result<uint8_t> fromHex(ox::CRStringView v) noexcept {
|
||||||
|
constexpr auto valMap = [] {
|
||||||
|
ox::Array<uint8_t, 128> out;
|
||||||
|
out['A'] = out['a'] = 10;
|
||||||
|
out['B'] = out['b'] = 11;
|
||||||
|
out['C'] = out['c'] = 12;
|
||||||
|
out['D'] = out['d'] = 13;
|
||||||
|
out['E'] = out['e'] = 14;
|
||||||
|
out['F'] = out['f'] = 15;
|
||||||
|
out['0'] = 0;
|
||||||
|
out['1'] = 1;
|
||||||
|
out['2'] = 2;
|
||||||
|
out['3'] = 3;
|
||||||
|
out['4'] = 4;
|
||||||
|
out['5'] = 5;
|
||||||
|
out['6'] = 6;
|
||||||
|
out['7'] = 7;
|
||||||
|
out['8'] = 8;
|
||||||
|
out['9'] = 9;
|
||||||
|
return out;
|
||||||
|
}();
|
||||||
|
if (!detail::isHexChar(v[0]) || !detail::isHexChar(v[1])) {
|
||||||
|
return OxError(1, "Invalid UUID");
|
||||||
|
}
|
||||||
|
if (v.len() != 2) {
|
||||||
|
return OxError(2);
|
||||||
|
}
|
||||||
|
uint8_t out = 0;
|
||||||
|
out += valMap[static_cast<unsigned>(v[0])] * 16u;
|
||||||
|
out += valMap[static_cast<unsigned>(v[1])];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr ox::BString<2> toHex(uint8_t v) noexcept {
|
constexpr ox::BString<2> toHex(uint8_t v) noexcept {
|
||||||
constexpr ox::Array<char, 16> valMap {
|
constexpr ox::Array<char, 16> valMap {
|
||||||
'0',
|
'0',
|
||||||
@ -42,6 +86,7 @@ constexpr ox::BString<2> toHex(uint8_t v) noexcept {
|
|||||||
out[2] = 0;
|
out[2] = 0;
|
||||||
return out.data();
|
return out.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UUID {
|
class UUID {
|
||||||
@ -51,13 +96,35 @@ class UUID {
|
|||||||
ox::Array<uint8_t, 16> m_value;
|
ox::Array<uint8_t, 16> m_value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void seed(const RandomSeed &seed) noexcept;
|
static void seedGenerator(const RandomSeed &seed) noexcept;
|
||||||
|
|
||||||
static ox::Result<UUID> generate() noexcept;
|
static ox::Result<UUID> generate() noexcept;
|
||||||
|
|
||||||
|
constexpr ox::Error fromString(ox::CRStringView s) noexcept {
|
||||||
|
if (s.len() < 36) {
|
||||||
|
return OxError(1, "Insufficient data contain complete UUID");
|
||||||
|
}
|
||||||
|
auto valueI = 0u;
|
||||||
|
for (auto i = 0u; i < s.len();) {
|
||||||
|
if (s[i] == '-') {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto seg = s.substr(i, i + 2);
|
||||||
|
if (seg.len() != 2) {
|
||||||
|
return OxError(1, "Invalid UUID");
|
||||||
|
}
|
||||||
|
oxRequire(val, detail::fromHex(seg));
|
||||||
|
m_value[valueI] = val;
|
||||||
|
i += 2;
|
||||||
|
++valueI;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::BString<36> toString() const noexcept {
|
constexpr UUIDStr toString() const noexcept {
|
||||||
ox::BString<36> out;
|
UUIDStr out;
|
||||||
auto i = 0u;
|
auto i = 0u;
|
||||||
constexpr auto printChars = [](
|
constexpr auto printChars = [](
|
||||||
ox::BString<36> *out, const Array<uint8_t, 16> &value, std::size_t cnt, unsigned i) {
|
ox::BString<36> *out, const Array<uint8_t, 16> &value, std::size_t cnt, unsigned i) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user