stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
uuid.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2016-2024 Amebis
4*/
5
6#pragma once
7
8#include "assert.hpp"
9#include "compat.hpp"
10#include "string.hpp"
11#include <stdint.h>
12#include <stdio.h>
13#if defined(_WIN32)
14#include "windows.h"
15#include <rpc.h>
16#else
17#include <uuid/uuid.h>
18#include <wchar.h>
19#endif
20
21namespace stdex
22{
29 inline void uuidtostr(_Out_writes_z_(39) char str[39], _In_ const uuid_t& id)
30 {
31 stdex_assert(str);
32#ifdef _WIN32
33 _snprintf_s_l(str, 39, _TRUNCATE, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
34 id.Data1,
35 static_cast<unsigned int>(id.Data2),
36 static_cast<unsigned int>(id.Data3),
37 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
38 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
39#else
40 snprintf(str, 39, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
41 *reinterpret_cast<const uint32_t*>(&id[0]),
42 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
43 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
44 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
45 static_cast<unsigned int>(id[10]), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id[13]), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
46#endif
47 }
48
55 inline void uuidtostr(_Out_writes_z_(39) wchar_t str[39], _In_ const uuid_t& id)
56 {
57 stdex_assert(str);
58#ifdef _WIN32
59 _snwprintf_s_l(str, 39, _TRUNCATE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
60 id.Data1,
61 static_cast<unsigned int>(id.Data2),
62 static_cast<unsigned int>(id.Data3),
63 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
64 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
65#else
66 swprintf(str, 39, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
67 *reinterpret_cast<const uint32_t*>(&id[0]),
68 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
69 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
70 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
71 static_cast<unsigned int>(id[10]), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id[13]), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
72#endif
73 }
74
84 template <class T> inline _Success_(return != 0) bool strtouuid(
85 _In_reads_or_z_opt_(count) const T* str,
86 _In_ size_t count,
87 _Out_ uuid_t& id)
88 {
89 size_t i = 0, j;
90 uint64_t n;
91
92 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
93 if (i >= count || str[i] != '{') return false;
94 ++i;
95 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
96 n = stdex::strtou64(&str[i], count - i, &j, 16);
97 if (n > UINT32_MAX) return false;
98#ifdef _WIN32
99 id.Data1 = static_cast<unsigned long>(n);
100#else
101 * reinterpret_cast<uint32_t*>(&id[0]) = static_cast<uint32_t>(n);
102#endif
103 i += j;
104 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
105 if (i >= count || str[i] != '-') return false;
106 ++i;
107 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
108 n = stdex::strtou64(&str[i], count - i, &j, 16);
109 if (n > UINT16_MAX) return false;
110#ifdef _WIN32
111 id.Data2 = static_cast<unsigned short>(n);
112#else
113 * reinterpret_cast<uint16_t*>(&id[4]) = static_cast<uint16_t>(n);
114#endif
115 i += j;
116 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
117 if (i >= count || str[i] != '-') return false;
118 ++i;
119 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
120 n = stdex::strtou64(&str[i], count - i, &j, 16);
121 if (n > UINT16_MAX) return false;
122#ifdef _WIN32
123 id.Data3 = static_cast<unsigned short>(n);
124#else
125 * reinterpret_cast<uint16_t*>(&id[6]) = static_cast<uint16_t>(n);
126#endif
127 i += j;
128 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
129 if (i >= count || str[i] != '-') return false;
130 ++i;
131 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
132 n = stdex::strtou64(&str[i], count - i, &j, 16);
133 if (n > UINT16_MAX) return false;
134#ifdef _WIN32
135 id.Data4[0] = static_cast<unsigned char>((n >> 8) & 0xff);
136 id.Data4[1] = static_cast<unsigned char>((n) & 0xff);
137#else
138 id[8] = static_cast<unsigned char>((n >> 8) & 0xff);
139 id[9] = static_cast<unsigned char>((n) & 0xff);
140#endif
141 i += j;
142 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
143 if (i >= count && str[i] != '-') return false;
144 ++i;
145 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
146 n = stdex::strtou64(&str[i], count - i, &j, 16);
147 if (n > 0xffffffffffff) return false;
148#ifdef _WIN32
149 id.Data4[2] = static_cast<unsigned char>((n >> 40) & 0xff);
150 id.Data4[3] = static_cast<unsigned char>((n >> 32) & 0xff);
151 id.Data4[4] = static_cast<unsigned char>((n >> 24) & 0xff);
152 id.Data4[5] = static_cast<unsigned char>((n >> 16) & 0xff);
153 id.Data4[6] = static_cast<unsigned char>((n >> 8) & 0xff);
154 id.Data4[7] = static_cast<unsigned char>((n) & 0xff);
155#else
156 id[10] = static_cast<unsigned char>((n >> 40) & 0xff);
157 id[11] = static_cast<unsigned char>((n >> 32) & 0xff);
158 id[12] = static_cast<unsigned char>((n >> 24) & 0xff);
159 id[13] = static_cast<unsigned char>((n >> 16) & 0xff);
160 id[14] = static_cast<unsigned char>((n >> 8) & 0xff);
161 id[15] = static_cast<unsigned char>((n) & 0xff);
162#endif
163 i += j;
164 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
165 if (i >= count || str[i] != '}') return false;
166 ++i;
167 for (; i < count && str[i] && stdex::isspace(str[i]); ++i);
168 return i >= count || !str[i];
169 }
170}