diff -r 9c5b1510919f -r bf573002ff72 calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp --- a/calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp Wed Jun 09 09:40:23 2010 +0300 +++ b/calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp Mon Jun 21 15:38:59 2010 +0300 @@ -45,6 +45,13 @@ #include "CalenEcomWatcher.h" // Watches for ECOM registry changes // CONSTANTS + +/* set the following to the number of 100ns ticks of the actual + resolution of your system's clock. + 800MHZ means 1s->800*(10^6) clock cycles + 100ns->80 clock cycles*/ +const TUint16 UUIDS_PER_TICK = 80; + /// Unnamed namespace for local definitions namespace { @@ -53,8 +60,7 @@ #endif const TInt KImeiLength = 15; // 15 chars from left of imei - - const TInt KAsciiFirstNumber = 48; // ASCII character 48 = '0'. + const TInt KAsciiFirstNumber = 48; // ASCII character 48 = '0'. const TInt KAsciiFirstLowercaseLetter = 97; // ASCII character 97 = 'a'. } // namespace @@ -91,8 +97,8 @@ TRACE_ENTRY_POINT; iMrEnabledCheck = ETrue; - iMrEnabled = EFalse; - + iMrEnabled = EFalse; + iInited = EFalse; TRACE_EXIT_POINT; } @@ -279,15 +285,17 @@ // http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt // Number of 100ns ticks since Oct 15 1582. - TInt64 timeStamp = GetTicksFromGregorianCalendarStartL(); - + TInt64 timeStamp; + GetSystemTime(timeStamp); + // This differs slightly from the spec in that the clock sequence is just a pseudo-random number. - TUint32 clockSeq = Math::Random(); - // IMEI is read the first time this is called, and stored for subsequent calls. - if(!iImeiNode) - { - iImeiNode = GetImeiAsNodeValueL(); - } + TUint32 clockSeq = Math::Random(); + + // IMEI is read the first time this is called, and stored for subsequent calls. + if(!iImeiNode) + { + iImeiNode = GetImeiAsNodeValueL(); + } HBufC8* resultBuf = DoCreateUidLC(clockSeq, timeStamp, iImeiNode); CleanupStack::Pop(resultBuf); @@ -313,7 +321,46 @@ TTimeIntervalMicroSeconds msDifference = timeNow.MicroSecondsFrom(gregorianStart); TRACE_EXIT_POINT; - return msDifference.Int64() * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count. + return ( timeNow.Int64() + msDifference.Int64() ) * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count. + } + +// ----------------------------------------------------------------------------- +// CCalenInterimUtils2Impl::GetSystemTime() +// This function returns the system time. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCalenInterimUtils2Impl::GetSystemTime(TInt64& aTimeStamp) + { + TRACE_ENTRY_POINT; + + if (!iInited) + { + aTimeStamp = GetTicksFromGregorianCalendarStartL(); + iThisTick = UUIDS_PER_TICK; + iInited = ETrue; + } + for( ; ; ) + { + aTimeStamp = GetTicksFromGregorianCalendarStartL(); + //if clock reading changed since last UUID generated... + if( iTimeLast != aTimeStamp ) + { + //reset count of uuids gen'd with this clock reading + iThisTick = 0; + iTimeLast = aTimeStamp; + break; + } + if( iThisTick < UUIDS_PER_TICK ) + { + iThisTick++; + break; + } + } + //add the count of uuids to low order bits of the clock reading + aTimeStamp += iThisTick; + + TRACE_EXIT_POINT; } // ----------------------------------------------------------------------------- @@ -370,104 +417,58 @@ TRACE_ENTRY_POINT; // The roast beef of the algorithm. Does all the shifting about as described in the web draft. - TUint32 time_low = aTimeStamp & 0xFFFFFFFF; - TUint16 time_mid = (aTimeStamp >> 32) & 0xFFFF; - TUint16 time_high = (aTimeStamp >> 48) & 0x0FFF; - time_high |= (1 << 12); - TUint8 clock_seq_low = aClockSeq & 0xFF; - TUint8 clock_seq_high = (aClockSeq & 0x3F00) >> 8; - clock_seq_high |= 0x80; - - // Can't use RArray as that's set up for minimum 4 bytes per item. - CArrayFixFlat *node = new (ELeave) CArrayFixFlat(6); - CleanupStack::PushL(node); - - // The rest of the function is mapping the 64, 32 and 16 bit numbers to 8 bit numbers - // while losing as little data as possible. - + SUuid uuid; + TUint8 hash[16]; + + uuid.time_low = aTimeStamp & 0xFFFFFFFF; + uuid.time_mid = (aTimeStamp >> 32) & 0xFFFF; + uuid.time_high_and_version = (aTimeStamp >> 48) & 0x0FFF; + uuid.time_high_and_version |= (1 << 12); + uuid.clock_seq_low = aClockSeq & 0xFF; + uuid.clock_seq_hi_and_reserved = (aClockSeq & 0x3F00) >> 8; + uuid.clock_seq_hi_and_reserved |= 0x80; + TUint64 mask = 0xFF0000000000; for(TInt i=0; i<=6; ++i) { TInt64 temp = aNodeValue & mask; temp >>= ((5-i)*8); - node->AppendL(temp); + uuid.node[i] = temp; mask = mask >> 8; } - TBuf8<16> rawOutput; - - rawOutput.Append( (time_low & 0xFF000000) >> 24 ); - rawOutput.Append( (time_low & 0x00FF0000) >> 16 ); - rawOutput.Append( (time_low & 0x0000FF00) >> 8 ); - rawOutput.Append( (time_low & 0x000000FF) ); - - rawOutput.Append( (time_mid & 0xFF00) >> 8 ); - rawOutput.Append( (time_mid & 0x00FF) ); - - rawOutput.Append( (time_high & 0xFF00) >> 8 ); - rawOutput.Append( (time_high & 0x00FF) ); - - rawOutput.Append( clock_seq_low ); - rawOutput.Append( clock_seq_high ); - - for(TInt i=0; i<6; ++i) - { - rawOutput.Append( node->At(i) ); - } - CleanupStack::PopAndDestroy(); // node - - TUint8 digest[16]; - HBufC8* resultBuf = rawOutput.AllocLC(); - TPtr8 resultBufPtr = resultBuf->Des(); - TUint length = resultBufPtr.Length(); - - // Create a new buffer to provide space for '\0' - HBufC8* newBuf = HBufC8::NewLC( length + 1 );//+1 space for '\0' - TPtr8 newBufPtr = newBuf->Des(); - newBufPtr.Copy(resultBufPtr); - - // Appends a zero terminator onto the end of this descriptor's data - // and returns a pointer to the data. - char* chPtrTemp = ( char*)newBufPtr.PtrZ(); - char* chPtr = ( char*) User::AllocL( length + 1 ); - strcpy( chPtr , chPtrTemp ); - - //md5 context - MD5_CTX* context = new MD5_CTX(); + //md5 context + MD5_CTX context; //initialize the context - MD5_Init(context); + MD5_Init(&context); //Append a string to the message - MD5_Update(context, chPtr, length ); + MD5_Update(&context, &uuid, sizeof(uuid) ); //Finish the message and return the digest. - MD5_Final(digest, context ); - + MD5_Final(hash, &context ); // Add the version field in the msb 4 bits. The value of version is 3. - digest[6] = digest[6] & 0x0F; - digest[6] |= (3 << 4); + hash[6] = hash[6] & 0x0F; + hash[6] |= (3 << 4); //Add the variant field in the msb 2 bits. The value of variant is 2. - digest[9] = digest[9] & 0x3F; - digest[9] |= 0x80; - - delete chPtr; - delete context; - CleanupStack::PopAndDestroy( newBuf ); - CleanupStack::PopAndDestroy( resultBuf ); + hash[8] = hash[8] & 0x3F; + hash[8] |= 0x80; + TBuf8<36> output; TInt i; for(i=0; i<16; ++i) - { - output.Append( ConvertToCharacterL( FirstFourBits( digest[i] ) ) ); - output.Append( ConvertToCharacterL( LastFourBits( digest[i] ) ) ); - if(i == 3 || i == 5 || i == 7 ||i == 9) - { - output.Append( '-' ); - } - } - HBufC8* md5ResultBuf = output.AllocLC(); + { + output.Append( ConvertToCharacterL( FirstFourBits( hash[i] ) ) ); + output.Append( ConvertToCharacterL( LastFourBits( hash[i] ) ) ); + if(i == 3 || i == 5 || i == 7 ||i == 9) + { + output.Append( '-' ); + } + } + HBufC8* retBuf = output.AllocLC(); TRACE_EXIT_POINT; - return md5ResultBuf; + return retBuf; + } // -----------------------------------------------------------------------------