| /*!**************************************************************************** | |
| @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 | |