From 73dd36f83008e8c2e25c702aab2269b464e5f6ba Mon Sep 17 00:00:00 2001 From: Marius Bancila Date: Fri, 8 Dec 2017 12:46:41 +0200 Subject: [PATCH] uuid from strings --- src/uuid.cpp | 75 +++++++++++++++++++++++++ src/uuid.h | 28 ++++++--- test/test_win/stdafx.cpp | Bin 592 -> 0 bytes test/test_win/stdafx.h | Bin 642 -> 0 bytes test/test_win/targetver.h | Bin 630 -> 0 bytes test/test_win/test_win.cpp | Bin 2074 -> 3726 bytes test/test_win/test_win.vcxproj | 5 +- test/test_win/test_win.vcxproj.filters | 3 - test/test_win/test_win.vcxproj.user | 6 ++ 9 files changed, 105 insertions(+), 12 deletions(-) delete mode 100644 test/test_win/stdafx.cpp delete mode 100644 test/test_win/stdafx.h delete mode 100644 test/test_win/targetver.h create mode 100644 test/test_win/test_win.vcxproj.user diff --git a/src/uuid.cpp b/src/uuid.cpp index ebb6997..00e7331 100644 --- a/src/uuid.cpp +++ b/src/uuid.cpp @@ -8,8 +8,83 @@ #include #endif +namespace +{ + template + constexpr inline unsigned char hex2char(TChar const ch) + { + if (ch >= static_cast('0') && ch <= static_cast('9')) + return ch - static_cast('0'); + if (ch >= static_cast('a') && ch <= static_cast('f')) + return 10 + ch - static_cast('a'); + if (ch >= static_cast('A') && ch <= static_cast('F')) + return 10 + ch - static_cast('A'); + return 0; + } + + template + constexpr inline bool is_hex(TChar const ch) + { + return + (ch >= static_cast('0') && ch <= static_cast('9')) || + (ch >= static_cast('a') && ch <= static_cast('f')) || + (ch >= static_cast('A') && ch <= static_cast('F')); + } + + template + constexpr inline unsigned char hexpair2char(TChar const a, TChar const b) + { + return (hex2char(a) << 4) | hex2char(b); + } +} + namespace uuids { + uuid::uuid(std::string const & str) + { + create(str.c_str(), str.size()); + } + + uuid::uuid(std::wstring const & str) + { + create(str.c_str(), str.size()); + } + + template + void uuid::create(TChar const * const str, size_t const size) + { + TChar digit = 0; + bool firstdigit = true; + size_t index = 0; + + for (size_t i = 0; i < size; ++i) + { + if (str[i] == static_cast('-')) continue; + + if (index >= 16 || !is_hex(str[i])) + { + std::fill(std::begin(data), std::end(data), 0); + return; + } + + if (firstdigit) + { + digit = str[i]; + firstdigit = false; + } + else + { + data[index++] = hexpair2char(digit, str[i]); + firstdigit = true; + } + } + + if (index < 16) + { + std::fill(std::begin(data), std::end(data), 0); + } + } + uuid make_uuid() { #ifdef _WIN32 diff --git a/src/uuid.h b/src/uuid.h index 247d6ac..42b0cb2 100644 --- a/src/uuid.h +++ b/src/uuid.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace uuids { @@ -59,6 +60,7 @@ namespace uuids // indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx enum class version_type { + none = 0, // only possible for nil or invalid uuids time_based = 1, // The time-based version specified in RFC 4122 dce_security = 2, // DCE Security version, with embedded POSIX UIDs. name_based_md5 = 3, // The name-based version specified in RFS 4122 with MD5 hashing @@ -91,10 +93,17 @@ namespace uuids typedef std::ptrdiff_t difference_type; public: - constexpr uuid() {} - constexpr uuid(std::array const & bytes) :data{bytes} {} + constexpr explicit uuid() {} + constexpr explicit uuid(std::array const & bytes) :data{bytes} {} + explicit uuid(uint8_t const * const bytes) + { + std::copy(bytes, bytes + 16, std::begin(data)); + } - variant_type variant() const noexcept + explicit uuid(std::string const & str); + explicit uuid(std::wstring const & str); + + constexpr variant_type variant() const noexcept { if ((data[8] & 0x80) == 0x00) return variant_type::ncs; @@ -106,7 +115,7 @@ namespace uuids return variant_type::future; } - version_type version() const + constexpr version_type version() const { if ((data[6] & 0xF0) == 0x10) return version_type::time_based; @@ -119,14 +128,14 @@ namespace uuids else if ((data[6] & 0xF0) == 0x50) return version_type::name_based_sha1; else - throw guid_exception("invalid guid"); + return version_type::none; } - std::size_t size() const noexcept { return 16; } + constexpr std::size_t size() const noexcept { return 16; } - bool is_nil() const noexcept + constexpr bool is_nil() const noexcept { - for (auto const e : data) if (e != 0) return false; + for (size_t i = 0; i < data.size(); ++i) if (data[i] != 0) return false; return true; } @@ -174,6 +183,9 @@ namespace uuids friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept; + template + void create(TChar const * const str, size_t const size); + template friend std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id); }; diff --git a/test/test_win/stdafx.cpp b/test/test_win/stdafx.cpp deleted file mode 100644 index b2a45687e01a04d7adc519fed991c0f75653ccef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmZ`%O>crg6r8h3|HH5KJd(=;cd;Rj5j?`Dz1g-I7*Aw zE@hlJI{yD=Jz+s5(h>|M-~(5~PN?NX9B2EQOb*9UgH)Y~nd5~~Ek3!68pR^^)O2;2 z80OWsM5|`#!f8ygYMZL~pC@1-ue2zmV17p>^2ZyNxHX>besarU`OEu~C->;+#~$z4 za;O`sv*6Gy*TpDb2b(ii>PODhoO*OXy&0(I!nt8?K6b)khdo&~c*TJ);O)V!*f(Xg Q#Eun4PrP;e{wAdQ2jl={v;Y7A diff --git a/test/test_win/stdafx.h b/test/test_win/stdafx.h deleted file mode 100644 index 94d4ed877dbfd8cd2c783931c444cad664143b10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmaJ<%Z`FT5UjJw{sYnLM(@V#$-9^R0UQRwu#ECB^7Cp{4I>V}Q z8vEtLe;CsQ`f9DHxFP?Ev!}!l=AXA(tbaPXB)?e2)ZxZ=WBxB^dUob-#=8i1_Gje& z#NH7xP7*QWxk;u;fEfw0WxN;+co0fK2Vs4B9U*sm0{`t1wOo&Foy0~*EXI^K{ z&F{}p2USW{Xp2p>*G`#oJ!s%(q!H-M(Ty4fmG}kNtEQTB%)V1m=}BwwfWPvrT#@e@ zH0NG}74Ao{glS)#QXA|NYdIfY7hrMp+Ji@H`t9kzWx_SD6;~Ri;cvXH)6CO{-I1p_IJPQ#X=r zigZeSqQguJz35q;zt9^Q_C^^>*mmuXUCp&pw^fPoGX+dho4RCrySs7j@9_UipWkA5 OQDt4mH~x-^Z~X_?9czaG diff --git a/test/test_win/test_win.cpp b/test/test_win/test_win.cpp index 535447294ebb1f7882bc5e2cab413f0b88d556d9..47cdec84938b86c3015bac40008a132df4184a8e 100644 GIT binary patch literal 3726 zcmdT{TaVH}6h6-;{)eHyu!$7eMOW9$laKxc6T)@@iBL#ecD=;Eu72kX!oN`Jjqct8wH~4+T?NrVgilM*Y#Nd}>U(k2#*R&Fd z3i~Pcg@ViQoda`43&9%;?FHa78iT@I?o)b7PasWS-p_5KUV_K4hWXaertlbjlyzkP5Q28mV!Ht0| zrQFT1&jp_?w#F_K9h|f!y%j8`YcVwyN6Tu)c3y%;1v^_Tdv8~*Syw@(kfVe@bG#QK z>&02vtj7<~V=WE6$75(fukfX1_;rRBE(+L&v#r;dGF#1RS|ZwR#J*p_d9*uc88p`> z%{x1qZ8UfCq~gEhdN)bnY1~8lLMU&hHxYC@EW*mg#s~?Bd%Al2YYdY_pQ(! z;muy3;P$v(v{YkIoeSOSpi~+zmTHPf4!NEa1BW8n*`|GT_-tzOkLT^;*`I_OHDNnD zI$ZaC9Mf|#)RA~^#(jKtY?EoHLjF&_; zswtzjL=UK^-1F-)eZo``Q$H+=zm4%?sZO!<;dw%5hL?YYjz5P!+=a&2*QX6lcwgabh&9=9 zw*2f`uk+n4f0qXuI*cNhG2ExUzPiKO^N`a2X=jeC$6)FGxzWzneh!?_H`H?er{H74 zXJvijYr?!m{PO<_gNQFtQFz+5aqKD8>-1@~-3-h#5a)=Ui0jndP4k@EB(>AmPQ3TX vQa_pbiOW!UQ|BDsx96|t)sVlwY2vT%WBzg8@qelczAoS=gQ{x1;GzBk89Nc^ delta 15 WcmeB^oh2~g-)0TQKWvlp_!Iy%4+Zf6 diff --git a/test/test_win/test_win.vcxproj b/test/test_win/test_win.vcxproj index f0db909..1fe8cc1 100644 --- a/test/test_win/test_win.vcxproj +++ b/test/test_win/test_win.vcxproj @@ -89,6 +89,7 @@ Disabled true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + stdcpplatest Console @@ -102,6 +103,7 @@ Disabled true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + stdcpplatest Console @@ -117,6 +119,7 @@ true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + stdcpplatest Console @@ -134,6 +137,7 @@ true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + stdcpplatest Console @@ -144,7 +148,6 @@ - diff --git a/test/test_win/test_win.vcxproj.filters b/test/test_win/test_win.vcxproj.filters index 7adf8d3..cc90555 100644 --- a/test/test_win/test_win.vcxproj.filters +++ b/test/test_win/test_win.vcxproj.filters @@ -15,9 +15,6 @@ - - Header Files - Header Files diff --git a/test/test_win/test_win.vcxproj.user b/test/test_win/test_win.vcxproj.user new file mode 100644 index 0000000..baf2417 --- /dev/null +++ b/test/test_win/test_win.vcxproj.user @@ -0,0 +1,6 @@ + + + + false + + \ No newline at end of file