|  | /*!**************************************************************************** | 
|  |  | 
|  | @file         PVRTHash.h | 
|  | @copyright    Copyright (c) Imagination Technologies Limited. | 
|  | @brief        A simple hash class which uses TEA to hash a string or given data | 
|  | into a 32-bit unsigned int. | 
|  |  | 
|  | ******************************************************************************/ | 
|  |  | 
|  | #ifndef PVRTHASH_H | 
|  | #define PVRTHASH_H | 
|  |  | 
|  | #include "PVRTString.h" | 
|  | #include "PVRTGlobal.h" | 
|  |  | 
|  | /*!**************************************************************************** | 
|  | @class         CPVRTHash | 
|  | @brief         A simple hash class which uses TEA to hash a string or other given | 
|  | data into a 32-bit unsigned int. | 
|  | ******************************************************************************/ | 
|  | class CPVRTHash | 
|  | { | 
|  | public: | 
|  | /*!*************************************************************************** | 
|  | @brief      	Constructor | 
|  | *****************************************************************************/ | 
|  | CPVRTHash() : m_uiHash(0) {} | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Copy Constructor | 
|  | @param[in]		rhs         CPVRTHash to copy. | 
|  | *****************************************************************************/ | 
|  | CPVRTHash(const CPVRTHash& rhs) : m_uiHash(rhs.m_uiHash) {} | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Overloaded constructor | 
|  | @param[in]		String      CPVRTString to create the CPVRTHash with. | 
|  | *****************************************************************************/ | 
|  | CPVRTHash(const CPVRTString& String) : m_uiHash(0) | 
|  | { | 
|  | if(String.length() > 0)		// Empty string. Don't set. | 
|  | { | 
|  | m_uiHash = MakeHash(String); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Overloaded constructor | 
|  | @param[in]		c_pszString String to create the CPVRTHash with. | 
|  | *****************************************************************************/ | 
|  | CPVRTHash(const char* c_pszString) : m_uiHash(0) | 
|  | { | 
|  | _ASSERT(c_pszString); | 
|  | if(c_pszString[0] != 0)		// Empty string. Don't set. | 
|  | { | 
|  | m_uiHash = MakeHash(c_pszString); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Overloaded constructor | 
|  | @param[in]		pData | 
|  | @param[in]		dataSize | 
|  | @param[in]		dataCount | 
|  | *****************************************************************************/ | 
|  | CPVRTHash(const void* pData, unsigned int dataSize, unsigned int dataCount) : m_uiHash(0) | 
|  | { | 
|  | _ASSERT(pData); | 
|  | _ASSERT(dataSize > 0); | 
|  |  | 
|  | if(dataCount > 0) | 
|  | { | 
|  | m_uiHash = MakeHash(pData, dataSize, dataCount); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Overloaded assignment. | 
|  | @param[in]		rhs | 
|  | @return			CPVRTHash & | 
|  | *****************************************************************************/ | 
|  | CPVRTHash& operator=(const CPVRTHash& rhs) | 
|  | { | 
|  | if(this != &rhs) | 
|  | { | 
|  | m_uiHash = rhs.m_uiHash; | 
|  | } | 
|  |  | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Converts to unsigned int. | 
|  | @return			int | 
|  | *****************************************************************************/ | 
|  | operator unsigned int() const | 
|  | { | 
|  | return m_uiHash; | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Generates a hash from a CPVRTString. | 
|  | @param[in]		String | 
|  | @return			The hash. | 
|  | *****************************************************************************/ | 
|  | static CPVRTHash MakeHash(const CPVRTString& String) | 
|  | { | 
|  | if(String.length() > 0) | 
|  | return MakeHash(String.c_str(), sizeof(char), (unsigned int) String.length()); | 
|  |  | 
|  | return CPVRTHash(); | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Generates a hash from a null terminated char array. | 
|  | @param[in]		c_pszString | 
|  | @return         The hash. | 
|  | *****************************************************************************/ | 
|  | static CPVRTHash MakeHash(const char* c_pszString) | 
|  | { | 
|  | _ASSERT(c_pszString); | 
|  |  | 
|  | if(c_pszString[0] == 0) | 
|  | return CPVRTHash(); | 
|  |  | 
|  | const char* pCursor = c_pszString; | 
|  | while(*pCursor) pCursor++; | 
|  | return MakeHash(c_pszString, sizeof(char), (unsigned int) (pCursor - c_pszString)); | 
|  | } | 
|  |  | 
|  | /*!*************************************************************************** | 
|  | @brief      	Generates a hash from generic data. This function uses the | 
|  | 32-bit Fowler/Noll/Vo algorithm which trades efficiency for | 
|  | slightly increased risk of collisions. This algorithm is | 
|  | public domain. More information can be found at: | 
|  | http://www.isthe.com/chongo/tech/comp/fnv/. | 
|  | @param[in]		pData | 
|  | @param[in]		dataSize | 
|  | @param[in]		dataCount | 
|  | @return			unsigned int			The hash. | 
|  | *****************************************************************************/ | 
|  | static CPVRTHash MakeHash(const void* pData, unsigned int dataSize, unsigned int dataCount) | 
|  | { | 
|  | _ASSERT(pData); | 
|  | _ASSERT(dataSize > 0); | 
|  |  | 
|  | #define FNV_PRIME		16777619U | 
|  | #define FNV_OFFSETBIAS	2166136261U | 
|  |  | 
|  | if(dataCount == 0) | 
|  | return CPVRTHash(); | 
|  |  | 
|  | CPVRTHash pvrHash; | 
|  | unsigned char* p = (unsigned char*)pData; | 
|  | pvrHash.m_uiHash = FNV_OFFSETBIAS; | 
|  | for(unsigned int i = 0; i < dataSize * dataCount; ++i) | 
|  | { | 
|  | pvrHash.m_uiHash = (pvrHash.m_uiHash * FNV_PRIME) ^ p[i]; | 
|  | } | 
|  |  | 
|  | return pvrHash; | 
|  | } | 
|  |  | 
|  | private: | 
|  | unsigned int		m_uiHash;		/// The hashed data. | 
|  | }; | 
|  |  | 
|  | #endif | 
|  |  |