121 #include <Iphlpapi.h>
123 #define getpid() _getpid()
124 #define srandom(seed) srand(seed)
125 #define random() rand()
128 #include <sys/time.h>
129 #if defined(R__LINUX) && !defined(R__WINGCC)
130 #include <sys/sysinfo.h>
133 #include <netinet/in.h>
144 TTHREAD_TLS(uuid_time_t) time_last;
145 TTHREAD_TLS(UShort_t) clockseq(0);
146 TTHREAD_TLS(Bool_t) firstTime(kTRUE);
147 uuid_time_t *time_last_ptr = TTHREAD_TLS_PTR(time_last);
150 R__LOCKGUARD(gROOTMutex);
155 seed = (UInt_t)(Long64_t(gSystem->Now()) + gSystem->GetPid());
157 using namespace std::chrono;
158 system_clock::time_point today = system_clock::now();
159 seed = (UInt_t)(system_clock::to_time_t ( today )) + ::getpid();
162 GetCurrentTime(time_last_ptr);
163 clockseq = 1+(UShort_t)(65536*random()/(RAND_MAX+1.0));
167 uuid_time_t timestamp;
170 GetCurrentTime(×tamp);
173 if (CmpTime(×tamp, time_last_ptr) == -1) {
174 clockseq = (clockseq + 1) & 0x3FFF;
175 if (clockseq == 0) clockseq++;
178 Format(clockseq, timestamp);
180 time_last = timestamp;
195 Int_t TUUID::CmpTime(uuid_time_t *t1, uuid_time_t *t2)
197 if (t1->high < t2->high)
return -1;
198 if (t1->high > t2->high)
return 1;
199 if (t1->low < t2->low)
return -1;
200 if (t1->low > t2->low)
return 1;
208 void TUUID::SetFromString(
const char *uuid)
213 int timeHiAndVersion;
214 int clockSeqHiAndRes;
218 sscanf(uuid,
"%8lx-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
224 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5]);
228 fTimeLow = (UInt_t) timeLo;
229 fTimeMid = (UShort_t) timeMid;
230 fTimeHiAndVersion = (UShort_t) timeHiAndVersion;
231 fClockSeqHiAndReserved = (UChar_t) clockSeqHiAndRes;
232 fClockSeqLow = (UChar_t) clockSeqLo;
233 fNode[0] = (UChar_t) node[0];
234 fNode[1] = (UChar_t) node[1];
235 fNode[2] = (UChar_t) node[2];
236 fNode[3] = (UChar_t) node[3];
237 fNode[4] = (UChar_t) node[4];
238 fNode[5] = (UChar_t) node[5];
245 TUUID::TUUID(
const char *uuid)
249 fTimeHiAndVersion = 0;
250 fClockSeqHiAndReserved = 0;
256 Error(
"TUUID",
"null string not allowed");
264 void TUUID::FillBuffer(
char *&buffer)
266 Version_t version = TUUID::Class_Version();
267 tobuf(buffer, version);
268 tobuf(buffer, fTimeLow);
269 tobuf(buffer, fTimeMid);
270 tobuf(buffer, fTimeHiAndVersion);
271 tobuf(buffer, fClockSeqHiAndReserved);
272 tobuf(buffer, fClockSeqLow);
273 for (Int_t i = 0; i < 6; i++)
274 tobuf(buffer, fNode[i]);
280 void TUUID::ReadBuffer(
char *&buffer)
283 frombuf(buffer, &version);
284 frombuf(buffer, &fTimeLow);
285 frombuf(buffer, &fTimeMid);
286 frombuf(buffer, &fTimeHiAndVersion);
287 frombuf(buffer, &fClockSeqHiAndReserved);
288 frombuf(buffer, &fClockSeqLow);
289 for (Int_t i = 0; i < 6; i++)
290 frombuf(buffer, &fNode[i]);
298 void TUUID::StreamerV1(TBuffer &b)
302 b >> fTimeHiAndVersion;
303 b >> fClockSeqHiAndReserved;
305 for (UInt_t i = 0; i < 6; i++) {
313 void TUUID::Format(UShort_t clockseq, uuid_time_t ts)
316 fTimeMid = (UShort_t)(ts.high & 0xFFFF);
317 fTimeHiAndVersion = (UShort_t)((ts.high >> 16) & 0x0FFF);
318 fTimeHiAndVersion |= (1 << 12);
319 fClockSeqLow = clockseq & 0xFF;
320 fClockSeqHiAndReserved = (clockseq & 0x3F00) >> 8;
321 fClockSeqHiAndReserved |= 0x80;
330 void TUUID::GetCurrentTime(uuid_time_t *timestamp)
332 const UShort_t uuids_per_tick = 1024;
334 TTHREAD_TLS(uuid_time_t) time_last;
335 TTHREAD_TLS(UShort_t) uuids_this_tick(0);
336 TTHREAD_TLS(Bool_t) init(kFALSE);
338 uuid_time_t *time_last_ptr = TTHREAD_TLS_PTR(time_last);
341 GetSystemTime(time_last_ptr);
342 uuids_this_tick = uuids_per_tick;
346 uuid_time_t time_now;
349 GetSystemTime(&time_now);
352 if (CmpTime(time_last_ptr, &time_now)) {
357 if (uuids_this_tick < uuids_per_tick) {
364 time_last = time_now;
366 if (uuids_this_tick != 0) {
367 if (time_now.low & 0x80000000) {
368 time_now.low += uuids_this_tick;
369 if (!(time_now.low & 0x80000000))
372 time_now.low += uuids_this_tick;
375 timestamp->high = time_now.high;
376 timestamp->low = time_now.low;
382 void TUUID::GetSystemTime(uuid_time_t *timestamp)
386 GetSystemTimeAsFileTime((FILETIME *)&time);
392 (
unsigned __int64) (1000*1000*10)
393 * (
unsigned __int64) (60 * 60 * 24)
394 * (
unsigned __int64) (17+30+31+365*18+5);
396 timestamp->high = time.HighPart;
397 timestamp->low = time.LowPart;
400 gettimeofday(&tp, 0);
404 ULong64_t uuid_time = ((ULong64_t)tp.tv_sec * 10000000) + (tp.tv_usec * 10) +
405 0x01B21DD213814000LL;
406 timestamp->high = (UInt_t) (uuid_time >> 32);
407 timestamp->low = (UInt_t) (uuid_time & 0xFFFFFFFF);
415 void TUUID::GetNodeIdentifier()
417 static UInt_t adr = 0;
424 struct ifaddrs *ifAddrStruct =
nullptr;
425 struct ifaddrs *ifa =
nullptr;
427 if (getifaddrs(&ifAddrStruct) != 0) {
430 for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
431 if (!ifa->ifa_addr) {
434 if (ifa->ifa_addr->sa_family != AF_INET) {
437 if (strncmp(ifa->ifa_name,
"lo",2) == 0) {
440 addr = ntohl(((
struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr);
445 if (ifAddrStruct !=
nullptr)
446 freeifaddrs(ifAddrStruct);
459 PIP_ADAPTER_INFO ainfo = (PIP_ADAPTER_INFO) malloc(
sizeof(IP_ADAPTER_INFO));
460 ULONG buflen =
sizeof(IP_ADAPTER_INFO);
461 DWORD stat = GetAdaptersInfo(ainfo, &buflen);
462 if (stat == ERROR_BUFFER_OVERFLOW) {
464 ainfo = (PIP_ADAPTER_INFO) malloc(buflen);
465 stat = GetAdaptersInfo(ainfo, &buflen);
467 if (stat != ERROR_SUCCESS)
471 PIP_ADAPTER_INFO adapter = ainfo;
473 sscanf(adapter->IpAddressList.IpAddress.String,
"%d.%d.%d.%d",
475 adr = (a << 24) | (b << 16) | (c << 8) | d;
481 memcpy(fNode, &adr, 4);
487 static UChar_t seed[16];
491 if (gSystem) adr = 2;
493 memcpy(fNode, seed,
sizeof(fNode));
494 fTimeHiAndVersion |= (3 << 12);
500 void TUUID::GetRandomInfo(UChar_t seed[16])
510 char hostname[MAX_COMPUTERNAME_LENGTH + 1];
513 memset(&r, 0,
sizeof(r));
516 GlobalMemoryStatus(&r.m);
520 GetSystemTimeAsFileTime(&r.t);
522 QueryPerformanceCounter(&r.pc);
524 r.tc = GetTickCount();
525 r.l = MAX_COMPUTERNAME_LENGTH + 1;
526 GetComputerName(r.hostname, &r.l);
529 #if defined(R__LINUX) && !defined(R__WINGCC)
536 memset(&r, 0,
sizeof(r));
538 #if defined(R__LINUX) && !defined(R__WINGCC)
541 gettimeofday(&r.t, 0);
542 gethostname(r.hostname, 256);
545 md5.Update((UChar_t *)&r,
sizeof(randomness));
552 void TUUID::Print()
const
554 printf(
"%s\n", AsString());
560 const char *TUUID::AsString()
const
562 static char uuid[40];
564 snprintf(uuid,40,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
565 fTimeLow, fTimeMid, fTimeHiAndVersion, fClockSeqHiAndReserved,
566 fClockSeqLow, fNode[0], fNode[1], fNode[2], fNode[3], fNode[4],
575 UShort_t TUUID::Hash()
const
577 Short_t c0 = 0, c1 = 0, x, y;
578 char *c = (
char *) &fTimeLow;
586 c0 += *c++; c1 += c0;
587 c0 += *c++; c1 += c0;
588 c0 += *c++; c1 += c0;
589 c0 += *c++; c1 += c0;
591 c0 += *c++; c1 += c0;
592 c0 += *c++; c1 += c0;
593 c0 += *c++; c1 += c0;
594 c0 += *c++; c1 += c0;
596 c0 += *c++; c1 += c0;
597 c0 += *c++; c1 += c0;
598 c0 += *c++; c1 += c0;
599 c0 += *c++; c1 += c0;
601 c0 += *c++; c1 += c0;
602 c0 += *c++; c1 += c0;
603 c0 += *c++; c1 += c0;
604 c0 += *c++; c1 += c0;
616 return UShort_t((y << 8) + x);
625 Int_t TUUID::Compare(
const TUUID &u)
const
627 #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1;
628 CHECK(fTimeLow, u.fTimeLow)
629 CHECK(fTimeMid, u.fTimeMid)
630 CHECK(fTimeHiAndVersion, u.fTimeHiAndVersion)
631 CHECK(fClockSeqHiAndReserved, u.fClockSeqHiAndReserved)
632 CHECK(fClockSeqLow, u.fClockSeqLow)
633 for (
int i = 0; i < 6; i++) {
634 if (fNode[i] < u.fNode[i])
636 if (fNode[i] > u.fNode[i])
646 TInetAddress TUUID::GetHostAddress()
const
648 if ((fTimeHiAndVersion >> 12) == 1) {
650 memcpy(&addr, fNode, 4);
651 return TInetAddress(
"????", addr, 0);
653 return TInetAddress();
659 TDatime TUUID::GetTime()
const
665 ts.high = (UInt_t)fTimeMid;
666 ts.high |= (UInt_t)((fTimeHiAndVersion & 0x0FFF) << 16);
671 ULong64_t high = ts.high;
672 ULong64_t uuid_time = (high << 32) + ts.low;
673 uuid_time -= 0x01B21DD213814000LL;
674 uuid_time /= 10000000LL;
675 UInt_t tt = (UInt_t) uuid_time;
684 void TUUID::GetUUID(UChar_t uuid[16])
const
686 memcpy(uuid, &fTimeLow, 16);
693 void TUUID::SetUUID(
const char *uuid)
696 Error(
"SetUUID",
"null string not allowed");
704 TBuffer &operator<<(TBuffer &buf,
const TUUID &uuid)
706 R__ASSERT( buf.IsWriting() );
708 const_cast<TUUID&
>(uuid).Streamer(buf);