uuid from strings

This commit is contained in:
Marius Bancila 2017-12-08 12:46:41 +02:00
parent 967ba08e7f
commit 73dd36f830
9 changed files with 105 additions and 12 deletions

View File

@ -8,8 +8,83 @@
#include <CoreFoundation/CFUUID.h>
#endif
namespace
{
template <typename TChar>
constexpr inline unsigned char hex2char(TChar const ch)
{
if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9'))
return ch - static_cast<TChar>('0');
if (ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f'))
return 10 + ch - static_cast<TChar>('a');
if (ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'))
return 10 + ch - static_cast<TChar>('A');
return 0;
}
template <typename TChar>
constexpr inline bool is_hex(TChar const ch)
{
return
(ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
(ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f')) ||
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
}
template <typename TChar>
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 <typename TChar>
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<TChar>('-')) 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

View File

@ -4,6 +4,7 @@
#include <sstream>
#include <iomanip>
#include <array>
#include <string_view>
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<uint8_t, 16> const & bytes) :data{bytes} {}
constexpr explicit uuid() {}
constexpr explicit uuid(std::array<uint8_t, 16> 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 <typename TChar>
void create(TChar const * const str, size_t const size);
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -89,6 +89,7 @@
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -102,6 +103,7 @@
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -117,6 +119,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -134,6 +137,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -144,7 +148,6 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\src\uuid.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\uuid.cpp" />

View File

@ -15,9 +15,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\uuid.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>