From 7e845c917b44b8e774d8faeb11c82244d448c554 Mon Sep 17 00:00:00 2001 From: Marius Bancila Date: Thu, 7 Dec 2017 12:05:55 +0200 Subject: [PATCH] basic structure uuid --- src/uuid.h | 234 +++++++++++++++++++++++++ test/test_win/.gitignore | 3 + test/test_win/stdafx.cpp | Bin 0 -> 592 bytes test/test_win/stdafx.h | Bin 0 -> 642 bytes test/test_win/targetver.h | Bin 0 -> 630 bytes test/test_win/test_win.cpp | Bin 0 -> 586 bytes test/test_win/test_win.sln | 31 ++++ test/test_win/test_win.vcxproj | 162 +++++++++++++++++ test/test_win/test_win.vcxproj.filters | 36 ++++ 9 files changed, 466 insertions(+) create mode 100644 src/uuid.h create mode 100644 test/test_win/.gitignore create mode 100644 test/test_win/stdafx.cpp create mode 100644 test/test_win/stdafx.h create mode 100644 test/test_win/targetver.h create mode 100644 test/test_win/test_win.cpp create mode 100644 test/test_win/test_win.sln create mode 100644 test/test_win/test_win.vcxproj create mode 100644 test/test_win/test_win.vcxproj.filters diff --git a/src/uuid.h b/src/uuid.h new file mode 100644 index 0000000..6e1a8e3 --- /dev/null +++ b/src/uuid.h @@ -0,0 +1,234 @@ +#pragma once + +#include +#include +#include +#include + +namespace uuids +{ + // UUID format https://tools.ietf.org/html/rfc4122 + // Field NDR Data Type Octet # Note + // -------------------------------------------------------------------------------------------------------------------------- + // time_low unsigned long 0 - 3 The low field of the timestamp. + // time_mid unsigned short 4 - 5 The middle field of the timestamp. + // time_hi_and_version unsigned short 6 - 7 The high field of the timestamp multiplexed with the version number. + // clock_seq_hi_and_reserved unsigned small 8 The high field of the clock sequence multiplexed with the variant. + // clock_seq_low unsigned small 9 The low field of the clock sequence. + // node character 10 - 15 The spatially unique node identifier. + // -------------------------------------------------------------------------------------------------------------------------- + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | time_low | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | time_mid | time_hi_and_version | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |clk_seq_hi_res | clk_seq_low | node (0-1) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | node (2-5) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // indicated by a bit pattern in octet 8, marked with N in xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx + enum class variant_type + { + // NCS backward compatibility (with the obsolete Apollo Network Computing System 1.5 UUID format) + // N bit pattern: 0xxx + // > the first 6 octets of the UUID are a 48-bit timestamp (the number of 4 microsecond units of time since 1 Jan 1980 UTC); + // > the next 2 octets are reserved; + // > the next octet is the "address family"; + // > the final 7 octets are a 56-bit host ID in the form specified by the address family + ncs, + + // RFC 4122/DCE 1.1 + // N bit pattern: 10xx + // > big-endian byte order + rfc, + + // Microsoft Corporation backward compatibility + // N bit pattern: 110x + // > little endian byte order + // > formely used in the Component Object Model (COM) library + microsoft, + + // reserved for possible future definition + // N bit pattern: 111x + future + }; + + // indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx + enum class version_type + { + 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 + random_number_based = 4, // The randomly or pseudo-randomly generated version specified in RFS 4122 + name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing + }; + + struct guid_exception : public std::runtime_error + { + explicit guid_exception(std::string const & message) + : std::runtime_error(message.c_str()) + { + } + + explicit guid_exception(char const * const message) + : std::runtime_error(message) + { + } + }; + + struct uuid + { + public: + typedef uint8_t value_type; + typedef uint8_t& reference; + typedef uint8_t const& const_reference; + typedef uint8_t* iterator; + typedef uint8_t const* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + public: + constexpr uuid() {} + + variant_type variant() const noexcept + { + if ((data[8] & 0x80) == 0x00) + return variant_type::ncs; + else if ((data[8] & 0xC0) == 0x80) + return variant_type::rfc; + else if ((data[8] & 0xE0) == 0xC0) + return variant_type::microsoft; + else + return variant_type::future; + } + + version_type version() const + { + if ((data[6] & 0xF0) == 0x10) + return version_type::time_based; + else if ((data[6] & 0xF0) == 0x20) + return version_type::dce_security; + else if ((data[6] & 0xF0) == 0x30) + return version_type::name_based_md5; + else if ((data[6] & 0xF0) == 0x40) + return version_type::random_number_based; + else if ((data[6] & 0xF0) == 0x50) + return version_type::name_based_sha1; + else + throw guid_exception("invalid guid"); + } + + std::size_t size() const noexcept { return 16; } + + bool is_nil() const noexcept + { + for (auto const e : data) if (e != 0) return false; + return true; + } + + void swap(uuid & other) noexcept + { + data.swap(other.data); + } + + friend void swap(uuid& lhs, uuid& rhs) noexcept + { + std::swap(lhs.data, rhs.data); + } + + iterator begin() noexcept { return &data[0]; } + const_iterator begin() const noexcept { return &data[0]; } + iterator end() noexcept { return &data[0] + size(); } + const_iterator end() const noexcept { return &data[0] + size(); } + + template, + class Alloc = std::allocator> + std::basic_string string(Alloc const & a = Alloc()) const + { + std::basic_stringstream sstr; + sstr << *this; + return sstr.str(); + } + + std::string string() const + { + std::stringstream sstr; + sstr << *this; + return sstr.str(); + } + + std::wstring wstring() const + { + std::wstringstream sstr; + sstr << *this; + return sstr.str(); + } + + private: + std::array data{ 0 }; + + friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept; + + template + friend std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id); + }; + + inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept + { + return lhs.data == rhs.data; + } + + inline bool operator!= (uuid const& lhs, uuid const& rhs) noexcept + { + return !(lhs == rhs); + } + + template + std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id) + { + return s << std::hex << std::setfill(static_cast('0')) + << std::setw(2) << (int)id.data[0] + << std::setw(2) << (int)id.data[1] + << std::setw(2) << (int)id.data[2] + << std::setw(2) << (int)id.data[3] + << '-' + << std::setw(2) << (int)id.data[4] + << std::setw(2) << (int)id.data[5] + << '-' + << std::setw(2) << (int)id.data[6] + << std::setw(2) << (int)id.data[7] + << '-' + << std::setw(2) << (int)id.data[8] + << std::setw(2) << (int)id.data[9] + << '-' + << std::setw(2) << (int)id.data[10] + << std::setw(2) << (int)id.data[11] + << std::setw(2) << (int)id.data[12] + << std::setw(2) << (int)id.data[13] + << std::setw(2) << (int)id.data[14] + << std::setw(2) << (int)id.data[15]; + } +} + +namespace std +{ + template <> + void swap(uuids::uuid & lhs, uuids::uuid & rhs); + + template <> + struct hash + { + typedef uuids::uuid argument_type; + typedef std::size_t result_type; + + result_type operator()(argument_type const &uuid) const + { + std::hash hasher; + return static_cast(hasher(uuid.string())); + } + }; +} \ No newline at end of file diff --git a/test/test_win/.gitignore b/test/test_win/.gitignore new file mode 100644 index 0000000..02032ac --- /dev/null +++ b/test/test_win/.gitignore @@ -0,0 +1,3 @@ +.vs +Debug +Release diff --git a/test/test_win/stdafx.cpp b/test/test_win/stdafx.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2a45687e01a04d7adc519fed991c0f75653ccef GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/test/test_win/stdafx.h b/test/test_win/stdafx.h new file mode 100644 index 0000000000000000000000000000000000000000..94d4ed877dbfd8cd2c783931c444cad664143b10 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/test/test_win/test_win.cpp b/test/test_win/test_win.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e71e04abbb4204d0783bf07209821808d409eccf GIT binary patch literal 586 zcma)(PfNo<5XIkF@H;H^(q0n1c+l#pA48CkHa3u?CA+2m!LP3VW@1AS5gB%OHuK)w zHi2`_Ylj#yV`lSU%UnYj3^>DuEZG*Ph5ba4kxajtd;v)J`6vZb#h{ zb8u&qZDAxPJ79+T)Yp81$#^gF?>f%LJuUvpGpDa8Ssy`nM9`J4x&8FkgGzYsc_rxb JyZ%0Q@C8 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {380B7F43-F7E1-4847-960B-978D0DD1E268} + Win32Proj + testwin + 10.0.16299.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + Create + Create + Create + Create + + + + + + + \ No newline at end of file diff --git a/test/test_win/test_win.vcxproj.filters b/test/test_win/test_win.vcxproj.filters new file mode 100644 index 0000000..2c975bc --- /dev/null +++ b/test/test_win/test_win.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file