From 61275c0f5ff38e896472a4389f37df409fc03af9 Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Sun, 15 Feb 2026 13:28:06 -0600 Subject: [PATCH] Add Uuids --- CMakeLists.txt | 8 +- Config.cmake.in | 15 +- Packaging/Linux/PKGBUILD | 2 +- Packaging/Linux/version.sh | 2 +- apps/tuuid.cpp | 24 +++ changelog.md | 8 + include/TessesFramework/Http/HttpUtils.hpp | 4 + .../Serialization/BitConverter.hpp | 34 ++++ .../TessesFramework/Streams/ByteReader.hpp | 5 + .../TessesFramework/Streams/ByteWriter.hpp | 4 +- include/TessesFramework/Uuid.hpp | 32 ++++ src/Http/HttpUtils.cpp | 33 ++++ src/Serialization/BitConverter.cpp | 143 +++++++++++++++ src/Streams/ByteReader.cpp | 31 +++- src/Streams/ByteWriter.cpp | 14 +- src/Uuid.cpp | 169 ++++++++++++++++++ 16 files changed, 509 insertions(+), 19 deletions(-) create mode 100644 apps/tuuid.cpp create mode 100644 changelog.md create mode 100644 include/TessesFramework/Uuid.hpp create mode 100644 src/Uuid.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b9f6a44..2543117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16) set(TESSESFRAMEWORK_MAJOR_VERSION 0) set(TESSESFRAMEWORK_MINOR_VERSION 0) -set(TESSESFRAMEWORK_PATCH_VERSION 1) +set(TESSESFRAMEWORK_PATCH_VERSION 2) project(TessesFramework VERSION ${TESSESFRAMEWORK_MAJOR_VERSION}.${TESSESFRAMEWORK_MINOR_VERSION}.${TESSESFRAMEWORK_PATCH_VERSION}) @@ -65,6 +65,7 @@ src/Crypto/MbedTLS/Crypto.cpp src/Args.cpp src/TF_Init.cpp src/HiddenField.cpp +src/Uuid.cpp src/BitTorrent/TorrentFile.cpp src/BitTorrent/TorrentStream.cpp ) @@ -418,6 +419,11 @@ add_executable(twatch apps/twatch.cpp) target_link_libraries(twatch PUBLIC tessesframework) install(TARGETS twatch DESTINATION "${CMAKE_INSTALL_BINDIR}") + +add_executable(tuuid apps/tuuid.cpp) + +target_link_libraries(tuuid PUBLIC tessesframework) +install(TARGETS tuuid DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() include(InstallRequiredSystemLibraries) diff --git a/Config.cmake.in b/Config.cmake.in index 22ae6d6..149735a 100644 --- a/Config.cmake.in +++ b/Config.cmake.in @@ -11,22 +11,11 @@ find_package(Threads REQUIRED) endif() endif() -set(TESSESFRAMEWORK_ENABLE_LIBWEBCAM @TESSESFRAMEWORK_ENABLE_LIBWEBCAM@) - -if(${TESSESFRAMEWORK_ENABLE_LIBWEBCAM}) -find_package(libwebcam) -endif() set(TESSESFRAMEWORK_ENABLE_SQLITE @TESSESFRAMEWORK_ENABLE_SQLITE@) set(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS @TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS@) -set(TESSESFRAMEWORK_ENABLE_SDL2 @TESSESFRAMEWORK_ENABLE_SDL2@) - - -if(${TESSESFRAMEWORK_ENABLE_SDL2}) -find_package(SDL2 REQUIRED) -find_package(SDL2_ttf REQUIRED) -find_package(SDL2_image REQUIRED) -endif() set(TESSESFRAMEWORK_ENABLE_NETWORKING @TESSESFRAMEWORK_ENABLE_NETWORKING@) set(TESSESFRAMEWORK_ENABLE_THREADING @TESSESFRAMEWORK_ENABLE_THREADING@) +set(TESSESFRAMEWORK_ENABLE_PROCESS @TESSESFRAMEWORK_ENABLE_PROCESS@) +set(TESSESFRAMEWORK_ENABLE_RPATH @TESSESFRAMEWORK_ENABLE_RPATH@) diff --git a/Packaging/Linux/PKGBUILD b/Packaging/Linux/PKGBUILD index 9936b8a..ef5f5f5 100644 --- a/Packaging/Linux/PKGBUILD +++ b/Packaging/Linux/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Mike Nolan pkgname=tesses-framework # '-bzr', '-git', '-hg' or '-svn' -pkgver=0.0.1 +pkgver=0.0.2 pkgrel=1 pkgdesc="" arch=('x86_64' 'powerpc') diff --git a/Packaging/Linux/version.sh b/Packaging/Linux/version.sh index e5af53f..06565cf 100644 --- a/Packaging/Linux/version.sh +++ b/Packaging/Linux/version.sh @@ -1 +1 @@ -export DEB_VERSION=0.0.1 \ No newline at end of file +export DEB_VERSION=0.0.2 \ No newline at end of file diff --git a/apps/tuuid.cpp b/apps/tuuid.cpp new file mode 100644 index 0000000..e6b9218 --- /dev/null +++ b/apps/tuuid.cpp @@ -0,0 +1,24 @@ +#include "TessesFramework/Uuid.hpp" +#include + +int main(int argc, char** argv) +{ + //e794499c + using namespace Tesses::Framework; + + Uuid uuid = Uuid::Generate(); + /*uuid.time_low = 0xe794499c; + uuid.time_mid = 0x823c; + uuid.time_hi_and_version = 0x304c; + uuid.clock_seq_hi_and_reserved = 0xa4; + + uuid.clock_seq_low = 0x59; + uuid.node[0] = 0x8f; + uuid.node[1] = 0xdc; + uuid.node[2] = 0xd9; + uuid.node[3] = 0x60; + uuid.node[4] = 0xb4; + uuid.node[5] = 0xac;*/ + + std::cout << uuid.ToString(Tesses::Framework::UuidStringifyConfig::LowercaseNoCurly) << std::endl; +} \ No newline at end of file diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..b3b357e --- /dev/null +++ b/changelog.md @@ -0,0 +1,8 @@ +# Changelog + +## 0.0.2 +Add UUIDs + + +## 0.0.1 +Start versioning \ No newline at end of file diff --git a/include/TessesFramework/Http/HttpUtils.hpp b/include/TessesFramework/Http/HttpUtils.hpp index 9380c4d..3d17102 100644 --- a/include/TessesFramework/Http/HttpUtils.hpp +++ b/include/TessesFramework/Http/HttpUtils.hpp @@ -143,10 +143,14 @@ struct CaseInsensitiveLess { class HttpUtils { public: + static char NibbleToHex(uint8_t b, bool isUppercase); static char NibbleToHex(uint8_t nibble); static uint8_t HexToNibble(char c); static std::string BytesToHex(const std::vector& data); static void BytesToHex(std::string& text,const std::vector& data); + + static std::string BytesToHex(const std::vector& data,bool isUppercase); + static void BytesToHex(std::string& text,const std::vector& data, bool isUppercase); static std::vector HexToBytes(const std::string& text); static void HexToBytes(std::vector& data,const std::string& text); static std::string MimeType(std::filesystem::path p); diff --git a/include/TessesFramework/Serialization/BitConverter.hpp b/include/TessesFramework/Serialization/BitConverter.hpp index af8b411..e04a8e3 100644 --- a/include/TessesFramework/Serialization/BitConverter.hpp +++ b/include/TessesFramework/Serialization/BitConverter.hpp @@ -1,5 +1,6 @@ #pragma once #include "../Common.hpp" +#include "../Uuid.hpp" namespace Tesses::Framework::Serialization { @@ -39,10 +40,43 @@ class BitConverter { static uint64_t ToUint64BE(uint8_t& b); static uint32_t ToUint32BE(uint8_t& b); static uint16_t ToUint16BE(uint8_t& b); + + static double ToDoubleLE(uint8_t& b); + static uint64_t ToUint64LE(uint8_t& b); + static uint32_t ToUint32LE(uint8_t& b); + static uint16_t ToUint16LE(uint8_t& b); + + static Uuid ToUuidBE(uint8_t& b); + + static Uuid ToUuidMS(uint8_t& b); + + static void ToUuidBE(uint8_t& b, Uuid& uuid); + + static void ToUuidMS(uint8_t& b, Uuid& uuid); + static void FromDoubleBE(uint8_t& b, double v); static void FromUint64BE(uint8_t& b, uint64_t v); static void FromUint32BE(uint8_t& b, uint32_t v); static void FromUint16BE(uint8_t& b, uint16_t v); + static void FromDoubleLE(uint8_t& b, double v); + static void FromUint64LE(uint8_t& b, uint64_t v); + static void FromUint32LE(uint8_t& b, uint32_t v); + static void FromUint16LE(uint8_t& b, uint16_t v); + + static void FromUuidBE(uint8_t& b, const Uuid& uuid); + + static void FromUuidMS(uint8_t& b, const Uuid& uuid); + + + static inline bool IsLittleEndian() + { + uint8_t a[2]; + a[0] = 0x01; + a[1] = 0xA4; + uint16_t num=0; + memcpy(&num,&a, 2); + return num != 420; + } }; } \ No newline at end of file diff --git a/include/TessesFramework/Streams/ByteReader.hpp b/include/TessesFramework/Streams/ByteReader.hpp index 32f3dd4..8318e9c 100644 --- a/include/TessesFramework/Streams/ByteReader.hpp +++ b/include/TessesFramework/Streams/ByteReader.hpp @@ -1,5 +1,6 @@ #pragma once #include "Stream.hpp" +#include "../Uuid.hpp" namespace Tesses::Framework::Streams { @@ -26,5 +27,9 @@ namespace Tesses::Framework::Streams float ReadF32LE(); double ReadF64BE(); double ReadF64LE(); + Uuid ReadUuidBE(); + Uuid ReadUuidMS(); + void ReadUuidBE(Uuid& uuid); + void ReadUuidMS(Uuid& uuid); }; } \ No newline at end of file diff --git a/include/TessesFramework/Streams/ByteWriter.hpp b/include/TessesFramework/Streams/ByteWriter.hpp index 5e0ab8b..68465e8 100644 --- a/include/TessesFramework/Streams/ByteWriter.hpp +++ b/include/TessesFramework/Streams/ByteWriter.hpp @@ -1,6 +1,6 @@ #pragma once #include "Stream.hpp" - +#include "../Uuid.hpp" namespace Tesses::Framework::Streams { class ByteWriter { @@ -27,5 +27,7 @@ namespace Tesses::Framework::Streams void WriteF32LE(float v); void WriteF64BE(double v); void WriteF64LE(double v); + void WriteUuidBE(const Uuid& uuid); + void WriteUuidMS(const Uuid& uuid); }; } \ No newline at end of file diff --git a/include/TessesFramework/Uuid.hpp b/include/TessesFramework/Uuid.hpp new file mode 100644 index 0000000..9151047 --- /dev/null +++ b/include/TessesFramework/Uuid.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "Common.hpp" + +namespace Tesses::Framework { + enum class UuidStringifyConfig { + IsUppercase=0b001, + HasCurly=0b010, + HasDashes=0b100, + UppercaseCompact = IsUppercase, + LowercaseCompact = 0, + UppercaseNoCurly = IsUppercase | HasDashes, + LowercaseNoCurly = HasDashes, + UppercaseCurly = IsUppercase | HasDashes | HasCurly, + LowercaseCurly = HasDashes | HasCurly + }; + struct Uuid { + Uuid() = default; + uint32_t time_low = 0; + uint16_t time_mid = 0; + uint16_t time_hi_and_version = 0; + uint8_t clock_seq_hi_and_reserved = 0; + uint8_t clock_seq_low = 0; + uint8_t node[6] = {0,0,0,0,0,0}; + + static Uuid Generate(); + static void Generate(Uuid& uuid); + + static bool TryParse(std::string text, Uuid& uuid); + + std::string ToString(UuidStringifyConfig cfg = UuidStringifyConfig::UppercaseCurly); + }; +} \ No newline at end of file diff --git a/src/Http/HttpUtils.cpp b/src/Http/HttpUtils.cpp index 305ff12..684297f 100644 --- a/src/Http/HttpUtils.cpp +++ b/src/Http/HttpUtils.cpp @@ -198,6 +198,19 @@ namespace Tesses::Framework::Http { strm << std::setfill(c) << std::setw(count) << text; return strm.str(); } + char HttpUtils::NibbleToHex(uint8_t b, bool isUppercase) + { + if(isUppercase) + { + b %= 16; + if(b >= 0 && b <= 9) + return b + '0'; + if(b >= 10 && b <= 15) + return b + ('A' - 10); + return 0; + } + return NibbleToHex(b); + } char HttpUtils::NibbleToHex(uint8_t b) { b %= 16; @@ -971,6 +984,12 @@ namespace Tesses::Framework::Http { BytesToHex(text,data); return text; } + std::string HttpUtils::BytesToHex(const std::vector& data, bool isUpper) + { + std::string text; + BytesToHex(text,data, isUpper); + return text; + } void HttpUtils::BytesToHex(std::string& text,const std::vector& data) { if(data.empty()) { @@ -984,6 +1003,20 @@ namespace Tesses::Framework::Http { text[i*2+1] += NibbleToHex(data[i]); } } + + void HttpUtils::BytesToHex(std::string& text,const std::vector& data, bool isUpper) + { + if(data.empty()) { + text.clear(); + return; + } + text.resize(data.size()*2); + for(size_t i = 0; i < data.size(); i++) + { + text[i*2] = NibbleToHex(data[i] >> 4, isUpper); + text[i*2+1] += NibbleToHex(data[i], isUpper); + } + } std::vector HttpUtils::HexToBytes(const std::string& text) { std::vector data; diff --git a/src/Serialization/BitConverter.cpp b/src/Serialization/BitConverter.cpp index 72651a7..20e9408 100644 --- a/src/Serialization/BitConverter.cpp +++ b/src/Serialization/BitConverter.cpp @@ -49,6 +49,46 @@ namespace Tesses::Framework::Serialization v |= (uint16_t)b2[1]; return v; } + double BitConverter::ToDoubleLE(uint8_t& b) + { + return ToDoubleBits(ToUint64LE(b)); + } + uint64_t BitConverter::ToUint64LE(uint8_t& b) + { + uint8_t* b2 = &b; + uint64_t v = 0; + v |= (uint64_t)b2[0]; + v |= ((uint64_t)b2[1] << 8); + v |= ((uint64_t)b2[2] << 16); + v |= ((uint64_t)b2[3] << 24); + v |= ((uint64_t)b2[4] << 32); + v |= ((uint64_t)b2[5] << 40); + v |= ((uint64_t)b2[6] << 48); + v |= ((uint64_t)b2[7] << 56); + + return v; + } + uint32_t BitConverter::ToUint32LE(uint8_t& b) + { + uint8_t* b2 = &b; + uint32_t v = 0; + v |= (uint32_t)b2[0]; + v |= ((uint32_t)b2[1] << 8); + v |= ((uint32_t)b2[2] << 16); + v |= ((uint32_t)b2[3] << 24); + + return v; + } + uint16_t BitConverter::ToUint16LE(uint8_t& b) + { + uint8_t* b2 = &b; + uint16_t v = 0; + + v |= (uint16_t)b2[0]; + v |= ((uint16_t)b2[1] << 8); + + return v; + } void BitConverter::FromDoubleBE(uint8_t& b, double v) { FromUint64BE(b,ToUintBits(v)); @@ -82,4 +122,107 @@ namespace Tesses::Framework::Serialization b2[1] = (uint8_t)v; } + void BitConverter::FromDoubleLE(uint8_t& b, double v) + { + FromUint64BE(b,ToUintBits(v)); + } + void BitConverter::FromUint64LE(uint8_t& b, uint64_t v) + { + uint8_t* b2 = &b; + b2[0] = (uint8_t)v; + b2[1] = (uint8_t)(v >> 8); + b2[2] = (uint8_t)(v >> 16); + b2[3] = (uint8_t)(v >> 24); + b2[4] = (uint8_t)(v >> 32); + b2[5] = (uint8_t)(v >> 40); + b2[6] = (uint8_t)(v >> 48); + b2[7] = (uint8_t)(v >> 56); + + } + void BitConverter::FromUint32LE(uint8_t& b, uint32_t v) + { + uint8_t* b2 = &b; + + b2[0] = (uint8_t)v; + b2[1] = (uint8_t)(v >> 8); + b2[2] = (uint8_t)(v >> 16); + b2[3] = (uint8_t)(v >> 24); + + } + void BitConverter::FromUint16LE(uint8_t& b, uint16_t v) + { + uint8_t* b2 = &b; + + + b2[0] = (uint8_t)v; + b2[1] = (uint8_t)(v >> 8); + } + void BitConverter::FromUuidBE(uint8_t& b, const Uuid& uuid) + { + uint8_t* b2 = &b; + FromUint32BE(b2[0], uuid.time_low); + FromUint32BE(b2[4], uuid.time_mid); + FromUint32BE(b2[6], uuid.time_hi_and_version); + b2[8] = uuid.clock_seq_hi_and_reserved; + b2[9] = uuid.clock_seq_low; + for(size_t i = 0; i < 6; i++) + b2[i+10] = uuid.node[i]; + + } + void BitConverter::FromUuidMS(uint8_t& b, const Uuid& uuid) + { + uint8_t* b2 = &b; + FromUint32LE(b2[0], uuid.time_low); + FromUint32LE(b2[4], uuid.time_mid); + FromUint32LE(b2[6], uuid.time_hi_and_version); + + b2[8] = uuid.clock_seq_hi_and_reserved; + b2[9] = uuid.clock_seq_low; + for(size_t i = 0; i < 6; i++) + b2[i+10] = uuid.node[i]; + + } + + Uuid BitConverter::ToUuidBE(uint8_t& b) + { + Uuid uuid; + BitConverter::ToUuidBE(b,uuid); + return uuid; + } + Uuid BitConverter::ToUuidMS(uint8_t& b) + { + Uuid uuid; + BitConverter::ToUuidMS(b,uuid); + return uuid; + } + + + void BitConverter::ToUuidBE(uint8_t& b, Uuid& uuid) + { + uint8_t* b2 = &b; + uuid.time_low = ToUint32BE(b2[0]); + + uuid.time_mid = ToUint16BE(b2[4]); + + uuid.time_hi_and_version = ToUint16BE(b2[6]); + + uuid.clock_seq_hi_and_reserved = b2[8]; + uuid.clock_seq_low = b2[9]; + for(size_t i = 0; i < 6; i++) + uuid.node[i]= b2[i+10]; + + } + + void BitConverter::ToUuidMS(uint8_t& b, Uuid& uuid) + { + uint8_t* b2 = &b; + uuid.time_low = ToUint32LE(b2[0]); + uuid.time_mid = ToUint16LE(b2[4]); + uuid.time_hi_and_version = ToUint16LE(b2[6]); + + uuid.clock_seq_hi_and_reserved = b2[8]; + uuid.clock_seq_low = b2[9]; + for(size_t i = 0; i < 6; i++) + uuid.node[i]= b2[i+10]; + } }; \ No newline at end of file diff --git a/src/Streams/ByteReader.cpp b/src/Streams/ByteReader.cpp index b6c7701..592651e 100644 --- a/src/Streams/ByteReader.cpp +++ b/src/Streams/ByteReader.cpp @@ -1,4 +1,5 @@ #include "TessesFramework/Streams/ByteReader.hpp" +#include "TessesFramework/Serialization/BitConverter.hpp" namespace Tesses::Framework::Streams { std::shared_ptr ByteReader::GetStream() @@ -149,5 +150,33 @@ namespace Tesses::Framework::Streams auto v=ReadU64LE(); return *(double*)&v; } - + + Uuid ByteReader::ReadUuidBE() + { + uint8_t data[16]; + if(this->strm->ReadBlock(data, 16) != 16) + throw std::runtime_error("End of file"); + return Serialization::BitConverter::ToUuidBE(data[0]); + } + Uuid ByteReader::ReadUuidMS() + { + uint8_t data[16]; + if(this->strm->ReadBlock(data, 16) != 16) + throw std::runtime_error("End of file"); + return Serialization::BitConverter::ToUuidMS(data[0]); + } + void ByteReader::ReadUuidBE(Uuid& uuid) + { + uint8_t data[16]; + if(this->strm->ReadBlock(data, 16) != 16) + throw std::runtime_error("End of file"); + Serialization::BitConverter::ToUuidBE(data[0],uuid); + } + void ByteReader::ReadUuidMS(Uuid& uuid) + { + uint8_t data[16]; + if(this->strm->ReadBlock(data, 16) != 16) + throw std::runtime_error("End of file"); + Serialization::BitConverter::ToUuidMS(data[0],uuid); + } } \ No newline at end of file diff --git a/src/Streams/ByteWriter.cpp b/src/Streams/ByteWriter.cpp index d349f7f..96ae633 100644 --- a/src/Streams/ByteWriter.cpp +++ b/src/Streams/ByteWriter.cpp @@ -1,4 +1,5 @@ #include "TessesFramework/Streams/ByteWriter.hpp" +#include "TessesFramework/Serialization/BitConverter.hpp" namespace Tesses::Framework::Streams { std::shared_ptr ByteWriter::GetStream() @@ -129,5 +130,16 @@ namespace Tesses::Framework::Streams uint64_t data = *(uint64_t*)&v; WriteU64LE(data); } - + void ByteWriter::WriteUuidBE(const Uuid& uuid) + { + uint8_t data[16]; + Serialization::BitConverter::FromUuidBE(data[0], uuid); + this->strm->WriteBlock(data, 16); + } + void ByteWriter::WriteUuidMS(const Uuid& uuid) + { + uint8_t data[16]; + Serialization::BitConverter::FromUuidMS(data[0], uuid); + this->strm->WriteBlock(data, 16); + } } \ No newline at end of file diff --git a/src/Uuid.cpp b/src/Uuid.cpp new file mode 100644 index 0000000..910a6b5 --- /dev/null +++ b/src/Uuid.cpp @@ -0,0 +1,169 @@ +#include "TessesFramework/Uuid.hpp" +#include "TessesFramework/Http/HttpUtils.hpp" +#include "TessesFramework/Crypto/Crypto.hpp" + +namespace Tesses::Framework { + Uuid Uuid::Generate() + { + //xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + Uuid uuid; + Uuid::Generate(uuid); + return uuid; + } + + void Uuid::Generate(Uuid& uuid) + { + std::vector bytes(16); + Crypto::RandomBytes(bytes, "TF_UUID"); + + uuid.time_low = (uint32_t)bytes[0]; + uuid.time_low |= (uint32_t)bytes[1] << 8; + uuid.time_low |= (uint32_t)bytes[2] << 16; + uuid.time_low |= (uint32_t)bytes[3] << 24; + uuid.time_mid = (uint16_t)bytes[4]; + uuid.time_mid |= (uint16_t)bytes[5] << 8; + uuid.time_hi_and_version = (uint16_t)bytes[6]; + uuid.time_hi_and_version |= (uint16_t)bytes[7] << 8; + uuid.clock_seq_hi_and_reserved = bytes[8]; + uuid.clock_seq_low = bytes[9]; + for(size_t i = 0; i < 6; i++) + { + uuid.node[i] = bytes[i+10]; + } + uuid.time_hi_and_version &= ~0x00F0; + uuid.time_hi_and_version |= 0x0040; + uuid.clock_seq_hi_and_reserved &= ~0b11000000; + uuid.clock_seq_hi_and_reserved |= 0b10000000; + + + } + + bool Uuid::TryParse(std::string text, Uuid& uuid) + { + std::array hex_digits; + size_t hex_offset = 0; + size_t text_offset = 0; + for(; text_offset < text.size(); text_offset++) + { + if(text[text_offset] == '{' && (text_offset != 0 || hex_offset != 0)) + return false; + if(text[text_offset] == '}' && hex_offset < 32) + return false; + if(text[text_offset] == '-' && hex_offset != 8 && hex_offset != 12 && hex_offset != 16 && hex_offset != 20) + return false; + if((text[text_offset] >= 'A' && text[text_offset] <= 'F') || (text[text_offset] >= 'a' && text[text_offset] <= 'f') || text[text_offset] >= '0' && text[text_offset] <= '9') + { + if(hex_offset >= 32) return false; + hex_digits[hex_offset] = Http::HttpUtils::HexToNibble(text[text_offset]); + hex_offset++; + } + else return false; + + } + + uint8_t b = hex_digits[0] >> 4 | hex_digits[1]; + uuid.time_low = (uint32_t)b; + b = hex_digits[2] >> 4 | hex_digits[3]; + uuid.time_low |= (uint32_t)b << 8; + b = hex_digits[4] >> 4 | hex_digits[5]; + uuid.time_low |= (uint32_t)b << 16; + b = hex_digits[6] >> 4 | hex_digits[7]; + uuid.time_low |= (uint32_t)b << 24; + + b = hex_digits[8] >> 4 | hex_digits[9]; + uuid.time_mid = (uint16_t)b; + b = hex_digits[10] >> 4 | hex_digits[11]; + uuid.time_mid |= (uint16_t)b << 8; + + b = hex_digits[12] >> 4 | hex_digits[13]; + uuid.time_hi_and_version = (uint16_t)b; + b = hex_digits[14] >> 4 | hex_digits[15]; + uuid.time_hi_and_version |= (uint16_t)b << 8; + + uuid.clock_seq_hi_and_reserved = hex_digits[16] >> 4 | hex_digits[17]; + + uuid.clock_seq_low = hex_digits[18] >> 4 | hex_digits[19]; + + for(size_t i = 0; i < 6; i++) + { + uuid.node[i] = hex_digits[20+(i*2)] >> 4 | hex_digits[21+(i*2)]; + } + + return true; + } + //9c4994e7-3c82-4c30-a459-8fdcd960b4ac + + std::string Uuid::ToString(UuidStringifyConfig cfg) + { + bool hasCurly = ((int)cfg & (int)UuidStringifyConfig::HasCurly) != 0; + bool isUppercase = ((int)cfg & (int)UuidStringifyConfig::IsUppercase) != 0; + bool hasDash = ((int)cfg & (int)UuidStringifyConfig::HasDashes) != 0; + + std::string uuid_str = ""; + if(hasCurly) + uuid_str += "{"; + + uint8_t byte = (uint8_t)(this->time_low & 0xFF); + + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + byte = (uint8_t)((this->time_low >> 8) & 0xFF); + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + byte = (uint8_t)((this->time_low >> 16) & 0xFF); + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + byte = (uint8_t)((this->time_low >> 24) & 0xFF); + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + + if(hasDash) + uuid_str += "-"; + + byte = (uint8_t)(this->time_mid & 0xFF); + + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + + byte = (uint8_t)((this->time_mid >> 8) & 0xFF); + + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + + if(hasDash) + uuid_str += "-"; + + byte = (uint8_t)(this->time_hi_and_version & 0xFF); + + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + + byte = (uint8_t)((this->time_hi_and_version >> 8) & 0xFF); + + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + if(hasDash) + uuid_str += "-"; + + uuid_str += Http::HttpUtils::NibbleToHex(this->clock_seq_hi_and_reserved>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(this->clock_seq_hi_and_reserved,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(this->clock_seq_low>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(this->clock_seq_low,isUppercase); + if(hasDash) + uuid_str += "-"; + + for(size_t i = 0; i < 6; i++) + { + byte = this->node[i]; + uuid_str += Http::HttpUtils::NibbleToHex(byte>>4,isUppercase); + uuid_str += Http::HttpUtils::NibbleToHex(byte,isUppercase); + } + + if(hasCurly) + uuid_str += "}"; + return uuid_str; + + + + } +} \ No newline at end of file