|
|
|
/*==LICENSE==*
|
|
|
|
|
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools
|
|
|
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Additional permissions under GNU GPL version 3 section 7
|
|
|
|
|
|
|
|
If you modify this Program, or any covered work, by linking or
|
|
|
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
|
|
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
|
|
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
|
|
|
(or a modified version of those libraries),
|
|
|
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
|
|
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
|
|
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
|
|
|
licensors of this Program grant you additional
|
|
|
|
permission to convey the resulting work. Corresponding Source for a
|
|
|
|
non-source form of such a combination shall include the source code for
|
|
|
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
|
|
|
work.
|
|
|
|
|
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
or by snail mail at:
|
|
|
|
Cyan Worlds, Inc.
|
|
|
|
14617 N Newport Hwy
|
|
|
|
Mead, WA 99021
|
|
|
|
|
|
|
|
*==LICENSE==*/
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.cpp
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
#include "pnUtStr.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Private data
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
// These random values were generated by the radioactive decay based
|
|
|
|
// random number generator at www.fourmilab.ch
|
|
|
|
static uint32_t s_hashValue[] = {
|
|
|
|
0xc30d2a72, 0x15efaec1, 0xd250c7d9, 0xaf3c60a8,
|
|
|
|
0x9608ae8f, 0x452c0e11, 0xb6840ffd, 0x3e36c913,
|
|
|
|
0x2864eace, 0x9b0a17d6, 0x108da74b, 0xf2c479c1,
|
|
|
|
0x8b4dd597, 0x97199bc0, 0x621f0cce, 0x1658553e,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
*
|
|
|
|
* Internal functions
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static unsigned IStrLen (const chartype str[]) {
|
|
|
|
unsigned chars = 0;
|
|
|
|
for (; *str++; ++chars)
|
|
|
|
NULL_STMT;
|
|
|
|
return chars;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static void IStrCopy (chartype * dest, const chartype source[], unsigned chars) {
|
|
|
|
while ((chars > 1) && ((*dest = *source++) != 0)) {
|
|
|
|
--chars;
|
|
|
|
++dest;
|
|
|
|
}
|
|
|
|
if (chars)
|
|
|
|
*dest = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static chartype * IStrDup (const chartype str[]) {
|
|
|
|
unsigned chars = IStrLen(str) + 1;
|
|
|
|
chartype * buffer = (chartype *)malloc(chars * sizeof(chartype));
|
|
|
|
IStrCopy(buffer, str, chars);
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<typename chartype>
|
|
|
|
static unsigned IStrPrintfValidate (chartype * dest, unsigned count, int result) {
|
|
|
|
if (!count)
|
|
|
|
return 0;
|
|
|
|
ASSERT(result <= (int)count);
|
|
|
|
if ((result < 0) || (result == (int)count)) {
|
|
|
|
dest[count - 1] = 0;
|
|
|
|
return count - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return (unsigned)result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static int IStrCmp (const chartype str1[], const chartype str2[], unsigned chars) {
|
|
|
|
for (; chars--; ++str1, ++str2) {
|
|
|
|
if (*str1 != *str2)
|
|
|
|
return (*str1 > *str2) ? 1 : -1;
|
|
|
|
if (!*str1)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static int IStrCmpI (const chartype str1[], const chartype str2[], unsigned chars) {
|
|
|
|
while (chars--) {
|
|
|
|
chartype ch1 = CharLowerFast(*str1++);
|
|
|
|
chartype ch2 = CharLowerFast(*str2++);
|
|
|
|
if (ch1 != ch2)
|
|
|
|
return (ch1 > ch2) ? 1 : -1;
|
|
|
|
if (!ch1)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static uint32_t IStrHash (const chartype str[], unsigned chars) {
|
|
|
|
uint32_t temp0 = 0xE2C15C9D;
|
|
|
|
uint32_t temp1 = 0x2170A28A;
|
|
|
|
uint32_t result = 0x325D1EAE;
|
|
|
|
for (unsigned ch; chars-- && ((ch = (unsigned)*str) != 0); ++str) {
|
|
|
|
temp0 = (temp0 << 3) ^ ch;
|
|
|
|
temp1 += s_hashValue[temp0 & 0x0F];
|
|
|
|
result ^= temp0 + temp1;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
template<class chartype>
|
|
|
|
static uint32_t IStrHashI (const chartype str[], unsigned chars) {
|
|
|
|
uint32_t temp0 = 0xE2C15C9D;
|
|
|
|
uint32_t temp1 = 0x2170A28A;
|
|
|
|
uint32_t result = 0x325D1EAE;
|
|
|
|
for (unsigned ch; chars-- && ((ch = (unsigned)*str) != 0); ++str) {
|
|
|
|
if ((ch >= 'a') && (ch <= 'z'))
|
|
|
|
ch = ch + 'A' - 'a';
|
|
|
|
temp0 = (temp0 << 3) ^ ch;
|
|
|
|
temp1 += s_hashValue[temp0 & 0x0F];
|
|
|
|
result ^= temp0 + temp1;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
*
|
|
|
|
* Exported functions
|
|
|
|
*
|
|
|
|
***/
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
char * StrDup (const char str[]) {
|
|
|
|
return IStrDup(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
wchar_t * StrDup (const wchar_t str[]) {
|
|
|
|
return IStrDup(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrPrintf (char * dest, unsigned count, const char format[], ...) {
|
|
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
|
|
int result = hsVsnprintf((char *)dest, count, (const char *)format, argList);
|
|
|
|
va_end(argList);
|
|
|
|
return IStrPrintfValidate(dest, count, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrPrintf (wchar_t * dest, unsigned count, const wchar_t format[], ...) {
|
|
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
|
|
int result = hsVsnwprintf(dest, count, format, argList);
|
|
|
|
va_end(argList);
|
|
|
|
return IStrPrintfValidate(dest, count, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrPrintfV (char * dest, unsigned count, const char format[], va_list args) {
|
|
|
|
int result = hsVsnprintf(dest, count, format, args);
|
|
|
|
return IStrPrintfValidate(dest, count, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrPrintfV (wchar_t * dest, unsigned count, const wchar_t format[], va_list args) {
|
|
|
|
int result = hsVsnwprintf(dest, count, format, args);
|
|
|
|
return IStrPrintfValidate(dest, count, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
int StrCmp (const char str1[], const char str2[], unsigned chars) {
|
|
|
|
return IStrCmp(str1, str2, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
int StrCmp (const wchar_t str1[], const wchar_t str2[], unsigned chars) {
|
|
|
|
return IStrCmp(str1, str2, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
int StrCmpI (const char str1[], const char str2[], unsigned chars) {
|
|
|
|
return IStrCmpI(str1, str2, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
int StrCmpI (const wchar_t str1[], const wchar_t str2[], unsigned chars) {
|
|
|
|
return IStrCmpI(str1, str2, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
void StrCopy (char * dest, const char source[], unsigned chars) {
|
|
|
|
IStrCopy(dest, source, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
void StrCopy (wchar_t * dest, const wchar_t source[], unsigned chars) {
|
|
|
|
IStrCopy(dest, source, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrLen (const char str[]) {
|
|
|
|
return IStrLen(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
unsigned StrLen (const wchar_t str[]) {
|
|
|
|
return IStrLen(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
uint32_t StrHash (const char str[], unsigned chars) {
|
|
|
|
return IStrHash(str, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
uint32_t StrHash (const wchar_t str[], unsigned chars) {
|
|
|
|
return IStrHash(str, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
uint32_t StrHashI (const char str[], unsigned chars) {
|
|
|
|
return IStrHashI(str, chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
uint32_t StrHashI (const wchar_t str[], unsigned chars) {
|
|
|
|
return IStrHashI(str, chars);
|
|
|
|
}
|