Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
3.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. // Unique ID generation
  8. //=============================================================================//
  9. #include "tier0/platform.h"
  10. #ifdef IS_WINDOWS_PC
  11. #include <windows.h> // UUIDCreate
  12. #else
  13. #include "checksum_crc.h"
  14. #endif
  15. #include "tier1/uniqueid.h"
  16. #include "tier1/utlbuffer.h"
  17. //-----------------------------------------------------------------------------
  18. // Creates a new unique id
  19. //-----------------------------------------------------------------------------
  20. void CreateUniqueId( UniqueId_t *pDest )
  21. {
  22. #ifdef IS_WINDOWS_PC
  23. Assert( sizeof( UUID ) == sizeof( *pDest ) );
  24. UuidCreate( (UUID *)pDest );
  25. #else
  26. // X360/linux TBD: Need a real UUID Implementation
  27. Q_memset( pDest, 0, sizeof( UniqueId_t ) );
  28. #endif
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Creates a new unique id from a string representation of one
  32. //-----------------------------------------------------------------------------
  33. bool UniqueIdFromString( UniqueId_t *pDest, const char *pBuf, int nMaxLen )
  34. {
  35. if ( nMaxLen == 0 )
  36. {
  37. nMaxLen = Q_strlen( pBuf );
  38. }
  39. char *pTemp = (char*)stackalloc( nMaxLen + 1 );
  40. V_strncpy( pTemp, pBuf, nMaxLen + 1 );
  41. --nMaxLen;
  42. while( (nMaxLen >= 0) && isspace( pTemp[nMaxLen] ) )
  43. {
  44. --nMaxLen;
  45. }
  46. pTemp[ nMaxLen + 1 ] = 0;
  47. while( *pTemp && isspace( *pTemp ) )
  48. {
  49. ++pTemp;
  50. }
  51. #ifdef IS_WINDOWS_PC
  52. Assert( sizeof( UUID ) == sizeof( *pDest ) );
  53. if ( RPC_S_OK != UuidFromString( (unsigned char *)pTemp, (UUID *)pDest ) )
  54. {
  55. InvalidateUniqueId( pDest );
  56. return false;
  57. }
  58. #else
  59. // X360TBD: Need a real UUID Implementation
  60. // For now, use crc to generate a unique ID from the UUID string.
  61. Q_memset( pDest, 0, sizeof( UniqueId_t ) );
  62. if ( nMaxLen > 0 )
  63. {
  64. CRC32_t crc;
  65. CRC32_Init( &crc );
  66. CRC32_ProcessBuffer( &crc, pBuf, nMaxLen );
  67. CRC32_Final( &crc );
  68. Q_memcpy( pDest, &crc, sizeof( CRC32_t ) );
  69. }
  70. #endif
  71. return true;
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Sets an object ID to be an invalid state
  75. //-----------------------------------------------------------------------------
  76. void InvalidateUniqueId( UniqueId_t *pDest )
  77. {
  78. Assert( pDest );
  79. memset( pDest, 0, sizeof( UniqueId_t ) );
  80. }
  81. bool IsUniqueIdValid( const UniqueId_t &id )
  82. {
  83. UniqueId_t invalidId;
  84. memset( &invalidId, 0, sizeof( UniqueId_t ) );
  85. return !IsUniqueIdEqual( invalidId, id );
  86. }
  87. bool IsUniqueIdEqual( const UniqueId_t &id1, const UniqueId_t &id2 )
  88. {
  89. return memcmp( &id1, &id2, sizeof( UniqueId_t ) ) == 0;
  90. }
  91. void UniqueIdToString( const UniqueId_t &id, char *pBuf, int nMaxLen )
  92. {
  93. pBuf[ 0 ] = 0;
  94. // X360TBD: Need a real UUID Implementation
  95. #ifdef IS_WINDOWS_PC
  96. UUID *self = ( UUID * )&id;
  97. unsigned char *outstring = NULL;
  98. UuidToString( self, &outstring );
  99. if ( outstring && *outstring )
  100. {
  101. Q_strncpy( pBuf, (const char *)outstring, nMaxLen );
  102. RpcStringFree( &outstring );
  103. }
  104. #endif
  105. }
  106. void CopyUniqueId( const UniqueId_t &src, UniqueId_t *pDest )
  107. {
  108. memcpy( pDest, &src, sizeof( UniqueId_t ) );
  109. }
  110. bool Serialize( CUtlBuffer &buf, const UniqueId_t &src )
  111. {
  112. // X360TBD: Need a real UUID Implementation
  113. #ifdef IS_WINDOWS_PC
  114. if ( buf.IsText() )
  115. {
  116. UUID *pId = ( UUID * )&src;
  117. unsigned char *outstring = NULL;
  118. UuidToString( pId, &outstring );
  119. if ( outstring && *outstring )
  120. {
  121. buf.PutString( (const char *)outstring );
  122. RpcStringFree( &outstring );
  123. }
  124. else
  125. {
  126. buf.PutChar( '\0' );
  127. }
  128. }
  129. else
  130. {
  131. buf.Put( &src, sizeof(UniqueId_t) );
  132. }
  133. return buf.IsValid();
  134. #else
  135. return false;
  136. #endif
  137. }
  138. bool Unserialize( CUtlBuffer &buf, UniqueId_t &dest )
  139. {
  140. if ( buf.IsText() )
  141. {
  142. int nTextLen = buf.PeekStringLength();
  143. char *pBuf = (char*)stackalloc( nTextLen );
  144. buf.GetStringManualCharCount( pBuf, nTextLen );
  145. UniqueIdFromString( &dest, pBuf, nTextLen );
  146. }
  147. else
  148. {
  149. buf.Get( &dest, sizeof(UniqueId_t) );
  150. }
  151. return buf.IsValid();
  152. }