📄 chxuuid.cpp
字号:
{ \
if (((add1)->lo&0x80000000UL)) \
{ \
(sum)->lo = (add1)->lo + (add2)->lo ; \
(sum)->hi = (add1)->hi + (add2)->hi+1 ; \
} \
else \
{ \
(sum)->lo = (add1)->lo + (add2)->lo ; \
(sum)->hi = (add1)->hi + (add2)->hi ; \
} \
} \
else \
{ \
(sum)->lo = (add1)->lo + (add2)->lo ; \
(sum)->hi = (add1)->hi + (add2)->hi ; \
if (!((sum)->lo&0x80000000UL)) \
(sum)->hi++ ; \
}
/*
* UADD_ULW_2_UVLW - macro to add a 32-bit unsigned integer to
* a 64-bit unsigned integer
*
* Note: see the UADD_UVLW_2_UVLW() macro
*
*/
#define UADD_ULW_2_UVLW(add1, add2, sum) \
{ \
(sum)->hi = (add2)->hi; \
if ((*add1) & (add2)->lo & 0x80000000UL) \
{ \
(sum)->lo = (*add1) + (add2)->lo; \
(sum)->hi++; \
} \
else \
{ \
(sum)->lo = (*add1) + (add2)->lo; \
if (!((sum)->lo & 0x80000000UL)) \
{ \
(sum)->hi++; \
} \
} \
}
/*
* UADD_UW_2_UVLW - macro to add a 16-bit unsigned integer to
* a 64-bit unsigned integer
*
* Note: see the UADD_UVLW_2_UVLW() macro
*
*/
#define UADD_UW_2_UVLW(add1, add2, sum) \
{ \
(sum)->hi = (add2)->hi; \
if ((add2)->lo & 0x80000000UL) \
{ \
(sum)->lo = (*add1) + (add2)->lo; \
if (!((sum)->lo & 0x80000000UL)) \
{ \
(sum)->hi++; \
} \
} \
else \
{ \
(sum)->lo = (*add1) + (add2)->lo; \
} \
}
CHXuuid::CHXuuid()
{
uuid_ttime_t t;
UINT16 *seedp, seed=0;
/*
* Generating our 'seed' value
*
* We start with the current time, but, since the resolution of clocks is
* system hardware dependent (eg. Ultrix is 10 msec.) and most likely
* coarser than our resolution (10 usec) we 'mixup' the bits by xor'ing
* all the bits together. This will have the effect of involving all of
* the bits in the determination of the seed value while remaining system
* independent. Then for good measure to ensure a unique seed when there
* are multiple processes creating UUID's on a system, we add in the PID.
*/
GetOSTime(&t);
seedp = (UINT16 *)(&t);
seed ^= *seedp++;
seed ^= *seedp++;
seed ^= *seedp++;
seed ^= *seedp++;
seed += HX_GET_PID();
/*
* init the random number generator
*/
m_pRand = new CMultiplePrimeRandom(seed);
GetOSTime (&m_time_last);
m_time_adjust = 0;
m_clock_seq = TrueRandom();
GenerateMachineID();
}
CHXuuid::CHXuuid(UCHAR machineID[MACHINEID_SIZE])
{
uuid_ttime_t t;
UINT16 *seedp, seed=0;
/*
* Generating our 'seed' value
*
* We start with the current time, but, since the resolution of clocks is
* system hardware dependent (eg. Ultrix is 10 msec.) and most likely
* coarser than our resolution (10 usec) we 'mixup' the bits by xor'ing
* all the bits together. This will have the effect of involving all of
* the bits in the determination of the seed value while remaining system
* independent. Then for good measure to ensure a unique seed when there
* are multiple processes creating UUID's on a system, we add in the PID.
*/
GetOSTime(&t);
seedp = (UINT16 *)(&t);
seed ^= *seedp++;
seed ^= *seedp++;
seed ^= *seedp++;
seed ^= *seedp++;
seed += HX_GET_PID();
/*
* init the random number generator
*/
m_pRand = new CMultiplePrimeRandom(seed);
GetOSTime (&m_time_last);
m_time_adjust = 0;
m_clock_seq = TrueRandom();
memcpy(m_machineID, machineID, sizeof(machineID)); /* Flawfinder: ignore */
}
CHXuuid::~CHXuuid()
{
if (m_pRand != NULL)
{
delete m_pRand;
}
}
//
// Changed this routine to avoid unaligned access errors on RISC
// processors. -dbrumley 10-15-98
//
void CHXuuid::GenerateMachineID()
{
ULONG32 rand;
UINT16 tick;
rand = m_pRand->GetRandomNumber();
tick = (UINT16)HX_GET_TICKCOUNT();
memcpy(m_machineID, (UCHAR*)&rand, sizeof rand); /* Flawfinder: ignore */
memcpy(&m_machineID[4], (UCHAR*)&tick, sizeof tick); /* Flawfinder: ignore */
}
/////////////////////////////////////////////////////////////////////////
// Method:
// CHXuuid::GetUuid
// Purpose:
// Loose implementation of version 3 UUID (creation of name-based UUID). This
// algorithm outputs the result of an MD5 hash of an internally generated
// namespace (GUID) and a name (input buffer). Unlike the version 3 UUID algorithm,
// the namespace is essentially generated at random, so UUIDs created from
// the same name at any point of time have a very high probability of being different.
HX_RESULT CHXuuid::GetUuid(uuid_tt* pUuid, const UCHAR* pBuffer, UINT32 ulBufferSize)
{
// Validate params
HX_ASSERT(pUuid && pBuffer && ulBufferSize);
if (!pUuid || !pBuffer || !ulBufferSize)
return HXR_INVALID_PARAMETER;
// Get a UUID to use as a namespace ID
HX_RESULT res = GetUuid(pUuid);
if (SUCCEEDED(res))
{
md5_state_t ctx;
md5_init(&ctx);
UCHAR aHashBuffer[20];
memset(aHashBuffer, 0, 20);
// MD5-hash the namespace ID with the name buffer
md5_append(&ctx, (const UCHAR*)pUuid, sizeof(uuid_tt));
md5_append(&ctx, (const UCHAR*)pBuffer, ulBufferSize);
md5_finish(aHashBuffer, &ctx);
// Copy the 128-bit hash result into the UUID. Memcpy one var at a time
// in case the struct is padded.
memcpy(&pUuid->time_low, aHashBuffer, sizeof(pUuid->time_low)); /* Flawfinder: ignore */
memcpy(&pUuid->time_mid, aHashBuffer+4, sizeof(pUuid->time_mid)); /* Flawfinder: ignore */
memcpy(&pUuid->time_hi_and_version, aHashBuffer+6, sizeof(pUuid->time_hi_and_version)); /* Flawfinder: ignore */
memcpy(&pUuid->clock_seq_hi_and_reserved, aHashBuffer+8, sizeof(pUuid->clock_seq_hi_and_reserved)); /* Flawfinder: ignore */
memcpy(&pUuid->clock_seq_low, aHashBuffer+9, sizeof(pUuid->clock_seq_low)); /* Flawfinder: ignore */
memcpy(&pUuid->node, aHashBuffer+10, sizeof(pUuid->node)); /* Flawfinder: ignore */
}
return res;
}
HX_RESULT CHXuuid::GetUuid(uuid_tt* uuid)
{
HX_RESULT theErr = HXR_OK;
#if defined(_WIN32) && !defined(WIN32_PLATFORM_PSPC)
if(CoCreateGuid((GUID*)uuid) != S_OK)
theErr = HXR_FAILED;
#else
BOOL got_no_time = FALSE;
do
{
/*
* get the current time
*/
GetOSTime (&m_time_now);
/*
* do stuff like:
*
* o check that our clock hasn't gone backwards and handle it
* accordingly with clock_seq
* o check that we're not generating uuid's faster than we
* can accommodate with our time_adjust fudge factor
*/
switch (TimeCmp(&m_time_now, &m_time_last))
{
case uuid_e_less_than:
NewClockSeq(m_clock_seq);
m_time_adjust = 0;
got_no_time = FALSE;
break;
case uuid_e_greater_than:
m_time_adjust = 0;
got_no_time = FALSE;
break;
case uuid_e_equal_to:
if (m_time_adjust == MAX_TIME_ADJUST)
{
/*
* spin your wheels while we wait for the clock to tick
*/
got_no_time = TRUE;
}
else
{
m_time_adjust++;
got_no_time = FALSE;
}
break;
default:
theErr = HXR_FAILED;
return theErr;
}
} while (got_no_time);
m_time_last.lo = m_time_now.lo;
m_time_last.hi = m_time_now.hi;
if (m_time_adjust != 0)
{
UADD_UW_2_UVLW (&m_time_adjust, &m_time_now, &m_time_now);
}
/*
* now construct a uuid with the information we've gathered
* plus a few constants
*/
uuid->time_low = m_time_now.lo;
uuid->time_mid = (UINT16)(m_time_now.hi & TIME_MID_MASK);
uuid->time_hi_and_version = (UINT16)
((m_time_now.hi & TIME_HIGH_MASK) >> TIME_HIGH_SHIFT_COUNT);
uuid->time_hi_and_version |= UUID_VERSION_BITS;
uuid->clock_seq_low = HX_SAFEINT(m_clock_seq & CLOCK_SEQ_LOW_MASK);
uuid->clock_seq_hi_and_reserved =
HX_SAFEINT((m_clock_seq & CLOCK_SEQ_HIGH_MASK) >> CLOCK_SEQ_HIGH_SHIFT_COUNT);
uuid->clock_seq_hi_and_reserved |= UUID_RESERVED_BITS;
memcpy (uuid->node, m_machineID, sizeof (m_machineID)); /* Flawfinder: ignore */
#endif // _WIN32
return theErr;
}
/*
**++
**
** ROUTINE NAME: uuid_to_string
**
**--
**/
HX_RESULT CHXuuid::HXUuidToString(const uuid_tt* uuid, CHXString* uuid_string)
{
HX_RESULT theErr = HXR_OK;
/*
* don't do anything if the output argument is NULL
*/
if (uuid_string == NULL)
{
return theErr;
}
char *theBuff = uuid_string->GetBuffer(UUID_C_UUID_STRING_MAX);
SafeSprintf(theBuff, UUID_C_UUID_STRING_MAX,
"%.4x%.4x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
HIWORD(uuid->time_low), LOWORD(uuid->time_low), uuid->time_mid,
uuid->time_hi_and_version, uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low,
(UCHAR) uuid->node[0], (UCHAR) uuid->node[1],
(UCHAR) uuid->node[2], (UCHAR) uuid->node[3],
(UCHAR) uuid->node[4], (UCHAR) uuid->node[5]);
uuid_string->ReleaseBuffer();
return theErr;
}
/*
**++
**
** ROUTINE NAME: uuid_from_string
**
**--
**/
static int ParseIIDString(
const char* uuid_string,
long& time_low,
int& time_mid,
int& time_hi_and_version,
int& clock_seq_hi_and_reserved,
int& clock_seq_low,
int* node /*[6]*/)
{
int count = 0;
#if defined(_OPENWAVE)
// XXXSAB Untested...
// No sscanf()...
const char* pCur = uuid_string;
char* pEnd = NULL;
unsigned long curVal;
// Skip leading white space
pCur += strspn(pCur, " \t");
curVal = strtoul(pCur, &pEnd, 16);
if (pEnd == (pCur + 8) && *pEnd == '-') time_low = curVal;
else return count;
pCur += 8; ++count;
curVal = strtoul(pCur, &pEnd, 16);
if (pEnd == (pCur + 4) && *pEnd == '-') time_mid = curVal;
else return count;
pCur += 4; ++count;
curVal = strtoul(pCur, &pEnd, 16);
if (pEnd == (pCur + 4) && *pEnd == '-') time_hi_and_version = curVal;
else return count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -