From 23b6374e9ad57b9edbd7b7c1d300275be5f23238 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Wed, 20 Apr 2016 17:37:37 +0200 Subject: [PATCH] Add ULONG PointerToID(void*) and IntPtrToID(size_t) that CRC 64bit pointers Sometimes pointers are casted to ULONG just to get an ID or tag - this is fine for 32bit pointers, but 64bit pointers will truncate which might result in not being so unique after all. CRC-ing the pointer should yield a more likely to be unique 32bit value. NULL is a special case that yields 0 instead of the CRC, so code that handles IDs/Tags with value 0 differently will continue to work. For 32bit builds, it just returns the pointer as ULONG. --- Sources/Engine/Base/CRC.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Sources/Engine/Base/CRC.h b/Sources/Engine/Base/CRC.h index 3d56397..eb93255 100644 --- a/Sources/Engine/Base/CRC.h +++ b/Sources/Engine/Base/CRC.h @@ -70,5 +70,35 @@ inline void CRC_AddBlock(ULONG &ulCRC, UBYTE *pubBlock, ULONG ulSize) // end crc calculation inline void CRC_Finish(ULONG &ulCRC) { ulCRC ^= 0xFFFFFFFF; }; +// in 32bit mode, it just returns iPtr ULONG, +// in 64bit mode it returns the CRC hash of iPtr (or 0 if ptr == NULL) +// so either way you should get a value that very likely uniquely identifies the pointer +inline ULONG IntPtrToID(size_t iPtr) +{ +#if PLATFORM_32BIT + return (ULONG)iPtr; +#else + // in case the code relies on 0 having special meaning because of NULL-pointers... + if(iPtr == 0) return 0; + ULONG ret; + CRC_Start(ret); + CRC_AddLONGLONG(ret, iPtr); + CRC_Finish(ret); + return ret; +#endif +} + +// in 32bit mode, it just returns the pointer's address as ULONG, +// in 64bit mode it returns the CRC hash of the pointer's address (or 0 if ptr == NULL) +// so either way you should get a value that very likely uniquely identifies the pointer +inline ULONG PointerToID(void* ptr) +{ +#if PLATFORM_32BIT + return (ULONG)(size_t)ptr; +#else + return IntPtrToID((size_t)ptr); +#endif +} + #endif /* include-once check. */