38 #include "blocxx/BLOCXX_config.h"
47 #if !defined(BLOCXX_WIN32)
59 namespace BLOCXX_NAMESPACE
66 typedef UInt64 uuid_time_t;
79 NonRecursiveMutex g_guard;
84 static const unsigned __int64 epoch = 116444736000000000L;
86 int gettimeofday(
struct timeval * tp,
int bogusParm)
89 SYSTEMTIME system_time;
90 ULARGE_INTEGER ularge;
92 GetSystemTime(&system_time);
93 SystemTimeToFileTime(&system_time, &file_time);
94 ularge.LowPart = file_time.dwLowDateTime;
95 ularge.HighPart = file_time.dwHighDateTime;
97 tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
98 tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
105 void getSystemTime(uuid_time_t *uuid_time)
108 gettimeofday(&tp, 0);
113 (
static_cast<unsigned long long>(tp.tv_sec) * 10000000) +
115 ((static_cast<unsigned long long>(0x01B21DD2)) << 32) +
120 uuid_time_t timeLast;
121 UInt16 uuidsThisTick;
122 bool currentTimeInited =
false;
123 void getCurrentTime(uuid_time_t *
timestamp)
126 if (!currentTimeInited)
128 getSystemTime(&timeLast);
130 currentTimeInited =
true;
132 getSystemTime(&timeNow);
133 if (timeLast != timeNow)
143 *timestamp = timeNow + uuidsThisTick;
148 bool nodeIdInitDone =
false;
149 void getNodeIdentifier(uuid_node_t *node)
156 Secure::rand(nodeId,
sizeof(nodeId));
159 nodeIdInitDone =
true;
161 memcpy(node->nodeId, nodeId,
sizeof(node->nodeId));
164 inline unsigned char decodeHex(
char c)
173 return c -
'A' + 0xA;
177 inline unsigned char fromHexStr(
char c1,
char c2,
const String& uuidStr)
179 if (!isxdigit(c1) || !isxdigit(c2))
181 BLOCXX_THROW(UUIDException, Format(
"Invalid UUID: %1", uuidStr).c_str());
183 return (decodeHex(c1) << 4) | decodeHex(c2);
186 inline char toHexHi(
unsigned char c)
188 unsigned char t = c >> 4;
189 return t >= 10 ? t - 10 +
'a' : t +
'0';
192 inline char toHexLow(
unsigned char c)
194 unsigned char t = c & 0xF;
195 return t >= 10 ? t - 10 +
'a' : t +
'0';
203 getCurrentTime(×tamp);
205 getNodeIdentifier(&node);
206 uuid_time_t last_time = g_state.timestamp;
207 UInt16 clockseq = g_state.clockSequence;
208 uuid_node_t last_node = g_state.nodeId;
210 if (timestamp < last_time)
215 g_state.timestamp = last_time;
216 g_state.clockSequence = clockseq;
217 g_state.nodeId = last_node;
221 UInt32 tmp =
static_cast<UInt32
>(timestamp & 0xFFFFFFFF);
230 tmp =
static_cast<UInt16
>((timestamp >> 32) & 0xFFFF);
235 tmp =
static_cast<UInt16
>(((timestamp >> 48) & 0x0FFF) | (1 << 12));
240 tmp = clockseq & 0xFF;
243 tmp = (clockseq & 0x3F00) >> 8 | 0x80;
245 memcpy(
m_uuid+10, &node, 6);
250 const char* s = uuidStr.
c_str();
251 if (uuidStr.
length() != 36 || s[8] !=
'-' || s[13] !=
'-' || s[18] !=
'-' || s[23] !=
'-')
255 m_uuid[0] = fromHexStr(s[0], s[1], uuidStr);
256 m_uuid[1] = fromHexStr(s[2], s[3], uuidStr);
257 m_uuid[2] = fromHexStr(s[4], s[5], uuidStr);
258 m_uuid[3] = fromHexStr(s[6], s[7], uuidStr);
259 m_uuid[4] = fromHexStr(s[9], s[10], uuidStr);
260 m_uuid[5] = fromHexStr(s[11], s[12], uuidStr);
261 m_uuid[6] = fromHexStr(s[14], s[15], uuidStr);
262 m_uuid[7] = fromHexStr(s[16], s[17], uuidStr);
263 m_uuid[8] = fromHexStr(s[19], s[20], uuidStr);
264 m_uuid[9] = fromHexStr(s[21], s[22], uuidStr);
265 m_uuid[10] = fromHexStr(s[24], s[25], uuidStr);
266 m_uuid[11] = fromHexStr(s[26], s[27], uuidStr);
267 m_uuid[12] = fromHexStr(s[28], s[29], uuidStr);
268 m_uuid[13] = fromHexStr(s[30], s[31], uuidStr);
269 m_uuid[14] = fromHexStr(s[32], s[33], uuidStr);
270 m_uuid[15] = fromHexStr(s[34], s[35], uuidStr);
278 const size_t uuidlen = 37;
279 char* buf =
new char[uuidlen];
280 buf[0] = toHexHi(
m_uuid[0]); buf[1] = toHexLow(
m_uuid[0]);
281 buf[2] = toHexHi(
m_uuid[1]); buf[3] = toHexLow(
m_uuid[1]);
282 buf[4] = toHexHi(
m_uuid[2]); buf[5] = toHexLow(
m_uuid[2]);
283 buf[6] = toHexHi(
m_uuid[3]); buf[7] = toHexLow(
m_uuid[3]);
285 buf[9] = toHexHi(
m_uuid[4]); buf[10] = toHexLow(
m_uuid[4]);
286 buf[11] = toHexHi(
m_uuid[5]); buf[12] = toHexLow(
m_uuid[5]);
288 buf[14] = toHexHi(
m_uuid[6]); buf[15] = toHexLow(
m_uuid[6]);
289 buf[16] = toHexHi(
m_uuid[7]); buf[17] = toHexLow(
m_uuid[7]);
291 buf[19] = toHexHi(
m_uuid[8]); buf[20] = toHexLow(
m_uuid[8]);
292 buf[21] = toHexHi(
m_uuid[9]); buf[22] = toHexLow(
m_uuid[9]);
294 buf[24] = toHexHi(
m_uuid[10]); buf[25] = toHexLow(
m_uuid[10]);
295 buf[26] = toHexHi(
m_uuid[11]); buf[27] = toHexLow(
m_uuid[11]);
296 buf[28] = toHexHi(
m_uuid[12]); buf[29] = toHexLow(
m_uuid[12]);
297 buf[30] = toHexHi(
m_uuid[13]); buf[31] = toHexLow(
m_uuid[13]);
298 buf[32] = toHexHi(
m_uuid[14]); buf[33] = toHexLow(
m_uuid[14]);
299 buf[34] = toHexHi(
m_uuid[15]); buf[35] = toHexLow(
m_uuid[15]);