mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
CWE Directory Reorganization
Rearrange directory structure of CWE to be loosely equivalent to the H'uru Plasma repository. Part 1: Movement of directories and files.
This commit is contained in:
62
Sources/Plasma/NucleusLib/pnUtils/Private/Unix/pnUtUxStr.cpp
Normal file
62
Sources/Plasma/NucleusLib/pnUtils/Private/Unix/pnUtUxStr.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*==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/Unix/pnUtUxStr.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
#ifdef HS_BUILD_FOR_UNIX
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// Dummy function to prevent a linker warning complaining about no public symbols if the
|
||||
// contents of the file get compiled out via pre-processor
|
||||
void UxStrPreventLNK4221Warning () {
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,61 @@
|
||||
/*==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/Unix/pnUtUxSync.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#ifdef HS_BUILD_FOR_UNIX
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// Dummy function to prevent a linker warning complaining about no public symbols if the
|
||||
// contents of the file get compiled out via pre-processor
|
||||
void UxSyncPreventLNK4221Warning () {
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,71 @@
|
||||
/*==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/Unix/pnUtUxUuid.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Uuid Unix implementation
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef HS_BUILD_FOR_UNIX
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
COMPILER_ASSERT(sizeof(Uuid) >= sizeof(uuid_t));
|
||||
|
||||
#else
|
||||
|
||||
// Dummy function to prevent a linker warning complaining about no public symbols if the
|
||||
// contents of the file get compiled out via pre-processor
|
||||
void UxUuidPreventLNK4221Warning () {
|
||||
}
|
||||
|
||||
#endif
|
41
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/W32Int.h
Normal file
41
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/W32Int.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*==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==*/
|
389
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Addr.cpp
Normal file
389
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Addr.cpp
Normal file
@ -0,0 +1,389 @@
|
||||
/*==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/Win32/pnUtW32Addr.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
||||
// hardcoded byte ordering -- Intel only
|
||||
#ifdef _M_IX86
|
||||
|
||||
const unsigned kHostClassALoopbackAddr = 0x7f000001; // 127.0.0.1
|
||||
const unsigned kHostClassALoopbackMask = 0x00ffffff;
|
||||
const unsigned kNetClassALoopbackAddr = 0x0100007f; // 127.0.0.1
|
||||
const unsigned kNetClassALoopbackMask = 0xffffff00;
|
||||
|
||||
const unsigned kHostClassANatAddr = 0x000000a0; // 10.0.0.0 - 10.255.255.255
|
||||
const unsigned kHostClassANatMask = 0x000000ff;
|
||||
const unsigned kNetClassANatAddr = 0x0a000000; // 10.0.0.0 - 10.255.255.255
|
||||
const unsigned kNetClassANatMask = 0xff000000;
|
||||
|
||||
const unsigned kHostClassBNetAddr = 0x000010ac; // 172.16.0.0 - 172.31.255.255
|
||||
const unsigned kHostClassBNetMask = 0x0000f0ff;
|
||||
const unsigned kNetClassBNetAddr = 0xac100000; // 172.16.0.0 - 172.31.255.255
|
||||
const unsigned kNetClassBNetMask = 0xfff00000;
|
||||
|
||||
const unsigned kHostClassCNatAddr = 0x0000a8c0; // 192.168.0.0 - 192.168.255.255
|
||||
const unsigned kHostClassCNatMask = 0x0000ffff;
|
||||
const unsigned kNetClassCNatAddr = 0xc0a80000; // 192.168.0.0 - 192.168.255.255
|
||||
const unsigned kNetClassCNatMask = 0xffff0000;
|
||||
|
||||
#else
|
||||
|
||||
#error "Must implement for this architecture"
|
||||
|
||||
#endif // ifdef _M_IX86
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Internal functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
// Address sort order:
|
||||
// (highest)
|
||||
// externally visible address
|
||||
// 10.0.0.0 - 10.255.255.255
|
||||
// 172.16.0.0 - 172.31.255.255
|
||||
// 192.168.0.0 - 192.168.255.255
|
||||
// 127.0.0.0 - 127.0.0.255
|
||||
// (lowest)
|
||||
static int NetAddressNodeSortValueNetOrder (NetAddressNode addr) {
|
||||
REF(NetAddressNodeSortValueNetOrder);
|
||||
// Loopback addresses
|
||||
if ((addr & kNetClassALoopbackMask) == (kNetClassALoopbackAddr & kNetClassALoopbackMask))
|
||||
return 4;
|
||||
|
||||
// Private addresses
|
||||
if ((addr & kNetClassCNatMask) == (kNetClassCNatAddr & kNetClassCNatMask))
|
||||
return 3;
|
||||
if ((addr & kNetClassBNetMask) == (kNetClassBNetAddr & kNetClassBNetMask))
|
||||
return 2;
|
||||
if ((addr & kNetClassANatMask) == (kNetClassANatAddr & kNetClassANatMask))
|
||||
return 1;
|
||||
|
||||
// Public addresses
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static int NetAddressNodeSortValueHostOrder (NetAddressNode addr) {
|
||||
// Loopback addresses
|
||||
if ((addr & kHostClassALoopbackMask) == (kHostClassALoopbackAddr & kHostClassALoopbackMask))
|
||||
return 4;
|
||||
|
||||
// Private addresses
|
||||
if ((addr & kHostClassCNatMask) == (kHostClassCNatAddr & kHostClassCNatMask))
|
||||
return 3;
|
||||
if ((addr & kHostClassBNetMask) == (kHostClassBNetAddr & kHostClassBNetMask))
|
||||
return 2;
|
||||
if ((addr & kHostClassANatMask) == (kHostClassANatAddr & kHostClassANatMask))
|
||||
return 1;
|
||||
|
||||
// Public addresses
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static NetAddressNode NodeFromString (const wchar * string[]) {
|
||||
// skip leading whitespace
|
||||
const wchar * str = *string;
|
||||
while (iswspace(*str))
|
||||
++str;
|
||||
|
||||
// This function handles partial ip addresses (61.33)
|
||||
// as well as full dotted quads. The address can be
|
||||
// terminated by whitespace or ':' as well as '\0'
|
||||
byte data[4];
|
||||
* (dword *) data = 0;
|
||||
for (unsigned i = sizeof(data); i--; ) {
|
||||
if (!iswdigit(*str))
|
||||
return (unsigned)-1;
|
||||
|
||||
unsigned value = StrToUnsigned(str, &str, 10);
|
||||
if (value >= 256)
|
||||
return (unsigned)-1;
|
||||
data[i] = (byte) value;
|
||||
|
||||
if (!*str || (*str == ':') || iswspace(*str))
|
||||
break;
|
||||
|
||||
static const wchar s_separator[] = L"\0...";
|
||||
if (*str++ != s_separator[i])
|
||||
return (unsigned)-1;
|
||||
}
|
||||
|
||||
*string = str;
|
||||
return * (NetAddressNode *) &data[0];
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
int NetAddressCompare (const NetAddress & a1, const NetAddress & a2) {
|
||||
const sockaddr_in & i1 = * (const sockaddr_in *) &a1;
|
||||
const sockaddr_in & i2 = * (const sockaddr_in *) &a2;
|
||||
|
||||
int d = i1.sin_addr.S_un.S_addr - i2.sin_addr.S_un.S_addr;
|
||||
return d ? d : i1.sin_port - i2.sin_port;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool NetAddressSameSystem (const NetAddress & a1, const NetAddress & a2) {
|
||||
const sockaddr_in & i1 = * (const sockaddr_in *) &a1;
|
||||
const sockaddr_in & i2 = * (const sockaddr_in *) &a2;
|
||||
return i1.sin_addr.S_un.S_addr == i2.sin_addr.S_un.S_addr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned NetAddressHash (const NetAddress & addr) {
|
||||
// by using only the node number as the hash value, users can safely use
|
||||
// hash value to find addresses by either using either "SameSystem" or "Equal"
|
||||
const sockaddr_in & iAddr = * (const sockaddr_in *) &addr;
|
||||
return iAddr.sin_addr.S_un.S_addr;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void NetAddressToString (
|
||||
const NetAddress & addr,
|
||||
wchar * str,
|
||||
unsigned chars,
|
||||
ENetAddressFormat format
|
||||
) {
|
||||
ASSERT(str);
|
||||
|
||||
static const wchar * s_fmts[] = {
|
||||
L"%S", // kNetAddressFormatNodeNumber
|
||||
L"%S:%u", // kNetAddressFormatAll
|
||||
};
|
||||
ASSERT(format < arrsize(s_fmts));
|
||||
const sockaddr_in & inetaddr = * (const sockaddr_in *) &addr;
|
||||
StrPrintf(
|
||||
str,
|
||||
chars,
|
||||
s_fmts[format],
|
||||
inet_ntoa(inetaddr.sin_addr),
|
||||
ntohs(inetaddr.sin_port)
|
||||
);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool NetAddressFromString (NetAddress * addr, const wchar str[], unsigned defaultPort) {
|
||||
ASSERT(addr);
|
||||
ASSERT(str);
|
||||
|
||||
// NetAddress is bigger than sockaddr_in so start by zeroing the whole thing
|
||||
ZEROPTR(addr);
|
||||
|
||||
for (;;) {
|
||||
NetAddressNode node = NodeFromString(&str);
|
||||
if (node == (unsigned)-1)
|
||||
break;
|
||||
|
||||
if (*str == L':')
|
||||
defaultPort = StrToUnsigned(str + 1, nil, 10);
|
||||
|
||||
sockaddr_in * inetaddr = (sockaddr_in *) addr;
|
||||
inetaddr->sin_family = AF_INET;
|
||||
inetaddr->sin_port = htons((word) defaultPort);
|
||||
inetaddr->sin_addr.S_un.S_addr = htonl(node);
|
||||
// inetaddr->sin_zero already zeroed
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// address already zeroed
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned NetAddressGetPort (
|
||||
const NetAddress & addr
|
||||
) {
|
||||
return ntohs(((sockaddr_in *) &addr)->sin_port);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void NetAddressSetPort (
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
) {
|
||||
((sockaddr_in *) addr)->sin_port = htons((word) port);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
NetAddressNode NetAddressGetNode (const NetAddress & addr) {
|
||||
return ntohl(((const sockaddr_in *) &addr)->sin_addr.S_un.S_addr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void NetAddressFromNode (
|
||||
NetAddressNode node,
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
) {
|
||||
ZEROPTR(addr);
|
||||
sockaddr_in * inetaddr = (sockaddr_in *) addr;
|
||||
inetaddr->sin_family = AF_INET;
|
||||
inetaddr->sin_addr.S_un.S_addr = htonl(node);
|
||||
inetaddr->sin_port = htons((word) port);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void NetAddressNodeToString (
|
||||
NetAddressNode node,
|
||||
wchar * str,
|
||||
unsigned chars
|
||||
) {
|
||||
in_addr addr;
|
||||
addr.S_un.S_addr = htonl(node);
|
||||
StrPrintf(str, chars, L"%S", inet_ntoa(addr));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
NetAddressNode NetAddressNodeFromString (
|
||||
const wchar string[],
|
||||
const wchar * endPtr[]
|
||||
) {
|
||||
if (!endPtr)
|
||||
endPtr = &string;
|
||||
*endPtr = string;
|
||||
return NodeFromString(endPtr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void NetAddressGetLoopback (
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
) {
|
||||
NetAddressFromNode(
|
||||
kHostClassALoopbackAddr,
|
||||
port,
|
||||
addr
|
||||
);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned NetAddressGetLocal (
|
||||
unsigned count,
|
||||
NetAddressNode addresses[]
|
||||
) {
|
||||
ASSERT(count);
|
||||
ASSERT(addresses);
|
||||
|
||||
for (;;) {
|
||||
// Get local computer name
|
||||
char name[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD size = arrsize(name);
|
||||
if (!GetComputerName(name, &size))
|
||||
StrCopy(name, "localhost", arrsize(name));
|
||||
|
||||
// Get IPv4 addresses for local system
|
||||
const struct hostent * host = gethostbyname(name);
|
||||
if (!host || !host->h_name)
|
||||
break;
|
||||
host = gethostbyname(host->h_name);
|
||||
if (!host)
|
||||
break;
|
||||
if (host->h_length != sizeof(dword))
|
||||
break;
|
||||
|
||||
// Count total number of addresses
|
||||
unsigned found = 0;
|
||||
const dword ** addr = (const dword **) host->h_addr_list;
|
||||
for (; *addr; ++addr)
|
||||
++found;
|
||||
if (!found)
|
||||
break;
|
||||
|
||||
// Create a buffer to sort the addresses
|
||||
NetAddressNode * dst;
|
||||
if (found > count)
|
||||
dst = ALLOCA(NetAddressNode, found);
|
||||
else
|
||||
dst = addresses;
|
||||
|
||||
// Fill address buffer
|
||||
const dword * src = * (const dword **) host->h_addr_list;
|
||||
for (unsigned index = 0; index < found; ++index)
|
||||
dst[index] = ntohl(src[index]);
|
||||
|
||||
// Sort addresses by priority
|
||||
QSORT(
|
||||
NetAddressNode,
|
||||
dst,
|
||||
found,
|
||||
NetAddressNodeSortValueHostOrder(elem1) - NetAddressNodeSortValueHostOrder(elem2)
|
||||
);
|
||||
|
||||
// Return the number of addresses the user actually requested
|
||||
if (found > count) {
|
||||
for (unsigned index = 0; index < count; ++index)
|
||||
addresses[index] = dst[index];
|
||||
return count;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// Initialize with a valid value
|
||||
addresses[0] = kHostClassALoopbackAddr;
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*==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/Win32/pnUtW32Dll.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
223
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Misc.cpp
Normal file
223
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Misc.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/*==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/Win32/pnUtW32Misc.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
static MEMORYSTATUSEX s_memstatus;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
const wchar * AppGetCommandLine () {
|
||||
return GetCommandLineW();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void MachineGetName (wchar *computerName, unsigned int length) {
|
||||
DWORD len = length;
|
||||
GetComputerNameW(computerName, &len);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* System status
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void MemoryGetStatus (MemoryStatus * status) {
|
||||
MEMORYSTATUSEX mem;
|
||||
mem.dwLength = sizeof(mem);
|
||||
GlobalMemoryStatusEx(&mem);
|
||||
|
||||
const qword BYTES_PER_MB = 1024 * 1024;
|
||||
status->totalPhysMB = unsigned(mem.ullTotalPhys / BYTES_PER_MB);
|
||||
status->availPhysMB = unsigned(mem.ullAvailPhys / BYTES_PER_MB);
|
||||
status->totalPageFileMB = unsigned(mem.ullTotalPageFile / BYTES_PER_MB);
|
||||
status->availPageFileMB = unsigned(mem.ullAvailPageFile / BYTES_PER_MB);
|
||||
status->totalVirtualMB = unsigned(mem.ullTotalVirtual / BYTES_PER_MB);
|
||||
status->availVirtualMB = unsigned(mem.ullAvailVirtual / BYTES_PER_MB);
|
||||
status->memoryLoad = mem.dwMemoryLoad;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void DiskGetStatus (ARRAY(DiskStatus) * disks) {
|
||||
for (;;) {
|
||||
DWORD length = GetLogicalDriveStrings(0, NULL);
|
||||
if (!length || length > 2048)
|
||||
break;
|
||||
|
||||
wchar * buffer = ALLOCA(wchar, length + 1);
|
||||
if (!GetLogicalDriveStringsW(length, buffer))
|
||||
break;
|
||||
|
||||
for (; *buffer; buffer += StrLen(buffer) + 1) {
|
||||
UINT driveType = GetDriveTypeW(buffer);
|
||||
if (driveType != DRIVE_FIXED)
|
||||
continue;
|
||||
|
||||
ULARGE_INTEGER freeBytes;
|
||||
ULARGE_INTEGER totalBytes;
|
||||
if (!GetDiskFreeSpaceExW(buffer, &freeBytes, &totalBytes, NULL))
|
||||
continue;
|
||||
|
||||
DiskStatus status;
|
||||
StrCopy(status.name, buffer, arrsize(status.name));
|
||||
|
||||
const qword BYTES_PER_MB = 1024 * 1024;
|
||||
status.totalSpaceMB = unsigned(totalBytes.QuadPart / BYTES_PER_MB);
|
||||
status.freeSpaceMB = unsigned(freeBytes.QuadPart / BYTES_PER_MB);
|
||||
|
||||
disks->Add(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// Loosely taken from MS's cpuid code sample
|
||||
void CpuGetInfo (
|
||||
word * cpuCaps,
|
||||
dword * cpuVendor,
|
||||
word * cpuSignature
|
||||
) {
|
||||
dword signature = 0;
|
||||
dword extended = 0;
|
||||
dword flags[2] = { 0, 0 };
|
||||
cpuVendor[0] = 0;
|
||||
|
||||
_asm {
|
||||
// Detect if cpuid instruction is supported by attempting
|
||||
// to change the ID bit of EFLAGS
|
||||
pushfd
|
||||
pop eax // get EFLAGS
|
||||
mov ecx, eax // store copy of original EFLAGS
|
||||
xor eax, 0x200000 // flip ID bit
|
||||
push eax
|
||||
popfd // replace EFLAGS
|
||||
pushfd // get EFLAGS
|
||||
pop eax
|
||||
xor eax, ecx
|
||||
je DONE
|
||||
|
||||
// Get processor id (GenuineIntel, AuthenticAMD, etc)
|
||||
xor eax, eax
|
||||
cpuid
|
||||
mov edi, cpuVendor
|
||||
mov [edi + 0], ebx
|
||||
mov [edi + 4], edx
|
||||
mov [edi + 8], ecx
|
||||
|
||||
// Check if capability flags are supported
|
||||
cmp eax, 1
|
||||
jl DONE
|
||||
|
||||
// Get processor capability flags and signature
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov signature, eax
|
||||
mov [flags + 0], edx
|
||||
mov [flags + 4], ecx
|
||||
|
||||
// Check for extended capabilities
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000001
|
||||
jl DONE
|
||||
|
||||
// Get extended capabilities
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
mov extended, edx
|
||||
|
||||
DONE:
|
||||
}
|
||||
|
||||
// Decode capability flags
|
||||
const static struct CpuCap {
|
||||
word cpuFlag;
|
||||
byte field;
|
||||
byte bit;
|
||||
} s_caps[] = {
|
||||
// feature field bit
|
||||
// ------- ----- ---
|
||||
{ kCpuCapCmov, 0, 15 },
|
||||
{ kCpuCapEst, 1, 7 },
|
||||
{ kCpuCapHtt, 0, 28 },
|
||||
{ kCpuCapMmx, 0, 23 },
|
||||
{ kCpuCapPsn, 0, 18 },
|
||||
{ kCpuCapSse, 0, 25 },
|
||||
{ kCpuCapSse2, 0, 26 },
|
||||
{ kCpuCapSse3, 1, 0 },
|
||||
{ kCpuCapTsc, 0, 4 },
|
||||
};
|
||||
for (unsigned i = 0; i < arrsize(s_caps); ++i) {
|
||||
const CpuCap & cap = s_caps[i];
|
||||
if (flags[cap.field] & (1 << cap.bit))
|
||||
*cpuCaps |= cap.cpuFlag;
|
||||
}
|
||||
|
||||
// Copy signature
|
||||
*cpuSignature = word(signature & 0xfff);
|
||||
|
||||
// If this is an AMD CPU, check for 3DNow support
|
||||
const char * vendorAmd = "AuthenticAMD";
|
||||
if (!MemCmp(vendorAmd, cpuVendor, 12)) {
|
||||
if (extended & (1 << 31))
|
||||
*cpuCaps |= kCpuCap3dNow;
|
||||
}
|
||||
}
|
861
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Path.cpp
Normal file
861
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Path.cpp
Normal file
@ -0,0 +1,861 @@
|
||||
/*==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/Win32/pnUtW32Path.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Local functions
|
||||
*
|
||||
***/
|
||||
|
||||
// make sure our definition is at least as big as the compiler's definition
|
||||
COMPILER_ASSERT(MAX_PATH >= _MAX_PATH);
|
||||
|
||||
|
||||
//===========================================================================
|
||||
static inline bool IsSlash (wchar c) {
|
||||
return (c == L'\\') || (c == L'/');
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static inline wchar ConvertSlash (wchar c) {
|
||||
return c != L'/' ? c : L'\\';
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static inline bool IsUncPath (const wchar path[]) {
|
||||
return IsSlash(path[0]) && IsSlash(path[1]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static const wchar * SkipUncDrive (const wchar path[]) {
|
||||
// UNC drive: "//server/share"
|
||||
|
||||
// skip over leading "//"
|
||||
path += 2;
|
||||
|
||||
// scan forward to end of server name
|
||||
for (;; ++path) {
|
||||
if (!*path)
|
||||
return path;
|
||||
if (IsSlash(*path))
|
||||
break;
|
||||
}
|
||||
|
||||
// skip over '/'
|
||||
++path;
|
||||
|
||||
// skip over share name
|
||||
for (;; ++path) {
|
||||
if (!*path)
|
||||
return path;
|
||||
if (IsSlash(*path))
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static wchar * PathSkipOverSeparator (wchar * path) {
|
||||
for (; *path; ++path) {
|
||||
if (IsSlash(*path))
|
||||
return path + 1;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static unsigned CommonPrefixLength (
|
||||
const wchar src1[],
|
||||
const wchar src2[]
|
||||
) {
|
||||
ASSERT(src1);
|
||||
ASSERT(src2);
|
||||
|
||||
wchar const * const base = src1;
|
||||
const wchar * common = nil;
|
||||
for (;;) {
|
||||
// Are the next components equal in length?
|
||||
const wchar * next1 = PathSkipOverSeparator(const_cast<wchar *>(src1));
|
||||
const wchar * next2 = PathSkipOverSeparator(const_cast<wchar *>(src2));
|
||||
const int componentLen = next1 - src1;
|
||||
if (componentLen != (next2 - src2))
|
||||
break;
|
||||
|
||||
// Are the next components equal in value?
|
||||
if (!StrCmpI(src1, src2, componentLen))
|
||||
common = next1;
|
||||
else
|
||||
break;
|
||||
|
||||
if (!*next1)
|
||||
break;
|
||||
src1 = next1 + 1;
|
||||
|
||||
if (!*next2)
|
||||
break;
|
||||
src2 = next2 + 1;
|
||||
}
|
||||
|
||||
if (!common)
|
||||
return 0;
|
||||
|
||||
// Compute length of common subchunk;
|
||||
// if it is "C:" convert it to "C:\"
|
||||
unsigned commonLen = common - base;
|
||||
if ((commonLen == 2) && (base[1] == L':'))
|
||||
++commonLen;
|
||||
return commonLen;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void GetProgramName (
|
||||
void * instance,
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
if (!GetModuleFileNameW((HINSTANCE) instance, dst, dstChars)) {
|
||||
ErrorAssert(__LINE__, __FILE__, "GetModuleName failed");
|
||||
*dst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
void PathGetModuleName (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
GetProgramName(ModuleGetInstance(), dst, dstChars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathGetProgramName (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
GetProgramName(nil, dst, dstChars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathFromString (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dstChars);
|
||||
|
||||
for (;;) {
|
||||
// enable src and dst to be the same buffer
|
||||
wchar temp[MAX_PATH];
|
||||
if (dst == src) {
|
||||
StrCopy(temp, src, arrsize(temp));
|
||||
src = temp;
|
||||
}
|
||||
|
||||
DWORD const result = GetFullPathNameW(src, dstChars, dst, 0);
|
||||
if (!result)
|
||||
break;
|
||||
if (dstChars < result)
|
||||
break;
|
||||
if (!dst[0])
|
||||
break;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathFromString (
|
||||
wchar * dst, // ASSERT(dst);
|
||||
const wchar src[], // ASSERT(src);
|
||||
unsigned dstChars, // ASSERT(dstChars);
|
||||
const wchar baseDir[] // ASSERT(baseDir);
|
||||
) {
|
||||
ASSERT(baseDir);
|
||||
ASSERT(dstChars);
|
||||
|
||||
// Save current directory
|
||||
wchar curr[MAX_PATH];
|
||||
PathGetCurrentDirectory(curr, arrsize(curr));
|
||||
|
||||
// Perform string conversion from specified directory
|
||||
bool result;
|
||||
if (0 != (result = PathSetCurrentDirectory(baseDir)))
|
||||
result = PathFromString(dst, src, dstChars);
|
||||
else
|
||||
*dst = 0;
|
||||
|
||||
// Restore directory
|
||||
PathSetCurrentDirectory(curr);
|
||||
return result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// this function was originally derived from _tsplitpath in the MSVCRT library,
|
||||
// but has been updated to support UNC paths and to avoid blasting off the end
|
||||
// of the buffers.
|
||||
void PathSplitPath (
|
||||
const wchar path[],
|
||||
wchar * drive,
|
||||
wchar * dir,
|
||||
wchar * fname,
|
||||
wchar * ext
|
||||
) {
|
||||
ASSERT(path);
|
||||
ASSERT(path != drive);
|
||||
ASSERT(path != dir);
|
||||
ASSERT(path != fname);
|
||||
ASSERT(path != ext);
|
||||
|
||||
// check for UNC path
|
||||
if (IsUncPath(path)) {
|
||||
const wchar * pathStart = path;
|
||||
path = SkipUncDrive(path);
|
||||
|
||||
if (drive)
|
||||
StrCopy(drive, pathStart, min(MAX_DRIVE, path - pathStart + 1));
|
||||
}
|
||||
// regular DOS path
|
||||
else if (path[0] && (path[1] == L':')) {
|
||||
if (drive) {
|
||||
ASSERT(MAX_DRIVE >= 3);
|
||||
drive[0] = path[0];
|
||||
drive[1] = L':';
|
||||
drive[2] = L'\0';
|
||||
}
|
||||
|
||||
path += 2; // skip over 'C' ':'
|
||||
}
|
||||
else if (drive) {
|
||||
*drive = 0;
|
||||
}
|
||||
|
||||
// extract path string, if any. Path now points to the first character
|
||||
// of the path, if any, or the filename or extension, if no path was
|
||||
// specified. Scan ahead for the last occurence, if any, of a '/' or
|
||||
// '\' path separator character. If none is found, there is no path.
|
||||
// We will also note the last '.' character found, if any, to aid in
|
||||
// handling the extension.
|
||||
const wchar *last_slash = nil, *last_dot = nil, *p = path;
|
||||
for (; *p; p++) {
|
||||
if (IsSlash(*p))
|
||||
last_slash = p + 1; // point to one beyond for later copy
|
||||
else if (*p == L'.')
|
||||
last_dot = p;
|
||||
}
|
||||
|
||||
if (last_slash) {
|
||||
if (dir)
|
||||
StrCopy(dir, path, min(MAX_DIR, last_slash - path + 1));
|
||||
path = last_slash;
|
||||
}
|
||||
else if (dir) {
|
||||
*dir = 0;
|
||||
}
|
||||
|
||||
// extract file name and extension, if any. Path now points to the
|
||||
// first character of the file name, if any, or the extension if no
|
||||
// file name was given. Dot points to the '.' beginning the extension,
|
||||
// if any.
|
||||
if (last_dot && (last_dot >= path)) {
|
||||
if (fname)
|
||||
StrCopy(fname, path, min(MAX_FNAME, last_dot - path + 1));
|
||||
if (ext)
|
||||
StrCopy(ext, last_dot, MAX_EXT);
|
||||
}
|
||||
else {
|
||||
if (fname)
|
||||
StrCopy(fname, path, MAX_FNAME);
|
||||
if (ext)
|
||||
*ext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathMakePath (
|
||||
wchar * path,
|
||||
unsigned chars,
|
||||
const wchar drive[],
|
||||
const wchar dir[],
|
||||
const wchar fname[],
|
||||
const wchar ext[]
|
||||
) {
|
||||
ASSERT(path);
|
||||
ASSERT(path != drive);
|
||||
ASSERT(path != dir);
|
||||
ASSERT(path != fname);
|
||||
ASSERT(path != ext);
|
||||
|
||||
// save space for string terminator
|
||||
if (!chars--)
|
||||
return;
|
||||
|
||||
// copy drive
|
||||
if (drive && *drive && chars) {
|
||||
do {
|
||||
*path++ = ConvertSlash(*drive++);
|
||||
} while (--chars && *drive);
|
||||
ASSERT(!IsSlash(path[-1]));
|
||||
}
|
||||
|
||||
// copy directory
|
||||
if (dir && *dir && chars) {
|
||||
do {
|
||||
*path++ = ConvertSlash(*dir++);
|
||||
} while (--chars && *dir);
|
||||
|
||||
// add trailing backslash
|
||||
if (chars && (path[-1] != '\\')) {
|
||||
*path++ = L'\\';
|
||||
chars--;
|
||||
}
|
||||
}
|
||||
|
||||
// copy filename
|
||||
if (fname && *fname && chars) {
|
||||
// skip leading backslash
|
||||
if (IsSlash(*fname))
|
||||
++fname;
|
||||
|
||||
do {
|
||||
*path++ = ConvertSlash(*fname++);
|
||||
} while (--chars && *fname);
|
||||
}
|
||||
|
||||
// copy extension
|
||||
if (ext && *ext && chars) {
|
||||
if (*ext != L'.') {
|
||||
*path++ = L'.';
|
||||
chars--;
|
||||
}
|
||||
while (chars-- && *ext)
|
||||
*path++ = ConvertSlash(*ext++);
|
||||
}
|
||||
|
||||
// add string terminator
|
||||
*path = L'\0';
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathMakeRelative (
|
||||
wchar *dst,
|
||||
unsigned fromFlags, // 0 or kPathFlagDirectory
|
||||
const wchar from[],
|
||||
unsigned toFlags, // 0 or kPathFlagDirectory
|
||||
const wchar to[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(from);
|
||||
ASSERT(to);
|
||||
ASSERT(dstChars);
|
||||
*dst = 0;
|
||||
|
||||
unsigned prefixLength = CommonPrefixLength(from, to);
|
||||
if (!prefixLength)
|
||||
return false;
|
||||
|
||||
wchar fromBuf[MAX_PATH];
|
||||
if (fromFlags & kPathFlagDirectory)
|
||||
StrCopy(fromBuf, from, arrsize(fromBuf));
|
||||
else
|
||||
PathRemoveFilename(fromBuf, from, arrsize(fromBuf));
|
||||
|
||||
wchar toBuf[MAX_PATH];
|
||||
if (toFlags & kPathFlagDirectory)
|
||||
StrCopy(toBuf, to, arrsize(toBuf));
|
||||
else
|
||||
PathRemoveFilename(toBuf, to, arrsize(toBuf));
|
||||
|
||||
const wchar * curr = fromBuf + prefixLength;
|
||||
if (*curr) {
|
||||
// build ..\.. part of the path
|
||||
if (IsSlash(*curr))
|
||||
curr++; // skip slash
|
||||
|
||||
while (*curr) {
|
||||
curr = PathSkipOverSeparator(const_cast<wchar *>(curr));
|
||||
StrPack(dst, *curr ? L"..\\" : L"..", dstChars);
|
||||
}
|
||||
}
|
||||
else {
|
||||
StrCopy(dst, L".", dstChars);
|
||||
}
|
||||
|
||||
if (to[prefixLength]) {
|
||||
// deal with root case
|
||||
if (!IsSlash(to[prefixLength]))
|
||||
--prefixLength;
|
||||
|
||||
ASSERT(IsSlash(to[prefixLength]));
|
||||
StrPack(dst, to + prefixLength, dstChars);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathIsRelative (
|
||||
const wchar src[]
|
||||
) {
|
||||
ASSERT(src);
|
||||
if (!src[0])
|
||||
return true;
|
||||
if (IsSlash(src[0]))
|
||||
return false;
|
||||
if (src[1] == L':')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * PathFindFilename (
|
||||
const wchar path[]
|
||||
) {
|
||||
ASSERT(path);
|
||||
|
||||
if (IsUncPath(path))
|
||||
path = SkipUncDrive(path);
|
||||
|
||||
const wchar * last_slash = path;
|
||||
for (const wchar * p = path; *p; p++) {
|
||||
if ((*p == L'/') || (*p == L'\\') || (*p == L':'))
|
||||
last_slash = p + 1;
|
||||
}
|
||||
|
||||
return last_slash;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * PathFindExtension (
|
||||
const wchar path[]
|
||||
) {
|
||||
ASSERT(path);
|
||||
|
||||
const wchar * last_dot = 0;
|
||||
const wchar * p = PathFindFilename(path);
|
||||
for ( ; *p; p++) {
|
||||
if (*p == L'.')
|
||||
last_dot = p;
|
||||
}
|
||||
|
||||
return last_dot ? last_dot : p;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathGetCurrentDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
DWORD result = GetCurrentDirectoryW(dstChars, dst);
|
||||
if (!result || (result >= dstChars)) {
|
||||
ErrorAssert(__LINE__, __FILE__, "GetDir failed");
|
||||
*dst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathGetTempDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
DWORD result = GetTempPathW(dstChars, dst);
|
||||
if (!result || (result >= dstChars))
|
||||
StrCopy(dst, L"C:\\temp\\", dstChars);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void PathGetUserDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar temp[MAX_PATH]; // GetSpecialFolder path requires a buffer of MAX_PATH size or larger
|
||||
if (SHGetSpecialFolderPathW(NULL, temp, CSIDL_PERSONAL, TRUE) == FALSE)
|
||||
StrCopy(temp, L"C:\\", arrsize(temp));
|
||||
|
||||
// append the product name
|
||||
PathAddFilename(dst, temp, ProductLongName(), dstChars);
|
||||
|
||||
#if BUILD_TYPE != BUILD_TYPE_LIVE
|
||||
// non-live builds live in a subdir
|
||||
PathAddFilename(dst, dst, BuildTypeString(), dstChars);
|
||||
#endif
|
||||
|
||||
// ensure it exists
|
||||
if (!PathDoesDirectoryExist(dst))
|
||||
PathCreateDirectory(dst, kPathCreateDirFlagEntireTree);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void PathGetLogDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
PathGetUserDirectory(dst, dstChars);
|
||||
PathAddFilename(dst, dst, L"Log", dstChars);
|
||||
if (!PathDoesDirectoryExist(dst))
|
||||
PathCreateDirectory(dst, kPathCreateDirFlagEntireTree);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void PathGetInitDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
PathGetUserDirectory(dst, dstChars);
|
||||
PathAddFilename(dst, dst, L"Init", dstChars);
|
||||
if (!PathDoesDirectoryExist(dst))
|
||||
PathCreateDirectory(dst, kPathCreateDirFlagEntireTree);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathSetCurrentDirectory (
|
||||
const wchar path[]
|
||||
) {
|
||||
ASSERT(path);
|
||||
return SetCurrentDirectoryW(path) != 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathSetProgramDirectory () {
|
||||
wchar dir[MAX_PATH];
|
||||
PathGetProgramDirectory(dir, arrsize(dir));
|
||||
PathSetCurrentDirectory(dir);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathFindFiles (
|
||||
ARRAY(PathFind) * paths,
|
||||
const wchar fileSpec[],
|
||||
unsigned pathFlags
|
||||
) {
|
||||
ASSERT(paths);
|
||||
ASSERT(fileSpec);
|
||||
|
||||
HANDLE find;
|
||||
WIN32_FIND_DATAW fd;
|
||||
wchar directory[MAX_PATH];
|
||||
PathRemoveFilename(directory, fileSpec, arrsize(directory));
|
||||
if (INVALID_HANDLE_VALUE == (find = FindFirstFileW(fileSpec, &fd))) {
|
||||
DWORD err = GetLastError();
|
||||
if ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND))
|
||||
ASSERTMSG(err, "PathFindFiles failed");
|
||||
}
|
||||
else {
|
||||
// find all the items in the current directory
|
||||
do {
|
||||
unsigned fileFlags = 0;
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if (! (pathFlags & kPathFlagDirectory))
|
||||
continue;
|
||||
|
||||
// don't add "." and ".."
|
||||
if (fd.cFileName[0] == L'.') {
|
||||
if (!fd.cFileName[1])
|
||||
continue;
|
||||
if (fd.cFileName[1] == L'.' && !fd.cFileName[2])
|
||||
continue;
|
||||
}
|
||||
|
||||
fileFlags = kPathFlagDirectory;
|
||||
}
|
||||
else {
|
||||
if (! (pathFlags & kPathFlagFile))
|
||||
continue;
|
||||
fileFlags = kPathFlagFile;
|
||||
}
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
|
||||
if (! (pathFlags & kPathFlagHidden))
|
||||
continue;
|
||||
fileFlags |= kPathFlagHidden;
|
||||
}
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
|
||||
if (! (pathFlags & kPathFlagSystem))
|
||||
continue;
|
||||
fileFlags |= kPathFlagSystem;
|
||||
}
|
||||
|
||||
// add this one to the list of found files
|
||||
PathFind * pf = paths->New();
|
||||
pf->flags = fileFlags;
|
||||
pf->fileLength = ((qword) fd.nFileSizeHigh << 32) | fd.nFileSizeLow;
|
||||
pf->lastWriteTime = * (const qword *) &fd.ftLastWriteTime;
|
||||
PathAddFilename(pf->name, directory, fd.cFileName, arrsize(pf->name));
|
||||
} while (FindNextFileW(find, &fd));
|
||||
FindClose(find);
|
||||
}
|
||||
|
||||
// check for directory recursing
|
||||
if ((pathFlags & kPathFlagRecurse) || StrStr(fileSpec, L"**")) {
|
||||
// recurse directories
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
wchar dirSpec[MAX_PATH];
|
||||
PathAddFilename(dirSpec, directory, L"*", arrsize(dirSpec));
|
||||
if (INVALID_HANDLE_VALUE == (find = FindFirstFileW(dirSpec, &fd))) {
|
||||
DWORD err = GetLastError();
|
||||
if ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND))
|
||||
ErrorAssert(__LINE__, __FILE__, "PathFindFiles failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// find all the directories in the current directory
|
||||
const wchar * spec = PathFindFilename(fileSpec);
|
||||
do {
|
||||
if (! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
continue;
|
||||
}
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
|
||||
if (! (pathFlags & kPathFlagHidden))
|
||||
continue;
|
||||
}
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
|
||||
if (! (pathFlags & kPathFlagSystem))
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't recurse "." and ".."
|
||||
if (fd.cFileName[0] == L'.') {
|
||||
if (!fd.cFileName[1])
|
||||
continue;
|
||||
if (fd.cFileName[1] == L'.' && !fd.cFileName[2])
|
||||
continue;
|
||||
}
|
||||
|
||||
// recursively search subdirectory
|
||||
PathAddFilename(dirSpec, directory, fd.cFileName, arrsize(dirSpec));
|
||||
PathAddFilename(dirSpec, dirSpec, spec, arrsize(dirSpec));
|
||||
PathFindFiles(paths, dirSpec, pathFlags);
|
||||
|
||||
} while (FindNextFileW(find, &fd));
|
||||
FindClose(find);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
EPathCreateDirError PathCreateDirectory (const wchar path[], unsigned flags) {
|
||||
ASSERT(path);
|
||||
|
||||
// convert from relative path to full path
|
||||
wchar dir[MAX_PATH];
|
||||
if (!PathFromString(dir, path, arrsize(dir))) {
|
||||
return kPathCreateDirErrInvalidPath;
|
||||
}
|
||||
|
||||
// are we going to build the entire directory tree?
|
||||
wchar * dirEnd;
|
||||
if (flags & kPathCreateDirFlagEntireTree) {
|
||||
dirEnd = dir;
|
||||
|
||||
// skip over leading slashes in UNC paths
|
||||
while (IsSlash(*dirEnd))
|
||||
++dirEnd;
|
||||
|
||||
// skip forward to first directory
|
||||
dirEnd = PathSkipOverSeparator(dirEnd);
|
||||
}
|
||||
// we're only creating the very last entry in the path
|
||||
else {
|
||||
dirEnd = dir + StrLen(dir);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
for (wchar saveChar = L' '; saveChar; *dirEnd++ = saveChar) {
|
||||
// find the end of the current directory string and terminate it
|
||||
dirEnd = PathSkipOverSeparator(dirEnd);
|
||||
saveChar = *dirEnd;
|
||||
*dirEnd = 0;
|
||||
|
||||
// create the directory and track the result from the last call
|
||||
result = CreateDirectoryW(dir, (LPSECURITY_ATTRIBUTES) nil);
|
||||
}
|
||||
|
||||
// if we successfully created the directory then we're done
|
||||
if (result) {
|
||||
// Avoid check for kPathCreateDirFlagOsError
|
||||
COMPILER_ASSERT(kPathCreateDirSuccess == NO_ERROR);
|
||||
return kPathCreateDirSuccess;
|
||||
}
|
||||
|
||||
unsigned error = GetLastError();
|
||||
switch (error) {
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return kPathCreateDirErrAccessDenied;
|
||||
|
||||
case ERROR_ALREADY_EXISTS: {
|
||||
DWORD attrib;
|
||||
if (0xffffffff == (attrib = GetFileAttributesW(dir)))
|
||||
return kPathCreateDirErrInvalidPath;
|
||||
|
||||
if (! (attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return kPathCreateDirErrFileWithSameName;
|
||||
|
||||
if (flags & kPathCreateDirFlagCreateNew)
|
||||
return kPathCreateDirErrDirExists;
|
||||
}
|
||||
return kPathCreateDirSuccess;
|
||||
|
||||
default:
|
||||
return kPathCreateDirErrInvalidPath;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathDeleteDirectory (const wchar path[], unsigned flags) {
|
||||
ASSERT(path);
|
||||
|
||||
// convert from relative path to full path
|
||||
wchar dir[MAX_PATH];
|
||||
if (!PathFromString(dir, path, arrsize(dir)))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
// Important: in order to ensure that we don't delete NTFS
|
||||
// partition links, we must ensure that this is a directory!
|
||||
dword attributes = GetFileAttributesW(dir);
|
||||
if (attributes == (dword) -1)
|
||||
break;
|
||||
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
break;
|
||||
if (attributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
break;
|
||||
|
||||
if (!RemoveDirectoryW(dir))
|
||||
break;
|
||||
|
||||
if ((flags & kPathCreateDirFlagEntireTree) == 0)
|
||||
break;
|
||||
|
||||
wchar * filename = PathFindFilename(dir);
|
||||
if (!filename)
|
||||
break;
|
||||
|
||||
// Move up one level in the directory hierarchy
|
||||
unsigned oldLength = StrLen(dir);
|
||||
while ((filename > dir) && IsSlash(filename[-1]))
|
||||
--filename;
|
||||
*filename = 0;
|
||||
if (oldLength == StrLen(dir))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathDoesFileExist (const wchar fileName[]) {
|
||||
dword attributes = GetFileAttributesW(fileName);
|
||||
if (attributes == (dword) -1)
|
||||
return false;
|
||||
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool PathDoesDirectoryExist (const wchar directory[]) {
|
||||
dword attributes = GetFileAttributesW(directory);
|
||||
if (attributes == (dword) -1)
|
||||
return false;
|
||||
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathDeleteFile (
|
||||
const wchar file[]
|
||||
) {
|
||||
return DeleteFileW(file) != 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathMoveFile (
|
||||
const wchar src[],
|
||||
const wchar dst[]
|
||||
) {
|
||||
return MoveFileW(src, dst) != 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool PathCopyFile (
|
||||
const wchar src[],
|
||||
const wchar dst[]
|
||||
) {
|
||||
return CopyFileW(src, dst, FALSE) != 0;
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*==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/Win32/pnUtW32Str.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToAnsi (char * dest, const wchar source[], unsigned destChars) {
|
||||
return StrToAnsi(dest, source, destChars, CP_ACP);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToAnsi (char * dest, const wchar source[], unsigned destChars, unsigned codePage) {
|
||||
ASSERT(destChars != (unsigned)-1);
|
||||
ASSERT(dest != nil);
|
||||
|
||||
int result = WideCharToMultiByte(codePage, 0, source, -1, dest, destChars, nil, nil);
|
||||
if (result)
|
||||
return result - 1; // return number of characters not including null terminator
|
||||
else if (destChars) {
|
||||
dest[destChars - 1] = 0; // null terminate the destination buffer
|
||||
return destChars - 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnicode (wchar * dest, const char source[], unsigned destChars) {
|
||||
return StrToUnicode(dest, source, destChars, CP_ACP);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnicode (wchar * dest, const char source[], unsigned destChars, unsigned codePage) {
|
||||
ASSERT(destChars != (unsigned)-1);
|
||||
ASSERT(dest != nil);
|
||||
|
||||
int result = MultiByteToWideChar(codePage, 0, source, -1, dest, destChars);
|
||||
if (result)
|
||||
return result - 1; // return number of characters not including null terminator
|
||||
else if (destChars) {
|
||||
dest[destChars - 1] = 0; // null terminate the destination buffer
|
||||
return destChars - 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
375
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Sync.cpp
Normal file
375
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Sync.cpp
Normal file
@ -0,0 +1,375 @@
|
||||
/*==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/Win32/pnUtW32Sync.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Spin lock functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
static inline void EnterSpinLock (long * spinLock) {
|
||||
for (;;)
|
||||
if (*spinLock < 0)
|
||||
if (!InterlockedIncrement(spinLock))
|
||||
return;
|
||||
else
|
||||
InterlockedDecrement(spinLock);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static inline void LeaveSpinLock (long * spinLock) {
|
||||
InterlockedDecrement(spinLock);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CLockWaitSet / CLockWaitSetAllocator
|
||||
*
|
||||
***/
|
||||
|
||||
class CLockWaitSet {
|
||||
private:
|
||||
unsigned m_refCount;
|
||||
HANDLE m_waitEvent;
|
||||
|
||||
public:
|
||||
LINK(CLockWaitSet) link;
|
||||
|
||||
inline CLockWaitSet ();
|
||||
inline ~CLockWaitSet ();
|
||||
inline void DecRef ();
|
||||
inline void IncRef ();
|
||||
inline void Signal ();
|
||||
inline void Wait ();
|
||||
};
|
||||
|
||||
class CLockWaitSetAllocator {
|
||||
private:
|
||||
CLockWaitSet m_array[256];
|
||||
CLockWaitSetAllocator * m_prev;
|
||||
LISTDECL(CLockWaitSet, link) m_spareList;
|
||||
LISTDECL(CLockWaitSet, link) m_usedList;
|
||||
|
||||
static CLockWaitSetAllocator * s_allocator;
|
||||
static long s_spinLock;
|
||||
|
||||
public:
|
||||
CLockWaitSetAllocator (CLockWaitSetAllocator * prev);
|
||||
~CLockWaitSetAllocator ();
|
||||
static CLockWaitSet * Alloc ();
|
||||
static void Free (CLockWaitSet * waitSet);
|
||||
static void __cdecl Shutdown ();
|
||||
};
|
||||
|
||||
CLockWaitSetAllocator * CLockWaitSetAllocator::s_allocator;
|
||||
long CLockWaitSetAllocator::s_spinLock = -1;
|
||||
|
||||
//===========================================================================
|
||||
CLockWaitSet::CLockWaitSet () {
|
||||
m_refCount = 0;
|
||||
m_waitEvent = CreateEvent(nil, true, false, nil);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CLockWaitSet::~CLockWaitSet () {
|
||||
ASSERT(!m_refCount);
|
||||
CloseHandle(m_waitEvent);
|
||||
m_waitEvent = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSet::DecRef () {
|
||||
ASSERT(m_refCount);
|
||||
if (!--m_refCount) {
|
||||
ResetEvent(m_waitEvent);
|
||||
CLockWaitSetAllocator::Free(this);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSet::IncRef () {
|
||||
++m_refCount;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSet::Signal () {
|
||||
ASSERT(m_refCount);
|
||||
SetEvent(m_waitEvent);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSet::Wait () {
|
||||
ASSERT(m_refCount);
|
||||
WaitForSingleObject(m_waitEvent, INFINITE);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CLockWaitSetAllocator::CLockWaitSetAllocator (CLockWaitSetAllocator * prev) {
|
||||
m_prev = prev;
|
||||
if (prev) {
|
||||
m_spareList.Link(&prev->m_spareList);
|
||||
m_usedList.Link(&prev->m_usedList);
|
||||
}
|
||||
for (unsigned index = arrsize(m_array); index--; )
|
||||
m_spareList.Link(&m_array[index]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CLockWaitSetAllocator::~CLockWaitSetAllocator () {
|
||||
DEL(m_prev);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CLockWaitSet * CLockWaitSetAllocator::Alloc () {
|
||||
EnterSpinLock(&s_spinLock);
|
||||
|
||||
// If there is no active allocator or if the active allocator is full,
|
||||
// create a new one
|
||||
if (!s_allocator || !s_allocator->m_spareList.Head()) {
|
||||
if (!s_allocator)
|
||||
atexit(Shutdown);
|
||||
s_allocator = NEW(CLockWaitSetAllocator)(s_allocator);
|
||||
}
|
||||
|
||||
// Get an available wait set from the active allocator
|
||||
CLockWaitSet * waitSet = s_allocator->m_spareList.Head();
|
||||
s_allocator->m_usedList.Link(waitSet);
|
||||
|
||||
LeaveSpinLock(&s_spinLock);
|
||||
return waitSet;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSetAllocator::Free (CLockWaitSet * waitSet) {
|
||||
EnterSpinLock(&s_spinLock);
|
||||
|
||||
// Return this wait set to the active allocator's spare list
|
||||
ASSERT(s_allocator);
|
||||
s_allocator->m_spareList.Link(waitSet);
|
||||
|
||||
LeaveSpinLock(&s_spinLock);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLockWaitSetAllocator::Shutdown () {
|
||||
EnterSpinLock(&s_spinLock);
|
||||
|
||||
// Free all allocators
|
||||
while (s_allocator) {
|
||||
CLockWaitSetAllocator * prev = s_allocator->m_prev;
|
||||
DEL(s_allocator);
|
||||
s_allocator = prev;
|
||||
}
|
||||
|
||||
LeaveSpinLock(&s_spinLock);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CLock
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
CLock::CLock () {
|
||||
m_waitSet = nil;
|
||||
m_spinLock = -1;
|
||||
m_readerCount = 0;
|
||||
m_writerCount = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CLock::~CLock () {
|
||||
ASSERT(!m_waitSet);
|
||||
ASSERT(m_spinLock == -1);
|
||||
ASSERT(!m_readerCount);
|
||||
ASSERT(!m_writerCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLock::EnterRead () {
|
||||
EnterSpinLock(&m_spinLock);
|
||||
for (;;) {
|
||||
|
||||
// If there are no writers, claim this lock for reading
|
||||
if (!m_writerCount) {
|
||||
++m_readerCount;
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, wait until the existing writer releases the lock
|
||||
CLockWaitSet * waitSet = m_waitSet = (m_waitSet ? m_waitSet : CLockWaitSetAllocator::Alloc());
|
||||
waitSet->IncRef();
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
waitSet->Wait();
|
||||
EnterSpinLock(&m_spinLock);
|
||||
waitSet->DecRef();
|
||||
|
||||
}
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLock::EnterWrite () {
|
||||
EnterSpinLock(&m_spinLock);
|
||||
for (;;) {
|
||||
|
||||
// If there are no readers or writers, claim this lock for writing
|
||||
if (!m_readerCount && !m_writerCount) {
|
||||
++m_writerCount;
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, wait until the existing writer or all existing readers
|
||||
// release the lock
|
||||
CLockWaitSet * waitSet = m_waitSet = (m_waitSet ? m_waitSet : CLockWaitSetAllocator::Alloc());
|
||||
waitSet->IncRef();
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
waitSet->Wait();
|
||||
EnterSpinLock(&m_spinLock);
|
||||
waitSet->DecRef();
|
||||
|
||||
}
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLock::LeaveRead () {
|
||||
EnterSpinLock(&m_spinLock);
|
||||
|
||||
// If this is the last reader, signal waiting threads to try claiming
|
||||
// the lock again
|
||||
ASSERT(m_readerCount);
|
||||
if (!--m_readerCount)
|
||||
if (m_waitSet) {
|
||||
m_waitSet->Signal();
|
||||
m_waitSet = nil;
|
||||
}
|
||||
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CLock::LeaveWrite () {
|
||||
EnterSpinLock(&m_spinLock);
|
||||
|
||||
// This is the last writer. Signal waiting threads to try claiming the
|
||||
// lock again.
|
||||
ASSERT(m_writerCount == 1);
|
||||
--m_writerCount;
|
||||
if (m_waitSet) {
|
||||
m_waitSet->Signal();
|
||||
m_waitSet = nil;
|
||||
}
|
||||
|
||||
LeaveSpinLock(&m_spinLock);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* CEvent
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
CEvent::CEvent (
|
||||
ECEventResetBehavior resetType,
|
||||
bool initialSet
|
||||
) {
|
||||
m_handle = CreateEvent(
|
||||
nil, // security attributes
|
||||
(resetType == kEventManualReset) ? true : false,
|
||||
initialSet,
|
||||
nil // name
|
||||
);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CEvent::~CEvent () {
|
||||
(void) CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CEvent::Signal () {
|
||||
SetEvent(m_handle);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CEvent::Reset () {
|
||||
ResetEvent(m_handle);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool CEvent::Wait (unsigned waitMs) {
|
||||
ThreadAssertCanBlock(__FILE__, __LINE__);
|
||||
return WaitForSingleObject(m_handle, waitMs) == WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Exported functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
long AtomicAdd (long * value, long increment) {
|
||||
return InterlockedExchangeAdd(value, increment);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
long AtomicSet (long * value, long set) {
|
||||
return InterlockedExchange(value, set);
|
||||
}
|
162
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Time.cpp
Normal file
162
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Time.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*==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/Win32/pnUtW32Time.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Local functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
static void FormatTime (
|
||||
qword time,
|
||||
wchar const dateFmt[],
|
||||
wchar const timeFmt[],
|
||||
unsigned chars,
|
||||
wchar * buffer
|
||||
) {
|
||||
COMPILER_ASSERT(sizeof(FILETIME) == sizeof(qword));
|
||||
|
||||
SYSTEMTIME sysTime;
|
||||
FileTimeToSystemTime((FILETIME *)&time, &sysTime);
|
||||
|
||||
unsigned offset = GetDateFormatW(
|
||||
LOCALE_SYSTEM_DEFAULT,
|
||||
0,
|
||||
&sysTime,
|
||||
dateFmt,
|
||||
buffer,
|
||||
chars
|
||||
);
|
||||
|
||||
if (timeFmt) {
|
||||
// if we printed any characters, move offset back to overwrite the string terminator
|
||||
if (offset)
|
||||
--offset;
|
||||
|
||||
offset += GetTimeFormatW(
|
||||
LOCALE_SYSTEM_DEFAULT,
|
||||
0,
|
||||
&sysTime,
|
||||
timeFmt,
|
||||
buffer + offset,
|
||||
chars - offset
|
||||
);
|
||||
}
|
||||
|
||||
// if we didn't print any characters, NULL terminate the buffer
|
||||
if (!offset && chars)
|
||||
buffer[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exported functions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
|
||||
//===========================================================================
|
||||
void TimeGetDesc (
|
||||
qword time,
|
||||
TimeDesc * desc
|
||||
) {
|
||||
ASSERT(desc);
|
||||
|
||||
SYSTEMTIME sysTime;
|
||||
COMPILER_ASSERT(sizeof(qword) == sizeof(FILETIME));
|
||||
FileTimeToSystemTime((FILETIME *) &time, &sysTime);
|
||||
|
||||
desc->year = sysTime.wYear;
|
||||
desc->month = sysTime.wMonth;
|
||||
desc->day = sysTime.wDay;
|
||||
desc->dayOfWeek = sysTime.wDayOfWeek;
|
||||
desc->hour = sysTime.wHour;
|
||||
desc->minute = sysTime.wMinute;
|
||||
desc->second = sysTime.wSecond;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
qword TimeGetTime () {
|
||||
qword time;
|
||||
COMPILER_ASSERT(sizeof(qword) == sizeof(FILETIME));
|
||||
GetSystemTimeAsFileTime((FILETIME *) &time);
|
||||
return time;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
qword TimeGetLocalTime () {
|
||||
qword time;
|
||||
COMPILER_ASSERT(sizeof(qword) == sizeof(FILETIME));
|
||||
GetSystemTimeAsFileTime((FILETIME *) &time);
|
||||
FileTimeToLocalFileTime((FILETIME *) &time, (FILETIME *) &time);
|
||||
return time;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void TimePrettyPrint (
|
||||
qword time,
|
||||
unsigned chars,
|
||||
wchar * buffer
|
||||
) {
|
||||
FormatTime(
|
||||
time,
|
||||
L"ddd MMM dd',' yyyy ",
|
||||
L"hh':'mm':'ss tt",
|
||||
chars,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif // HS_BUILD_FOR_WIN32
|
187
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Uuid.cpp
Normal file
187
Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Uuid.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*==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/Win32/pnUtW32Uuid.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#if 0
|
||||
|
||||
COMPILER_ASSERT(sizeof(Uuid) >= sizeof(GUID));
|
||||
|
||||
void Uuid::Clear()
|
||||
{
|
||||
UuidCreateNil( (GUID *)this );
|
||||
}
|
||||
|
||||
int Uuid::CompareTo( const Uuid * v ) const
|
||||
{
|
||||
RPC_STATUS s;
|
||||
return UuidCompare( (GUID *)this, (GUID *)v, &s );
|
||||
}
|
||||
|
||||
bool Uuid::IsEqualTo( const Uuid * v ) const
|
||||
{
|
||||
return ( CompareTo( v )==0 );
|
||||
}
|
||||
|
||||
void Uuid::CopyFrom( const Uuid * v )
|
||||
{
|
||||
memcpy( (void*)fData, (const void*)v->fData, sizeof(fData) );
|
||||
}
|
||||
|
||||
bool Uuid::IsNull() const
|
||||
{
|
||||
RPC_STATUS s;
|
||||
return 1 == UuidIsNil( (GUID *)this, &s );
|
||||
}
|
||||
|
||||
bool Uuid::FromString( const char * str )
|
||||
{
|
||||
Clear();
|
||||
if ( !str )
|
||||
return false;
|
||||
return RPC_S_OK == UuidFromString( (unsigned char *)str, (GUID *)this );
|
||||
}
|
||||
|
||||
bool Uuid::ToString( std::string & out ) const
|
||||
{
|
||||
out = "";
|
||||
unsigned char * ubuf;
|
||||
RPC_STATUS s;
|
||||
s = UuidToString( (GUID *) this, &ubuf );
|
||||
bool success = ( s==RPC_S_OK );
|
||||
if ( success )
|
||||
out = (char*)ubuf;
|
||||
RpcStringFree( &ubuf );
|
||||
return success;
|
||||
}
|
||||
|
||||
// static
|
||||
Uuid Uuid::Generate()
|
||||
{
|
||||
Uuid result;
|
||||
UuidCreate( (GUID *)&result );
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
COMPILER_ASSERT(sizeof(Uuid) >= sizeof(GUID));
|
||||
|
||||
//============================================================================
|
||||
Uuid GuidGenerate () {
|
||||
Uuid result;
|
||||
UuidCreate( (GUID *)&result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void GuidClear (Uuid * uuid) {
|
||||
UuidCreateNil((GUID *)uuid);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool GuidFromString (const wchar str[], Uuid * uuid) {
|
||||
ASSERT(uuid);
|
||||
COMPILER_ASSERT(sizeof(wchar) == sizeof(unsigned short));
|
||||
return RPC_S_OK == UuidFromStringW((unsigned short *) str, (GUID *) uuid);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool GuidFromString (const char str[], Uuid * uuid) {
|
||||
ASSERT(uuid);
|
||||
return RPC_S_OK == UuidFromStringA((unsigned char *) str, (GUID *) uuid);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
int GuidCompare (const Uuid & a, const Uuid & b) {
|
||||
RPC_STATUS s;
|
||||
return UuidCompare((GUID *)&a, (GUID *)&b, &s);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool GuidIsNil (const Uuid & uuid) {
|
||||
RPC_STATUS s;
|
||||
return 1 == UuidIsNil((GUID *)&uuid, &s );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
const wchar * GuidToString (const Uuid & uuid, wchar * dst, unsigned chars) {
|
||||
wchar * src;
|
||||
RPC_STATUS s;
|
||||
s = UuidToStringW( (GUID *) &uuid, (unsigned short**)&src );
|
||||
if (RPC_S_OK == s)
|
||||
StrCopy(dst, src, chars);
|
||||
else
|
||||
StrCopy(dst, L"", chars);
|
||||
RpcStringFreeW( (unsigned short**)&src );
|
||||
return dst;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
const char * GuidToString (const Uuid & uuid, char * dst, unsigned chars) {
|
||||
byte * src;
|
||||
RPC_STATUS s;
|
||||
s = UuidToStringA( (GUID *) &uuid, &src );
|
||||
if (RPC_S_OK == s)
|
||||
StrCopy(dst, (char *)src, chars);
|
||||
else
|
||||
StrCopy(dst, "", chars);
|
||||
RpcStringFreeA(&src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
#endif // HS_BUILD_FOR_WIN32
|
96
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAddr.cpp
Normal file
96
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAddr.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*==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/pnUtAddr.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* CNetAddressHash
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
CNetAddressHash::CNetAddressHash (
|
||||
const NetAddress & addr
|
||||
) : m_addr(addr)
|
||||
, m_equals(nil)
|
||||
{ }
|
||||
|
||||
//============================================================================
|
||||
CNetAddressHash::CNetAddressHash (
|
||||
const NetAddress & addr,
|
||||
FNetAddressEqualityProc equals
|
||||
) : m_addr(addr)
|
||||
, m_equals(equals)
|
||||
{ }
|
||||
|
||||
//============================================================================
|
||||
bool CNetAddressHash::operator== (const CNetAddressHash & rhs) const {
|
||||
ASSERT(m_equals);
|
||||
return m_equals(m_addr, rhs.m_addr);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned CNetAddressHash::GetHash () const {
|
||||
return NetAddressHash(m_addr);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
const NetAddress & CNetAddressHash::GetAddr () const {
|
||||
return m_addr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exported data
|
||||
*
|
||||
***/
|
||||
|
||||
NetAddress kNilNetAddress;
|
170
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAddr.h
Normal file
170
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAddr.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*==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/pnUtAddr.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTADDR_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAddr.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTADDR_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Types and constants
|
||||
*
|
||||
***/
|
||||
|
||||
|
||||
struct NetAddress {
|
||||
byte data[24];
|
||||
};
|
||||
|
||||
typedef unsigned NetAddressNode;
|
||||
|
||||
|
||||
extern NetAddress kNilNetAddress;
|
||||
|
||||
typedef bool (*FNetAddressEqualityProc)(
|
||||
const NetAddress & a1,
|
||||
const NetAddress & a2
|
||||
);
|
||||
|
||||
|
||||
class CNetAddressHash {
|
||||
NetAddress m_addr;
|
||||
FNetAddressEqualityProc m_equals;
|
||||
public:
|
||||
CNetAddressHash (
|
||||
const NetAddress & addr
|
||||
);
|
||||
CNetAddressHash (
|
||||
const NetAddress & addr,
|
||||
FNetAddressEqualityProc equals
|
||||
// Useful values for 'equals':
|
||||
// NetAddressEqual --> address node and port numbers match
|
||||
// NetAddressSameSystem --> address node numbers match
|
||||
);
|
||||
void operator= (const CNetAddressHash & rhs) const; // not impl.
|
||||
bool operator== (const CNetAddressHash & rhs) const;
|
||||
unsigned GetHash () const;
|
||||
const NetAddress & GetAddr () const;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
***/
|
||||
|
||||
enum ENetAddressFormat {
|
||||
kNetAddressFormatNodeNumber,
|
||||
kNetAddressFormatAll,
|
||||
kNumNetAddressFormats
|
||||
};
|
||||
|
||||
unsigned NetAddressHash (const NetAddress & addr);
|
||||
|
||||
int NetAddressCompare (const NetAddress & a1, const NetAddress & a2);
|
||||
bool NetAddressSameSystem (const NetAddress & a1, const NetAddress & a2);
|
||||
inline bool NetAddressEqual (const NetAddress & a1, const NetAddress & a2) {
|
||||
return NetAddressCompare(a1, a2) == 0;
|
||||
}
|
||||
|
||||
void NetAddressToString (
|
||||
const NetAddress & addr,
|
||||
wchar * str,
|
||||
unsigned chars,
|
||||
ENetAddressFormat format
|
||||
);
|
||||
|
||||
// 'str' must be in the form of a dotted IP address (IPv4 or IPv6)
|
||||
// - names which require DNS lookup will cause the function to return false
|
||||
bool NetAddressFromString (
|
||||
NetAddress * addr,
|
||||
const wchar str[],
|
||||
unsigned defaultPort
|
||||
);
|
||||
|
||||
unsigned NetAddressGetPort (
|
||||
const NetAddress & addr
|
||||
);
|
||||
void NetAddressSetPort (
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
);
|
||||
|
||||
void NetAddressNodeToString (
|
||||
NetAddressNode node,
|
||||
wchar * str,
|
||||
unsigned chars
|
||||
);
|
||||
NetAddressNode NetAddressNodeFromString (
|
||||
const wchar string[],
|
||||
const wchar * endPtr[]
|
||||
);
|
||||
|
||||
NetAddressNode NetAddressGetNode (
|
||||
const NetAddress & addr
|
||||
);
|
||||
void NetAddressFromNode (
|
||||
NetAddressNode node,
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
);
|
||||
|
||||
void NetAddressGetLoopback (
|
||||
unsigned port,
|
||||
NetAddress * addr
|
||||
);
|
||||
|
||||
// Returns number of addresses set, which is guaranteed to be non-zero.
|
||||
// Furthermore, it sorts the addresses so that loopback and NAT addresses
|
||||
// are at the end of the array, and "real" addresses are at the beginning.
|
||||
unsigned NetAddressGetLocal (
|
||||
unsigned count,
|
||||
NetAddressNode addresses[]
|
||||
);
|
79
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAllIncludes.h
Normal file
79
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtAllIncludes.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*==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/pnUtAllIncludes.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTALLINCLUDES_H
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTALLINCLUDES_H
|
||||
|
||||
|
||||
#include "pnUtCoreLib.h" // must be first in list
|
||||
#include "pnUtPragma.h"
|
||||
#include "pnUtAddr.h"
|
||||
#include "pnUtUuid.h"
|
||||
#include "pnUtMath.h"
|
||||
#include "pnUtSort.h"
|
||||
#include "pnUtArray.h"
|
||||
#include "pnUtList.h"
|
||||
#include "pnUtHash.h"
|
||||
#include "pnUtPriQ.h"
|
||||
#include "pnUtSync.h"
|
||||
#include "pnUtTime.h"
|
||||
#include "pnUtTls.h"
|
||||
#include "pnUtStr.h"
|
||||
#include "pnUtRef.h"
|
||||
#include "pnUtPath.h"
|
||||
#include "pnUtBigNum.h"
|
||||
#include "pnUtCmd.h"
|
||||
#include "pnUtMisc.h"
|
||||
#include "pnUtCrypt.h"
|
||||
#include "pnUtEndian.h"
|
||||
#include "pnUtSpareList.h"
|
||||
#include "pnUtSubst.h"
|
||||
#include "pnUtRand.h"
|
||||
#include "pnUtBase64.h"
|
||||
#include "pnUtSkipList.h"
|
||||
|
||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTALLINCLUDES_H
|
102
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtArray.cpp
Normal file
102
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtArray.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*==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/pnUtArray.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CBaseArray
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
unsigned CBaseArray::CalcAllocGrowth (unsigned newAlloc, unsigned oldAlloc, unsigned * chunkSize) {
|
||||
|
||||
// If this is the initial allocation, or if the new allocation is more
|
||||
// than twice as big as the old allocation and larger than the chunk
|
||||
// size, then allocate exactly the amount of memory requested
|
||||
if (!oldAlloc || (newAlloc >= max(2 * oldAlloc, *chunkSize)))
|
||||
return newAlloc;
|
||||
|
||||
// Otherwise, allocate memory beyond what was requested in preparation
|
||||
// for future requests, so that we can reduce the time spent performing
|
||||
// memory management
|
||||
|
||||
// For small allocations, double the size of the buffer each time
|
||||
if (newAlloc < *chunkSize)
|
||||
return max(newAlloc, 2 * oldAlloc);
|
||||
|
||||
// For larger allocations, grow by the chunk size each time
|
||||
if (oldAlloc + *chunkSize > newAlloc) {
|
||||
|
||||
// If the application appears to be growing the array a chunk size
|
||||
// at a time and has allocated at least 16 chunks, double the chunk
|
||||
// size
|
||||
if (newAlloc >= 16 * *chunkSize)
|
||||
*chunkSize *= 2;
|
||||
|
||||
return oldAlloc + *chunkSize;
|
||||
}
|
||||
unsigned remainder = newAlloc % *chunkSize;
|
||||
if (remainder)
|
||||
return newAlloc + *chunkSize - remainder;
|
||||
else
|
||||
return newAlloc;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void * CBaseArray::ReallocPtr (void * ptr, unsigned bytes) {
|
||||
REF(ptr);
|
||||
void * newPtr = nil;
|
||||
if (bytes) {
|
||||
newPtr = ALLOCFLAGS(bytes, ARR_MEMORY_FLAGS);
|
||||
}
|
||||
return newPtr;
|
||||
}
|
1087
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtArray.h
Normal file
1087
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtArray.h
Normal file
File diff suppressed because it is too large
Load Diff
186
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBase64.cpp
Normal file
186
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBase64.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
/*==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/pnUtBase64.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
||||
static const char kEncode64[] = {
|
||||
// 0000000000111111111122222222223333333333444444444455555555556666
|
||||
// 0123456789012345678901234567890123456789012345678901234567890123
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
};
|
||||
|
||||
// Note that the decode table contains one special entry:
|
||||
// The '-' character (0x2d) maps to 63 just like '/' (0x2f)
|
||||
// so that URLs will work with Base64Decode when we implement them.
|
||||
#define kTerminator 127
|
||||
#define xx kTerminator
|
||||
static const char kDecode64[] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,62,xx,63,xx,63,
|
||||
52,53,54,55,56,57,58,59,60,61,xx,xx,xx,xx,xx,xx,
|
||||
xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
|
||||
15,16,17,18,19,20,21,22,23,24,25,xx,xx,xx,xx,xx,
|
||||
xx,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
|
||||
41,42,43,44,45,46,47,48,49,50,51,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,
|
||||
};
|
||||
#undef xx
|
||||
|
||||
static const char kFillchar = '=';
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
unsigned Base64Encode (
|
||||
unsigned srcChars,
|
||||
const byte srcData[],
|
||||
unsigned dstChars,
|
||||
char * dstData
|
||||
) {
|
||||
ASSERT(srcData);
|
||||
ASSERT(dstChars >= Base64EncodeSize(srcChars));
|
||||
ASSERT(dstData);
|
||||
|
||||
REF(dstChars);
|
||||
|
||||
const char * dstBase = dstData;
|
||||
const byte * srcTerm = srcData + srcChars;
|
||||
for (;;) switch (srcTerm - srcData) {
|
||||
case 0:
|
||||
*dstData++ = 0;
|
||||
return dstData - dstBase;
|
||||
|
||||
case 1:
|
||||
*dstData++ = kEncode64[ ((srcData[0] >> 2) & 0x3f) ];
|
||||
*dstData++ = kEncode64[ ((srcData[0] << 4) & 0x30) ];
|
||||
*dstData++ = kFillchar;
|
||||
*dstData++ = kFillchar;
|
||||
*dstData++ = 0;
|
||||
return dstData - dstBase;
|
||||
|
||||
case 2:
|
||||
*dstData++ = kEncode64[ ((srcData[0] >> 2) & 0x3f) ];
|
||||
*dstData++ = kEncode64[ ((srcData[0] << 4) & 0x30) + ((srcData[1] >> 4) & 0x0f) ];
|
||||
*dstData++ = kEncode64[ ((srcData[1] << 2) & 0x3c) ];
|
||||
*dstData++ = kFillchar;
|
||||
*dstData++ = 0;
|
||||
return dstData - dstBase;
|
||||
|
||||
default:
|
||||
*dstData++ = kEncode64[ ((srcData[0] >> 2) & 0x3f) ];
|
||||
*dstData++ = kEncode64[ ((srcData[0] << 4) & 0x30) + ((srcData[1] >> 4) & 0x0f) ];
|
||||
*dstData++ = kEncode64[ ((srcData[1] << 2) & 0x3c) + ((srcData[2] >> 6) & 0x03) ];
|
||||
*dstData++ = kEncode64[ (srcData[2] & 0x3f) ];
|
||||
srcData += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned Base64Decode (
|
||||
unsigned srcChars,
|
||||
const char srcData[],
|
||||
unsigned dstChars,
|
||||
byte * dstData
|
||||
) {
|
||||
ASSERT(srcData);
|
||||
ASSERT(dstChars >= Base64DecodeSize(srcChars));
|
||||
ASSERT(dstData);
|
||||
REF(dstChars);
|
||||
|
||||
const byte * dstBase = dstData;
|
||||
const char * srcTerm = srcData + srcChars;
|
||||
while (srcTerm - srcData >= 4) {
|
||||
|
||||
*dstData++ = (byte) (
|
||||
(kDecode64[srcData[0]] << 2 & 0xfc)
|
||||
+(kDecode64[srcData[1]] >> 4 & 0x03)
|
||||
);
|
||||
|
||||
if (kDecode64[srcData[2]] == kTerminator)
|
||||
break;
|
||||
|
||||
*dstData++ = (byte) (
|
||||
(kDecode64[srcData[1]] << 4 & 0xf0)
|
||||
+(kDecode64[srcData[2]] >> 2 & 0x0f)
|
||||
);
|
||||
|
||||
if (kDecode64[srcData[3]] == kTerminator)
|
||||
break;
|
||||
|
||||
*dstData++ = (byte) (
|
||||
(kDecode64[srcData[2]] << 6 & 0xc0)
|
||||
+(kDecode64[srcData[3]])
|
||||
);
|
||||
|
||||
srcData += 4;
|
||||
}
|
||||
|
||||
return dstData - dstBase;
|
||||
}
|
82
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBase64.h
Normal file
82
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBase64.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*==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/pnUtBase64.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTBASE64_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBase64.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTBASE64_H
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Base64 Codec API
|
||||
*
|
||||
***/
|
||||
|
||||
const unsigned kBase64EncodeBlock = 4;
|
||||
const unsigned kBase64EncodeMultiple = 3;
|
||||
|
||||
inline unsigned Base64EncodeSize (unsigned srcChars) {
|
||||
return srcChars * kBase64EncodeBlock / kBase64EncodeMultiple + kBase64EncodeBlock;
|
||||
}
|
||||
unsigned Base64Encode (
|
||||
unsigned srcChars,
|
||||
const byte srcData[],
|
||||
unsigned dstChars,
|
||||
char * dstData
|
||||
);
|
||||
|
||||
inline unsigned Base64DecodeSize (unsigned srcChars) {
|
||||
return srcChars * kBase64EncodeMultiple / kBase64EncodeBlock + kBase64EncodeMultiple;
|
||||
}
|
||||
unsigned Base64Decode (
|
||||
unsigned srcChars,
|
||||
const char srcData[],
|
||||
unsigned dstChars,
|
||||
byte * dstData
|
||||
);
|
1401
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBigNum.cpp
Normal file
1401
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBigNum.cpp
Normal file
File diff suppressed because it is too large
Load Diff
126
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBigNum.h
Normal file
126
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBigNum.h
Normal file
@ -0,0 +1,126 @@
|
||||
/*==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/pnUtBigNum.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTBIGNUM_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtBigNum.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTBIGNUM_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* BigNum class
|
||||
*
|
||||
***/
|
||||
|
||||
class BigNum : private ARRAY(dword) {
|
||||
public:
|
||||
typedef dword Val; // must match base array
|
||||
typedef qword DVal; // must be twice as large as Val
|
||||
|
||||
private:
|
||||
bool m_isTemp;
|
||||
|
||||
void DivNormalized (const BigNum & a, const BigNum & b, BigNum * remainder);
|
||||
void ModNormalized (const BigNum & a, const BigNum & b);
|
||||
|
||||
inline static DVal Mul (Val a, Val b);
|
||||
|
||||
inline void SetVal (unsigned index, Val value);
|
||||
inline void SetVal (unsigned index, DVal value, Val * carry);
|
||||
inline void Trim (unsigned count);
|
||||
inline BigNum * UseTempAlloc (Val * ptr, unsigned count);
|
||||
|
||||
public:
|
||||
BigNum ();
|
||||
BigNum (const BigNum & a);
|
||||
BigNum (unsigned a);
|
||||
BigNum (unsigned bytes, const void * data);
|
||||
BigNum (const wchar str[], Val radix);
|
||||
~BigNum ();
|
||||
|
||||
// Constant parameters need not be distinct from the destination or from
|
||||
// each other
|
||||
|
||||
void Add (const BigNum & a, Val b);
|
||||
void Add (const BigNum & a, const BigNum & b);
|
||||
int Compare (Val a) const;
|
||||
int Compare (const BigNum & a) const;
|
||||
void Div (const BigNum & a, Val b, Val * remainder);
|
||||
void Div (const BigNum & a, const BigNum & b, BigNum * remainder);
|
||||
void FromData (unsigned bytes, const void * data);
|
||||
void FromStr (const wchar str[], Val radix);
|
||||
void Gcd (const BigNum & a, const BigNum & b);
|
||||
const void * GetData (unsigned * bytes) const;
|
||||
unsigned HighBitPos () const;
|
||||
bool InverseMod (const BigNum & a, const BigNum & b);
|
||||
bool IsMultiple (Val a) const;
|
||||
bool IsOdd () const;
|
||||
bool IsPrime () const;
|
||||
unsigned LowBitPos () const;
|
||||
void Mod (const BigNum & a, const BigNum & b);
|
||||
void Mul (const BigNum & a, Val b);
|
||||
void Mul (const BigNum & a, const BigNum & b);
|
||||
void MulMod (const BigNum & a, const BigNum & b, const BigNum & c);
|
||||
void PowMod (Val a, const BigNum & b, const BigNum & c);
|
||||
void PowMod (const BigNum & a, const BigNum & b, const BigNum & c);
|
||||
void Rand (const BigNum & a, BigNum * seed);
|
||||
void Rand (unsigned bits, BigNum * seed);
|
||||
void RandPrime (unsigned bits, BigNum * seed);
|
||||
void Set (const BigNum & a);
|
||||
void Set (unsigned a);
|
||||
void SetBits (unsigned setBitsOffset, unsigned setBitsCount);
|
||||
void SetOne ();
|
||||
void SetZero ();
|
||||
void Shl (const BigNum & a, unsigned b);
|
||||
void Shr (const BigNum & a, unsigned b);
|
||||
void Square (const BigNum & a);
|
||||
void Sub (const BigNum & a, Val b);
|
||||
void Sub (const BigNum & a, const BigNum & b);
|
||||
void ToStr (BigNum * buffer, Val radix) const;
|
||||
|
||||
};
|
699
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.cpp
Normal file
699
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.cpp
Normal file
@ -0,0 +1,699 @@
|
||||
/*==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/pnUtCmd.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
||||
#define WHITESPACE L" \"\t\r\n\x1A"
|
||||
#define FLAGS L"-/"
|
||||
#define SEPARATORS L"=:"
|
||||
#define TOGGLES L"+-"
|
||||
#define ALL WHITESPACE FLAGS SEPARATORS TOGGLES
|
||||
|
||||
static const unsigned kMaxTokenLength = MAX_PATH;
|
||||
|
||||
struct CmdArgData {
|
||||
CmdArgDef def;
|
||||
union {
|
||||
bool boolVal;
|
||||
float floatVal;
|
||||
int intVal;
|
||||
const wchar * strVal;
|
||||
unsigned unsignedVal;
|
||||
} val;
|
||||
wchar * buffer;
|
||||
unsigned nameChars;
|
||||
bool isSpecified;
|
||||
|
||||
~CmdArgData () {
|
||||
if (buffer)
|
||||
FREE(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdTokState {
|
||||
CCmdParser * parser;
|
||||
unsigned pendingIndex;
|
||||
unsigned unflaggedIndex;
|
||||
};
|
||||
|
||||
class CICmdParser {
|
||||
private:
|
||||
FARRAYOBJ(CmdArgData) m_argArray;
|
||||
FARRAY(unsigned) m_idLookupArray;
|
||||
unsigned m_requiredCount;
|
||||
FARRAY(unsigned) m_unflaggedArray;
|
||||
|
||||
inline bool CheckFlag (unsigned flags, unsigned flag, unsigned mask) const;
|
||||
void Error (const CmdTokState * state, ECmdError errorCode, const wchar arg[], const wchar value[]) const;
|
||||
bool LookupFlagged (const wchar ** name, unsigned * lastIndex) const;
|
||||
bool ProcessValue (CmdTokState * state, unsigned index, const wchar str[]);
|
||||
void SetDefaultValue (CmdArgData & arg);
|
||||
bool TokenizeFlags (CmdTokState * state, const wchar str[]);
|
||||
|
||||
public:
|
||||
CICmdParser (const CmdArgDef def[], unsigned defCount);
|
||||
bool CheckAllRequiredArguments (CmdTokState * state);
|
||||
const CmdArgData * FindArgById (unsigned id) const;
|
||||
const CmdArgData * FindArgByName (const wchar name[]) const;
|
||||
bool Tokenize (CmdTokState * state, const wchar str[]);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* CICmdParser implementation
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::CheckFlag (unsigned flags, unsigned flag, unsigned mask) const {
|
||||
return ((flags & mask) == flag);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::CheckAllRequiredArguments (CmdTokState * state) {
|
||||
bool result = (state->unflaggedIndex >= m_requiredCount);
|
||||
if (!result)
|
||||
Error(state, kCmdErrorTooFewArgs, nil, nil);
|
||||
return result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CICmdParser::CICmdParser (const CmdArgDef def[], unsigned defCount) {
|
||||
unsigned loop;
|
||||
|
||||
// Save the argument definitions
|
||||
unsigned maxId = 0;
|
||||
unsigned unflaggedCount = 0;
|
||||
m_argArray.SetCount(defCount);
|
||||
for (loop = 0; loop < defCount; ++loop) {
|
||||
|
||||
// Check whether this argument is flagged
|
||||
bool flagged = CheckFlag(def[loop].flags, kCmdArgFlagged, kCmdMaskArg);
|
||||
|
||||
// Disallow names on unflagged arguments
|
||||
ASSERT(flagged || !def[loop].name);
|
||||
|
||||
// Store the argument data
|
||||
CmdArgData & arg = m_argArray[loop];
|
||||
arg.def = def[loop];
|
||||
arg.buffer = nil;
|
||||
arg.nameChars = def[loop].name ? StrLen(def[loop].name) : 0;
|
||||
arg.isSpecified = false;
|
||||
SetDefaultValue(arg);
|
||||
maxId = max(maxId, def[loop].id);
|
||||
|
||||
// Track the number of unflagged arguments
|
||||
if (!flagged)
|
||||
++unflaggedCount;
|
||||
|
||||
}
|
||||
|
||||
// Build the id lookup table
|
||||
unsigned idTableSize = min(maxId + 1, defCount * 2);
|
||||
m_idLookupArray.SetCount(idTableSize);
|
||||
m_idLookupArray.Zero();
|
||||
for (loop = 0; loop < defCount; ++loop)
|
||||
if (def[loop].id < idTableSize)
|
||||
m_idLookupArray[def[loop].id] = loop;
|
||||
|
||||
// Build the unflagged array
|
||||
unsigned unflaggedIndex = 0;
|
||||
m_unflaggedArray.SetCount(unflaggedCount);
|
||||
for (loop = 0; loop < defCount; ++loop)
|
||||
if (CheckFlag(def[loop].flags, kCmdArgRequired, kCmdMaskArg))
|
||||
m_unflaggedArray[unflaggedIndex++] = loop;
|
||||
m_requiredCount = unflaggedIndex;
|
||||
for (loop = 0; loop < defCount; ++loop)
|
||||
if (!(CheckFlag(def[loop].flags, kCmdArgFlagged, kCmdMaskArg) ||
|
||||
CheckFlag(def[loop].flags, kCmdArgRequired, kCmdMaskArg)))
|
||||
m_unflaggedArray[unflaggedIndex++] = loop;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CICmdParser::Error (const CmdTokState * state, ECmdError errorCode, const wchar arg[], const wchar value[]) const {
|
||||
|
||||
// Compose the error text
|
||||
// (This text is only provided as a shortcut for trivial applications that
|
||||
// don't want to compose their own text. Normally, an application would
|
||||
// compose error text using its own localized strings.)
|
||||
unsigned chars = 256 + (arg ? StrLen(arg) : 0) + (value ? StrLen(value) : 0);
|
||||
wchar * buffer = (wchar *)ALLOC(chars * sizeof(wchar));
|
||||
switch (errorCode) {
|
||||
|
||||
case kCmdErrorInvalidArg:
|
||||
StrPrintf(buffer, chars, L"Invalid argument: %s", arg);
|
||||
break;
|
||||
|
||||
case kCmdErrorInvalidValue:
|
||||
StrPrintf(buffer, chars, L"Argument %s invalid value: %s", arg, value);
|
||||
break;
|
||||
|
||||
case kCmdErrorTooFewArgs:
|
||||
StrPrintf(buffer, chars, L"Too few arguments");
|
||||
break;
|
||||
|
||||
case kCmdErrorTooManyArgs:
|
||||
StrPrintf(buffer, chars, L"Too many arguments: %s", arg);
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(errorCode);
|
||||
}
|
||||
|
||||
// Call the error handler
|
||||
state->parser->OnError(buffer, errorCode, arg, value);
|
||||
|
||||
// Free memory
|
||||
FREE(buffer);
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const CmdArgData * CICmdParser::FindArgById (unsigned id) const {
|
||||
|
||||
// Search for the argument with this id
|
||||
unsigned index;
|
||||
if (id < m_idLookupArray.Count())
|
||||
index = m_idLookupArray[id];
|
||||
else
|
||||
for (index = 0; index < m_argArray.Count(); ++index)
|
||||
if (m_argArray[index].def.id == id)
|
||||
break;
|
||||
|
||||
// Verify that we found the correct argument
|
||||
if ( (index >= m_argArray.Count()) ||
|
||||
(m_argArray[index].def.id != id) )
|
||||
return nil;
|
||||
|
||||
// Return the argument data
|
||||
return &m_argArray[index];
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const CmdArgData * CICmdParser::FindArgByName (const wchar name[]) const {
|
||||
|
||||
// Search for an argument with this name
|
||||
unsigned index = (unsigned)-1;
|
||||
if (!LookupFlagged(&name, &index))
|
||||
return nil;
|
||||
|
||||
// Return the argument data
|
||||
return &m_argArray[index];
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::LookupFlagged (const wchar ** name, unsigned * lastIndex) const {
|
||||
unsigned argCount = m_argArray.Count();
|
||||
unsigned chars = StrLen(*name);
|
||||
unsigned bestIndex = (unsigned)-1;
|
||||
unsigned bestChars = 0;
|
||||
|
||||
// Check whether this argument is a suffix to any previously
|
||||
// provided prefix in this token
|
||||
for (unsigned prevChars = (*lastIndex != (unsigned)-1) ? m_argArray[*lastIndex].nameChars : 0;
|
||||
(prevChars != (unsigned)-1) && !bestChars;
|
||||
--prevChars) {
|
||||
const CmdArgData & prev = prevChars ? m_argArray[*lastIndex] : *(const CmdArgData *)nil;
|
||||
|
||||
// Find this argument in the list
|
||||
for (unsigned index = 0; index < argCount; ++index) {
|
||||
const CmdArgData & arg = m_argArray[index];
|
||||
|
||||
// Ignore non-flagged arguments
|
||||
if (!CheckFlag(arg.def.flags, kCmdArgFlagged, kCmdMaskArg))
|
||||
continue;
|
||||
|
||||
// Ignore this argument if it wouldn't beat the previous best match
|
||||
if (arg.nameChars < bestChars + prevChars)
|
||||
continue;
|
||||
|
||||
// Ignore this argument if it doesn't match the prefix
|
||||
bool caseSensitive = CheckFlag(arg.def.flags, kCmdCaseSensitive, kCmdCaseSensitive);
|
||||
if ( prevChars &&
|
||||
( (prevChars >= arg.nameChars) ||
|
||||
( caseSensitive && StrCmp(arg.def.name, prev.def.name, prevChars)) ||
|
||||
(!caseSensitive && StrCmpI(arg.def.name, prev.def.name, prevChars)) ) )
|
||||
continue;
|
||||
|
||||
// Ignore this argument if it doesn't match the suffix
|
||||
if ( ( caseSensitive && StrCmp(*name, arg.def.name + prevChars, arg.nameChars - prevChars)) ||
|
||||
(!caseSensitive && StrCmpI(*name, arg.def.name + prevChars, arg.nameChars - prevChars)) )
|
||||
continue;
|
||||
|
||||
// Track the best match
|
||||
bestIndex = index;
|
||||
bestChars = arg.nameChars - prevChars;
|
||||
if (bestChars == chars)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return the result
|
||||
*name += bestChars;
|
||||
*lastIndex = bestIndex;
|
||||
return (bestChars != 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::ProcessValue (CmdTokState * state, unsigned index, const wchar str[]) {
|
||||
CmdArgData & arg = m_argArray[index];
|
||||
arg.isSpecified = true;
|
||||
unsigned argType = arg.def.flags & kCmdMaskType;
|
||||
switch (argType) {
|
||||
|
||||
case kCmdTypeBool:
|
||||
if (*str == '+')
|
||||
arg.val.boolVal = true;
|
||||
else if (*str == '-')
|
||||
arg.val.boolVal = false;
|
||||
else if (!*str)
|
||||
arg.val.boolVal = CheckFlag(arg.def.flags, kCmdBoolSet, kCmdMaskBool);
|
||||
else
|
||||
Error(state, kCmdErrorInvalidValue, arg.def.name, str);
|
||||
break;
|
||||
|
||||
case kCmdTypeFloat:
|
||||
{
|
||||
const wchar * endPtr;
|
||||
arg.val.floatVal = StrToFloat(str, &endPtr);
|
||||
if (*endPtr)
|
||||
Error(state, kCmdErrorInvalidValue, arg.def.name, str);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCmdTypeInt:
|
||||
{
|
||||
const wchar * endPtr;
|
||||
arg.val.intVal = StrToInt(str, &endPtr);
|
||||
if (*endPtr)
|
||||
Error(state, kCmdErrorInvalidValue, arg.def.name, str);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCmdTypeString:
|
||||
if (arg.buffer)
|
||||
FREE(arg.buffer);
|
||||
arg.buffer = StrDup(str);
|
||||
arg.val.strVal = arg.buffer;
|
||||
break;
|
||||
|
||||
case kCmdTypeUnsigned:
|
||||
{
|
||||
const wchar * endPtr;
|
||||
arg.val.unsignedVal = StrToUnsigned(str, &endPtr, 10);
|
||||
if (*endPtr)
|
||||
Error(state, kCmdErrorInvalidValue, arg.def.name, str);
|
||||
}
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(argType);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CICmdParser::SetDefaultValue (CmdArgData & arg) {
|
||||
unsigned argType = arg.def.flags & kCmdMaskType;
|
||||
switch (argType) {
|
||||
|
||||
case kCmdTypeBool:
|
||||
arg.val.boolVal = !CheckFlag(arg.def.flags, kCmdBoolSet, kCmdMaskBool);
|
||||
break;
|
||||
|
||||
case kCmdTypeInt:
|
||||
arg.val.intVal = 0;
|
||||
break;
|
||||
|
||||
case kCmdTypeUnsigned:
|
||||
arg.val.unsignedVal = 0;
|
||||
break;
|
||||
|
||||
case kCmdTypeFloat:
|
||||
arg.val.floatVal = 0.0f;
|
||||
break;
|
||||
|
||||
case kCmdTypeString:
|
||||
arg.val.strVal = L"";
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(argType);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::Tokenize (CmdTokState * state, const wchar str[]) {
|
||||
wchar buffer[kMaxTokenLength];
|
||||
bool result = true;
|
||||
while (result && StrTokenize(&str, buffer, arrsize(buffer), WHITESPACE)) {
|
||||
|
||||
// If the previous argument is awaiting a value, then use this token
|
||||
// as the value
|
||||
if (state->pendingIndex != (unsigned)-1) {
|
||||
result = ProcessValue(state, state->pendingIndex, buffer);
|
||||
state->pendingIndex = (unsigned)-1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Identify and process flagged parameters
|
||||
if (StrChr(FLAGS, buffer[0]) && TokenizeFlags(state, buffer))
|
||||
continue;
|
||||
|
||||
// Process unflagged parameters
|
||||
if (state->unflaggedIndex < m_unflaggedArray.Count()) {
|
||||
result = ProcessValue(state, m_unflaggedArray[state->unflaggedIndex++], buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Process extra parameters
|
||||
if (state->parser->OnExtra(buffer))
|
||||
continue;
|
||||
|
||||
// Process invalid parameters
|
||||
Error(state, kCmdErrorTooManyArgs, buffer, nil);
|
||||
result = false;
|
||||
break;
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CICmdParser::TokenizeFlags (CmdTokState * state, const wchar str[]) {
|
||||
|
||||
// Process each separately flagged token within the string
|
||||
wchar buffer[kMaxTokenLength];
|
||||
bool result = true;
|
||||
while (result && StrTokenize(&str, buffer, arrsize(buffer), ALL)) {
|
||||
if (!buffer[0])
|
||||
continue;
|
||||
|
||||
// Process each flag within the token
|
||||
unsigned lastIndex = (unsigned)-1;
|
||||
const wchar * bufferPtr = buffer;
|
||||
while (result) {
|
||||
|
||||
// Lookup the argument name
|
||||
result = LookupFlagged(&bufferPtr, &lastIndex);
|
||||
if (!result) {
|
||||
Error(state, kCmdErrorInvalidArg, bufferPtr, nil);
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// If this argument is boolean, allow it to share a common prefix
|
||||
// with the next argument. In this case there is no place for
|
||||
// the user to provide a value, so use the default value.
|
||||
if (*bufferPtr &&
|
||||
CheckFlag(m_argArray[lastIndex].def.flags, kCmdTypeBool, kCmdMaskType)) {
|
||||
result = ProcessValue(state, lastIndex, L"");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (!result)
|
||||
break;
|
||||
|
||||
// Check for an argument value provided using a separator
|
||||
if (*str && StrChr(SEPARATORS, *str)) {
|
||||
result = ProcessValue(state, lastIndex, str + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process values for boolean arguments
|
||||
if (CheckFlag(m_argArray[lastIndex].def.flags, kCmdTypeBool, kCmdMaskType)) {
|
||||
|
||||
// Check for a value provided with a toggle
|
||||
if (*str && StrChr(TOGGLES, *str)) {
|
||||
wchar tempStr[] = {*str, 0};
|
||||
result = ProcessValue(state, lastIndex, tempStr);
|
||||
++str;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for a default value
|
||||
else {
|
||||
result = ProcessValue(state, lastIndex, L"");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Process values for non-boolean arguments
|
||||
else {
|
||||
|
||||
// Check for an argument value immediately following the name
|
||||
if (*bufferPtr) {
|
||||
result = ProcessValue(state, lastIndex, bufferPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for an argument value in the next token
|
||||
else {
|
||||
state->pendingIndex = lastIndex;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* CCmdParser implementation
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
CCmdParser::CCmdParser () {
|
||||
fParser = nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CCmdParser::CCmdParser (const CmdArgDef def[], unsigned defCount) {
|
||||
Initialize(def, defCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CCmdParser::~CCmdParser () {
|
||||
DEL(fParser);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::GetBool (unsigned id) const {
|
||||
return fParser->FindArgById(id)->val.boolVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::GetBool (const wchar name[]) const {
|
||||
return fParser->FindArgByName(name)->val.boolVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
float CCmdParser::GetFloat (unsigned id) const {
|
||||
return fParser->FindArgById(id)->val.floatVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
float CCmdParser::GetFloat (const wchar name[]) const {
|
||||
return fParser->FindArgByName(name)->val.floatVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int CCmdParser::GetInt (unsigned id) const {
|
||||
return fParser->FindArgById(id)->val.intVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int CCmdParser::GetInt (const wchar name[]) const {
|
||||
return fParser->FindArgByName(name)->val.intVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * CCmdParser::GetString (unsigned id) const {
|
||||
return fParser->FindArgById(id)->val.strVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * CCmdParser::GetString (const wchar name[]) const {
|
||||
return fParser->FindArgByName(name)->val.strVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned CCmdParser::GetUnsigned (unsigned id) const {
|
||||
return fParser->FindArgById(id)->val.unsignedVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned CCmdParser::GetUnsigned (const wchar name[]) const {
|
||||
return fParser->FindArgByName(name)->val.unsignedVal;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CCmdParser::Initialize (const CmdArgDef def[], unsigned defCount) {
|
||||
fParser = NEW(CICmdParser)(def, defCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::IsSpecified (unsigned id) const {
|
||||
if (const CmdArgData * data = fParser->FindArgById(id))
|
||||
return data->isSpecified;
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::IsSpecified (const wchar name[]) const {
|
||||
if (const CmdArgData * data = fParser->FindArgByName(name))
|
||||
return data->isSpecified;
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CCmdParser::OnError (const wchar str[], ECmdError errorCode, const wchar arg[], const wchar value[]) {
|
||||
REF(str);
|
||||
REF(errorCode);
|
||||
REF(arg);
|
||||
REF(value);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::OnExtra (const wchar str[]) {
|
||||
REF(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CCmdParser::Parse (const wchar cmdLine[]) {
|
||||
// If no command line was passed, use the application's command line,
|
||||
// skipping past the program name
|
||||
if (!cmdLine) {
|
||||
cmdLine = AppGetCommandLine();
|
||||
StrTokenize(&cmdLine, nil, 0, WHITESPACE);
|
||||
while (*cmdLine == L' ')
|
||||
++cmdLine;
|
||||
}
|
||||
|
||||
// Process the command line
|
||||
CmdTokState state = {
|
||||
this,
|
||||
(unsigned)-1, // pending index
|
||||
0 // unflagged index
|
||||
};
|
||||
bool result;
|
||||
result = fParser->Tokenize(&state, cmdLine);
|
||||
if (result)
|
||||
result = fParser->CheckAllRequiredArguments(&state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CCmdParserSimple
|
||||
*
|
||||
***/
|
||||
|
||||
|
||||
//===========================================================================
|
||||
CCmdParserSimple::CCmdParserSimple (
|
||||
unsigned requiredStringCount,
|
||||
unsigned optionalStringCount,
|
||||
const wchar flaggedBoolNames[] // double null terminated if used
|
||||
) {
|
||||
|
||||
// Count the number of flagged arguments
|
||||
unsigned flaggedBoolCount = 0;
|
||||
const wchar * curr;
|
||||
if (flaggedBoolNames)
|
||||
for (curr = flaggedBoolNames; *curr; curr += StrLen(curr) + 1)
|
||||
++flaggedBoolCount;
|
||||
|
||||
// Build the argument definition array
|
||||
unsigned totalCount = requiredStringCount + optionalStringCount + flaggedBoolCount;
|
||||
FARRAY(CmdArgDef) argDef(totalCount);
|
||||
unsigned index = 0;
|
||||
for (; index < requiredStringCount; ++index) {
|
||||
argDef[index].flags = kCmdArgRequired | kCmdTypeString;
|
||||
argDef[index].name = nil;
|
||||
argDef[index].id = index + 1;
|
||||
}
|
||||
for (; index < requiredStringCount + optionalStringCount; ++index) {
|
||||
argDef[index].flags = kCmdArgOptional | kCmdTypeString;
|
||||
argDef[index].name = nil;
|
||||
argDef[index].id = index + 1;
|
||||
}
|
||||
for (curr = flaggedBoolNames; index < totalCount; ++index) {
|
||||
argDef[index].flags = kCmdArgFlagged | kCmdTypeBool;
|
||||
argDef[index].name = curr;
|
||||
argDef[index].id = 0;
|
||||
curr += StrLen(curr) + 1;
|
||||
}
|
||||
|
||||
// Initialize the parser
|
||||
Initialize(argDef.Ptr(), argDef.Count());
|
||||
|
||||
}
|
144
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.h
Normal file
144
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*==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/pnUtCmd.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCMD_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCMD_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
***/
|
||||
|
||||
// Sets of mutually exclusive flags
|
||||
const unsigned kCmdArgFlagged = 0x0 << 0; // default
|
||||
const unsigned kCmdArgOptional = 0x1 << 0;
|
||||
const unsigned kCmdArgRequired = 0x2 << 0;
|
||||
const unsigned kCmdMaskArg = 0xf << 0;
|
||||
|
||||
const unsigned kCmdTypeBool = 0x0 << 4; // default
|
||||
const unsigned kCmdTypeInt = 0x1 << 4;
|
||||
const unsigned kCmdTypeUnsigned = 0x2 << 4;
|
||||
const unsigned kCmdTypeFloat = 0x3 << 4;
|
||||
const unsigned kCmdTypeString = 0x4 << 4;
|
||||
const unsigned kCmdMaskType = 0xf << 4;
|
||||
|
||||
const unsigned kCmdBoolSet = 0x0 << 8; // default
|
||||
const unsigned kCmdBoolUnset = 0x1 << 8;
|
||||
const unsigned kCmdMaskBool = 0xf << 8;
|
||||
|
||||
// Other flags
|
||||
const unsigned kCmdCaseSensitive = 0x1 << 28;
|
||||
|
||||
|
||||
// Error codes
|
||||
enum ECmdError {
|
||||
kCmdErrorInvalidArg,
|
||||
kCmdErrorInvalidValue,
|
||||
kCmdErrorTooFewArgs,
|
||||
kCmdErrorTooManyArgs,
|
||||
kNumCmdErrors
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
***/
|
||||
|
||||
struct CmdArgDef {
|
||||
unsigned flags;
|
||||
const wchar * name; // must be compile-time constant
|
||||
unsigned id;
|
||||
};
|
||||
|
||||
class CCmdParser {
|
||||
class CICmdParser * fParser;
|
||||
|
||||
static void DispatchError (const wchar str[], ECmdError errorCode, const wchar arg[], const wchar value[], void * param);
|
||||
static bool DispatchExtra (const wchar str[], void * param);
|
||||
|
||||
protected:
|
||||
CCmdParser ();
|
||||
void Initialize (const CmdArgDef def[], unsigned defCount);
|
||||
|
||||
public:
|
||||
CCmdParser (const CmdArgDef def[], unsigned defCount);
|
||||
virtual ~CCmdParser ();
|
||||
|
||||
bool GetBool (unsigned id) const;
|
||||
bool GetBool (const wchar name[]) const;
|
||||
float GetFloat (unsigned id) const;
|
||||
float GetFloat (const wchar name[]) const;
|
||||
int GetInt (unsigned id) const;
|
||||
int GetInt (const wchar name[]) const;
|
||||
const wchar * GetString (unsigned id) const;
|
||||
const wchar * GetString (const wchar name[]) const;
|
||||
unsigned GetUnsigned (unsigned id) const;
|
||||
unsigned GetUnsigned (const wchar name[]) const;
|
||||
bool IsSpecified (unsigned id) const;
|
||||
bool IsSpecified (const wchar name[]) const;
|
||||
|
||||
virtual void OnError (const wchar str[], ECmdError errorCode, const wchar arg[], const wchar value[]);
|
||||
virtual bool OnExtra (const wchar str[]);
|
||||
|
||||
bool Parse (const wchar cmdLine[] = nil);
|
||||
};
|
||||
|
||||
class CCmdParserSimple : public CCmdParser {
|
||||
public:
|
||||
CCmdParserSimple (
|
||||
unsigned requiredStringCount,
|
||||
unsigned optionalStringCount,
|
||||
const wchar flaggedBoolNames[] // double null terminated if used
|
||||
);
|
||||
|
||||
};
|
60
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCoreLib.h
Normal file
60
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCoreLib.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*==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/pnUtCoreLib.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCORELIB_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCoreLib.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCORELIB_H
|
||||
|
||||
#pragma warning(push, 0)
|
||||
|
||||
#include "HeadSpin.h"
|
||||
#include "hsWindows.h"
|
||||
#include "hsCritSect.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#pragma warning(pop)
|
657
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCrypt.cpp
Normal file
657
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCrypt.cpp
Normal file
@ -0,0 +1,657 @@
|
||||
/*==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/pnUtCrypt.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "openssl/md5.h"
|
||||
#include "openssl/sha.h"
|
||||
|
||||
// OpenSSL's RC4 algorithm has bugs and randomly corrupts data
|
||||
//#define OPENSSL_RC4
|
||||
#ifdef OPENSSL_RC4
|
||||
#include "openssl/rc4.h"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Opaque types
|
||||
*
|
||||
***/
|
||||
|
||||
struct CryptKey {
|
||||
ECryptAlgorithm algorithm;
|
||||
void * handle;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
||||
namespace Crypt {
|
||||
|
||||
ShaDigest s_shaSeed;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Internal functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void Md5Process (
|
||||
void * dest,
|
||||
unsigned sourceCount,
|
||||
const unsigned sourceBytes[],
|
||||
const void * sourcePtrs[]
|
||||
) {
|
||||
// initialize digest
|
||||
MD5_CTX md5;
|
||||
MD5_Init(&md5);
|
||||
|
||||
// hash data streams
|
||||
for (unsigned index = 0; index < sourceCount; ++index)
|
||||
MD5_Update(&md5, sourcePtrs[index], sourceBytes[index]);
|
||||
|
||||
// complete hashing
|
||||
MD5_Final((unsigned char *)dest, &md5);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void ShaProcess (
|
||||
void * dest,
|
||||
unsigned sourceCount,
|
||||
const unsigned sourceBytes[],
|
||||
const void * sourcePtrs[]
|
||||
) {
|
||||
// initialize digest
|
||||
SHA_CTX sha;
|
||||
SHA_Init(&sha);
|
||||
|
||||
// hash data streams
|
||||
for (unsigned index = 0; index < sourceCount; ++index)
|
||||
SHA_Update(&sha, sourcePtrs[index], sourceBytes[index]);
|
||||
|
||||
// complete hashing
|
||||
SHA_Final((unsigned char *)dest, &sha);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void Sha1Process (
|
||||
void * dest,
|
||||
unsigned sourceCount,
|
||||
const unsigned sourceBytes[],
|
||||
const void * sourcePtrs[]
|
||||
) {
|
||||
// initialize digest
|
||||
SHA_CTX sha;
|
||||
SHA1_Init(&sha);
|
||||
|
||||
// hash data streams
|
||||
for (unsigned index = 0; index < sourceCount; ++index)
|
||||
SHA1_Update(&sha, sourcePtrs[index], sourceBytes[index]);
|
||||
|
||||
// complete hashing
|
||||
SHA1_Final((unsigned char *)dest, &sha);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* RC4
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef OPENSSL_RC4
|
||||
//============================================================================
|
||||
static void Rc4Codec (
|
||||
CryptKey * key,
|
||||
bool encrypt,
|
||||
ARRAY(byte) * dest,
|
||||
unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
) {
|
||||
REF(encrypt); // RC4 uses the same algorithm to both encrypt and decrypt
|
||||
dest->SetCount(sourceBytes);
|
||||
RC4((RC4_KEY *)key->handle, sourceBytes, (const unsigned char *)sourceData, dest->Ptr());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
static void Rc4Codec (
|
||||
CryptKey * key,
|
||||
bool encrypt,
|
||||
unsigned bytes,
|
||||
void * data
|
||||
) {
|
||||
REF(encrypt); // RC4 uses the same algorithm to both encrypt and decrypt
|
||||
byte * temp = ALLOCA(byte, bytes);
|
||||
RC4((RC4_KEY *)key->handle, bytes, (const unsigned char *)data, temp);
|
||||
MemCopy(data, temp, bytes);
|
||||
}
|
||||
|
||||
#else // OPENSSL_RC4
|
||||
|
||||
//===========================================================================
|
||||
void KeyRc4::Codec (bool encrypt, ARRAY(byte) * dest, unsigned sourceBytes, const void * sourceData) {
|
||||
REF(encrypt); // RC4 uses the same algorithm to both encrypt and decrypt
|
||||
dest->SetCount(sourceBytes);
|
||||
|
||||
byte * destDataPtr = (byte *)dest->Ptr();
|
||||
const byte * sourceDataPtr = (const byte *)sourceData;
|
||||
|
||||
for (unsigned index = 0; index < sourceBytes; ++index) {
|
||||
m_x = (m_x + 1) & 0xff;
|
||||
m_y = (m_state[m_x] + m_y) & 0xff;
|
||||
SWAP(m_state[m_x], m_state[m_y]);
|
||||
|
||||
const unsigned offset = (m_state[m_x] + m_state[m_y]) & 0xff;
|
||||
destDataPtr[index] = (byte)(sourceDataPtr[index] ^ m_state[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void KeyRc4::KeyGen (
|
||||
unsigned randomBytes,
|
||||
const void * randomData,
|
||||
ARRAY(byte) * privateData
|
||||
) {
|
||||
// Allocate an output digest
|
||||
struct Digest { dword data[5]; };
|
||||
privateData->SetCount(sizeof(Digest));
|
||||
Digest * digest = (Digest *)privateData->Ptr();
|
||||
|
||||
// Perform the hash
|
||||
{
|
||||
// Initialize the hash values with the repeating pattern of random
|
||||
// data
|
||||
unsigned offset = 0;
|
||||
for (; offset < sizeof(Digest); ++offset)
|
||||
((byte *)digest)[offset] = ((const byte *)randomData)[offset % randomBytes];
|
||||
for (; offset < randomBytes; ++offset)
|
||||
((byte *)digest)[offset % sizeof(Digest)] ^= ((const byte *)randomData)[offset];
|
||||
|
||||
// 32-bit rotate left
|
||||
#ifdef _MSC_VER
|
||||
#define ROTL(n, X) _rotl(X, n)
|
||||
#else
|
||||
#define ROTL(n, X) (((X) << (n)) | ((X) >> (32 - (n))))
|
||||
#endif
|
||||
#define f1(x,y,z) (z ^ (x & (y ^ z))) // Rounds 0-19
|
||||
#define K1 0x5A827999L // Rounds 0-19
|
||||
#define subRound(a, b, c, d, e, f, k, data) (e += ROTL(5, a) + f(b, c, d) + k + data, b = ROTL(30, b))
|
||||
|
||||
// first five subrounds from SHA1
|
||||
dword A = 0x67452301;
|
||||
dword B = 0xEFCDAB89;
|
||||
dword C = 0x98BADCFE;
|
||||
dword D = 0x10325476;
|
||||
dword E = 0xC3D2E1F0;
|
||||
subRound(A, B, C, D, E, f1, K1, digest->data[ 0]);
|
||||
subRound(E, A, B, C, D, f1, K1, digest->data[ 1]);
|
||||
subRound(D, E, A, B, C, f1, K1, digest->data[ 2]);
|
||||
subRound(C, D, E, A, B, f1, K1, digest->data[ 3]);
|
||||
subRound(B, C, D, E, A, f1, K1, digest->data[ 4]);
|
||||
digest->data[0] += A;
|
||||
digest->data[1] += B;
|
||||
digest->data[2] += C;
|
||||
digest->data[3] += D;
|
||||
digest->data[4] += E;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void KeyRc4::Initialize (unsigned bytes, const void * data) {
|
||||
ASSERT(bytes);
|
||||
ASSERT(data);
|
||||
|
||||
// Initialize key with default values
|
||||
{
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
for (unsigned offset = 0; offset < arrsize(m_state); ++offset)
|
||||
m_state[offset] = (byte) offset;
|
||||
}
|
||||
|
||||
// Seed key from digest
|
||||
{
|
||||
unsigned index1 = 0;
|
||||
unsigned index2 = 0;
|
||||
for (unsigned offset = 0; offset < arrsize(m_state); ++offset) {
|
||||
ASSERT(index1 < bytes);
|
||||
index2 = (((const byte *)data)[index1] + m_state[offset] + index2) & 0xff;
|
||||
SWAP(m_state[offset], m_state[index2]);
|
||||
if (++index1 == bytes)
|
||||
index1 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENSSL_RC4
|
||||
|
||||
} using namespace Crypt;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void CryptDigest (
|
||||
ECryptAlgorithm algorithm,
|
||||
void * dest, // must be sized to the algorithm's digest size
|
||||
const unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
) {
|
||||
CryptDigest(
|
||||
algorithm,
|
||||
dest,
|
||||
1,
|
||||
&sourceBytes,
|
||||
&sourceData
|
||||
);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptDigest (
|
||||
ECryptAlgorithm algorithm,
|
||||
void * dest, // must be sized to the algorithm's digest size
|
||||
unsigned sourceCount,
|
||||
const unsigned sourceBytes[], // [sourceCount]
|
||||
const void * sourcePtrs[] // [sourceCount]
|
||||
) {
|
||||
switch (algorithm) {
|
||||
case kCryptMd5:
|
||||
Md5Process(dest, sourceCount, sourceBytes, sourcePtrs);
|
||||
break;
|
||||
|
||||
case kCryptSha:
|
||||
ShaProcess(dest, sourceCount, sourceBytes, sourcePtrs);
|
||||
break;
|
||||
|
||||
case kCryptSha1:
|
||||
Sha1Process(dest, sourceCount, sourceBytes, sourcePtrs);
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CryptKey * CryptKeyCreate (
|
||||
ECryptAlgorithm algorithm,
|
||||
unsigned bytes,
|
||||
const void * data
|
||||
) {
|
||||
CryptKey * key = nil;
|
||||
switch (algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
RC4_KEY * rc4 = NEW(RC4_KEY);
|
||||
RC4_set_key(rc4, bytes, (const unsigned char *)data);
|
||||
key = NEW(CryptKey);
|
||||
key->algorithm = kCryptRc4;
|
||||
key->handle = rc4;
|
||||
#else
|
||||
KeyRc4 * rc4 = NEWZERO(KeyRc4)(bytes, data);
|
||||
key = NEW(CryptKey);
|
||||
key->algorithm = kCryptRc4;
|
||||
key->handle = rc4;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// break;
|
||||
|
||||
DEFAULT_FATAL(algorithm);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Not exposed in header because is not used at the moment and I don't want a big rebuild right now :)
|
||||
void CryptKeyGenerate (
|
||||
ECryptAlgorithm algorithm,
|
||||
unsigned keyBits, // used for algorithms with variable key strength
|
||||
unsigned randomBytes,
|
||||
const void * randomData,
|
||||
ARRAY(byte) * privateData,
|
||||
ARRAY(byte) * publicData // only for public key cryptography
|
||||
) {
|
||||
// Allocate and fill in private and/or public key classes
|
||||
switch (algorithm) {
|
||||
|
||||
case kCryptRc4:
|
||||
KeyRc4::KeyGen(
|
||||
randomBytes,
|
||||
randomData,
|
||||
privateData
|
||||
);
|
||||
break;
|
||||
|
||||
case kCryptRsa:
|
||||
REF(keyBits);
|
||||
REF(publicData);
|
||||
#if 0
|
||||
KeyRsa::KeyGen(
|
||||
keyBits,
|
||||
randomBytes,
|
||||
randomData,
|
||||
privateData,
|
||||
publicData
|
||||
);
|
||||
break;
|
||||
#endif // fall thru to fatal...
|
||||
|
||||
DEFAULT_FATAL(algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptKeyClose (
|
||||
CryptKey * key
|
||||
) {
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
DEL(key->handle);
|
||||
DEL(key);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned CryptKeyGetBlockSize (
|
||||
CryptKey * key
|
||||
) {
|
||||
switch (key->algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
return 1;
|
||||
#else
|
||||
KeyRc4 * rc4 = (KeyRc4 *)key->handle;
|
||||
return rc4->GetBlockSize();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// return RsaGetBlockSize(key);
|
||||
|
||||
DEFAULT_FATAL(algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptCreateRandomSeed (
|
||||
unsigned bytes,
|
||||
byte * data
|
||||
) {
|
||||
COMPILER_ASSERT(SHA_DIGEST_LENGTH == 20);
|
||||
|
||||
// Combine seed with input data
|
||||
{
|
||||
unsigned seedIndex = 0;
|
||||
unsigned dataIndex = 0;
|
||||
unsigned cur = 0;
|
||||
unsigned end = max(bytes, sizeof(s_shaSeed));
|
||||
for (; cur < end; ++cur) {
|
||||
((byte *) &s_shaSeed)[seedIndex] ^= data[dataIndex];
|
||||
if (++seedIndex >= sizeof(s_shaSeed))
|
||||
seedIndex = 0;
|
||||
if (++dataIndex >= bytes)
|
||||
dataIndex = 0;
|
||||
}
|
||||
|
||||
s_shaSeed.data[2] ^= (dword) &bytes;
|
||||
s_shaSeed.data[3] ^= (dword) bytes;
|
||||
s_shaSeed.data[4] ^= (dword) data;
|
||||
}
|
||||
|
||||
// Hash seed
|
||||
ShaDigest digest;
|
||||
CryptDigest(kCryptSha, &digest, sizeof(s_shaSeed), &s_shaSeed);
|
||||
|
||||
// Update output with contents of digest
|
||||
{
|
||||
unsigned src = 0;
|
||||
unsigned dst = 0;
|
||||
unsigned cur = 0;
|
||||
unsigned end = max(bytes, sizeof(digest));
|
||||
for (; cur < end; ++cur) {
|
||||
data[dst] ^= ((const byte *) &digest)[src];
|
||||
if (++src >= sizeof(digest))
|
||||
src = 0;
|
||||
if (++dst >= bytes)
|
||||
dst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine seed with digest
|
||||
s_shaSeed.data[0] ^= digest.data[0];
|
||||
s_shaSeed.data[1] ^= digest.data[1];
|
||||
s_shaSeed.data[2] ^= digest.data[2];
|
||||
s_shaSeed.data[3] ^= digest.data[3];
|
||||
s_shaSeed.data[4] ^= digest.data[4];
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptHashPassword (
|
||||
const wchar username[],
|
||||
const wchar password[],
|
||||
ShaDigest * namePassHash
|
||||
) {
|
||||
unsigned passlen = StrLen(password);
|
||||
unsigned userlen = StrLen(username);
|
||||
|
||||
wchar * buffer = ALLOCA(wchar, passlen + userlen);
|
||||
StrCopy(buffer, password, passlen);
|
||||
StrCopy(buffer + passlen, username, userlen);
|
||||
StrLower(buffer + passlen); // lowercase the username
|
||||
|
||||
CryptDigest(
|
||||
kCryptSha,
|
||||
namePassHash,
|
||||
(userlen + passlen) * sizeof(buffer[0]),
|
||||
buffer
|
||||
);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptHashPasswordChallenge (
|
||||
unsigned clientChallenge,
|
||||
unsigned serverChallenge,
|
||||
const ShaDigest & namePassHash,
|
||||
ShaDigest * challengeHash
|
||||
) {
|
||||
#include <pshpack1.h>
|
||||
struct {
|
||||
dword clientChallenge;
|
||||
dword serverChallenge;
|
||||
ShaDigest namePassHash;
|
||||
} buffer;
|
||||
#include <poppack.h>
|
||||
buffer.clientChallenge = clientChallenge;
|
||||
buffer.serverChallenge = serverChallenge;
|
||||
buffer.namePassHash = namePassHash;
|
||||
CryptDigest(kCryptSha, challengeHash, sizeof(buffer), &buffer);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptCreateFastWeakChallenge (
|
||||
unsigned * challenge,
|
||||
unsigned val1,
|
||||
unsigned val2
|
||||
) {
|
||||
s_shaSeed.data[0] ^= TimeGetMs(); // looping time
|
||||
s_shaSeed.data[0] ^= _rotl(s_shaSeed.data[0], 1);
|
||||
s_shaSeed.data[0] ^= (unsigned) TimeGetTime(); // global time
|
||||
s_shaSeed.data[0] ^= _rotl(s_shaSeed.data[0], 1);
|
||||
s_shaSeed.data[0] ^= *challenge; // unknown
|
||||
s_shaSeed.data[0] ^= _rotl(s_shaSeed.data[0], 1);
|
||||
s_shaSeed.data[0] ^= (unsigned) challenge; // variable address
|
||||
s_shaSeed.data[0] ^= _rotl(s_shaSeed.data[0], 1);
|
||||
s_shaSeed.data[0] ^= val1;
|
||||
s_shaSeed.data[0] ^= _rotl(s_shaSeed.data[0], 1);
|
||||
s_shaSeed.data[0] ^= val2;
|
||||
*challenge = s_shaSeed.data[0];
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptEncrypt (
|
||||
CryptKey * key,
|
||||
ARRAY(byte) * dest,
|
||||
unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
) {
|
||||
switch (key->algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
Rc4Codec(key, true, dest, sourceBytes, sourceData);
|
||||
#else
|
||||
KeyRc4 * rc4 = (KeyRc4 *)key->handle;
|
||||
rc4->Codec(true, dest, sourceBytes, sourceData);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// RsaCodec(key, true, dest, sourceBytes, sourceData);
|
||||
// break;
|
||||
|
||||
DEFAULT_FATAL(key->algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptEncrypt (
|
||||
CryptKey * key,
|
||||
unsigned bytes,
|
||||
void * data
|
||||
) {
|
||||
ASSERT(1 == CryptKeyGetBlockSize(key));
|
||||
|
||||
switch (key->algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
Rc4Codec(key, true, bytes, data);
|
||||
#else
|
||||
ARRAY(byte) dest;
|
||||
dest.Reserve(bytes);
|
||||
CryptEncrypt(key, &dest, bytes, data);
|
||||
MemCopy(data, dest.Ptr(), bytes);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// RsaCodec(key, true, dest, sourceBytes, sourceData);
|
||||
// break;
|
||||
|
||||
DEFAULT_FATAL(key->algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptDecrypt (
|
||||
CryptKey * key,
|
||||
ARRAY(byte) * dest,
|
||||
unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
) {
|
||||
switch (key->algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
Rc4Codec(key, false, dest, sourceBytes, sourceData);
|
||||
#else
|
||||
KeyRc4 * rc4 = (KeyRc4 *)key->handle;
|
||||
rc4->Codec(false, dest, sourceBytes, sourceData);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// RsaCodec(key, false, dest, sourceBytes, sourceData);
|
||||
// break;
|
||||
|
||||
DEFAULT_FATAL(key->algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CryptDecrypt (
|
||||
CryptKey * key,
|
||||
unsigned bytes,
|
||||
void * data
|
||||
) {
|
||||
ASSERT(1 == CryptKeyGetBlockSize(key));
|
||||
|
||||
switch (key->algorithm) {
|
||||
case kCryptRc4: {
|
||||
#ifdef OPENSSL_RC4
|
||||
Rc4Codec(key, false, bytes, data);
|
||||
#else
|
||||
ARRAY(byte) dest;
|
||||
dest.Reserve(bytes);
|
||||
CryptDecrypt(key, &dest, bytes, data);
|
||||
MemCopy(data, dest.Ptr(), bytes);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case kCryptRsa: // Not implemented; fall-thru to FATAL
|
||||
// RsaCodec(key, false, dest, sourceBytes, sourceData);
|
||||
// break;
|
||||
|
||||
DEFAULT_FATAL(key->algorithm);
|
||||
}
|
||||
}
|
182
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCrypt.h
Normal file
182
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCrypt.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*==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/pnUtCrypt.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCRYPT_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCrypt.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCRYPT_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Types and constants
|
||||
*
|
||||
***/
|
||||
|
||||
struct CryptKey;
|
||||
|
||||
enum ECryptAlgorithm {
|
||||
kCryptSha,
|
||||
kCryptSha1,
|
||||
kCryptMd5,
|
||||
kCryptRc4,
|
||||
kCryptRsa,
|
||||
kNumCryptAlgorithms
|
||||
};
|
||||
|
||||
struct ShaDigest {
|
||||
dword data[5];
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Digest functions
|
||||
*
|
||||
***/
|
||||
|
||||
void CryptDigest (
|
||||
ECryptAlgorithm algorithm,
|
||||
void * dest, // must be sized to the algorithm's digest size
|
||||
const unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
);
|
||||
|
||||
void CryptDigest (
|
||||
ECryptAlgorithm algorithm,
|
||||
void * dest, // must be sized to the algorithm's digest size
|
||||
unsigned sourceCount,
|
||||
const unsigned sourceBytes[], // [sourceCount]
|
||||
const void * sourcePtrs[] // [sourceCount]
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Key generation
|
||||
*
|
||||
***/
|
||||
|
||||
CryptKey * CryptKeyCreate (
|
||||
ECryptAlgorithm algorithm,
|
||||
unsigned bytes,
|
||||
const void * data
|
||||
);
|
||||
|
||||
void CryptKeyClose (
|
||||
CryptKey * key
|
||||
);
|
||||
|
||||
void CryptKeyGenerate (
|
||||
ECryptAlgorithm algorithm,
|
||||
unsigned keyBits, // used for algorithms with variable key strength
|
||||
unsigned randomBytes,
|
||||
const void * randomData,
|
||||
ARRAY(byte) * privateData,
|
||||
ARRAY(byte) * publicData // only for public key cryptography
|
||||
);
|
||||
|
||||
unsigned CryptKeyGetBlockSize (
|
||||
CryptKey * key
|
||||
);
|
||||
|
||||
void CryptCreateRandomSeed (
|
||||
unsigned bytes,
|
||||
byte * data
|
||||
);
|
||||
|
||||
void CryptHashPassword (
|
||||
const wchar username[],
|
||||
const wchar password[],
|
||||
ShaDigest * namePassHash
|
||||
);
|
||||
|
||||
void CryptHashPasswordChallenge (
|
||||
unsigned clientChallenge,
|
||||
unsigned serverChallenge,
|
||||
const ShaDigest & namePassHash,
|
||||
ShaDigest * challengeHash
|
||||
);
|
||||
|
||||
void CryptCreateFastWeakChallenge (
|
||||
unsigned * challenge,
|
||||
unsigned val1,
|
||||
unsigned val2
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Encryption and Decryption
|
||||
*
|
||||
***/
|
||||
|
||||
void CryptEncrypt (
|
||||
CryptKey * key,
|
||||
ARRAY(byte) * dest,
|
||||
unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
);
|
||||
|
||||
void CryptEncrypt (
|
||||
CryptKey * key,
|
||||
unsigned bytes,
|
||||
void * data
|
||||
);
|
||||
|
||||
void CryptDecrypt (
|
||||
CryptKey * key,
|
||||
ARRAY(byte) * dest, // padded out to the algorithm's block size
|
||||
unsigned sourceBytes,
|
||||
const void * sourceData
|
||||
);
|
||||
|
||||
void CryptDecrypt (
|
||||
CryptKey * key,
|
||||
unsigned bytes,
|
||||
void * data
|
||||
);
|
146
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtEndian.cpp
Normal file
146
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtEndian.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
/*==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/pnUtEndian.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Big endian functions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef BIG_ENDIAN
|
||||
|
||||
//===========================================================================
|
||||
void EndianConvert (word * array, unsigned count) {
|
||||
for (; count--; ++array)
|
||||
*array = Endian(*array);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void EndianConvert (dword * array, unsigned count) {
|
||||
for (; count--; ++array)
|
||||
*array = Endian(*array);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void EndianConvert (qword * array, unsigned count) {
|
||||
for (; count--; ++array)
|
||||
*array = Endian(*array);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void EndianConvert (byte * data, unsigned elemCount, unsigned elemBytes) {
|
||||
switch (elemBytes) {
|
||||
case sizeof(byte):
|
||||
break;
|
||||
|
||||
case sizeof(word):
|
||||
EndianConvert((word *)data, elemCount);
|
||||
break;
|
||||
|
||||
case sizeof(dword):
|
||||
EndianConvert((dword *)data, elemCount);
|
||||
break;
|
||||
|
||||
case sizeof(qword):
|
||||
EndianConvert((qword *)data, elemCount);
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(elemBytes);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void EndianCopy (unsigned * dst, const word src[], unsigned count) {
|
||||
for (; count--; ++src, ++dst)
|
||||
*dst = (unsigned)Endian(*src);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void EndianCopy (unsigned * dst, const dword src[], unsigned count) {
|
||||
for (; count--; ++src, ++dst)
|
||||
*dst = (unsigned)Endian(*src);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void EndianCopy (unsigned * dst, const qword src[], unsigned count) {
|
||||
for (; count--; ++src, ++dst)
|
||||
*dst = (unsigned)Endian(*src);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void EndianCopy (
|
||||
void * dst,
|
||||
const byte src[],
|
||||
unsigned elemCount,
|
||||
unsigned elemBytes
|
||||
) {
|
||||
switch (elemBytes) {
|
||||
case sizeof(byte):
|
||||
MemCopy(dst, src, elemCount);
|
||||
break;
|
||||
|
||||
case sizeof(word):
|
||||
EndianCopy((word *)dst, (const word *)src, elemCount);
|
||||
break;
|
||||
|
||||
case sizeof(dword):
|
||||
EndianCopy((dword *)dst, (const dword *)src, elemCount);
|
||||
break;
|
||||
|
||||
case sizeof(qword):
|
||||
EndianCopy((qword *)dst, (const qword *)src, elemCount);
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(elemBytes);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BIG_ENDIAN
|
214
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtEndian.h
Normal file
214
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtEndian.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*==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/pnUtEndian.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTENDIAN_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtEndian.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTENDIAN_H
|
||||
|
||||
// NOTE: Because we predominantly run on little-endian CPUs, we don't
|
||||
// convert to "network order" when sending integers across the network
|
||||
// (tcp uses big-endian regardless of underlying hardware) and instead
|
||||
// use little-endian as the "native" language of our network messages.
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Types and constants
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef _M_IX86
|
||||
# define LITTLE_ENDIAN 1
|
||||
#else
|
||||
# define BIG_ENDIAN 1
|
||||
// That was a pretty weak check for endian-ness, if it
|
||||
// failed then we probably need to strengthen it a bit.
|
||||
# error "Are you sure this is a big-endian CPU?"
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Little endian functions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
|
||||
//============================================================================
|
||||
inline word Endian (word value) { return value; }
|
||||
inline dword Endian (dword value) { return value; }
|
||||
inline qword Endian (qword value) { return value; }
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianConvert (
|
||||
word * array,
|
||||
unsigned count
|
||||
) {
|
||||
REF(array);
|
||||
REF(count);
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianConvert (
|
||||
dword * array,
|
||||
unsigned count
|
||||
) {
|
||||
REF(array);
|
||||
REF(count);
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianConvert (
|
||||
qword * array,
|
||||
unsigned count
|
||||
) {
|
||||
REF(array);
|
||||
REF(count);
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianConvert (
|
||||
byte * data,
|
||||
unsigned elemCount,
|
||||
unsigned elemBytes
|
||||
) {
|
||||
REF(data);
|
||||
REF(elemCount);
|
||||
REF(elemBytes);
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianCopy (
|
||||
word * dst,
|
||||
const word src[],
|
||||
unsigned count
|
||||
) {
|
||||
MemCopy(dst, src, count * sizeof(word));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianCopy (
|
||||
dword * dst,
|
||||
const dword src[],
|
||||
unsigned count
|
||||
) {
|
||||
MemCopy(dst, src, count * sizeof(dword));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianCopy (
|
||||
qword * dst,
|
||||
const qword src[],
|
||||
unsigned count
|
||||
) {
|
||||
MemCopy(dst, src, count * sizeof(qword));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline void EndianCopy (
|
||||
void * dst,
|
||||
const byte src[],
|
||||
unsigned elemCount,
|
||||
unsigned elemBytes
|
||||
) {
|
||||
MemCopy(dst, src, elemCount * elemBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // LITTLE_ENDIAN
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Big endian functions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef BIG_ENDIAN
|
||||
|
||||
//===========================================================================
|
||||
inline word Endian (word value) {
|
||||
return (value >> 8) | (value << 8);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline dword Endian (dword value) {
|
||||
return ((value) << 24) |
|
||||
((value & 0x0000ff00) << 8) |
|
||||
((value & 0x00ff0000) >> 8) |
|
||||
((value) >> 24);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline qword Endian (qword value) {
|
||||
return ((value) << 56) |
|
||||
((value & 0x000000000000ff00) << 40) |
|
||||
((value & 0x0000000000ff0000) << 24) |
|
||||
((value & 0x00000000ff000000) << 8) |
|
||||
((value & 0x000000ff00000000) >> 8) |
|
||||
((value & 0x0000ff0000000000) >> 24) |
|
||||
((value & 0x00ff000000000000) >> 40) |
|
||||
((value) >> 56);
|
||||
}
|
||||
|
||||
void EndianConvert (word * array, unsigned count);
|
||||
void EndianConvert (dword * array, unsigned count);
|
||||
void EndianConvert (qword * array, unsigned count);
|
||||
void EndianConvert (byte * data, unsigned elemCount, unsigned elemBytes);
|
||||
void EndianCopy (word * dst, const word src[], unsigned count);
|
||||
void EndianCopy (dword * dst, const dword src[], unsigned count);
|
||||
void EndianCopy (qword * dst, const dword src[], unsigned count);
|
||||
void EndianCopy (void * dst, const byte src[], unsigned elemCount, unsigned elemBytes);
|
||||
|
||||
#endif
|
94
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.cpp
Normal file
94
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*==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/pnUtHash.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CHashValue
|
||||
*
|
||||
***/
|
||||
|
||||
// These random values were generated by the radioactive decay based
|
||||
// random number generator at www.fourmilab.ch
|
||||
const dword CHashValue::s_hashTable[] = {
|
||||
0xe8fd2035, 0xaf1add63, 0x049fb872, 0xcf9bb8eb, 0xc30d2a72, 0x15efaec1, 0xd250c7d9, 0xaf3c60a8,
|
||||
0x17ae32ff, 0x4089cd9e, 0x91dd6936, 0x093f880d, 0x9608ae8f, 0x452c0e11, 0xb6840ffd, 0x3e36c913,
|
||||
0x393114fd, 0xa72556b2, 0x7c338fb7, 0x4e445027, 0x2864eace, 0x9b0a17d6, 0x108da74b, 0xf2c479c1,
|
||||
0x288a43ac, 0x241e8411, 0x12ace782, 0xfb015799, 0x8b4dd597, 0x97199bc0, 0x621f0cce, 0x1658553e,
|
||||
0x99697839, 0xe3efb551, 0xbc1a2625, 0x54583c22, 0x9693d685, 0x612f910a, 0x080ccee8, 0xd00a43c9,
|
||||
0x86e6984d, 0x793245cf, 0x5335afa0, 0xdb8734d8, 0xfe5ab506, 0x3aae2ec1, 0x0aac22a3, 0xf3cd2c16,
|
||||
0x3d3039d1, 0x070b576d, 0x3a624bff, 0x0e185383, 0x78316efa, 0xafbef9ad, 0x556130cc, 0x54813111,
|
||||
0xc0e59be8, 0x30010241, 0x2cfa9040, 0x5a039832, 0x68a8a31d, 0xac786303, 0xe81b7dea, 0x2e3d7f5a,
|
||||
0xabb30a5c, 0xab08fef0, 0xf88cdc9d, 0x962d8361, 0x82ae270c, 0xc45a6e9c, 0x506a3f62, 0xed7c8f10,
|
||||
0x64631545, 0xea26488a, 0xd39f06f7, 0xafa35b6b, 0xdd1f83fb, 0x60b57a99, 0x636373ee, 0x05e82732,
|
||||
0xb2eaf275, 0x4763208c, 0x49499166, 0x8e436c6a, 0x3a4f831a, 0x57b7c11e, 0xbd751298, 0x6217ffbc,
|
||||
0x789efe70, 0x91d695cc, 0xa7e9049e, 0x12b74cdb, 0x40a2d8e6, 0x4dd33013, 0x506ec265, 0x81b2a421,
|
||||
0xdf98bac4, 0x554e33d0, 0x514decf9, 0x4374274c, 0x70b09e64, 0xac951473, 0xd6bb35eb, 0xa65ed4cf,
|
||||
0x71f724ac, 0x91e8da43, 0xe386dcee, 0x45bc6b20, 0x08ddf47a, 0xadac9571, 0x44d3cddf, 0x535ace85,
|
||||
0x5ac801cc, 0x89e90941, 0xa0507200, 0xe4b2a9b2, 0x00922b39, 0x2848f374, 0xfbe97b80, 0x77ea2e00,
|
||||
0x05eea617, 0x2bf0baf7, 0x0c97f929, 0x4d3190c0, 0x31f58de0, 0x7cae5dc4, 0x39f33590, 0x9cd39b3f,
|
||||
0x98b0bf46, 0x393169f1, 0x9f8271da, 0x0b85462f, 0xb8b81857, 0xed66ce2c, 0x6f97f3bb, 0x87e8c7dd,
|
||||
0x55741d88, 0x9ccd43b8, 0xe537d98a, 0x64a28550, 0x165ba5bf, 0xe4229568, 0x1af7c624, 0x059b9f7a,
|
||||
0x38129d4a, 0x73dca9ba, 0xe0185118, 0x48560fdb, 0xb7d0ec6b, 0x1acd6d4b, 0x84ab7a10, 0xcd9bf830,
|
||||
0x539d6be2, 0xfdcb65f4, 0x183a4dd7, 0xc4425aa4, 0xa3934d5f, 0xf71b8023, 0x30c109f7, 0x512e5128,
|
||||
0x7decdea5, 0xd3aded88, 0x34288710, 0x0c07a16e, 0xec0299da, 0x1e738f1b, 0xd7b898e1, 0x1b7318fd,
|
||||
0x3b67392d, 0x60da77b3, 0x614d4804, 0xb854468a, 0x4dbfc9fd, 0x85185833, 0x56095260, 0xb85d0771,
|
||||
0xbfe579e7, 0x51ca011b, 0xcebd2983, 0x4d56cda1, 0x5ec08b9a, 0x6bf9aa6f, 0x7da1e2c0, 0x4499dd84,
|
||||
0x95ca5ba3, 0xd0f9e77b, 0x5d099253, 0xbe943272, 0x1a87fe96, 0x29584d77, 0x0344f269, 0x2bdafede,
|
||||
0x4ababc94, 0x7a06acb7, 0x0a4c1efe, 0x8699f00f, 0x0f74e313, 0x0469ac17, 0x80f17875, 0xa6aecf16,
|
||||
0x0d772a15, 0x60eb0850, 0xa852be33, 0xe1574793, 0x7847204c, 0x1cea62ac, 0xb5948e41, 0x0e574ae9,
|
||||
0xdeb24de3, 0xe6472a0b, 0xaaaaf355, 0xa271aeae, 0xf3d5d209, 0x4f8fa676, 0x25ff71c9, 0x3f38d7df,
|
||||
0x0a8cd458, 0x5c6ad602, 0x06d0c0ec, 0x0d84ac0f, 0xf3cc4a59, 0xd6f04d8c, 0x1b3c3229, 0xc8281f6d,
|
||||
0x9410dd7c, 0x502519d1, 0x4449a76a, 0x88ba67b6, 0x8f710894, 0x7b63230e, 0xc095db28, 0x155a4ac7,
|
||||
0x0d418a5d, 0xe2b69e59, 0xeab4ac50, 0x0de06aae, 0x60f272fa, 0x408aefd8, 0x01c3435a, 0x0880c1e3,
|
||||
0x4f23137b, 0x9dfd6434, 0xd1e25d94, 0xbad4c88a, 0x0746edf9, 0x8103a9aa, 0xc8c73617, 0xe0f2759a,
|
||||
0x00161c79, 0xd4545360, 0x1763cc5b, 0x296361fa, 0xbc35858d, 0xdaed5e93, 0x0b9d0aed, 0x01c45a64,
|
||||
};
|
||||
|
740
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.h
Normal file
740
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.h
Normal file
@ -0,0 +1,740 @@
|
||||
/*==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/pnUtHash.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTHASH_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTHASH_H
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
***/
|
||||
|
||||
// Define a field inside an object that is used to link it into a hash table
|
||||
#define HASHLINK(object) THashLink< object >
|
||||
|
||||
// Define a POINTER to a hash table, not a hash table
|
||||
#define HASHTABLE(object,key) THashTable< object, key >
|
||||
|
||||
// Define a hash table:
|
||||
// - starts with kSlotMinCount rows
|
||||
// - can grow to kDefaultSlotMaxCount rows
|
||||
// (hash table grows when a row contains more than kGrowOnListSize entries
|
||||
#define HASHTABLEDECL(object,key,link) THashTableDecl< object, key, offsetof(object,link), 0 >
|
||||
|
||||
// Define a hash table in situations when a forward reference prevents use of HASHTABLEDECL
|
||||
// - Size characteristics are identical to HASHTABLEDECL
|
||||
#define HASHTABLEDYN(object,key) THashTableDyn< object, key >
|
||||
|
||||
// Define a hash table with:
|
||||
// - starts with <size>
|
||||
// - row table never grows
|
||||
#define HASHTABLEDECLSIZE(object,key,link,size) THashTableDecl<object, key, offsetof(object,link), size >
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Forward declarations
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class THashLink;
|
||||
|
||||
template<class T>
|
||||
class TBaseHashTable;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashLink
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class THashLink {
|
||||
friend class TBaseHashTable<T>;
|
||||
|
||||
private:
|
||||
unsigned m_hash;
|
||||
LINK(T) m_linkToFull;
|
||||
LINK(T) m_linkToSlot;
|
||||
|
||||
public:
|
||||
inline bool IsLinked () const;
|
||||
inline T * Next ();
|
||||
inline const T * Next () const;
|
||||
inline T * Prev ();
|
||||
inline const T * Prev () const;
|
||||
inline void Unlink ();
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
bool THashLink<T>::IsLinked () const {
|
||||
return m_linkToFull.IsLinked();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * THashLink<T>::Next () {
|
||||
return m_linkToFull.Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * THashLink<T>::Next () const {
|
||||
return m_linkToFull.Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * THashLink<T>::Prev () {
|
||||
return m_linkToFull.Prev();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * THashLink<T>::Prev () const {
|
||||
return m_linkToFull.Prev();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void THashLink<T>::Unlink () {
|
||||
m_linkToFull.Unlink();
|
||||
m_linkToSlot.Unlink();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TBaseHashTable
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TBaseHashTable {
|
||||
|
||||
private:
|
||||
enum { kSlotMinCount = 8 };
|
||||
enum { kDefaultSlotMaxCount = 1024 };
|
||||
enum { kGrowOnListSize = 5 };
|
||||
|
||||
LIST(T) m_fullList;
|
||||
int m_linkOffset;
|
||||
FARRAYOBJ(LIST(T)) m_slotListArray;
|
||||
unsigned m_slotMask; // always set to a power of two minus one
|
||||
unsigned m_slotMaxCount;
|
||||
|
||||
inline bool CheckGrowTable (LIST(T) * slotList);
|
||||
inline const THashLink<T> & GetLink (const T * object) const;
|
||||
inline THashLink<T> & GetLink (T * object);
|
||||
inline void SetSlotCount (unsigned count);
|
||||
|
||||
protected:
|
||||
inline unsigned GetHash (const T * object) const;
|
||||
inline unsigned & GetHash (T * object);
|
||||
inline const LIST(T) & GetSlotList (unsigned hash) const;
|
||||
inline LIST(T) & GetSlotList (unsigned hash);
|
||||
inline void SetLinkOffset (int linkOffset, unsigned maxSize);
|
||||
inline void SetSlotMaxCount (unsigned count);
|
||||
|
||||
public:
|
||||
inline TBaseHashTable ();
|
||||
inline TBaseHashTable (const TBaseHashTable<T> & source);
|
||||
inline TBaseHashTable<T> & operator= (const TBaseHashTable<T> & source);
|
||||
|
||||
inline void Add (T * object, unsigned hash);
|
||||
inline void Clear ();
|
||||
inline void Delete (T * object);
|
||||
inline T * Head ();
|
||||
inline const T * Head () const;
|
||||
inline T * Next (const T * object);
|
||||
inline const T * Next (const T * object) const;
|
||||
inline void Order (T * linkedObject, ELinkType linkType, T * existingObject);
|
||||
inline T * Prev (const T * object);
|
||||
inline const T * Prev (const T * object) const;
|
||||
inline T * Tail ();
|
||||
inline const T * Tail () const;
|
||||
inline void Unlink (T * object);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
TBaseHashTable<T>::TBaseHashTable () {
|
||||
m_slotMask = 0;
|
||||
m_slotMaxCount = kDefaultSlotMaxCount;
|
||||
// more initialization done during call to SetLinkOffset()
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
TBaseHashTable<T>::TBaseHashTable (const TBaseHashTable<T> & source) {
|
||||
REF(source);
|
||||
#ifdef HS_DEBUGGING
|
||||
FATAL("No copy constructor");
|
||||
#endif
|
||||
TBaseHashTable();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
TBaseHashTable<T> & TBaseHashTable<T>::operator= (const TBaseHashTable<T> & source) {
|
||||
REF(source);
|
||||
#ifdef HS_DEBUGGING
|
||||
FATAL("No assignment operator");
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::Add (T * object, unsigned hash) {
|
||||
GetHash(object) = hash;
|
||||
|
||||
LIST(T) * list = &GetSlotList(hash);
|
||||
if (CheckGrowTable(list))
|
||||
list = &GetSlotList(hash);
|
||||
|
||||
m_fullList.Link(object);
|
||||
list->Link(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
bool TBaseHashTable<T>::CheckGrowTable (LIST(T) * list) {
|
||||
|
||||
unsigned nextCount = (m_slotMask + 1) * 2;
|
||||
if (nextCount > m_slotMaxCount)
|
||||
return false;
|
||||
|
||||
unsigned listCount = 0;
|
||||
for (T * curr = list->Head(); curr; curr = list->Next(curr))
|
||||
++listCount;
|
||||
|
||||
if (listCount + 1 < kGrowOnListSize)
|
||||
return false;
|
||||
|
||||
SetSlotCount(nextCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::Clear () {
|
||||
m_fullList.Clear();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::Delete (T * object) {
|
||||
DEL(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
unsigned TBaseHashTable<T>::GetHash (const T * object) const {
|
||||
return GetLink(object).m_hash;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
unsigned & TBaseHashTable<T>::GetHash (T * object) {
|
||||
return GetLink(object).m_hash;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const THashLink<T> & TBaseHashTable<T>::GetLink (const T * object) const {
|
||||
return *(const THashLink<T> *)((const byte *)object + m_linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
THashLink<T> & TBaseHashTable<T>::GetLink (T * object) {
|
||||
return *(THashLink<T> *)((byte *)object + m_linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const LIST(T) & TBaseHashTable<T>::GetSlotList (unsigned hash) const {
|
||||
return m_slotListArray[hash & m_slotMask];
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
LIST(T) & TBaseHashTable<T>::GetSlotList (unsigned hash) {
|
||||
return m_slotListArray[hash & m_slotMask];
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TBaseHashTable<T>::Head () {
|
||||
return m_fullList.Head();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TBaseHashTable<T>::Head () const {
|
||||
return m_fullList.Head();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TBaseHashTable<T>::Next (const T * object) {
|
||||
return m_fullList.Next(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TBaseHashTable<T>::Next (const T * object) const {
|
||||
return m_fullList.Next(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::Order (T * linkedObject, ELinkType linkType, T * existingObject) {
|
||||
THashLink<T> & link = GetLink(linkedObject);
|
||||
REF(link);
|
||||
ASSERT(link.m_linkToFull.IsLinked());
|
||||
m_fullList.Link(linkedObject, linkType, existingObject);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TBaseHashTable<T>::Prev (const T * object) {
|
||||
return m_fullList.Prev(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TBaseHashTable<T>::Prev (const T * object) const {
|
||||
return m_fullList.Prev(object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::SetLinkOffset (int linkOffset, unsigned maxSize) {
|
||||
ASSERT(!m_fullList.Head());
|
||||
ASSERT(!m_slotListArray.Count());
|
||||
ASSERT(!m_slotMask);
|
||||
|
||||
m_linkOffset = linkOffset;
|
||||
m_fullList.SetLinkOffset(m_linkOffset + offsetof(THashLink<T>, m_linkToFull));
|
||||
|
||||
if (!m_slotMask)
|
||||
SetSlotCount(max(kSlotMinCount, MathNextPow2(maxSize)));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::SetSlotCount (unsigned count) {
|
||||
ASSERT(!(count & (count - 1))); // power of two
|
||||
ASSERT(count >= 2);
|
||||
|
||||
if (count == m_slotMask + 1)
|
||||
return;
|
||||
m_slotMask = count - 1;
|
||||
|
||||
m_slotListArray.ZeroCount();
|
||||
m_slotListArray.SetCount(count);
|
||||
for (unsigned loop = 0; loop < count; ++loop)
|
||||
m_slotListArray[loop].SetLinkOffset(m_linkOffset + offsetof(THashLink<T>, m_linkToSlot));
|
||||
|
||||
for (T * curr = Head(); curr; curr = Next(curr))
|
||||
GetSlotList(GetHash(curr)).Link(curr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::SetSlotMaxCount (unsigned count) {
|
||||
if (count)
|
||||
m_slotMaxCount = max(kSlotMinCount, count);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TBaseHashTable<T>::Tail () {
|
||||
return m_fullList.Tail();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TBaseHashTable<T>::Tail () const {
|
||||
return m_fullList.Tail();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TBaseHashTable<T>::Unlink (T * object) {
|
||||
THashLink<T> & link = GetLink(object);
|
||||
link.Unlink();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashTable
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T, class K>
|
||||
class THashTable : public TBaseHashTable<T> {
|
||||
|
||||
public:
|
||||
inline void Add (T * object);
|
||||
inline void Add (T * object, unsigned hash);
|
||||
inline T * Find (const K & key);
|
||||
inline T * FindNext (const K & key, T * object);
|
||||
inline const T * Find (const K & key) const;
|
||||
inline const T * FindNext (const K & key, const T * object) const;
|
||||
inline T * Unduplicate (T * object, const K & key);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
inline void THashTable<T,K>::Add (T * object) {
|
||||
TBaseHashTable<T>::Add(object, object->GetHash());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
inline void THashTable<T,K>::Add (T * object, unsigned hash) {
|
||||
TBaseHashTable<T>::Add(object, hash);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
T * THashTable<T,K>::Find (const K & key) {
|
||||
return (T *)((const THashTable<T,K> *)this)->Find(key);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
T * THashTable<T,K>::FindNext (const K & key, T * object) {
|
||||
return (T *)((const THashTable<T,K> *)this)->FindNext(key, object);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
const T * THashTable<T,K>::Find (const K & key) const {
|
||||
unsigned hash = key.GetHash();
|
||||
const LIST(T) & slotList = GetSlotList(hash);
|
||||
for (const T * curr = slotList.Head(); curr; curr = slotList.Next(curr))
|
||||
if ((GetHash(curr) == hash) && (*curr == key))
|
||||
return curr;
|
||||
return nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
const T * THashTable<T,K>::FindNext (const K & key, const T * object) const {
|
||||
unsigned hash = key.GetHash();
|
||||
const LIST(T) & slotList = GetSlotList(hash);
|
||||
for (const T * curr = slotList.Next(object); curr; curr = slotList.Next(curr))
|
||||
if ((GetHash(curr) == hash) && (*curr == key))
|
||||
return curr;
|
||||
return nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
T * THashTable<T,K>::Unduplicate (T * object, const K & key) {
|
||||
T * existing = Find(key);
|
||||
if (existing) {
|
||||
DEL(object);
|
||||
return existing;
|
||||
}
|
||||
else {
|
||||
Add(object);
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashTableDecl
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T, class K, int linkOffset, unsigned maxSize>
|
||||
class THashTableDecl : public THashTable<T,K> {
|
||||
|
||||
public:
|
||||
inline THashTableDecl ();
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K, int linkOffset, unsigned maxSize>
|
||||
THashTableDecl<T,K,linkOffset,maxSize>::THashTableDecl () {
|
||||
SetLinkOffset(linkOffset, maxSize);
|
||||
SetSlotMaxCount(maxSize);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashTableDyn
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T, class K>
|
||||
class THashTableDyn : public THashTable<T,K> {
|
||||
|
||||
public:
|
||||
void Initialize (int linkOffset, unsigned maxSize = 0);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T, class K>
|
||||
void THashTableDyn<T,K>::Initialize (int linkOffset, unsigned maxSize) {
|
||||
SetLinkOffset(linkOffset, maxSize);
|
||||
SetSlotMaxCount(maxSize);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashKeyVal
|
||||
*
|
||||
***/
|
||||
|
||||
template <class T>
|
||||
class THashKeyVal {
|
||||
public:
|
||||
THashKeyVal () : m_value(0) { }
|
||||
THashKeyVal (const T & value) : m_value(value) { }
|
||||
bool operator== (const THashKeyVal & rhs) const {
|
||||
return m_value == rhs.m_value;
|
||||
}
|
||||
unsigned GetHash () const {
|
||||
CHashValue hash(&m_value, sizeof(m_value));
|
||||
return hash.GetHash();
|
||||
}
|
||||
const T & GetValue () const { return m_value; }
|
||||
void SetValue (const T & value) { m_value = value; }
|
||||
|
||||
protected:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CHashKeyStrPtr / CHashKeyStrPtrI
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
template<class C>
|
||||
class THashKeyStrBase {
|
||||
public:
|
||||
const C * GetString () const {
|
||||
return m_str;
|
||||
}
|
||||
|
||||
protected:
|
||||
THashKeyStrBase () : m_str(nil) { }
|
||||
THashKeyStrBase (const C str[]) : m_str(str) { }
|
||||
virtual ~THashKeyStrBase () { }
|
||||
|
||||
const C * m_str;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class C>
|
||||
class THashKeyStrCmp : public THashKeyStrBase<C> {
|
||||
public:
|
||||
bool operator== (const THashKeyStrCmp & rhs) const {
|
||||
return StrCmp(m_str, rhs.m_str) == 0;
|
||||
}
|
||||
unsigned GetHash () const {
|
||||
return StrHash(m_str);
|
||||
}
|
||||
|
||||
protected:
|
||||
THashKeyStrCmp () { }
|
||||
THashKeyStrCmp (const C str[]) : THashKeyStrBase<C>(str) { }
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class C>
|
||||
class THashKeyStrCmpI : public THashKeyStrBase<C> {
|
||||
public:
|
||||
bool operator== (const THashKeyStrCmpI & rhs) const {
|
||||
return StrCmpI(m_str, rhs.m_str) == 0;
|
||||
}
|
||||
unsigned GetHash () const {
|
||||
return StrHashI(m_str);
|
||||
}
|
||||
protected:
|
||||
|
||||
THashKeyStrCmpI () { }
|
||||
THashKeyStrCmpI (const C str[]) : THashKeyStrBase<C>(str) { }
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashKeyStrPtr
|
||||
*
|
||||
***/
|
||||
|
||||
template <class C, class T>
|
||||
class THashKeyStrPtr : public T {
|
||||
public:
|
||||
THashKeyStrPtr () { }
|
||||
THashKeyStrPtr (const C str[]) : T(str) { }
|
||||
void SetString (const C str[]) {
|
||||
m_str = str;
|
||||
}
|
||||
};
|
||||
|
||||
typedef THashKeyStrPtr< wchar, THashKeyStrCmp<wchar> > CHashKeyStrPtr;
|
||||
typedef THashKeyStrPtr< wchar, THashKeyStrCmpI<wchar> > CHashKeyStrPtrI;
|
||||
typedef THashKeyStrPtr< char, THashKeyStrCmp<char> > CHashKeyStrPtrChar;
|
||||
typedef THashKeyStrPtr< char, THashKeyStrCmpI<char> > CHashKeyStrPtrCharI;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* THashKeyStr
|
||||
*
|
||||
***/
|
||||
|
||||
template <class C, class T>
|
||||
class THashKeyStr : public T {
|
||||
public:
|
||||
THashKeyStr () { }
|
||||
THashKeyStr (const C str[]) { SetString(str); }
|
||||
THashKeyStr (const THashKeyStr &); // intentionally unimplemented
|
||||
THashKeyStr & operator= (const THashKeyStr &); // intentionally unimplemented
|
||||
~THashKeyStr () {
|
||||
SetString(nil);
|
||||
}
|
||||
void SetString (const C str[]) { // deprecated
|
||||
if (m_str)
|
||||
FREE(const_cast<C *>(m_str));
|
||||
if (str)
|
||||
m_str = StrDup(str);
|
||||
else
|
||||
m_str = nil;
|
||||
}
|
||||
};
|
||||
|
||||
typedef THashKeyStr< wchar, THashKeyStrCmp<wchar> > CHashKeyStr;
|
||||
typedef THashKeyStr< wchar, THashKeyStrCmpI<wchar> > CHashKeyStrI;
|
||||
typedef THashKeyStr< char, THashKeyStrCmp<char> > CHashKeyStrChar;
|
||||
typedef THashKeyStr< char, THashKeyStrCmpI<char> > CHashKeyStrCharI;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CHashValue
|
||||
*
|
||||
***/
|
||||
|
||||
class CHashValue {
|
||||
private:
|
||||
static const dword s_hashTable[];
|
||||
|
||||
dword m_result;
|
||||
|
||||
inline void Construct () { m_result = 0x325d1eae; }
|
||||
|
||||
public:
|
||||
static dword LookupHashBits (unsigned value) { ASSERT(value < 0x100); return s_hashTable[value]; }
|
||||
|
||||
inline CHashValue () { Construct() ; }
|
||||
inline CHashValue (const CHashValue & source) { m_result = source.m_result; }
|
||||
inline CHashValue (const void * data, unsigned bytes) { Construct(); Hash(data, bytes); }
|
||||
inline CHashValue & operator= (const CHashValue & source) { m_result = source.m_result; return *this; }
|
||||
inline bool operator== (const CHashValue & source) const { return (m_result == source.m_result); }
|
||||
|
||||
inline dword GetHash () const { return m_result; }
|
||||
|
||||
__forceinline void Hash (const void * data, unsigned bytes);
|
||||
__forceinline void Hash8 (unsigned data);
|
||||
__forceinline void Hash16 (unsigned data);
|
||||
__forceinline void Hash32 (unsigned data);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
void CHashValue::Hash (const void * data, unsigned bytes) {
|
||||
for (const byte * curr = (const byte *)data, * term = curr + bytes; curr != term; ++curr)
|
||||
Hash8(*curr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CHashValue::Hash8 (unsigned data) {
|
||||
m_result += s_hashTable[m_result >> 24] ^ (m_result >> 6) ^ s_hashTable[data & 0xff];
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CHashValue::Hash16 (unsigned data) {
|
||||
Hash8(data);
|
||||
Hash8(data >> 8);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CHashValue::Hash32 (unsigned data) {
|
||||
Hash8(data);
|
||||
Hash8(data >> 8);
|
||||
Hash8(data >> 16);
|
||||
Hash8(data >> 24);
|
||||
}
|
129
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.cpp
Normal file
129
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*==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/pnUtList.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CBaseList
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
void CBaseList::Link (CBaseList * list, byte * afterNode, byte * beforeNode, ELinkType linkType, byte * existingNode) {
|
||||
|
||||
// Verify that the two lists share a common link offset
|
||||
ASSERT(m_linkOffset != LINK_OFFSET_UNINIT);
|
||||
ASSERT(m_linkOffset == list->m_linkOffset);
|
||||
|
||||
// Verify that the two lists are distinct
|
||||
CBaseLink * sourceTerminator = &list->m_terminator;
|
||||
ASSERT(sourceTerminator != &m_terminator);
|
||||
|
||||
// Find the first and last nodes to move from the source list
|
||||
CBaseLink * afterLink = afterNode ? GetLink(afterNode) : sourceTerminator;
|
||||
CBaseLink * beforeLink = beforeNode ? GetLink(beforeNode) : sourceTerminator;
|
||||
CBaseLink * firstLink = afterLink->NextLink();
|
||||
CBaseLink * lastLink = beforeLink->m_prevLink;
|
||||
if (lastLink == afterLink)
|
||||
return;
|
||||
ASSERT(firstLink != beforeLink);
|
||||
|
||||
// Store nodes for later use in linking
|
||||
byte * firstNode = afterLink->m_next;
|
||||
byte * lastNextNode = lastLink->m_next;
|
||||
ASSERT(firstNode);
|
||||
ASSERT(lastNextNode);
|
||||
|
||||
// Find the previous and next nodes in the destination list which will
|
||||
// bound all of the nodes of the source list
|
||||
CBaseLink * existingLink = existingNode ? GetLink(existingNode) : &m_terminator;
|
||||
CBaseLink * prevLink, * nextLink;
|
||||
switch (linkType) {
|
||||
|
||||
case kListLinkAfter:
|
||||
prevLink = existingLink;
|
||||
nextLink = existingLink->NextLink();
|
||||
break;
|
||||
|
||||
case kListLinkBefore:
|
||||
prevLink = existingLink->m_prevLink;
|
||||
nextLink = existingLink;
|
||||
break;
|
||||
|
||||
DEFAULT_FATAL(linkType);
|
||||
|
||||
}
|
||||
|
||||
// Update the first and last nodes of the moved range to point to the
|
||||
// previous and next nodes in the destination list
|
||||
firstLink->m_prevLink = prevLink;
|
||||
lastLink->m_next = prevLink->m_next;
|
||||
|
||||
// Update the previous and next nodes in the destination list to point to
|
||||
// the first and last nodes of the source range
|
||||
nextLink->m_prevLink = lastLink;
|
||||
prevLink->m_next = firstNode;
|
||||
|
||||
// Update the before and after links from the source list to point to
|
||||
// each other
|
||||
afterLink->m_next = lastNextNode;
|
||||
beforeLink->m_prevLink = afterLink;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseList::UnlinkAll () {
|
||||
for (CBaseLink * link = m_terminator.m_prevLink, * prev; link != &m_terminator; link = prev) {
|
||||
prev = link->m_prevLink;
|
||||
link->InitializeLinksWithOffset(m_linkOffset);
|
||||
}
|
||||
m_terminator.InitializeLinksWithOffset(m_linkOffset);
|
||||
}
|
||||
|
650
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.h
Normal file
650
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.h
Normal file
@ -0,0 +1,650 @@
|
||||
/*==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/pnUtList.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTLIST_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtList.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTLIST_H
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
***/
|
||||
|
||||
enum ELinkType {
|
||||
kListUnlinked,
|
||||
kListLinkAfter,
|
||||
kListLinkBefore,
|
||||
kListHead = kListLinkAfter,
|
||||
kListTail = kListLinkBefore
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
***/
|
||||
|
||||
#define LINK(class) TLink< class >
|
||||
#define LIST(class) TList< class >
|
||||
#define LISTDECL(class,field) TListDecl< class, offsetof(class,field) >
|
||||
#define LISTDYN(class) TListDyn< class >
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Forward declarations
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TLink;
|
||||
|
||||
template<class T>
|
||||
class TList;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CBaseLink
|
||||
*
|
||||
***/
|
||||
|
||||
class CBaseLink {
|
||||
friend class CBaseList;
|
||||
|
||||
inline static bool TermCheck (byte * ptr);
|
||||
inline static byte * TermMark (byte * ptr);
|
||||
inline static byte * TermUnmarkAlways (byte * ptr);
|
||||
|
||||
protected:
|
||||
CBaseLink * volatile m_prevLink;
|
||||
byte * volatile m_next;
|
||||
|
||||
inline int CalcLinkOffset () const;
|
||||
inline void InitializeLinks ();
|
||||
inline void InitializeLinksWithOffset (int linkOffset);
|
||||
inline void InsertAfter (byte * node, CBaseLink * prevLink, int linkOffset);
|
||||
inline void InsertBefore (byte * node, CBaseLink * nextLink);
|
||||
inline byte * Next () const;
|
||||
inline byte * NextIgnoreTerm () const;
|
||||
inline byte * NextUnchecked () const;
|
||||
inline CBaseLink * NextLink () const;
|
||||
inline CBaseLink * NextLink (int linkOffset) const;
|
||||
inline byte * Prev () const;
|
||||
inline void UnlinkFromNeighbors ();
|
||||
|
||||
public:
|
||||
inline CBaseLink ();
|
||||
inline CBaseLink (const CBaseLink & source);
|
||||
inline ~CBaseLink ();
|
||||
inline CBaseLink & operator= (const CBaseLink & source);
|
||||
inline bool IsLinked () const;
|
||||
inline void Unlink ();
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink::CBaseLink () {
|
||||
InitializeLinks();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink::CBaseLink (const CBaseLink & source) {
|
||||
REF(source);
|
||||
#ifdef HS_DEBUGGING
|
||||
if (source.IsLinked())
|
||||
FATAL("No copy constructor");
|
||||
#endif
|
||||
InitializeLinks();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink::~CBaseLink () {
|
||||
UnlinkFromNeighbors();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink & CBaseLink::operator= (const CBaseLink & source) {
|
||||
REF(source);
|
||||
#ifdef HS_DEBUGGING
|
||||
FATAL("No assignment operator");
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int CBaseLink::CalcLinkOffset () const {
|
||||
return (int)((byte *)this - m_prevLink->NextIgnoreTerm());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::InitializeLinks () {
|
||||
ASSERT(!((unsigned_ptr)this & 3));
|
||||
m_prevLink = this;
|
||||
m_next = TermMark((byte *)this);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::InitializeLinksWithOffset (int linkOffset) {
|
||||
m_prevLink = this;
|
||||
m_next = TermMark((byte *)this - linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::InsertAfter (byte * node, CBaseLink * prevLink, int linkOffset) {
|
||||
UnlinkFromNeighbors();
|
||||
m_prevLink = prevLink;
|
||||
m_next = prevLink->m_next;
|
||||
prevLink->NextLink(linkOffset)->m_prevLink = this;
|
||||
prevLink->m_next = node;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::InsertBefore (byte * node, CBaseLink * nextLink) {
|
||||
UnlinkFromNeighbors();
|
||||
m_prevLink = nextLink->m_prevLink;
|
||||
m_next = m_prevLink->m_next;
|
||||
nextLink->m_prevLink->m_next = node;
|
||||
nextLink->m_prevLink = this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CBaseLink::IsLinked () const {
|
||||
return (m_prevLink != this);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::Next () const {
|
||||
return TermCheck(m_next) ? nil : m_next;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::NextIgnoreTerm () const {
|
||||
return TermUnmarkAlways(m_next);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::NextUnchecked () const {
|
||||
return m_next;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink * CBaseLink::NextLink () const {
|
||||
return (CBaseLink *)(NextIgnoreTerm() + CalcLinkOffset());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink * CBaseLink::NextLink (int linkOffset) const {
|
||||
ASSERT(linkOffset == CalcLinkOffset());
|
||||
return (CBaseLink *)(NextIgnoreTerm() + linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::Prev () const {
|
||||
return m_prevLink->m_prevLink->Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CBaseLink::TermCheck (byte * ptr) {
|
||||
return (unsigned_ptr)ptr & 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::TermMark (byte * ptr) {
|
||||
// Converts an unmarked pointer to a marked pointer
|
||||
ASSERT(!TermCheck(ptr));
|
||||
return (byte *)((unsigned_ptr)ptr + 1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseLink::TermUnmarkAlways (byte * ptr) {
|
||||
// Returns an unmarked pointer regardless of whether the source pointer
|
||||
// was marked on unmarked
|
||||
return (byte *)((unsigned_ptr)ptr & ~1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::Unlink () {
|
||||
UnlinkFromNeighbors();
|
||||
InitializeLinks();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseLink::UnlinkFromNeighbors () {
|
||||
NextLink()->m_prevLink = m_prevLink;
|
||||
m_prevLink->m_next = m_next;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TLink
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TLink : public CBaseLink {
|
||||
|
||||
public:
|
||||
inline T * Next ();
|
||||
inline const T * Next () const;
|
||||
inline T * NextUnchecked ();
|
||||
inline const T * NextUnchecked () const;
|
||||
inline T * Prev ();
|
||||
inline const T * Prev () const;
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TLink<T>::Next () {
|
||||
return (T *)CBaseLink::Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TLink<T>::Next () const {
|
||||
return (const T *)CBaseLink::Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TLink<T>::NextUnchecked () {
|
||||
return (T *)CBaseLink::NextUnchecked();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TLink<T>::NextUnchecked () const {
|
||||
return (const T *)CBaseLink::NextUnchecked();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TLink<T>::Prev () {
|
||||
return (T *)CBaseLink::Prev();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TLink<T>::Prev () const {
|
||||
return (const T *)CBaseLink::Prev();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CBaseList
|
||||
*
|
||||
***/
|
||||
|
||||
class CBaseList {
|
||||
|
||||
private:
|
||||
enum { LINK_OFFSET_UNINIT = 0xDDDDDDDD };
|
||||
|
||||
int m_linkOffset;
|
||||
CBaseLink m_terminator;
|
||||
|
||||
protected:
|
||||
inline CBaseLink * GetLink (const byte * node) const;
|
||||
inline byte * Head () const;
|
||||
inline bool IsLinked (const byte * node) const;
|
||||
inline void Link (byte * node, ELinkType linkType, byte * existingNode);
|
||||
void Link (CBaseList * list, byte * afterNode, byte * beforeNode, ELinkType linkType, byte * existingNode);
|
||||
inline byte * Next (const byte * node) const;
|
||||
inline byte * NextUnchecked (const byte * node) const;
|
||||
inline byte * Prev (byte * node) const;
|
||||
inline byte * Tail () const;
|
||||
inline void Unlink (byte * node);
|
||||
|
||||
public:
|
||||
inline CBaseList ();
|
||||
inline CBaseList (const CBaseList & source);
|
||||
inline ~CBaseList ();
|
||||
inline CBaseList & operator= (const CBaseList & source);
|
||||
inline void SetLinkOffset (int linkOffset);
|
||||
void UnlinkAll ();
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
CBaseList::CBaseList () {
|
||||
m_linkOffset = LINK_OFFSET_UNINIT;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseList::CBaseList (const CBaseList & source) {
|
||||
m_linkOffset = LINK_OFFSET_UNINIT;
|
||||
REF(source);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseList::~CBaseList () {
|
||||
if (m_terminator.IsLinked())
|
||||
UnlinkAll();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseList & CBaseList::operator= (const CBaseList & source) {
|
||||
REF(source);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
CBaseLink * CBaseList::GetLink (const byte * node) const {
|
||||
return (CBaseLink *)(node + m_linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseList::Head () const {
|
||||
return m_terminator.Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool CBaseList::IsLinked (const byte * node) const {
|
||||
ASSERT(node);
|
||||
return GetLink(node)->IsLinked();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseList::Link (byte * node, ELinkType linkType, byte * existingNode) {
|
||||
ASSERT(node != existingNode);
|
||||
ASSERT(m_linkOffset != LINK_OFFSET_UNINIT);
|
||||
ASSERT((linkType == kListLinkAfter) || (linkType == kListLinkBefore));
|
||||
if (linkType == kListLinkAfter)
|
||||
GetLink(node)->InsertAfter(node, existingNode ? GetLink(existingNode) : &m_terminator, m_linkOffset);
|
||||
else
|
||||
GetLink(node)->InsertBefore(node, existingNode ? GetLink(existingNode) : &m_terminator);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseList::Next (const byte * node) const {
|
||||
ASSERT(node);
|
||||
return GetLink(node)->Next();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseList::NextUnchecked (const byte * node) const {
|
||||
ASSERT(node);
|
||||
return GetLink(node)->NextUnchecked();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseList::Prev (byte * node) const {
|
||||
ASSERT(node);
|
||||
return GetLink(node)->Prev();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseList::SetLinkOffset (int linkOffset) {
|
||||
ASSERT(!Head());
|
||||
|
||||
m_linkOffset = linkOffset;
|
||||
m_terminator.InitializeLinksWithOffset(linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
byte * CBaseList::Tail () const {
|
||||
return m_terminator.Prev();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseList::Unlink (byte * node) {
|
||||
ASSERT(node);
|
||||
GetLink(node)->Unlink();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TList
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TList : public CBaseList {
|
||||
|
||||
private:
|
||||
inline T * NewFlags (unsigned flags, ELinkType linkType, T * existingNode, const char file[], int line);
|
||||
|
||||
public:
|
||||
inline void Clear ();
|
||||
inline void Delete (T * node);
|
||||
inline T * Head ();
|
||||
inline const T * Head () const;
|
||||
inline bool IsLinked (const T * node) const;
|
||||
inline void Link (T * node, ELinkType linkType = kListTail, T * existingNode = nil);
|
||||
inline void Link (TList<T> * list, ELinkType linkType = kListTail, T * existingNode = nil);
|
||||
inline void Link (TList<T> * list, T * afterNode, T * beforeNode, ELinkType linkType = kListTail, T * existingNode = nil);
|
||||
inline T * New (ELinkType linkType = kListTail, T * existingNode = nil, const char file[] = nil, int line = 0);
|
||||
inline T * NewZero (ELinkType linkType = kListTail, T * existingNode = nil, const char file[] = nil, int line = 0);
|
||||
inline T * Next (const T * node);
|
||||
inline const T * Next (const T * node) const;
|
||||
inline T * NextUnchecked (const T * node);
|
||||
inline const T * NextUnchecked (const T * node) const;
|
||||
inline T * Prev (const T * node);
|
||||
inline const T * Prev (const T * node) const;
|
||||
inline T * Tail ();
|
||||
inline const T * Tail () const;
|
||||
inline void Unlink (T * node);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TList<T>::Clear () {
|
||||
for (T * curr; (curr = Head()) != nil; Delete(curr))
|
||||
;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TList<T>::Delete (T * node) {
|
||||
DEL(node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TList<T>::Head () {
|
||||
return (T *)CBaseList::Head();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
const T * TList<T>::Head () const {
|
||||
return (const T *)CBaseList::Head();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
bool TList<T>::IsLinked (const T * node) const {
|
||||
return CBaseList::IsLinked((const byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TList<T>::Link (T * node, ELinkType linkType, T * existingNode) {
|
||||
CBaseList::Link((byte *)node, linkType, (byte *)existingNode);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TList<T>::Link (TList<T> * list, ELinkType linkType, T * existingNode) {
|
||||
CBaseList::Link(list, nil, nil, linkType, (byte *)existingNode);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TList<T>::Link (TList<T> * list, T * afterNode, T * beforeNode, ELinkType linkType, T * existingNode) {
|
||||
CBaseList::Link(list, (byte *)afterNode, (byte *)beforeNode, linkType, (byte *)existingNode);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::Next (const T * node) {
|
||||
return (T *)CBaseList::Next((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline const T * TList<T>::Next (const T * node) const {
|
||||
return (const T *)CBaseList::Next((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::NextUnchecked (const T * node) {
|
||||
return (T *)CBaseList::NextUnchecked((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline const T * TList<T>::NextUnchecked (const T * node) const {
|
||||
return (const T *)CBaseList::NextUnchecked((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::New (ELinkType linkType, T * existingNode, const char file[], int line) {
|
||||
return NewFlags(0, linkType, existingNode, file, line);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::NewFlags (unsigned flags, ELinkType linkType, T * existingNode, const char file[], int line) {
|
||||
if (!file) {
|
||||
file = __FILE__;
|
||||
line = __LINE__;
|
||||
}
|
||||
T * node = new(MemAlloc(sizeof(T), flags, file, line)) T;
|
||||
if (linkType != kListUnlinked)
|
||||
Link(node, linkType, existingNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::NewZero (ELinkType linkType, T * existingNode, const char file[], int line) {
|
||||
return NewFlags(MEM_ZERO, linkType, existingNode, file, line);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::Prev (const T * node) {
|
||||
return (T *)CBaseList::Prev((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline const T * TList<T>::Prev (const T * node) const {
|
||||
return (const T *)CBaseList::Prev((byte *)node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline T * TList<T>::Tail () {
|
||||
return (T *)CBaseList::Tail();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline const T * TList<T>::Tail () const {
|
||||
return (const T *)CBaseList::Tail();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
inline void TList<T>::Unlink (T * node) {
|
||||
CBaseList::Unlink((byte *)node);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TListDecl
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T, int linkOffset>
|
||||
class TListDecl : public TList<T> {
|
||||
|
||||
public:
|
||||
inline TListDecl ();
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T, int linkOffset>
|
||||
TListDecl<T,linkOffset>::TListDecl () {
|
||||
SetLinkOffset(linkOffset);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TListDyn
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TListDyn : public TList<T> {
|
||||
|
||||
public:
|
||||
void Initialize (int linkOffset);
|
||||
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TListDyn<T>::Initialize (int linkOffset) {
|
||||
SetLinkOffset(linkOffset);
|
||||
}
|
97
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMath.cpp
Normal file
97
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMath.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*==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/pnUtMath.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exported bit manipulation functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
#ifndef _M_IX86
|
||||
|
||||
unsigned MathHighBitPos (dword val) {
|
||||
ASSERT(val);
|
||||
double f = (double)val;
|
||||
return (*((dword *)&f + 1) >> 20) - 1023;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
__declspec(naked) unsigned __fastcall MathHighBitPos (dword) {
|
||||
__asm {
|
||||
bsr eax, ecx
|
||||
ret 0
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
#ifndef _M_IX86
|
||||
|
||||
unsigned MathLowBitPos (dword val) {
|
||||
val &= ~(val - 1); // clear all but the low bit
|
||||
ASSERT(val);
|
||||
double f = (double)val;
|
||||
return (*((dword *)&f + 1) >> 20) - 1023;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
__declspec(naked) unsigned __fastcall MathLowBitPos (dword) {
|
||||
__asm {
|
||||
bsf eax, ecx
|
||||
ret 0
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
116
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMath.h
Normal file
116
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMath.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*==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/pnUtMath.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMATH_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMath.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMATH_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Calling conventions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef _M_IX86
|
||||
#define MATHCALL __fastcall
|
||||
#else
|
||||
#define MATHCALL
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Bit manipulation functions
|
||||
*
|
||||
***/
|
||||
|
||||
unsigned MATHCALL MathLowBitPos (dword val);
|
||||
unsigned MATHCALL MathHighBitPos (dword val);
|
||||
|
||||
//===========================================================================
|
||||
inline unsigned MathBitCount (dword val) {
|
||||
val = val - ((val >> 1) & 033333333333) - ((val >> 2) & 011111111111);
|
||||
val = ((val + (val >> 3)) & 030707070707);
|
||||
val = val + (val >> 6);
|
||||
val = (val + (val >> 12) + (val >> 24)) & 077;
|
||||
return val;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline unsigned MathBitMaskCreate (unsigned count) {
|
||||
ASSERT(count <= 8 * sizeof(unsigned));
|
||||
return count ? ((2 << (count - 1)) - 1) : 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline dword MathHighBitValue (dword val) {
|
||||
return val ? 1 << MathHighBitPos(val) : 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline bool MathIsPow2 (unsigned val) {
|
||||
return !(val & (val - 1));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline unsigned MathLowBitValue (unsigned val) {
|
||||
return val & ~(val - 1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline unsigned MathNextMultiplePow2 (unsigned val, unsigned multiple) {
|
||||
ASSERT(multiple);
|
||||
ASSERT(MathIsPow2(multiple));
|
||||
return (val + (multiple - 1)) & ~(multiple - 1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline dword MathNextPow2 (dword val) {
|
||||
return MathIsPow2(val) ? val : 1 << (MathHighBitPos(val) + 1);
|
||||
}
|
92
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.cpp
Normal file
92
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*==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/pnUtMisc.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private data
|
||||
*
|
||||
***/
|
||||
|
||||
static void * s_moduleInstance;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Public functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void ModuleSetInstance (void * instance) {
|
||||
s_moduleInstance = instance;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void * ModuleGetInstance () {
|
||||
return s_moduleInstance;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Dll initialization
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
BOOL WINAPI PreDllMain (HANDLE handle, DWORD reason, LPVOID) {
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
ModuleSetInstance(handle);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
166
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.h
Normal file
166
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.h
Normal file
@ -0,0 +1,166 @@
|
||||
/*==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/pnUtMisc.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMISC_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMISC_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
***/
|
||||
|
||||
const wchar UNICODE_BOM = 0xfeff; // Unicode byte-order mark
|
||||
const char UTF8_BOM[] = "\xef\xbb\xbf";
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Module instance functions
|
||||
*
|
||||
***/
|
||||
|
||||
void ModuleSetInstance (void * instance);
|
||||
void * ModuleGetInstance ();
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Command line functions
|
||||
*
|
||||
***/
|
||||
|
||||
const wchar * AppGetCommandLine ();
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* System info functions
|
||||
*
|
||||
***/
|
||||
void MachineGetName (wchar * computerName, unsigned length = 32);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Misc types
|
||||
*
|
||||
***/
|
||||
|
||||
// used to dump the internal state of a module
|
||||
typedef void (__cdecl * FStateDump)(
|
||||
void * param,
|
||||
const wchar fmt[],
|
||||
...
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Dll initialization
|
||||
*
|
||||
***/
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
#define SRV_MODULE_PRE_INIT() \
|
||||
extern BOOL WINAPI PreDllMain (HANDLE handle, DWORD reason, LPVOID); \
|
||||
extern "C" BOOL (WINAPI *_pRawDllMain)(HANDLE, DWORD, LPVOID) = PreDllMain
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* System status
|
||||
*
|
||||
***/
|
||||
|
||||
struct MemoryStatus {
|
||||
unsigned totalPhysMB; // total physical memory
|
||||
unsigned availPhysMB; // free physical memory
|
||||
unsigned totalPageFileMB; // total page file size
|
||||
unsigned availPageFileMB; // free page file size
|
||||
unsigned totalVirtualMB; // total virtual address space for calling process
|
||||
unsigned availVirtualMB; // available virtual address space for calling process
|
||||
unsigned memoryLoad; // 0..100
|
||||
};
|
||||
void MemoryGetStatus (MemoryStatus * status);
|
||||
|
||||
struct DiskStatus {
|
||||
wchar name[16];
|
||||
unsigned totalSpaceMB;
|
||||
unsigned freeSpaceMB;
|
||||
};
|
||||
|
||||
void DiskGetStatus (ARRAY(DiskStatus) * disks);
|
||||
|
||||
|
||||
void CpuGetInfo (
|
||||
word * cpuCaps,
|
||||
dword * cpuVendor,
|
||||
word * cpuSignature
|
||||
);
|
||||
|
||||
// CPU capability flags
|
||||
const unsigned kCpuCap3dNow = 1<<0;
|
||||
const unsigned kCpuCapCmov = 1<<1; // conditional move
|
||||
const unsigned kCpuCapEst = 1<<2; // enhanced speed step
|
||||
const unsigned kCpuCapHtt = 1<<3; // hyperthreading
|
||||
const unsigned kCpuCapMmx = 1<<4; // multimedia extensions
|
||||
const unsigned kCpuCapPsn = 1<<5; // processor serial number
|
||||
const unsigned kCpuCapSse = 1<<6; // streaming SIMD extensions
|
||||
const unsigned kCpuCapSse2 = 1<<7;
|
||||
const unsigned kCpuCapSse3 = 1<<8;
|
||||
const unsigned kCpuCapTsc = 1<<9; // time stamp counter
|
||||
|
||||
// Macros for packing and unpacking CPU signature
|
||||
#define CPU_SIGNATURE(family, model, stepping) ((stepping) | (model << 4) | (family << 8))
|
||||
#define CPU_SIGNATURE_FAMILY(sig) ((sig >> 8) & 0xf)
|
||||
#define CPU_SIGNATURE_MODEL(sig) ((sig >> 4) & 0xf)
|
||||
#define CPU_SIGNATURE_STEPPING(sig) (sig & 0xf)
|
290
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.cpp
Normal file
290
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
/*==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/pnUtPath.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Exported functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
void PathGetProgramDirectory (
|
||||
wchar *dst,
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
PathGetProgramName(dst, dstChars);
|
||||
PathRemoveFilename(dst, dst, dstChars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathAddFilename (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
const wchar fname[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar temp[MAX_PATH];
|
||||
if (dst == src) {
|
||||
StrCopy(temp, src, arrsize(temp));
|
||||
src = temp;
|
||||
}
|
||||
else if (dst == fname) {
|
||||
StrCopy(temp, fname, arrsize(temp));
|
||||
fname = temp;
|
||||
}
|
||||
|
||||
PathMakePath(dst, dstChars, 0, src, fname, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathRemoveFilename (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar drive[MAX_DRIVE];
|
||||
wchar dir[MAX_DIR];
|
||||
PathSplitPath(src, drive, dir, 0, 0);
|
||||
PathMakePath(dst, dstChars, drive, dir, 0, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathRemoveExtension (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar drive[MAX_DRIVE];
|
||||
wchar dir[MAX_DIR];
|
||||
wchar fname[MAX_FNAME];
|
||||
PathSplitPath(src, drive, dir, fname, 0);
|
||||
PathMakePath(dst, dstChars, drive, dir, fname, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathSetExtension (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
const wchar ext[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dst != ext);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar drive[MAX_DRIVE];
|
||||
wchar dir[MAX_DIR];
|
||||
wchar fname[MAX_FNAME];
|
||||
PathSplitPath(src, drive, dir, fname, 0);
|
||||
PathMakePath(dst, dstChars, drive, dir, fname, ext);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathAddExtension (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
const wchar ext[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dst != ext);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar drive[MAX_DRIVE];
|
||||
wchar dir[MAX_DIR];
|
||||
wchar fname[MAX_FNAME];
|
||||
wchar oldext[MAX_EXT];
|
||||
PathSplitPath(src, drive, dir, fname, oldext);
|
||||
PathMakePath(
|
||||
dst,
|
||||
dstChars,
|
||||
drive,
|
||||
dir,
|
||||
fname,
|
||||
oldext[0] ? oldext : ext
|
||||
);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PathRemoveDirectory (
|
||||
wchar *dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(dstChars);
|
||||
|
||||
wchar fname[MAX_FNAME];
|
||||
wchar ext[MAX_EXT];
|
||||
PathSplitPath(src, 0, 0, fname, ext);
|
||||
PathMakePath(dst, dstChars, 0, 0, fname, ext);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Email formatting functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void PathSplitEmail (
|
||||
const wchar emailAddr[],
|
||||
wchar * user,
|
||||
unsigned userChars,
|
||||
wchar * domain,
|
||||
unsigned domainChars,
|
||||
wchar * tld,
|
||||
unsigned tldChars,
|
||||
wchar * subDomains,
|
||||
unsigned subDomainChars,
|
||||
unsigned subDomainCount
|
||||
) {
|
||||
ASSERT(emailAddr);
|
||||
|
||||
#define SUB_DOMAIN(i) subDomains[(i) * subDomainChars]
|
||||
|
||||
// null-terminate all output parameters
|
||||
if (userChars) {
|
||||
ASSERT(user);
|
||||
user[0] = 0;
|
||||
}
|
||||
if (domainChars) {
|
||||
ASSERT(domain);
|
||||
domain[0] = 0;
|
||||
}
|
||||
if (tldChars) {
|
||||
ASSERT(tld);
|
||||
tld[0] = 0;
|
||||
}
|
||||
if (subDomainChars || subDomainCount) {
|
||||
ASSERT(subDomains);
|
||||
for (unsigned i = 0; i < subDomainCount; ++i)
|
||||
SUB_DOMAIN(i) = 0;
|
||||
}
|
||||
|
||||
// bail now if email address is zero-length
|
||||
unsigned len = StrLen(emailAddr);
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
// copy email address so we can tokenize it
|
||||
wchar * tmp = ALLOCA(wchar, len + 1);
|
||||
StrCopy(tmp, emailAddr, len + 1);
|
||||
const wchar * work = tmp;
|
||||
|
||||
// parse user
|
||||
wchar token[MAX_PATH];
|
||||
if (!StrTokenize(&work, token, arrsize(token), L"@"))
|
||||
return;
|
||||
|
||||
// copy user to output parameter
|
||||
if (userChars)
|
||||
StrCopy(user, token, userChars);
|
||||
|
||||
// skip past the '@' symbol
|
||||
if (!*work++)
|
||||
return;
|
||||
|
||||
// parse all domains
|
||||
ARRAY(wchar *) arr;
|
||||
while (StrTokenize(&work, token, arrsize(token), L".")) {
|
||||
unsigned toklen = StrLen(token);
|
||||
wchar * str = ALLOCA(wchar, toklen + 1);
|
||||
StrCopy(str, token, toklen + 1);
|
||||
arr.Add(str);
|
||||
}
|
||||
|
||||
// copy domains to output parameters
|
||||
unsigned index = 0;
|
||||
if (arr.Count() > 2) {
|
||||
// all domains except for the last two are sub-domains
|
||||
for (index = 0; index < arr.Count() - 2; ++index) {
|
||||
if (index < subDomainCount)
|
||||
if (subDomains)
|
||||
StrCopy(&SUB_DOMAIN(index), arr[index], subDomainChars);
|
||||
}
|
||||
}
|
||||
if (arr.Count() > 1) {
|
||||
// second to last domain is the primary domain
|
||||
if (domain)
|
||||
StrCopy(domain, arr[index], domainChars);
|
||||
// last comes the top level domain
|
||||
++index;
|
||||
if (tld)
|
||||
StrCopy(tld, arr[index], tldChars);
|
||||
}
|
||||
else if (arr.Count() == 1) {
|
||||
// if only one domain, return it as a sub-domain
|
||||
if (index < subDomainCount)
|
||||
if (subDomains)
|
||||
StrCopy(&SUB_DOMAIN(index), arr[index], subDomainChars);
|
||||
}
|
||||
|
||||
#undef SUB_DOMAIN
|
||||
}
|
325
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.h
Normal file
325
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.h
Normal file
@ -0,0 +1,325 @@
|
||||
/*==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/pnUtPath.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPATH_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPATH_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Path definitions
|
||||
*
|
||||
***/
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 260
|
||||
#endif
|
||||
|
||||
#define MAX_DRIVE 256
|
||||
#define MAX_DIR 256
|
||||
#define MAX_FNAME 256
|
||||
#define MAX_EXT 256
|
||||
|
||||
|
||||
|
||||
const unsigned kPathFlagFile = 1<<0;
|
||||
const unsigned kPathFlagDirectory = 1<<1;
|
||||
const unsigned kPathFlagHidden = 1<<2;
|
||||
const unsigned kPathFlagSystem = 1<<3;
|
||||
const unsigned kPathFlagRecurse = 1<<4; // also set if "**" used in filespec
|
||||
|
||||
struct PathFind {
|
||||
unsigned flags;
|
||||
qword fileLength;
|
||||
qword lastWriteTime;
|
||||
wchar name[MAX_PATH];
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Path "get" functions
|
||||
*
|
||||
***/
|
||||
|
||||
void PathFindFiles (
|
||||
ARRAY(PathFind) * paths,
|
||||
const wchar fileSpec[],
|
||||
unsigned pathFlags
|
||||
);
|
||||
void PathGetProgramName (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
void PathGetModuleName (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// this function will use the current directory if <src> is a relative path
|
||||
// (see PathSetCurrentDirectory/PathGetCurrentDirectory)
|
||||
bool PathFromString (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
);
|
||||
bool PathFromString (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars,
|
||||
const wchar baseDir[]
|
||||
);
|
||||
|
||||
bool PathDoesFileExist (
|
||||
const wchar fileName[]
|
||||
);
|
||||
bool PathDoesDirectoryExist (
|
||||
const wchar directory[]
|
||||
);
|
||||
|
||||
bool PathDeleteFile (
|
||||
const wchar file[]
|
||||
);
|
||||
bool PathMoveFile (
|
||||
const wchar src[],
|
||||
const wchar dst[]
|
||||
);
|
||||
bool PathCopyFile (
|
||||
const wchar src[],
|
||||
const wchar dst[]
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Path building functions
|
||||
*
|
||||
***/
|
||||
|
||||
void PathSplitPath (
|
||||
const wchar path[],
|
||||
wchar * drive,
|
||||
wchar * dir,
|
||||
wchar * fname,
|
||||
wchar * ext
|
||||
);
|
||||
|
||||
void PathMakePath (
|
||||
wchar * path,
|
||||
unsigned chars,
|
||||
const wchar drive[],
|
||||
const wchar dir[],
|
||||
const wchar fname[],
|
||||
const wchar ext[]
|
||||
);
|
||||
|
||||
// c:\dir1 + dir2\file.txt => c:\dir1\dir2\file.txt
|
||||
void PathAddFilename (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
const wchar fname[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\dir1\dir2\file.txt => c:\dir1\dir2\ * note trailing backslash
|
||||
void PathRemoveFilename (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\file.txt => c:\dir1\dir2\file
|
||||
void PathRemoveExtension (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\file + .out => c:\file.out
|
||||
// c:\file. + .out => c:\file.out
|
||||
// c:\file.txt + .out => c:\file.out
|
||||
void PathSetExtension (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
const wchar ext[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\file + .out => c:\file.out
|
||||
// c:\file. + .out => c:\file.
|
||||
// c:\file.txt + .out => c:\file.txt
|
||||
void PathAddExtension (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
const wchar ext[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\dir1\dir2\file.txt => file.txt
|
||||
void PathRemoveDirectory (
|
||||
wchar * dst,
|
||||
const wchar src[],
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
// c:\dir1\dir2\file.txt - c:\dir1 => .\dir2\file.txt
|
||||
// c:\dir1\dir2\file1.txt - c:\dir1\dir4\file2.txt => ..\dir4\file2.txt
|
||||
bool PathMakeRelative (
|
||||
wchar * dst,
|
||||
unsigned fromFlags,
|
||||
const wchar from[],
|
||||
unsigned toFlags,
|
||||
const wchar to[],
|
||||
unsigned dstChars
|
||||
);
|
||||
bool PathIsRelative (
|
||||
const wchar src[]
|
||||
);
|
||||
|
||||
const wchar * PathFindFilename (const wchar path[]);
|
||||
inline wchar * PathFindFilename (wchar * path) {
|
||||
return const_cast<wchar *>(PathFindFilename(const_cast<const wchar *>(path)));
|
||||
}
|
||||
|
||||
const wchar * PathFindExtension (const wchar path[]);
|
||||
inline wchar * PathFindExtension (wchar * path) {
|
||||
return const_cast<wchar *>(PathFindExtension(const_cast<const wchar *>(path)));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Directory functions
|
||||
*
|
||||
***/
|
||||
|
||||
// Create directory
|
||||
enum EPathCreateDirError {
|
||||
kPathCreateDirSuccess,
|
||||
kPathCreateDirErrInvalidPath,
|
||||
kPathCreateDirErrAccessDenied,
|
||||
kPathCreateDirErrFileWithSameName,
|
||||
kPathCreateDirErrDirExists, // Directory exists and kPathCreateDirFlagCreateNew was specified
|
||||
};
|
||||
|
||||
// Setting this flag causes the function to create the entire directory
|
||||
// tree from top to bottom. Clearing this flag causes the function to
|
||||
// create only the last entry in the path.
|
||||
const unsigned kPathCreateDirFlagEntireTree = 1<<0;
|
||||
|
||||
// Setting this flag causes the function to create the last entry in the path
|
||||
// ONLY if it doesn't already exist. If it does exist the function will return
|
||||
// kPathCreateDirErrDirExistes.
|
||||
const unsigned kPathCreateDirFlagCreateNew = 1<<1;
|
||||
|
||||
|
||||
EPathCreateDirError PathCreateDirectory (
|
||||
const wchar path[],
|
||||
unsigned flags
|
||||
);
|
||||
void PathDeleteDirectory (
|
||||
const wchar path[],
|
||||
unsigned flags
|
||||
);
|
||||
|
||||
|
||||
// Set directory
|
||||
bool PathSetCurrentDirectory (const wchar path[]);
|
||||
void PathSetProgramDirectory ();
|
||||
|
||||
|
||||
// Get directory
|
||||
void PathGetProgramDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
void PathGetCurrentDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
void PathGetTempDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
|
||||
// Product and user-specific common directory locations
|
||||
void PathGetUserDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
void PathGetLogDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
void PathGetInitDirectory (
|
||||
wchar * dst,
|
||||
unsigned dstChars
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Email formatting functions
|
||||
*
|
||||
***/
|
||||
|
||||
// you may send nil for any fields you don't care about
|
||||
void PathSplitEmail (
|
||||
const wchar emailAddr[],
|
||||
wchar * user,
|
||||
unsigned userChars,
|
||||
wchar * domain,
|
||||
unsigned domainChars,
|
||||
wchar * tld,
|
||||
unsigned tldChars,
|
||||
wchar * subDomains, // (wchar *)&subs --> wchar subs[16][256];
|
||||
unsigned subDomainChars, // arrsize(subs[0]) --> 256
|
||||
unsigned subDomainCount // arrsize(subs) --> 16
|
||||
);
|
55
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPragma.h
Normal file
55
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPragma.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*==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/pnUtPragma.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPRAGMA_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPragma.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPRAGMA_H
|
||||
|
||||
|
||||
#pragma warning(disable: 4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
|
487
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPriQ.h
Normal file
487
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPriQ.h
Normal file
@ -0,0 +1,487 @@
|
||||
/*==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/pnUtPriQ.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPRIQ_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPriQ.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTPRIQ_H
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
***/
|
||||
|
||||
#define PRIORITY_TIME(class) TPriorityTime< class >
|
||||
#define PRIORITY_NUMERIC(class,type) TPriorityNumeric< class,type >
|
||||
|
||||
#define PRIQ(class,priority) TPriorityQueue< class,priority >
|
||||
#define PRIQDECL(class,priority,field) TPriorityQueueDecl< class,priority,offsetof(class,field) >
|
||||
#define PRIQDYN(class,priority) TPriorityQueueDyn< class,priority >
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* class TPriorityQueue
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C, class P>
|
||||
class TBasePriority;
|
||||
|
||||
template<class C, class P>
|
||||
class TPriorityQueue {
|
||||
|
||||
public:
|
||||
TPriorityQueue ();
|
||||
~TPriorityQueue ();
|
||||
|
||||
C * const & operator[] (unsigned index) const;
|
||||
|
||||
void Clear ();
|
||||
unsigned Count () const;
|
||||
C * Delete (C * object);
|
||||
C * Dequeue ();
|
||||
void Enqueue (C * object);
|
||||
C * const * Ptr () const;
|
||||
C * Root () const;
|
||||
C * const * Term () const;
|
||||
void UnlinkAll ();
|
||||
|
||||
public:
|
||||
// Intentionally unimplemented
|
||||
TPriorityQueue (TPriorityQueue const &);
|
||||
TPriorityQueue const & operator= (TPriorityQueue const &);
|
||||
|
||||
protected:
|
||||
void SetLinkOffset (int offset);
|
||||
|
||||
private:
|
||||
unsigned IndexChild (unsigned index) const;
|
||||
unsigned IndexParent (unsigned index) const;
|
||||
void Link (unsigned index);
|
||||
P * Priority (C * object);
|
||||
P const * Priority (C const * object) const;
|
||||
void Remove (unsigned index);
|
||||
void Unlink (unsigned index);
|
||||
|
||||
enum { LINK_OFFSET_UNINIT = 0xdddddddd };
|
||||
|
||||
int m_linkOffset;
|
||||
ARRAY(C *) m_array;
|
||||
|
||||
friend TBasePriority<C,P>;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline C * const & TPriorityQueue<C,P>::operator[] (unsigned index) const {
|
||||
return m_array[index];
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline TPriorityQueue<C,P>::TPriorityQueue () :
|
||||
m_linkOffset(LINK_OFFSET_UNINIT) {
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline TPriorityQueue<C,P>::~TPriorityQueue () {
|
||||
UnlinkAll();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TPriorityQueue<C,P>::Clear () {
|
||||
|
||||
// Deleting an object could cause other objects in the queue to be deleted
|
||||
// so we can't make any assumptions about indices or counts of items in the array
|
||||
while (C * head = Dequeue())
|
||||
DEL(head);
|
||||
|
||||
m_array.Clear();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline unsigned TPriorityQueue<C,P>::Count () const {
|
||||
return m_array.Count();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
C * TPriorityQueue<C,P>::Delete (C * object) {
|
||||
|
||||
// get the object's priority queue and position
|
||||
P * priority = Priority(object);
|
||||
const TPriorityQueue<C,P> * queue = priority->GetLink();
|
||||
unsigned index = priority->GetIndex();
|
||||
|
||||
// delete the object
|
||||
DEL(object);
|
||||
|
||||
// return the next object in that queue
|
||||
if (queue && (index < queue->Count()))
|
||||
return (*queue)[index];
|
||||
else
|
||||
return nil;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
C * TPriorityQueue<C,P>::Dequeue () {
|
||||
if (!m_array.Count())
|
||||
return nil;
|
||||
C * value = m_array[0];
|
||||
Remove(0);
|
||||
return value;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
void TPriorityQueue<C,P>::Enqueue (C * object) {
|
||||
P * priority = Priority(object);
|
||||
|
||||
// Verify that the object is not already linked into a priority queue.
|
||||
// The original implementation of this function silently refused to
|
||||
// enqueue at a new priority if the object was already in this queue.
|
||||
// Since this behavior requires callers to check whether the object is
|
||||
// already enqueued, we now simply assert that.
|
||||
ASSERT(!priority->IsLinked());
|
||||
|
||||
unsigned index = m_array.Add(object);
|
||||
unsigned parent = IndexParent(index);
|
||||
|
||||
// shift value toward root
|
||||
while (index && priority->IsPriorityHigher(*Priority(m_array[parent]))) {
|
||||
m_array[index] = m_array[parent];
|
||||
Link(index);
|
||||
index = parent;
|
||||
parent = IndexParent(index);
|
||||
}
|
||||
|
||||
// assign and link the new value
|
||||
m_array[index] = object;
|
||||
Link(index);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline unsigned TPriorityQueue<C,P>::IndexChild (unsigned index) const {
|
||||
return (index << 1) + 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline unsigned TPriorityQueue<C,P>::IndexParent (unsigned index) const {
|
||||
return (index - 1) >> 1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TPriorityQueue<C,P>::Link (unsigned index) {
|
||||
Priority(m_array[index])->Link(this, index);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline P * TPriorityQueue<C,P>::Priority (C * object) {
|
||||
ASSERT(m_linkOffset != LINK_OFFSET_UNINIT);
|
||||
return (P *)((byte *)object + m_linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline P const * TPriorityQueue<C,P>::Priority (C const * object) const {
|
||||
ASSERT(m_linkOffset != LINK_OFFSET_UNINIT);
|
||||
return (P const *)((byte const *)object + m_linkOffset);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline C * const * TPriorityQueue<C,P>::Ptr () const {
|
||||
return m_array.Ptr();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
void TPriorityQueue<C,P>::Remove (unsigned index) {
|
||||
|
||||
// reset the priority link fields
|
||||
Unlink(index);
|
||||
|
||||
// save the terminal leaf node
|
||||
C * value = m_array.Pop();
|
||||
P * priority = Priority(value);
|
||||
|
||||
const unsigned count = m_array.Count();
|
||||
if (count == index)
|
||||
return;
|
||||
|
||||
// rebalance upwards from the position of the deleted entry
|
||||
unsigned parent;
|
||||
unsigned entry = index;
|
||||
if (entry && priority->IsPriorityHigher(*Priority(m_array[parent = IndexParent(entry)]))) {
|
||||
do {
|
||||
m_array[entry] = m_array[parent];
|
||||
Link(entry);
|
||||
entry = parent;
|
||||
} while (entry && priority->IsPriorityHigher(*Priority(m_array[parent = IndexParent(entry)])));
|
||||
m_array[entry] = value;
|
||||
Link(entry);
|
||||
|
||||
entry = index;
|
||||
value = m_array[index];
|
||||
priority = Priority(value);
|
||||
}
|
||||
|
||||
// rebalance downwards from the position of the deleted entry
|
||||
for (;;) {
|
||||
unsigned child = IndexChild(entry);
|
||||
if (child >= count)
|
||||
break;
|
||||
|
||||
unsigned sibling = child + 1;
|
||||
if ( (sibling < count) &&
|
||||
(Priority(m_array[sibling])->IsPriorityHigher(*Priority(m_array[child]))) )
|
||||
child = sibling;
|
||||
|
||||
if (priority->IsPriorityHigher(*Priority(m_array[child])))
|
||||
break;
|
||||
|
||||
m_array[entry] = m_array[child];
|
||||
Link(entry);
|
||||
entry = child;
|
||||
}
|
||||
|
||||
m_array[entry] = value;
|
||||
Link(entry);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline C * TPriorityQueue<C,P>::Root () const {
|
||||
return m_array.Count() ? m_array[0] : nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TPriorityQueue<C,P>::SetLinkOffset (int offset) {
|
||||
ASSERT(m_linkOffset == LINK_OFFSET_UNINIT);
|
||||
m_linkOffset = offset;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline C * const * TPriorityQueue<C,P>::Term () const {
|
||||
return m_array.Term();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TPriorityQueue<C,P>::Unlink (unsigned index) {
|
||||
Priority(m_array[index])->Link(nil, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TPriorityQueue<C,P>::UnlinkAll () {
|
||||
for (unsigned loop = m_array.Count(); loop--; )
|
||||
Unlink(loop);
|
||||
m_array.ZeroCount();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TPriorityQueueDecl
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C, class P, int linkOffset>
|
||||
class TPriorityQueueDecl : public TPriorityQueue<C,P> {
|
||||
public:
|
||||
TPriorityQueueDecl () { SetLinkOffset(linkOffset); }
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TPriorityQueueDyn
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C, class P>
|
||||
class TPriorityQueueDyn : public TPriorityQueue<C,P> {
|
||||
public:
|
||||
void Initialize (int linkOffset) { SetLinkOffset(linkOffset); }
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* class TBasePriority
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C, class P>
|
||||
class TBasePriority {
|
||||
|
||||
public:
|
||||
TBasePriority () : m_queue(nil), m_index(0) { }
|
||||
virtual ~TBasePriority () { Unlink(); }
|
||||
|
||||
void Unlink () { if (m_queue) m_queue->Remove(m_index); }
|
||||
bool IsLinked () const { return m_queue != nil; }
|
||||
|
||||
public:
|
||||
TBasePriority (const TBasePriority &);
|
||||
const TBasePriority & operator= (const TBasePriority &);
|
||||
|
||||
protected:
|
||||
void Relink ();
|
||||
|
||||
private:
|
||||
void Link (TPriorityQueue<C,P> * queue, unsigned index);
|
||||
const TPriorityQueue<C,P> * GetLink () const { return m_queue; }
|
||||
unsigned GetIndex () const { return m_index; }
|
||||
|
||||
private:
|
||||
TPriorityQueue<C,P> * m_queue;
|
||||
unsigned m_index;
|
||||
|
||||
friend TPriorityQueue<C,P>;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
inline void TBasePriority<C,P>::Link (TPriorityQueue<C,P> * queue, unsigned index) {
|
||||
m_queue = queue;
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class C, class P>
|
||||
void TBasePriority<C,P>::Relink () {
|
||||
|
||||
// cache m_queue, since m_queue->Remove() will set it to nil
|
||||
TPriorityQueue<C,P> * queue = m_queue;
|
||||
if (!queue)
|
||||
return;
|
||||
C * object = (*queue)[m_index];
|
||||
queue->Remove(m_index);
|
||||
queue->Enqueue(object);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* class TPriorityNumeric
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C,class T>
|
||||
class TPriorityNumeric : public TBasePriority< C, TPriorityNumeric<C,T> > {
|
||||
|
||||
public:
|
||||
TPriorityNumeric () : m_value(0) { }
|
||||
TPriorityNumeric (T value) : m_value(value) { }
|
||||
void Set (T value) {
|
||||
if (value == m_value)
|
||||
return;
|
||||
m_value = value;
|
||||
Relink();
|
||||
}
|
||||
T Get () const {
|
||||
return m_value;
|
||||
}
|
||||
bool IsPriorityHigher (const TPriorityNumeric<C,T> & source) {
|
||||
return m_value > source.m_value;
|
||||
}
|
||||
bool IsPriorityHigher (T value) const {
|
||||
return m_value > value;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* class TPriorityTime
|
||||
*
|
||||
***/
|
||||
|
||||
template<class C>
|
||||
class TPriorityTime : public TBasePriority< C, TPriorityTime<C> > {
|
||||
|
||||
public:
|
||||
TPriorityTime () : m_time(0) { }
|
||||
TPriorityTime (unsigned time) : m_time(time) { }
|
||||
|
||||
void Set (unsigned time) {
|
||||
if (m_time == time)
|
||||
return;
|
||||
m_time = time;
|
||||
Relink();
|
||||
}
|
||||
unsigned Get () const {
|
||||
return m_time;
|
||||
}
|
||||
bool IsPriorityHigher (const TPriorityTime<C> & source) const {
|
||||
return (int)(m_time - source.m_time) < 0;
|
||||
}
|
||||
bool IsPriorityHigher (unsigned time) const {
|
||||
return (int)(m_time - time) < 0;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_time;
|
||||
};
|
185
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRand.cpp
Normal file
185
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRand.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/*==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/pnUtRand.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private
|
||||
*
|
||||
***/
|
||||
|
||||
class RandomContext {
|
||||
dword m_seed;
|
||||
dword m_value;
|
||||
|
||||
void UpdateValue ();
|
||||
|
||||
public:
|
||||
RandomContext ();
|
||||
|
||||
void Reset ();
|
||||
void SetSeed (unsigned seed);
|
||||
float GetFloat ();
|
||||
float GetFloat (float minVal, float maxVal);
|
||||
unsigned GetUnsigned ();
|
||||
unsigned GetUnsigned (unsigned minVal, unsigned maxVal);
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private data
|
||||
*
|
||||
***/
|
||||
|
||||
static const dword kDefaultRandomSeed = 0x075bd924;
|
||||
|
||||
static RandomContext s_random;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* RandomContext
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
RandomContext::RandomContext ()
|
||||
: m_seed(kDefaultRandomSeed)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void RandomContext::UpdateValue () {
|
||||
const dword A = 0xbc8f;
|
||||
const dword Q = 0xadc8;
|
||||
const dword R = 0x0d47;
|
||||
|
||||
dword div = m_value / Q;
|
||||
m_value = A * (m_value - Q * div) - R * div;
|
||||
if (m_value > kRandomMax)
|
||||
m_value -= kRandomMax + 1;
|
||||
if (!m_value)
|
||||
m_value = kDefaultRandomSeed;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void RandomContext::Reset () {
|
||||
m_value = m_seed;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void RandomContext::SetSeed (unsigned seed) {
|
||||
// Never allow a seed of zero
|
||||
m_seed = seed ? seed : kDefaultRandomSeed;
|
||||
Reset();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
float RandomContext::GetFloat () {
|
||||
UpdateValue();
|
||||
return m_value * (1.0f / kRandomMax);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
float RandomContext::GetFloat (float minVal, float maxVal) {
|
||||
float value = GetFloat();
|
||||
return minVal + value * (maxVal - minVal);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned RandomContext::GetUnsigned () {
|
||||
UpdateValue();
|
||||
return (unsigned)m_value;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned RandomContext::GetUnsigned (unsigned minVal, unsigned maxVal) {
|
||||
unsigned value = GetUnsigned();
|
||||
return minVal + value % (maxVal - minVal + 1);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
void RandReset () {
|
||||
s_random.Reset();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void RandSetSeed (unsigned seed) {
|
||||
s_random.SetSeed(seed);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
float RandFloat () {
|
||||
return s_random.GetFloat();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
float RandFloat (float minVal, float maxVal) {
|
||||
return s_random.GetFloat(minVal, maxVal);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned RandUnsigned () {
|
||||
return s_random.GetUnsigned();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned RandUnsigned (unsigned minVal, unsigned maxVal) {
|
||||
return s_random.GetUnsigned(minVal, maxVal);
|
||||
}
|
67
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRand.h
Normal file
67
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRand.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*==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/pnUtRand.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTRAND_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRand.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTRAND_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Psuedo-random number generator
|
||||
*
|
||||
***/
|
||||
|
||||
const dword kRandomMax = 0x7fffffff;
|
||||
|
||||
void RandReset ();
|
||||
void RandSetSeed (unsigned seed);
|
||||
float RandFloat ();
|
||||
float RandFloat (float minVal, float maxVal);
|
||||
unsigned RandUnsigned ();
|
||||
unsigned RandUnsigned (unsigned minVal, unsigned maxVal);
|
185
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRef.h
Normal file
185
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRef.h
Normal file
@ -0,0 +1,185 @@
|
||||
/*==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/pnUtRef.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTREF_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtRef.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTREF_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Debug macros
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef REFCOUNT_DEBUGGING
|
||||
#define REFTRACE DEBUG_MSG
|
||||
#else
|
||||
#define REFTRACE NULL_STMT
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* AtomicRef
|
||||
* Thread safe reference count
|
||||
*
|
||||
***/
|
||||
|
||||
class AtomicRef {
|
||||
#ifdef HS_DEBUGGING
|
||||
bool zeroed;
|
||||
#endif
|
||||
public:
|
||||
inline AtomicRef ()
|
||||
: m_ref(0)
|
||||
#ifdef HS_DEBUGGING
|
||||
, zeroed(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
inline void AcknowledgeZeroRef () {
|
||||
#ifdef HS_DEBUGGING
|
||||
zeroed = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline long IncRef () {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev = AtomicAdd(&m_ref, 1);
|
||||
REFTRACE("Inc %p: %u", this, prev+1);
|
||||
return prev+1;
|
||||
}
|
||||
inline long IncRef (const char tag[]) {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev = AtomicAdd(&m_ref, 1);
|
||||
REF(tag);
|
||||
REFTRACE("Inc %p %s: %u", this, tag, prev+1);
|
||||
return prev+1;
|
||||
}
|
||||
inline long IncRef (unsigned n) {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev = AtomicAdd(&m_ref, n);
|
||||
REFTRACE("Inc %p: %u", this, prev+n);
|
||||
return prev+n;
|
||||
}
|
||||
inline long IncRef (unsigned n, const char tag[]) {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev = AtomicAdd(&m_ref, n);
|
||||
REF(tag);
|
||||
REFTRACE("Inc %p %s: %u", this, tag, prev+n);
|
||||
return prev+n;
|
||||
}
|
||||
|
||||
inline long DecRef () {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev;
|
||||
if ((prev = AtomicAdd(&m_ref, -1)) == 1) {
|
||||
#ifdef HS_DEBUGGING
|
||||
zeroed = true;
|
||||
#endif
|
||||
OnZeroRef();
|
||||
}
|
||||
REFTRACE("Dec %p: %u", this, prev-1);
|
||||
return prev-1;
|
||||
}
|
||||
inline long DecRef (const char tag[]) {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
long prev;
|
||||
if ((prev = AtomicAdd(&m_ref, -1)) == 1) {
|
||||
#ifdef HS_DEBUGGING
|
||||
zeroed = true;
|
||||
#endif
|
||||
OnZeroRef();
|
||||
}
|
||||
REF(tag);
|
||||
REFTRACE("Dec %p %s: %u", this, tag, prev-1);
|
||||
return prev-1;
|
||||
}
|
||||
|
||||
inline void TransferRef (
|
||||
const char oldTag[],
|
||||
const char newTag[]
|
||||
) {
|
||||
#ifdef HS_DEBUGGING
|
||||
ASSERT(!zeroed);
|
||||
#endif
|
||||
REF(oldTag);
|
||||
REF(newTag);
|
||||
REFTRACE("Inc %p %s: (xfer)", this, newTag);
|
||||
REFTRACE("Dec %p %s: (xfer)", this, oldTag);
|
||||
}
|
||||
|
||||
inline unsigned GetRefCount () {
|
||||
return m_ref;
|
||||
}
|
||||
|
||||
inline virtual void OnZeroRef () {
|
||||
DEL(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline virtual ~AtomicRef () {
|
||||
ASSERT(!m_ref);
|
||||
}
|
||||
|
||||
private:
|
||||
long m_ref;
|
||||
};
|
477
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSkipList.h
Normal file
477
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSkipList.h
Normal file
@ -0,0 +1,477 @@
|
||||
/*==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/pnUtSkipList.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSKIPLIST_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSkipList.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSKIPLIST_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
***/
|
||||
|
||||
#define SKIPLIST(type, keyType, keyField, cmp) TSkipList< type, keyType, offsetof(type, keyField), cmp >
|
||||
#define SKIPLIST_NUMERIC(type, keyType, keyField) SKIPLIST(type, keyType, keyField, TSkipListNumericCmp<keyType>)
|
||||
#define SKIPLIST_STRING(type, keyType, keyField) SKIPLIST(type, keyType, keyField, TSkipListStringCmp<keyType>)
|
||||
#define SKIPLIST_STRINGI(type, keyType, keyField) SKIPLIST(type, keyType, keyField, TSkipListStringCmpI<keyType>)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Typedefs
|
||||
*
|
||||
***/
|
||||
|
||||
typedef void * SkipListTag;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Comparers
|
||||
*
|
||||
***/
|
||||
|
||||
|
||||
template<class K>
|
||||
class TSkipListNumericCmp {
|
||||
public:
|
||||
static bool Eq (const K & a, const K & b) { return a == b; }
|
||||
static bool Lt (const K & a, const K & b) { return a < b; }
|
||||
};
|
||||
|
||||
template<class K>
|
||||
class TSkipListStringCmp {
|
||||
public:
|
||||
static bool Eq (const K & a, const K & b) { return StrCmp(a, b, (unsigned)-1) == 0; }
|
||||
static bool Lt (const K & a, const K & b) { return StrCmp(a, b, (unsigned)-1) < 0; }
|
||||
};
|
||||
|
||||
template<class K>
|
||||
class TSkipListStringCmpI {
|
||||
public:
|
||||
static bool Eq (const K & a, const K & b) { return StrCmpI(a, b, (unsigned)-1) == 0; }
|
||||
static bool Lt (const K & a, const K & b) { return StrCmpI(a, b, (unsigned)-1) < 0; }
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* TSkipList
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
class TSkipList {
|
||||
private:
|
||||
enum { kMaxLevels = 32 };
|
||||
|
||||
template<class T, class K>
|
||||
struct TNode {
|
||||
const K * key;
|
||||
T * object;
|
||||
unsigned level;
|
||||
TNode<T, K> * prev;
|
||||
TNode<T, K> * next[1]; // variable size array
|
||||
};
|
||||
typedef TNode<T,K> Node;
|
||||
|
||||
unsigned m_level;
|
||||
Node * m_head;
|
||||
Node * m_stop;
|
||||
unsigned m_randomBits;
|
||||
unsigned m_randomsLeft;
|
||||
|
||||
Node * AllocNode (unsigned levels);
|
||||
void FreeNode (Node * node);
|
||||
unsigned RandomLevel ();
|
||||
|
||||
public:
|
||||
inline TSkipList ();
|
||||
inline ~TSkipList ();
|
||||
inline void Clear ();
|
||||
inline void Delete (T * object);
|
||||
inline T * Find (const K & key, SkipListTag * tag = nil) const;
|
||||
inline T * FindNext (SkipListTag * tag) const;
|
||||
inline T * Head (SkipListTag * tag) const;
|
||||
inline T * Next (SkipListTag * tag) const;
|
||||
inline T * Prev (SkipListTag * tag) const;
|
||||
inline T * Tail (SkipListTag * tag) const;
|
||||
inline void Link (T * object);
|
||||
inline void Unlink (T * object);
|
||||
inline void Unlink (SkipListTag * tag);
|
||||
inline void UnlinkAll ();
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
inline void Print () const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* TSkipList private member functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
typename TSkipList<T,K,keyOffset,Cmp>::TNode<T,K> * TSkipList<T,K,keyOffset,Cmp>::AllocNode (unsigned level) {
|
||||
|
||||
unsigned size = offsetof(Node, next) + (level + 1) * sizeof(Node);
|
||||
Node * node = (Node *)ALLOC(size);
|
||||
node->level = level;
|
||||
return node;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::FreeNode (TNode<T,K> * node) {
|
||||
|
||||
FREE(node);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
unsigned TSkipList<T,K,keyOffset,Cmp>::RandomLevel () {
|
||||
|
||||
unsigned level = 0;
|
||||
unsigned bits = 0;
|
||||
|
||||
while (!bits) {
|
||||
bits = m_randomBits % 4;
|
||||
if (!bits)
|
||||
++level;
|
||||
m_randomBits >>= 2;
|
||||
m_randomsLeft -= 2;
|
||||
if (!m_randomsLeft) {
|
||||
m_randomBits = RandUnsigned();
|
||||
m_randomsLeft = 30;
|
||||
}
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* TSkipList public member functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
TSkipList<T,K,keyOffset,Cmp>::TSkipList () {
|
||||
|
||||
m_level = 0;
|
||||
m_head = AllocNode(kMaxLevels);
|
||||
m_stop = AllocNode(0);
|
||||
m_randomBits = RandUnsigned();
|
||||
m_randomsLeft = 30;
|
||||
|
||||
// Initialize header and stop skip node pointers
|
||||
m_stop->prev = m_head;
|
||||
m_stop->object = nil;
|
||||
m_stop->next[0] = nil;
|
||||
m_head->object = nil;
|
||||
for (unsigned index = 0; index < kMaxLevels; ++index)
|
||||
m_head->next[index] = m_stop;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
TSkipList<T,K,keyOffset,Cmp>::~TSkipList () {
|
||||
|
||||
UnlinkAll();
|
||||
ASSERT(m_stop->prev == m_head);
|
||||
FreeNode(m_head);
|
||||
FreeNode(m_stop);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::Clear () {
|
||||
|
||||
Node * ptr = m_head->next[0];
|
||||
while (ptr != m_stop) {
|
||||
Node * next = ptr->next[0];
|
||||
DEL(ptr->object);
|
||||
FreeNode(ptr);
|
||||
ptr = next;
|
||||
}
|
||||
|
||||
m_stop->prev = m_head;
|
||||
for (unsigned index = 0; index < kMaxLevels; ++index)
|
||||
m_head->next[index] = m_stop;
|
||||
m_level = 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::Delete (T * object) {
|
||||
|
||||
Unlink(object);
|
||||
DEL(object);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::Find (const K & key, SkipListTag * tag) const {
|
||||
|
||||
Node * node = m_head;
|
||||
|
||||
m_stop->key = &key;
|
||||
for (int level = (int)m_level; level >= 0; --level)
|
||||
while (Cmp::Lt(*node->next[level]->key, key))
|
||||
node = node->next[level];
|
||||
|
||||
node = node->next[0];
|
||||
if (node != m_stop && Cmp::Eq(*node->key, *m_stop->key)) {
|
||||
if (tag)
|
||||
*tag = node;
|
||||
return node->object;
|
||||
}
|
||||
else {
|
||||
if (tag)
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::FindNext (SkipListTag * tag) const {
|
||||
|
||||
Node * node = (Node *)*tag;
|
||||
|
||||
m_stop->key = node->key;
|
||||
for (int level = (int)node->level; level >= 0; --level)
|
||||
while (Cmp::Lt(*node->next[level]->key, *m_stop->key))
|
||||
node = node->next[level];
|
||||
|
||||
node = node->next[0];
|
||||
if (node != m_stop && Cmp::Eq(*node->key, *m_stop->key)) {
|
||||
*tag = node;
|
||||
return node->object;
|
||||
}
|
||||
else {
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::Head (SkipListTag * tag) const {
|
||||
|
||||
ASSERT(tag);
|
||||
Node * first = m_head->next[0];
|
||||
if (first == m_stop) {
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
*tag = first;
|
||||
return first->object;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::Next (SkipListTag * tag) const {
|
||||
|
||||
ASSERT(tag);
|
||||
Node * node = (Node *)*tag;
|
||||
ASSERT(node);
|
||||
if (node->next[0] == m_stop) {
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
*tag = node->next[0];
|
||||
return node->next[0]->object;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::Prev (SkipListTag * tag) const {
|
||||
|
||||
ASSERT(tag);
|
||||
Node * node = (Node *)*tag;
|
||||
ASSERT(node);
|
||||
if (node->prev == m_head) {
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
*tag = node->prev;
|
||||
return node->prev->object;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
T * TSkipList<T,K,keyOffset,Cmp>::Tail (SkipListTag * tag) const {
|
||||
|
||||
ASSERT(tag);
|
||||
Node * last = m_stop->prev;
|
||||
if (last == m_head) {
|
||||
*tag = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
*tag = last;
|
||||
return last->object;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::Link (T * object) {
|
||||
|
||||
const K * key = (const K *)((const byte *)object + keyOffset);
|
||||
|
||||
// Find the node's insertion point
|
||||
m_stop->key = key;
|
||||
Node * update[kMaxLevels];
|
||||
Node * node = m_head;
|
||||
for (int level = (int)m_level; level >= 0; --level) {
|
||||
while (Cmp::Lt(*node->next[level]->key, *key))
|
||||
node = node->next[level];
|
||||
update[level] = node;
|
||||
}
|
||||
node = node->next[0];
|
||||
|
||||
{
|
||||
// Select a level for the skip node
|
||||
unsigned newLevel = RandomLevel();
|
||||
if (newLevel > m_level) {
|
||||
if (m_level < kMaxLevels - 1) {
|
||||
newLevel = ++m_level;
|
||||
update[newLevel] = m_head;
|
||||
}
|
||||
else
|
||||
newLevel = m_level;
|
||||
}
|
||||
|
||||
// Create the node and insert it into the skip list
|
||||
Node * node = AllocNode(newLevel);
|
||||
node->key = key;
|
||||
node->object = object;
|
||||
for (unsigned level = newLevel; level >= 1; --level) {
|
||||
node->next[level] = update[level]->next[level];
|
||||
update[level]->next[level] = node;
|
||||
}
|
||||
node->prev = update[0];
|
||||
node->next[0] = update[0]->next[0];
|
||||
update[0]->next[0]->prev = node;
|
||||
update[0]->next[0] = node;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::Unlink (T * object) {
|
||||
|
||||
const K * key = (const K *)((const byte *)object + keyOffset);
|
||||
|
||||
Node * node = m_head;
|
||||
Node * update[kMaxLevels];
|
||||
int level = m_level;
|
||||
|
||||
for (;;) {
|
||||
// Find the node being unlinked
|
||||
m_stop->key = key;
|
||||
for (; level >= 0; --level) {
|
||||
while (Cmp::Lt(*node->next[level]->key, *key))
|
||||
node = node->next[level];
|
||||
update[level] = node;
|
||||
}
|
||||
node = node->next[0];
|
||||
|
||||
// Node wasn't found so do nothing
|
||||
if (*node->key != *key || node == m_stop)
|
||||
return;
|
||||
|
||||
if (node->object == object)
|
||||
break;
|
||||
}
|
||||
|
||||
// Update all links
|
||||
for (level = m_level; level >= 1; --level) {
|
||||
if (update[level]->next[level] != node)
|
||||
continue;
|
||||
update[level]->next[level] = node->next[level];
|
||||
}
|
||||
ASSERT(update[0]->next[0] == node);
|
||||
node->next[0]->prev = update[0];
|
||||
update[0]->next[0] = node->next[0];
|
||||
|
||||
// Update header
|
||||
while (m_level && m_head->next[m_level] == m_stop)
|
||||
--m_level;
|
||||
|
||||
FreeNode(node);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template<class T, class K, unsigned keyOffset, class Cmp>
|
||||
void TSkipList<T,K,keyOffset,Cmp>::UnlinkAll () {
|
||||
|
||||
Node * ptr = m_head->next[0];
|
||||
while (ptr != m_stop) {
|
||||
Node * next = ptr->next[0];
|
||||
FreeNode(ptr);
|
||||
ptr = next;
|
||||
}
|
||||
|
||||
m_stop->prev = m_head;
|
||||
for (unsigned index = 0; index < kMaxLevels; ++index)
|
||||
m_head->next[index] = m_stop;
|
||||
m_level = 0;
|
||||
}
|
241
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSort.h
Normal file
241
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSort.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*==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/pnUtSort.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSORT_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSort.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSORT_H
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* QSORT
|
||||
*
|
||||
* This version of QuickSort is similar to the one in the C runtime library,
|
||||
* but is implemented as a macro to allow more flexible usage.
|
||||
*
|
||||
* With the C runtime library version, when data external to the sort array
|
||||
* is needed to make sorting decisions, that data must be stored in file- or
|
||||
* global-scope variables. This creates thread safety problems which can
|
||||
* only be resolved through the use of synchronization objects. The version
|
||||
* of QuickSort provided here does not require function calls to make
|
||||
* sorting decisions, so all data can be kept in stack variables.
|
||||
*
|
||||
* The expression used for making comparisons allows the same return values
|
||||
* as the comparison function used by the C runtime library, and can in fact
|
||||
* be a function call to a comparison function that was originally designed
|
||||
* for use by the C runtime library.
|
||||
* > 0 if elem1 greater than elem2
|
||||
* = 0 if elem1 equivalent to elem2
|
||||
* < 0 if elem1 less than elem2
|
||||
*
|
||||
* However, this implementation of QuickSort never requires a distinction
|
||||
* between the case where elem1 is less than elem2 and the case where elem1
|
||||
* is equivalent to elem2, so it is possible to use the following more
|
||||
* efficient return values:
|
||||
* > 0 if elem1 is greater than elem2
|
||||
* <= 0 if elem1 is less than or equivalent to elem2
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
#define QSORT(T, ptr, count, expr) { \
|
||||
\
|
||||
/* Largest possible stack count required is 1 + log2(size) */ \
|
||||
T * loStack[32]; \
|
||||
T * hiStack[32]; \
|
||||
unsigned stackPos = 0; \
|
||||
\
|
||||
if ((count) >= 2) { \
|
||||
T * lo = (ptr); \
|
||||
T * hi = lo + (count); \
|
||||
for (;;) { \
|
||||
\
|
||||
/* Pick a partitioning element */ \
|
||||
T * mid = lo + (hi - lo) / 2; \
|
||||
\
|
||||
/* Swap it to the beginning of the array */ \
|
||||
SWAP(*mid, *lo); \
|
||||
\
|
||||
/* Partition the array into three pieces, one consisting of */ \
|
||||
/* elements <= the partitioning element, one of elements */ \
|
||||
/* equal to it, and one of elements >= to it. */ \
|
||||
T * loPart = lo; \
|
||||
T * hiPart = hi; \
|
||||
for (;;) { \
|
||||
/* val(i) <= val(lo) for lo <= i <= loPart */ \
|
||||
/* val(i) >= val(lo) for hiPart <= i <= hi */ \
|
||||
\
|
||||
for (;;) { \
|
||||
if (++loPart == hi) \
|
||||
break; \
|
||||
T const & elem1 = *loPart; \
|
||||
T const & elem2 = *lo; \
|
||||
int result = (expr); \
|
||||
if (result > 0) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
for (;;) { \
|
||||
if (--hiPart == lo) \
|
||||
break; \
|
||||
T const & elem1 = *lo; \
|
||||
T const & elem2 = *hiPart; \
|
||||
int result = (expr); \
|
||||
if (result > 0) \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (hiPart < loPart) \
|
||||
break; \
|
||||
\
|
||||
/* val(loPart) > val(lo) */ \
|
||||
/* val(hiPart) < val(lo) */ \
|
||||
\
|
||||
SWAP(*loPart, *hiPart); \
|
||||
\
|
||||
/* val(loPart) < val(lo) */ \
|
||||
/* val(hiPart) > val(lo) */ \
|
||||
} \
|
||||
\
|
||||
/* val(i) <= val(lo) for lo <= i <= hiPart */ \
|
||||
/* val(i) == val(lo) for hiPart < i < loPart */ \
|
||||
/* val(i) >= val(lo) for loPart <= i <= hi */ \
|
||||
\
|
||||
/* Put the partitioning element in place */ \
|
||||
SWAP(*lo, *hiPart); \
|
||||
\
|
||||
/* val(i) <= val(hiPart) for lo <= i < hiPart */ \
|
||||
/* val(i) == val(lo) for hiPart <= i < loPart */ \
|
||||
/* val(i) >= val(hiPart) for loPart <= i < hi */ \
|
||||
\
|
||||
/* Sort the subarrays [lo, hiPart-1] and [loPart, hi]. */ \
|
||||
/* We sort the smaller one first to minimize stack usage. */ \
|
||||
if (hiPart - lo >= hi - loPart) { \
|
||||
if (lo + 1 < hiPart) { \
|
||||
/* Store the bigger subarray */ \
|
||||
loStack[stackPos] = lo; \
|
||||
hiStack[stackPos] = hiPart; \
|
||||
++stackPos; \
|
||||
} \
|
||||
if (loPart + 1 < hi) { \
|
||||
/* Sort the smaller subarray */ \
|
||||
lo = loPart; \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
if (loPart + 1 < hi) { \
|
||||
/* Store the bigger subarray */ \
|
||||
loStack[stackPos] = loPart; \
|
||||
hiStack[stackPos] = hi; \
|
||||
++stackPos; \
|
||||
} \
|
||||
if (lo + 1 < hiPart) { \
|
||||
/* Sort the smaller subarray */ \
|
||||
hi = hiPart; \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* Pop the next subarray off the stack */ \
|
||||
if (stackPos--) { \
|
||||
lo = loStack[stackPos]; \
|
||||
hi = hiStack[stackPos]; \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* BSEARCH
|
||||
*
|
||||
* This macro binary searches a sorted array to find an existing entry or
|
||||
* the position where a TRACKED_NEW entry should be placed. It returns the index of
|
||||
* the first entry for which the expression is false (zero or negative), or
|
||||
* count if the expression is true (positive) for all entries.
|
||||
*
|
||||
* Typically the expression will return:
|
||||
* > 0 if (sortKey > elem)
|
||||
* <= 0 if (sortKey <= elem)
|
||||
*
|
||||
* The final parameter to the macro is the address of a variable which is
|
||||
* filled with the resulting index.
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
#define BSEARCH(T, ptr, count, expr, addrOfIndex) { \
|
||||
\
|
||||
const T * low = (ptr); \
|
||||
const T * high = (ptr) + (count); /* first entry for which */ \
|
||||
/* expr is false */ \
|
||||
\
|
||||
if (low != high) \
|
||||
for (;;) { \
|
||||
const T & elem = *(low + (high - low) / 2); \
|
||||
int result = (expr); \
|
||||
if (result > 0) { \
|
||||
if (&elem == low) \
|
||||
break; \
|
||||
low = &elem; \
|
||||
} \
|
||||
else { \
|
||||
high = &elem; \
|
||||
if (&elem == low) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
*(addrOfIndex) = high - (ptr); \
|
||||
\
|
||||
}
|
171
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSpareList.cpp
Normal file
171
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSpareList.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*==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/pnUtSpareList.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Exported functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
CBaseSpareList::CBaseSpareList ()
|
||||
: m_allocHead(nil),
|
||||
m_spareHead(nil),
|
||||
m_chunkSize(0)
|
||||
{
|
||||
#ifdef SPARELIST_TRACK_MEMORY
|
||||
m_unfreedObjects = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void * CBaseSpareList::Alloc (unsigned objectSize, const char typeName[]) {
|
||||
// if there aren't any spare nodes available then make more
|
||||
if (!m_spareHead)
|
||||
GrowSpareList(objectSize, typeName);
|
||||
|
||||
// dequeue the head of the spare list
|
||||
void * const object = m_spareHead;
|
||||
m_spareHead = m_spareHead->spareNext;
|
||||
#ifdef SPARELIST_TRACK_MEMORY
|
||||
m_unfreedObjects++;
|
||||
#endif
|
||||
|
||||
// initialize memory to a freaky value in debug mode
|
||||
#ifdef HS_DEBUGGING
|
||||
MemSet(object, (byte) ((unsigned) object >> 4), objectSize);
|
||||
#endif
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseSpareList::Free (void * object, unsigned objectSize) {
|
||||
// initialize memory to a freaky value in debug mode
|
||||
#ifdef HS_DEBUGGING
|
||||
MemSet(object, (byte) ((unsigned) object >> 4), objectSize);
|
||||
#else
|
||||
REF(objectSize);
|
||||
#endif
|
||||
|
||||
// link memory block onto head of spare list
|
||||
((SpareNode *) object)->spareNext = m_spareHead;
|
||||
m_spareHead = (SpareNode *) object;
|
||||
#ifdef SPARELIST_TRACK_MEMORY
|
||||
m_unfreedObjects--;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseSpareList::GrowSpareList (unsigned objectSize, const char typeName[]) {
|
||||
// Grow the allocation by a substantial amount each time
|
||||
// to reduce the time spent in memory managament
|
||||
m_chunkSize *= 2;
|
||||
const unsigned MIN_ALLOC = max(1, 256/objectSize);
|
||||
const unsigned MAX_ALLOC = max(512, 32*1024/objectSize);
|
||||
if (m_chunkSize < MIN_ALLOC)
|
||||
m_chunkSize = MIN_ALLOC;
|
||||
else if (m_chunkSize > MAX_ALLOC)
|
||||
m_chunkSize = MAX_ALLOC;
|
||||
|
||||
// allocate a block of memory to hold a bunch
|
||||
// of T-objects, but allocate them as "raw" memory
|
||||
AllocNode * allocNode = (AllocNode *) MemAlloc(
|
||||
sizeof(AllocNode) + objectSize * m_chunkSize,
|
||||
0, // flags
|
||||
typeName, // file
|
||||
0 // line
|
||||
);
|
||||
|
||||
// link allocation onto head of allocation list
|
||||
allocNode->allocNext = m_allocHead;
|
||||
m_allocHead = allocNode;
|
||||
|
||||
// chain newly created raw memory units together onto the spare list
|
||||
SpareNode * spareCurr = (SpareNode *) (allocNode + 1);
|
||||
SpareNode * spareEnd = (SpareNode *) ((byte *) spareCurr + objectSize * m_chunkSize);
|
||||
do {
|
||||
spareCurr->spareNext = m_spareHead;
|
||||
m_spareHead = spareCurr;
|
||||
spareCurr = (SpareNode *) ((byte *) spareCurr + objectSize);
|
||||
} while (spareCurr < spareEnd);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void CBaseSpareList::CleanUp (const char typeName[]) {
|
||||
// warn of resource leaks
|
||||
#ifdef SPARELIST_TRACK_MEMORY
|
||||
if (m_unfreedObjects && !ErrorGetOption(kErrOptDisableMemLeakChecking)) {
|
||||
#ifdef CLIENT
|
||||
{
|
||||
char buffer[256];
|
||||
StrPrintf(buffer, arrsize(buffer), "Memory leak: %s", typeName);
|
||||
FATAL(buffer);
|
||||
}
|
||||
#else
|
||||
{
|
||||
DEBUG_MSG("Memory leak: %s", typeName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
REF(typeName);
|
||||
#endif
|
||||
|
||||
// walk chain of AllocNodes and free each of them
|
||||
while (m_allocHead) {
|
||||
AllocNode * allocNext = m_allocHead->allocNext;
|
||||
FREE(m_allocHead);
|
||||
m_allocHead = allocNext;
|
||||
}
|
||||
|
||||
m_spareHead = nil;
|
||||
}
|
147
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSpareList.h
Normal file
147
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSpareList.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*==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/pnUtSpareList.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSPARELIST_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSpareList.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSPARELIST_H
|
||||
|
||||
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
#define SPARELIST_TRACK_MEMORY
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CBaseSpareList
|
||||
*
|
||||
***/
|
||||
|
||||
class CBaseSpareList {
|
||||
public:
|
||||
CBaseSpareList ();
|
||||
|
||||
protected:
|
||||
struct SpareNode {
|
||||
SpareNode * spareNext;
|
||||
};
|
||||
SpareNode * m_spareHead;
|
||||
|
||||
void * Alloc (unsigned objectSize, const char typeName[]);
|
||||
void CleanUp (const char typeName[]);
|
||||
void Free (void * object, unsigned objectSize);
|
||||
|
||||
private:
|
||||
union AllocNode {
|
||||
AllocNode * allocNext;
|
||||
qword align;
|
||||
};
|
||||
AllocNode * m_allocHead;
|
||||
unsigned m_chunkSize;
|
||||
|
||||
#ifdef SPARELIST_TRACK_MEMORY
|
||||
unsigned m_unfreedObjects;
|
||||
#endif
|
||||
|
||||
void GrowSpareList (unsigned objectSize, const char typeName[]);
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* TSpareList
|
||||
*
|
||||
***/
|
||||
|
||||
template<class T>
|
||||
class TSpareList : public CBaseSpareList {
|
||||
private:
|
||||
enum { OBJECT_SIZE = MAX(sizeof(T), sizeof(SpareNode)) };
|
||||
|
||||
public:
|
||||
~TSpareList () { CleanUp(); }
|
||||
|
||||
void * Alloc ();
|
||||
void CleanUp ();
|
||||
void Delete (T * node);
|
||||
void Free (T * node);
|
||||
T * New ();
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void * TSpareList<T>::Alloc () {
|
||||
return CBaseSpareList::Alloc(OBJECT_SIZE, typeid(T).raw_name());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TSpareList<T>::CleanUp () {
|
||||
CBaseSpareList::CleanUp(typeid(T).raw_name());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TSpareList<T>::Delete (T * node) {
|
||||
node->~T();
|
||||
CBaseSpareList::Free(node, OBJECT_SIZE);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void TSpareList<T>::Free (T * node) {
|
||||
CBaseSpareList::Free(node, OBJECT_SIZE);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
T * TSpareList<T>::New () {
|
||||
return new(CBaseSpareList::Alloc(OBJECT_SIZE, typeid(T).raw_name())) T;
|
||||
}
|
772
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.cpp
Normal file
772
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.cpp
Normal file
@ -0,0 +1,772 @@
|
||||
/*==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 "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Private data
|
||||
*
|
||||
***/
|
||||
|
||||
// These random values were generated by the radioactive decay based
|
||||
// random number generator at www.fourmilab.ch
|
||||
static dword s_hashValue[] = {
|
||||
0xc30d2a72, 0x15efaec1, 0xd250c7d9, 0xaf3c60a8,
|
||||
0x9608ae8f, 0x452c0e11, 0xb6840ffd, 0x3e36c913,
|
||||
0x2864eace, 0x9b0a17d6, 0x108da74b, 0xf2c479c1,
|
||||
0x8b4dd597, 0x97199bc0, 0x621f0cce, 0x1658553e,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Internal functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static chartype * IStrDup (const chartype str[]) {
|
||||
unsigned chars = IStrLen(str) + 1;
|
||||
chartype * buffer = (chartype *)ALLOC(chars * sizeof(chartype));
|
||||
IStrCopy(buffer, str, chars);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static chartype * IStrDupLen (const chartype str[], unsigned chars) {
|
||||
unsigned len = IStrLen(str) + 1;
|
||||
if (len > chars)
|
||||
len = chars;
|
||||
chartype * buffer = (chartype *)ALLOC(len * sizeof(chartype));
|
||||
IStrCopy(buffer, str, len);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype, class findchartype>
|
||||
static chartype * IStrChr (chartype * str, findchartype ch, unsigned chars) {
|
||||
for (; chars--; ++str)
|
||||
if (*str == ch)
|
||||
return str;
|
||||
else if (!*str)
|
||||
break;
|
||||
return nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype, class findchartype>
|
||||
static chartype * IStrChrR (chartype * str, findchartype ch) {
|
||||
chartype * start = str;
|
||||
for (; *str; ++str)
|
||||
NULL_STMT;
|
||||
while (str-- > start)
|
||||
if (*str == ch)
|
||||
return str;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static inline bool ICharUnicodeToUtf8 (char ** dest, const wchar * source[], unsigned destChars) {
|
||||
unsigned ch = *(*source)++;
|
||||
bool result = false;
|
||||
if (ch < 0x80) {
|
||||
if (destChars >= 1) {
|
||||
*(*dest)++ = (char)ch;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else if (ch < 0x800) {
|
||||
if (destChars >= 2) {
|
||||
*(*dest)++ = (char)(0xc0 | (ch >> 6));
|
||||
*(*dest)++ = (char)(0x80 | (ch & 0x3f));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (destChars >= 3) {
|
||||
*(*dest)++ = (char)(0xe0 | (ch >> 12));
|
||||
*(*dest)++ = (char)(0x80 | ((ch >> 6) & 0x3f));
|
||||
*(*dest)++ = (char)(0x80 | (ch & 0x3f));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static inline void ICharUtf8ToUnicode (wchar ** dest, const char * source[]) {
|
||||
unsigned result, remaining;
|
||||
if ((**source & 0xf0) == 0xe0) {
|
||||
result = *(*source)++ & 0x0f;
|
||||
remaining = 2;
|
||||
}
|
||||
else if ((**source & 0xe0) == 0xc0) {
|
||||
result = *(*source)++ & 0x1f;
|
||||
remaining = 1;
|
||||
}
|
||||
else if ((**source & 0x80) == 0x00) {
|
||||
result = *(*source)++;
|
||||
remaining = 0;
|
||||
}
|
||||
else {
|
||||
// unsupported code sequence (>0xffff)
|
||||
++(*source);
|
||||
return;
|
||||
}
|
||||
for (; remaining-- && *source; ++*source)
|
||||
if ((**source & 0xc0) == 0x80)
|
||||
result = (result << 6) | (**source & 0x3f);
|
||||
*(*dest)++ = (wchar)result;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
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 void IStrCopy (chartype * dest, const chartype source[], unsigned chars) {
|
||||
while ((chars > 1) && ((*dest = *source++) != 0)) {
|
||||
--chars;
|
||||
++dest;
|
||||
}
|
||||
if (chars)
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// returns StrLen(dest)
|
||||
template<class chartype>
|
||||
static unsigned IStrCopyLen (chartype * dest, const chartype source[], unsigned chars) {
|
||||
chartype * const start = dest;
|
||||
while ((chars > 1) && ((*dest = *source++) != 0)) {
|
||||
--chars;
|
||||
++dest;
|
||||
}
|
||||
if (chars)
|
||||
*dest = 0;
|
||||
return dest - start;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static void IStrPack (chartype * dest, const chartype source[], unsigned chars) {
|
||||
while ((chars > 1) && *dest) {
|
||||
--chars;
|
||||
++dest;
|
||||
}
|
||||
while ((chars > 1) && ((*dest = *source++) != 0)) {
|
||||
--chars;
|
||||
++dest;
|
||||
}
|
||||
if (chars)
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static chartype * IStrStr (chartype source[], const chartype match[]) {
|
||||
if (!*match)
|
||||
return source;
|
||||
|
||||
for (chartype * curr = source; *curr; ++curr) {
|
||||
chartype * s1 = curr;
|
||||
const chartype * s2 = match;
|
||||
while (*s1 && *s2 && *s1 == *s2)
|
||||
s1++, s2++;
|
||||
if (!*s2)
|
||||
return curr;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static chartype * IStrStrI (chartype source[], const chartype match[]) {
|
||||
if (!*match)
|
||||
return source;
|
||||
|
||||
for (chartype * curr = source; *curr; ++curr) {
|
||||
chartype * s1 = curr;
|
||||
const chartype * s2 = match;
|
||||
while (*s1 && *s2 && (CharLowerFast(*s1) == CharLowerFast(*s2)))
|
||||
s1++, s2++;
|
||||
if (!*s2)
|
||||
return curr;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static unsigned IStrLen (const chartype str[]) {
|
||||
unsigned chars = 0;
|
||||
for (; *str++; ++chars)
|
||||
NULL_STMT;
|
||||
return chars;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static void IStrLower (chartype * dest, unsigned chars) {
|
||||
while ((chars > 1) && ((*dest = CharLowerFast(*dest)) != 0)) {
|
||||
--chars;
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static void IStrLower (chartype * dest, const chartype source[], unsigned chars) {
|
||||
while ((chars > 1) && ((*dest = CharLowerFast(*source)) != 0)) {
|
||||
--chars;
|
||||
++dest;
|
||||
++source;
|
||||
}
|
||||
if (chars)
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static dword IStrHash (const chartype str[], unsigned chars) {
|
||||
dword temp0 = 0xE2C15C9D;
|
||||
dword temp1 = 0x2170A28A;
|
||||
dword 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 dword IStrHashI (const chartype str[], unsigned chars) {
|
||||
dword temp0 = 0xE2C15C9D;
|
||||
dword temp1 = 0x2170A28A;
|
||||
dword 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;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static bool IStrTokenize (const chartype * source[], chartype * dest, unsigned chars, const chartype whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
|
||||
// Skip past leading whitespace
|
||||
bool inQuotes = false;
|
||||
unsigned whitespaceSkipped = 0;
|
||||
while (**source && IStrChr(whitespace, **source, (unsigned)-1) && whitespaceSkipped < maxWhitespaceSkipCount) {
|
||||
inQuotes = (**source == '\"');
|
||||
++*source;
|
||||
++whitespaceSkipped;
|
||||
if (inQuotes)
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy the token
|
||||
unsigned offset = 0;
|
||||
while (**source &&
|
||||
((inQuotes && (**source != '\"')) || !IStrChr(whitespace, **source, (unsigned)-1))) {
|
||||
if (offset + 1 < chars)
|
||||
dest[offset++] = **source;
|
||||
++*source;
|
||||
}
|
||||
|
||||
// Skip past the terminating quote
|
||||
if (inQuotes && (**source == '\"'))
|
||||
++*source;
|
||||
|
||||
// Null terminate the destination buffer
|
||||
if (chars) {
|
||||
ASSERT(offset < chars);
|
||||
dest[offset] = 0;
|
||||
}
|
||||
|
||||
// Upon return, 'source' is guaranteed to point to the first character
|
||||
// following the returned token (and following any closing quotes)
|
||||
|
||||
return (offset || inQuotes);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
template<class chartype>
|
||||
static bool IStrTokenize (const chartype * source[], ARRAY(chartype) * destArray, const chartype whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
|
||||
// Verify that the destination array is empty
|
||||
ASSERT(!destArray->Count());
|
||||
|
||||
// Skip past leading whitespace
|
||||
bool inQuotes = false;
|
||||
unsigned whitespaceSkipped = 0;
|
||||
while (**source && IStrChr(whitespace, **source, (unsigned)-1) && whitespaceSkipped < maxWhitespaceSkipCount) {
|
||||
inQuotes = (**source == '\"');
|
||||
++*source;
|
||||
++whitespaceSkipped;
|
||||
if (inQuotes)
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy the token
|
||||
bool added = false;
|
||||
while (**source &&
|
||||
((inQuotes && (**source != '\"')) || !IStrChr(whitespace, **source, (unsigned)-1))) {
|
||||
destArray->Add(**source);
|
||||
added = true;
|
||||
++*source;
|
||||
}
|
||||
|
||||
// Skip past the terminating quote
|
||||
if (inQuotes && (**source == '\"'))
|
||||
++*source;
|
||||
|
||||
// Null terminate the destination array
|
||||
destArray->Add(0);
|
||||
|
||||
// Upon return, 'source' is guaranteed to point to the first character
|
||||
// following the returned token (and following any closing quotes)
|
||||
|
||||
return (added || inQuotes);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Exported functions
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
char * StrDup (const char str[]) {
|
||||
return IStrDup(str);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrDup (const wchar str[]) {
|
||||
return IStrDup(str);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
char * StrDupLen (const char str[], unsigned chars) {
|
||||
return IStrDupLen(str, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrDupLen (const wchar str[], unsigned chars) {
|
||||
return IStrDupLen(str, chars);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
wchar * StrDupToUnicode (const char str[]) {
|
||||
unsigned bytes = StrBytes(str) * sizeof(wchar);
|
||||
wchar * dst = (wchar*)ALLOC(bytes);
|
||||
StrToUnicode(dst, str, bytes / sizeof(wchar));
|
||||
return dst;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
char * StrDupToAnsi (const wchar str[]) {
|
||||
unsigned bytes = StrBytes(str) / sizeof(wchar);
|
||||
char * dst = (char*)ALLOC(bytes);
|
||||
StrToAnsi(dst, str, bytes);
|
||||
return dst;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrBytes (const char str[]) { // includes space for terminator
|
||||
return (IStrLen(str) + 1) * sizeof(str[0]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrBytes (const wchar str[]) { // includes space for terminator
|
||||
return (IStrLen(str) + 1) * sizeof(str[0]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
char * StrChr (char * str, char ch, unsigned chars) {
|
||||
return IStrChr(str, ch, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrChr (wchar * str, wchar ch, unsigned chars) {
|
||||
return IStrChr(str, ch, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const char * StrChr (const char str[], char ch, unsigned chars) {
|
||||
return IStrChr(str, ch, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * StrChr (const wchar str[], wchar ch, unsigned chars) {
|
||||
return IStrChr(str, ch, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
char * StrChrR (char * str, char ch) {
|
||||
return IStrChrR(str, ch);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrChrR (wchar * str, wchar ch) {
|
||||
return IStrChrR(str, ch);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const char * StrChrR (const char str[], char ch) {
|
||||
return IStrChrR(str, ch);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * StrChrR (const wchar str[], wchar ch) {
|
||||
return IStrChrR(str, ch);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrPrintf (char * dest, unsigned count, const char format[], ...) {
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
int result = _vsnprintf((char *)dest, count, (const char *)format, argList);
|
||||
va_end(argList);
|
||||
return IStrPrintfValidate(dest, count, result);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrPrintf (wchar * dest, unsigned count, const wchar format[], ...) {
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
int result = _vsnwprintf(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 = _vsnprintf(dest, count, format, args);
|
||||
return IStrPrintfValidate(dest, count, result);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrPrintfV (wchar * dest, unsigned count, const wchar format[], va_list args) {
|
||||
int result = _vsnwprintf(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 str1[], const wchar 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 str1[], const wchar str2[], unsigned chars) {
|
||||
return IStrCmpI(str1, str2, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrCopy (char * dest, const char source[], unsigned chars) {
|
||||
IStrCopy(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrCopy (wchar * dest, const wchar source[], unsigned chars) {
|
||||
IStrCopy(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrCopyLen (char * dest, const char source[], unsigned chars) {
|
||||
return IStrCopyLen(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrCopyLen (wchar * dest, const wchar source[], unsigned chars) {
|
||||
return IStrCopyLen(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrPack (char * dest, const char source[], unsigned chars) {
|
||||
IStrPack(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrPack (wchar * dest, const wchar source[], unsigned chars) {
|
||||
IStrPack(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
char * StrStr (char * source, const char match[]) {
|
||||
return IStrStr(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const char * StrStr (const char source[], const char match[]) {
|
||||
return IStrStr<const char>(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrStr (wchar * source, const wchar match[]) {
|
||||
return IStrStr(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * StrStr (const wchar source[], const wchar match[]) {
|
||||
return IStrStr<const wchar>(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
char * StrStrI (char * source, const char match[]) {
|
||||
return IStrStrI(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const char * StrStrI (const char source[], const char match[]) {
|
||||
return IStrStrI<const char>(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
wchar * StrStrI (wchar * source, const wchar match[]) {
|
||||
return IStrStrI(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
const wchar * StrStrI (const wchar source[], const wchar match[]) {
|
||||
return IStrStrI<const wchar>(source, match);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrLen (const char str[]) {
|
||||
return IStrLen(str);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrLen (const wchar str[]) {
|
||||
return IStrLen(str);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrUnicodeToUtf8 (char * dest, const wchar source[], unsigned destChars) {
|
||||
char * destCurr = dest;
|
||||
char * destTerm = dest + destChars;
|
||||
while (*source && (destCurr + 1 < destTerm))
|
||||
if (!ICharUnicodeToUtf8(&destCurr, &source, destTerm - destCurr - 1))
|
||||
break;
|
||||
if (destCurr < destTerm)
|
||||
*destCurr = 0;
|
||||
return destCurr - dest; // dest chars not including null terminator
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrUtf8ToUnicode (wchar * dest, const char source[], unsigned destChars) {
|
||||
wchar * destCurr = dest;
|
||||
wchar * destTerm = dest + destChars;
|
||||
while (*source && (destCurr + 1 < destTerm))
|
||||
ICharUtf8ToUnicode(&destCurr, &source);
|
||||
if (destCurr < destTerm)
|
||||
*destCurr = 0;
|
||||
return destCurr - dest; // dest chars not including null terminator
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
float StrToFloat (const char source[], const char ** endptr) {
|
||||
return (float) strtod(source, const_cast<char **>(endptr));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
float StrToFloat (const wchar source[], const wchar ** endptr) {
|
||||
return (float) wcstod(source, const_cast<wchar **>(endptr));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int StrToInt (const char source[], const char ** endptr) {
|
||||
return strtol(source, const_cast<char **>(endptr), 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int StrToInt (const wchar source[], const wchar ** endptr) {
|
||||
return wcstol(source, const_cast<wchar **>(endptr), 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnsigned (char source[], char ** endptr, int radix) {
|
||||
return strtoul(source, const_cast<char **>(endptr), radix);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnsigned (wchar source[], wchar ** endptr, int radix) {
|
||||
return wcstoul(source, const_cast<wchar **>(endptr), radix);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnsigned (const char source[], const char ** endptr, int radix) {
|
||||
return strtoul(source, const_cast<char **>(endptr), radix);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
unsigned StrToUnsigned (const wchar source[], const wchar ** endptr, int radix) {
|
||||
return wcstoul(source, const_cast<wchar **>(endptr), radix);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrLower (char * dest, unsigned chars) {
|
||||
IStrLower(dest, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrLower (wchar * dest, unsigned chars) {
|
||||
IStrLower(dest, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrLower (char * dest, const char source[], unsigned chars) {
|
||||
IStrLower(dest, source, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void StrLower (wchar * dest, const wchar source[], unsigned chars) {
|
||||
IStrLower(dest, source, chars);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
dword StrHash (const char str[], unsigned chars) {
|
||||
return IStrHash(str, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
dword StrHash (const wchar str[], unsigned chars) {
|
||||
return IStrHash(str, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
dword StrHashI (const char str[], unsigned chars) {
|
||||
return IStrHashI(str, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
dword StrHashI (const wchar str[], unsigned chars) {
|
||||
return IStrHashI(str, chars);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool StrTokenize (const char * source[], char * dest, unsigned chars, const char whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
return IStrTokenize(source, dest, chars, whitespace, maxWhitespaceSkipCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool StrTokenize (const wchar * source[], wchar * dest, unsigned chars, const wchar whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
return IStrTokenize(source, dest, chars, whitespace, maxWhitespaceSkipCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool StrTokenize (const char * source[], ARRAY(char) * destArray, const char whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
return IStrTokenize(source, destArray, whitespace, maxWhitespaceSkipCount);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool StrTokenize (const wchar * source[], ARRAY(wchar) * destArray, const wchar whitespace[], unsigned maxWhitespaceSkipCount) {
|
||||
return IStrTokenize(source, destArray, whitespace, maxWhitespaceSkipCount);
|
||||
}
|
156
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.h
Normal file
156
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*==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.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSTR_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtStr.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSTR_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* String functions
|
||||
*
|
||||
***/
|
||||
|
||||
inline char CharLowerFast (char ch) { return ((ch >= 'A') && (ch <= 'Z')) ? (char )(ch + 'a' - 'A') : ch; }
|
||||
inline wchar CharLowerFast (wchar ch) { return ((ch >= L'A') && (ch <= L'Z')) ? (wchar)(ch + L'a' - L'A') : ch; }
|
||||
|
||||
inline char CharUpperFast (char ch) { return ((ch >= 'a') && (ch <= 'z')) ? (char )(ch + 'A' - 'a') : ch; }
|
||||
inline wchar CharUpperFast (wchar ch) { return ((ch >= L'a') && (ch <= L'z')) ? (wchar)(ch + L'A' - L'a') : ch; }
|
||||
|
||||
unsigned StrBytes (const char str[]); // includes space for terminator
|
||||
unsigned StrBytes (const wchar str[]); // includes space for terminator
|
||||
|
||||
char * StrChr (char * str, char ch, unsigned chars = (unsigned)-1);
|
||||
wchar * StrChr (wchar * str, wchar ch, unsigned chars = (unsigned)-1);
|
||||
const char * StrChr (const char str[], char ch, unsigned chars = (unsigned)-1);
|
||||
const wchar * StrChr (const wchar str[], wchar ch, unsigned chars = (unsigned)-1);
|
||||
|
||||
unsigned StrPrintf (char * dest, unsigned count, const char format[], ...);
|
||||
unsigned StrPrintf (wchar * dest, unsigned count, const wchar format[], ...);
|
||||
|
||||
unsigned StrPrintfV (char * dest, unsigned count, const char format[], va_list args);
|
||||
unsigned StrPrintfV (wchar * dest, unsigned count, const wchar format[], va_list args);
|
||||
|
||||
unsigned StrLen (const char str[]);
|
||||
unsigned StrLen (const wchar str[]);
|
||||
|
||||
char * StrDup (const char str[]);
|
||||
wchar * StrDup (const wchar str[]);
|
||||
|
||||
char * StrDupLen (const char str[], unsigned chars);
|
||||
wchar * StrDupLen (const wchar str[], unsigned chars);
|
||||
|
||||
wchar * StrDupToUnicode (const char str[]);
|
||||
char * StrDupToAnsi (const wchar str[]);
|
||||
|
||||
int StrCmp (const char str1[], const char str2[], unsigned chars = (unsigned)-1);
|
||||
int StrCmp (const wchar str1[], const wchar str2[], unsigned chars = (unsigned)-1);
|
||||
|
||||
int StrCmpI (const char str1[], const char str2[], unsigned chars = (unsigned)-1);
|
||||
int StrCmpI (const wchar str1[], const wchar str2[], unsigned chars = (unsigned)-1);
|
||||
|
||||
char * StrStr (char * source, const char match[]);
|
||||
const char * StrStr (const char source[], const char match[]);
|
||||
wchar * StrStr (wchar * source, const wchar match[]);
|
||||
const wchar * StrStr (const wchar source[], const wchar match[]);
|
||||
|
||||
char * StrStrI (char * source, const char match[]);
|
||||
const char * StrStrI (const char source[], const char match[]);
|
||||
wchar * StrStrI (wchar * source, const wchar match[]);
|
||||
const wchar * StrStrI (const wchar source[], const wchar match[]);
|
||||
|
||||
char * StrChrR (char * str, char ch);
|
||||
wchar * StrChrR (wchar * str, wchar ch);
|
||||
const char * StrChrR (const char str[], char ch);
|
||||
const wchar * StrChrR (const wchar str[], wchar ch);
|
||||
|
||||
void StrCopy (char * dest, const char source[], unsigned chars);
|
||||
void StrCopy (wchar * dest, const wchar source[], unsigned chars);
|
||||
|
||||
unsigned StrCopyLen (char * dest, const char source[], unsigned chars);
|
||||
unsigned StrCopyLen (wchar * dest, const wchar source[], unsigned chars);
|
||||
|
||||
void StrPack (char * dest, const char source[], unsigned chars);
|
||||
void StrPack (wchar * dest, const wchar source[], unsigned chars);
|
||||
|
||||
unsigned StrToAnsi (char * dest, const wchar source[], unsigned destChars);
|
||||
unsigned StrToAnsi (char * dest, const wchar source[], unsigned destChars, unsigned codePage);
|
||||
|
||||
unsigned StrToUnicode (wchar * dest, const char source[], unsigned destChars);
|
||||
unsigned StrToUnicode (wchar * dest, const char source[], unsigned destChars, unsigned codePage);
|
||||
|
||||
unsigned StrUnicodeToUtf8 (char * dest, const wchar source[], unsigned destChars);
|
||||
unsigned StrUtf8ToUnicode (wchar * dest, const char source[], unsigned destChars);
|
||||
|
||||
float StrToFloat (const char source[], const char ** endptr);
|
||||
float StrToFloat (const wchar source[], const wchar ** endptr);
|
||||
|
||||
int StrToInt (const char source[], const char ** endptr);
|
||||
int StrToInt (const wchar source[], const wchar ** endptr);
|
||||
|
||||
unsigned StrToUnsigned (char source[], char ** endptr, int radix);
|
||||
unsigned StrToUnsigned (wchar source[], wchar ** endptr, int radix);
|
||||
unsigned StrToUnsigned (const char source[], const char ** endptr, int radix);
|
||||
unsigned StrToUnsigned (const wchar source[], const wchar ** endptr, int radix);
|
||||
|
||||
void StrLower (char * dest, unsigned chars = (unsigned) -1);
|
||||
void StrLower (wchar * dest, unsigned chars = (unsigned) -1);
|
||||
void StrLower (char * dest, const char source[], unsigned chars);
|
||||
void StrLower (wchar * dest, const wchar source[], unsigned chars);
|
||||
|
||||
dword StrHash (const char str[], unsigned chars = (unsigned)-1);
|
||||
dword StrHash (const wchar str[], unsigned chars = (unsigned)-1);
|
||||
|
||||
dword StrHashI (const char str[], unsigned chars = (unsigned)-1);
|
||||
dword StrHashI (const wchar str[], unsigned chars = (unsigned)-1);
|
||||
|
||||
bool StrTokenize (const char * source[], char * dest, unsigned chars, const char whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1);
|
||||
bool StrTokenize (const wchar * source[], wchar * dest, unsigned chars, const wchar whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1);
|
||||
bool StrTokenize (const char * source[], ARRAY(char) * destArray, const char whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1);
|
||||
bool StrTokenize (const wchar * source[], ARRAY(wchar) * destArray, const wchar whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1);
|
302
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSubst.cpp
Normal file
302
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSubst.cpp
Normal file
@ -0,0 +1,302 @@
|
||||
/*==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/pnUtSubst.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#define SUBST_BLOCK SubstParsedData<chartype>::SubstBlock<chartype>
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Internal functions
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
template <typename chartype>
|
||||
bool IVarSubstitute (
|
||||
ARRAY(chartype) * dst,
|
||||
const chartype src[],
|
||||
unsigned varCount,
|
||||
const chartype * varNames[], // [varCount]
|
||||
const chartype * varValues[] // [varCount]
|
||||
) {
|
||||
ASSERT(dst);
|
||||
ASSERT(src);
|
||||
ASSERT(varNames);
|
||||
ASSERT(varValues);
|
||||
|
||||
dst->Reserve(StrLen(src) * 5/4);
|
||||
|
||||
bool result = true;
|
||||
while (*src) {
|
||||
// Copy non-substituted strings and escape %% symbols
|
||||
if ((*src != L'%') || (*++src == L'%')) {
|
||||
dst->Push(*src++);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find variable definition
|
||||
const chartype * varStart = src;
|
||||
const chartype * varEnd = StrChr(varStart, L'%');
|
||||
if (!varEnd) {
|
||||
// Skip % character and continue
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validate variable name length
|
||||
chartype varBuffer[256];
|
||||
if (varEnd - varStart >= arrsize(varBuffer)) {
|
||||
result = false;
|
||||
src = varEnd + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy variable name excluding trailing '%'
|
||||
StrCopy(varBuffer, varStart, varEnd - varStart + 1);
|
||||
src = varEnd + 1;
|
||||
|
||||
// Find the variable value and perform substitution
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i < varCount; ++i) {
|
||||
if (StrCmp(varBuffer, varNames[i]))
|
||||
continue;
|
||||
dst->Add(varValues[i], StrLen(varValues[i]));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that variable definition exists
|
||||
result = result && found;
|
||||
}
|
||||
|
||||
// Terminate string
|
||||
dst->Push(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template <typename chartype>
|
||||
bool IParseForSubst (
|
||||
SubstParsedData<chartype> * dest,
|
||||
const chartype src[]
|
||||
) {
|
||||
const chartype * current = src;
|
||||
bool result = true;
|
||||
while (*current) {
|
||||
// Copy non-substituted strings and escape %% symbols
|
||||
if ((*current != L'%') || (*++current == L'%')) {
|
||||
current++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find variable definition
|
||||
const chartype * varStart = current;
|
||||
const chartype * varEnd = StrChr(varStart, L'%');
|
||||
if (!varEnd) {
|
||||
// Skip % character and continue
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We've found a variable, copy the current data to a new object
|
||||
if (current != src) {
|
||||
int strLen = (current - src) - 1;
|
||||
SUBST_BLOCK * block = NEW(SUBST_BLOCK);
|
||||
block->isVar = false;
|
||||
block->strLen = strLen;
|
||||
block->data = (chartype*)ALLOCZERO((strLen + 1) * sizeof(chartype));
|
||||
MemCopy(block->data, src, strLen * sizeof(chartype));
|
||||
|
||||
dest->blocks.Add(block);
|
||||
}
|
||||
|
||||
// Validate variable name length
|
||||
chartype varBuffer[256];
|
||||
if (varEnd - varStart >= arrsize(varBuffer)) {
|
||||
result = false;
|
||||
src = current = varEnd + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy variable name excluding trailing '%'
|
||||
int strLen = (varEnd - varStart);
|
||||
SUBST_BLOCK * block = NEW(SUBST_BLOCK);
|
||||
block->isVar = true;
|
||||
block->strLen = strLen;
|
||||
block->data = (chartype*)ALLOCZERO((strLen + 1) * sizeof(chartype));
|
||||
MemCopy(block->data, varStart, strLen * sizeof(chartype));
|
||||
|
||||
dest->blocks.Add(block);
|
||||
|
||||
src = current = varEnd + 1;
|
||||
}
|
||||
|
||||
// Check and see if there's any data remaining
|
||||
if (current != src) {
|
||||
int strLen = (current - src);
|
||||
SUBST_BLOCK * block = NEW(SUBST_BLOCK);
|
||||
block->isVar = false;
|
||||
block->strLen = strLen;
|
||||
block->data = (chartype*)ALLOCZERO((strLen + 1) * sizeof(chartype));
|
||||
MemCopy(block->data, src, strLen * sizeof(chartype));
|
||||
|
||||
dest->blocks.Add(block);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
template <typename chartype>
|
||||
bool IVarSubstPreParsed (
|
||||
ARRAY(chartype) * dst,
|
||||
const SubstParsedData<chartype> * src,
|
||||
unsigned varCount,
|
||||
const chartype * varNames[], // [varCount]
|
||||
const chartype * varValues[] // [varCount]
|
||||
) {
|
||||
unsigned approxTotalSize = 0;
|
||||
for (unsigned i = 0; i < src->blocks.Count(); ++i) {
|
||||
approxTotalSize += src->blocks[i]->strLen;
|
||||
}
|
||||
|
||||
dst->Reserve(approxTotalSize * 5/4);
|
||||
|
||||
bool foundAll = true;
|
||||
for (unsigned blockIndex = 0; blockIndex < src->blocks.Count(); ++blockIndex) {
|
||||
SUBST_BLOCK * block = src->blocks[blockIndex];
|
||||
if (block->isVar) {
|
||||
bool found = false;
|
||||
for (unsigned varIndex = 0; varIndex < varCount; ++varIndex) {
|
||||
if (StrCmp(block->data, varNames[varIndex])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dst->Add(varValues[varIndex], StrLen(varValues[varIndex]));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
foundAll &= found;
|
||||
}
|
||||
else {
|
||||
dst->Add(block->data, block->strLen);
|
||||
}
|
||||
}
|
||||
dst->Push(0);
|
||||
|
||||
return foundAll;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
bool ParseForSubst (
|
||||
SubstParsedData<wchar> * dest,
|
||||
const wchar src[]
|
||||
) {
|
||||
return IParseForSubst(dest, src);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool ParseForSubst (
|
||||
SubstParsedData<char> * dest,
|
||||
const char src[]
|
||||
) {
|
||||
return IParseForSubst(dest, src);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool VarSubstitute (
|
||||
ARRAY(wchar) * dst,
|
||||
const wchar src[],
|
||||
unsigned varCount,
|
||||
const wchar * varNames[], // [varCount]
|
||||
const wchar * varValues[] // [varCount]
|
||||
) {
|
||||
return IVarSubstitute(dst, src, varCount, varNames, varValues);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool VarSubstitute (
|
||||
ARRAY(char) * dst,
|
||||
const char src[],
|
||||
unsigned varCount,
|
||||
const char * varNames[], // [varCount]
|
||||
const char * varValues[] // [varCount]
|
||||
) {
|
||||
return IVarSubstitute(dst, src, varCount, varNames, varValues);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool VarSubstitute (
|
||||
ARRAY(wchar) * dst,
|
||||
const SubstParsedData<wchar> * src,
|
||||
unsigned varCount,
|
||||
const wchar * varNames[], // [varCount]
|
||||
const wchar * varValues[] // [varCount]
|
||||
) {
|
||||
return IVarSubstPreParsed(dst, src, varCount, varNames, varValues);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool VarSubstitute (
|
||||
ARRAY(char) * dst,
|
||||
const SubstParsedData<char> * src,
|
||||
unsigned varCount,
|
||||
const char * varNames[], // [varCount]
|
||||
const char * varValues[] // [varCount]
|
||||
) {
|
||||
return IVarSubstPreParsed(dst, src, varCount, varNames, varValues);
|
||||
}
|
119
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSubst.h
Normal file
119
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSubst.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*==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/pnUtSubst.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSUBST_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSubst.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSUBST_H
|
||||
|
||||
template<typename chartype>
|
||||
struct SubstParsedData {
|
||||
template<typename chartype>
|
||||
struct SubstBlock {
|
||||
bool isVar;
|
||||
chartype * data;
|
||||
unsigned strLen;
|
||||
|
||||
SubstBlock()
|
||||
: isVar(false)
|
||||
, data(nil)
|
||||
{
|
||||
}
|
||||
|
||||
~SubstBlock() {
|
||||
FREE(data);
|
||||
}
|
||||
};
|
||||
|
||||
ARRAY(SubstBlock<chartype>*) blocks;
|
||||
|
||||
~SubstParsedData() {
|
||||
for (unsigned i = 0; i < blocks.Count(); ++i) {
|
||||
SubstBlock<chartype> * block = blocks[i];
|
||||
DEL(block);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool ParseForSubst (
|
||||
SubstParsedData<wchar> * dest,
|
||||
const wchar src[]
|
||||
);
|
||||
bool ParseForSubst (
|
||||
SubstParsedData<char> * dest,
|
||||
const char src[]
|
||||
);
|
||||
|
||||
// Return value is for validation purposes only; it may be ignored
|
||||
bool VarSubstitute (
|
||||
ARRAY(wchar) * dst,
|
||||
const wchar src[],
|
||||
unsigned varCount,
|
||||
const wchar * varNames[], // [varCount]
|
||||
const wchar * varValues[] // [varCount]
|
||||
);
|
||||
bool VarSubstitute (
|
||||
ARRAY(char) * dst,
|
||||
const char src[],
|
||||
unsigned varCount,
|
||||
const char * varNames[], // [varCount]
|
||||
const char * varValues[] // [varCount]
|
||||
);
|
||||
bool VarSubstitute (
|
||||
ARRAY(wchar) * dst,
|
||||
const SubstParsedData<wchar> * src,
|
||||
unsigned varCount,
|
||||
const wchar * varNames[], // [varCount]
|
||||
const wchar * varValues[] // [varCount]
|
||||
);
|
||||
bool VarSubstitute (
|
||||
ARRAY(char) * dst,
|
||||
const SubstParsedData<char> * src,
|
||||
unsigned varCount,
|
||||
const char * varNames[], // [varCount]
|
||||
const char * varValues[] // [varCount]
|
||||
);
|
134
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSync.h
Normal file
134
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSync.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*==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/pnUtSync.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSYNC_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtSync.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTSYNC_H
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Atomic operations
|
||||
*
|
||||
***/
|
||||
|
||||
// *value += increment; return original value of *value; thread safe
|
||||
long AtomicAdd (long * value, long increment);
|
||||
|
||||
// *value = value; return original value of *value; thread safe
|
||||
long AtomicSet (long * value, long set);
|
||||
|
||||
|
||||
#define ATOMIC_ONCE(code) { \
|
||||
static long s_count = 1; \
|
||||
if (AtomicSet(&s_count, 0)) \
|
||||
code; \
|
||||
} //
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CLock
|
||||
* (reader/writer lock)
|
||||
*
|
||||
***/
|
||||
|
||||
class CLockWaitSet;
|
||||
|
||||
class CLock {
|
||||
private:
|
||||
CLockWaitSet * m_waitSet;
|
||||
long m_spinLock;
|
||||
unsigned m_readerCount;
|
||||
unsigned m_writerCount;
|
||||
|
||||
public:
|
||||
CLock ();
|
||||
~CLock ();
|
||||
void EnterRead ();
|
||||
void EnterWrite ();
|
||||
void LeaveRead ();
|
||||
void LeaveWrite ();
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* CEvent
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
typedef HANDLE EventHandle;
|
||||
#else
|
||||
# error "CEvent: Not implemented on this platform"
|
||||
#endif
|
||||
|
||||
const unsigned kEventWaitForever = (unsigned)-1;
|
||||
|
||||
enum ECEventResetBehavior {
|
||||
kEventManualReset,
|
||||
kEventAutoReset,
|
||||
};
|
||||
|
||||
class CEvent {
|
||||
EventHandle m_handle;
|
||||
public:
|
||||
CEvent (
|
||||
ECEventResetBehavior resetType,
|
||||
bool initialSet = false
|
||||
);
|
||||
~CEvent ();
|
||||
|
||||
void Signal ();
|
||||
void Reset ();
|
||||
bool Wait (unsigned waitMs);
|
||||
|
||||
const EventHandle & Handle () const { return m_handle; }
|
||||
};
|
||||
|
92
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTime.cpp
Normal file
92
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTime.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*==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/pnUtTime.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//===========================================================================
|
||||
void TimeGetElapsedDesc (
|
||||
dword minutesElapsed,
|
||||
TimeElapsedDesc * desc
|
||||
) {
|
||||
|
||||
const unsigned kMinutesPerHour = 60;
|
||||
const unsigned kMinutesPerDay = 1440;
|
||||
const unsigned kMinutesPerWeek = 10080;
|
||||
const unsigned kMinutesPerMonth = 43830;
|
||||
const unsigned kMinutesPerYear = 525960;
|
||||
|
||||
dword & elapsed = minutesElapsed;
|
||||
desc->years = (elapsed / kMinutesPerYear); elapsed -= desc->years * kMinutesPerYear;
|
||||
desc->months = (elapsed / kMinutesPerMonth); elapsed -= desc->months * kMinutesPerMonth;
|
||||
desc->weeks = (elapsed / kMinutesPerWeek); elapsed -= desc->weeks * kMinutesPerWeek;
|
||||
desc->days = (elapsed / kMinutesPerDay); elapsed -= desc->days * kMinutesPerDay;
|
||||
desc->hours = (elapsed / kMinutesPerHour); elapsed -= desc->hours * kMinutesPerHour;
|
||||
desc->minutes = elapsed;
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
dword TimeGetSecondsSince2001Utc () {
|
||||
qword time = TimeGetTime();
|
||||
dword seconds = (dword)((time - kTime1601To2001) / kTimeIntervalsPerSecond);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
dword TimeGetSecondsSince1970Utc () {
|
||||
qword time = TimeGetTime();
|
||||
dword seconds = (dword)((time - kTime1601To1970) / kTimeIntervalsPerSecond);
|
||||
return seconds;
|
||||
}
|
129
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTime.h
Normal file
129
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTime.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*==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/pnUtTime.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTIME_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTime.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTIME_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Time formatting functions
|
||||
*
|
||||
***/
|
||||
|
||||
struct TimeDesc {
|
||||
unsigned year;
|
||||
unsigned month; // [1, 12]
|
||||
unsigned day;
|
||||
unsigned dayOfWeek; // [0, 6]
|
||||
unsigned hour; // [0, 23]
|
||||
unsigned minute; // [0, 59]
|
||||
unsigned second; // [0, 59]
|
||||
};
|
||||
|
||||
struct TimeElapsedDesc {
|
||||
unsigned years;
|
||||
unsigned months; // [0, 12]
|
||||
unsigned days; // [0, 7]
|
||||
unsigned weeks; // [0, 6]
|
||||
unsigned hours; // [0, 23]
|
||||
unsigned minutes; // [0, 59]
|
||||
};
|
||||
|
||||
void TimeGetDesc (
|
||||
qword time,
|
||||
TimeDesc * desc
|
||||
);
|
||||
|
||||
void TimeGetElapsedDesc (
|
||||
dword minutesElapsed,
|
||||
TimeElapsedDesc * desc
|
||||
);
|
||||
|
||||
void TimePrettyPrint (
|
||||
qword time,
|
||||
unsigned chars,
|
||||
wchar * buffer
|
||||
);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Time query functions
|
||||
*
|
||||
***/
|
||||
|
||||
const qword kTimeIntervalsPerMs = 10000;
|
||||
const qword kTimeIntervalsPerSecond = 1000 * kTimeIntervalsPerMs;
|
||||
const qword kTimeIntervalsPerMinute = 60 * kTimeIntervalsPerSecond;
|
||||
const qword kTimeIntervalsPerHour = 60 * kTimeIntervalsPerMinute;
|
||||
const qword kTimeIntervalsPerDay = 24 * kTimeIntervalsPerHour;
|
||||
|
||||
// millisecond timer; wraps ~49 days
|
||||
dword TimeGetMs ();
|
||||
|
||||
// 100 nanosecond intervals; won't wrap in our lifetimes
|
||||
qword TimeGetTime ();
|
||||
qword TimeGetLocalTime ();
|
||||
|
||||
// Minutes elapsed since 2001 UTC
|
||||
dword TimeGetMinutes ();
|
||||
|
||||
// Seconds elapsed since 00:00:00 January 1, 2001 UTC
|
||||
dword TimeGetSecondsSince2001Utc ();
|
||||
|
||||
// Seconds elapsed since 00:00:00 January 1, 1970 UTC (the Unix Epoch)
|
||||
dword TimeGetSecondsSince1970Utc ();
|
||||
|
||||
|
||||
// These magic numbers taken from Microsoft's "Shared Source CLI implementation" source code.
|
||||
// http://msdn.microsoft.com/library/en-us/Dndotnet/html/mssharsourcecli.asp
|
||||
|
||||
static const qword kTime1601To1970 = 11644473600 * kTimeIntervalsPerSecond;
|
||||
static const qword kTime1601To2001 = 12622780800 * kTimeIntervalsPerSecond;
|
83
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTls.cpp
Normal file
83
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTls.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*==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/pnUtTls.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
|
||||
//============================================================================
|
||||
void ThreadLocalAlloc (unsigned * id) {
|
||||
ASSERT(id);
|
||||
*id = TlsAlloc();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void ThreadLocalFree (unsigned id) {
|
||||
(void)TlsFree(id);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void * ThreadLocalGetValue (unsigned id) {
|
||||
return TlsGetValue(id);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void ThreadLocalSetValue (unsigned id, void * value) {
|
||||
TlsSetValue(id, value);
|
||||
}
|
||||
|
||||
#else
|
||||
# error "TLS not implemented for this platform"
|
||||
#endif
|
72
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTls.h
Normal file
72
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTls.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*==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/pnUtTls.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTLS_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTls.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTLS_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Thread local storage functions
|
||||
*
|
||||
***/
|
||||
|
||||
const unsigned kTlsInvalidValue = (unsigned) -1;
|
||||
|
||||
void ThreadLocalAlloc (unsigned * id);
|
||||
void ThreadLocalFree (unsigned id);
|
||||
void * ThreadLocalGetValue (unsigned id);
|
||||
void ThreadLocalSetValue (unsigned id, void * value);
|
||||
|
||||
|
||||
// Thread capability functions - prevents deadlocks and performance
|
||||
// bottlenecks by disallowing some threads certain operations.
|
||||
void ThreadAllowBlock ();
|
||||
void ThreadDenyBlock ();
|
||||
void ThreadAssertCanBlock (const char file[], int line);
|
57
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTypes.h
Normal file
57
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTypes.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*==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/pnUtTypes.h
|
||||
*
|
||||
*
|
||||
* By Eric Anderson (10/10/2005)
|
||||
* Copyright 2005 Cyan Worlds, Inc.
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTYPES_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtTypes.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTTYPES_H
|
||||
|
||||
|
103
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtUuid.cpp
Normal file
103
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtUuid.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/*==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/pnUtUuid.cpp
|
||||
*
|
||||
***/
|
||||
|
||||
#include "../Pch.h"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
const Uuid kNilGuid;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Exports
|
||||
*
|
||||
***/
|
||||
|
||||
//============================================================================
|
||||
Uuid::Uuid (const wchar str[]) {
|
||||
|
||||
GuidFromString(str, this);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
Uuid::Uuid (const byte buf[], unsigned length) {
|
||||
|
||||
GuidFromHex(buf, length, this);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
unsigned GuidHash (const Uuid & uuid) {
|
||||
|
||||
CHashValue hash(&uuid.data, sizeof(uuid.data));
|
||||
return hash.GetHash();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
static const wchar s_hexChars[] = L"0123456789ABCDEF";
|
||||
const wchar * GuidToHex (const Uuid & uuid, wchar * dst, unsigned chars) {
|
||||
|
||||
wchar * str = ALLOCA(wchar, sizeof(uuid.data) * 2 + 1);
|
||||
wchar * cur = str;
|
||||
|
||||
for (unsigned i = 0; i < sizeof(uuid.data); ++i) {
|
||||
*cur++ = s_hexChars[(uuid.data[i] >> 4) & 0x0f];
|
||||
*cur++ = s_hexChars[uuid.data[i] & 0x0f];
|
||||
}
|
||||
*cur = 0;
|
||||
|
||||
StrCopy(dst, str, chars);
|
||||
return dst;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool GuidFromHex (const byte buf[], unsigned length, Uuid * uuid) {
|
||||
|
||||
ASSERT(length == msizeof(Uuid, data));
|
||||
MemCopy(uuid->data, buf, msizeof(Uuid, data));
|
||||
return true;
|
||||
}
|
119
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtUuid.h
Normal file
119
Sources/Plasma/NucleusLib/pnUtils/Private/pnUtUuid.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*==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/pnUtUuid.h
|
||||
*
|
||||
***/
|
||||
|
||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTUUID_H
|
||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtUuid.h included more than once"
|
||||
#endif
|
||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTUUID_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
***/
|
||||
|
||||
struct Uuid;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
***/
|
||||
|
||||
extern const Uuid kNilGuid;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
***/
|
||||
|
||||
// Using 'Guid' here instead of 'Uuid' to avoid name clash with windows API =(
|
||||
|
||||
Uuid GuidGenerate ();
|
||||
void GuidClear (Uuid * uuid);
|
||||
bool GuidFromString (const wchar str[], Uuid * uuid);
|
||||
bool GuidFromString (const char str[], Uuid * uuid);
|
||||
int GuidCompare (const Uuid & a, const Uuid & b);
|
||||
inline bool GuidsAreEqual (const Uuid & a, const Uuid & b) { return 0 == GuidCompare(a, b); }
|
||||
bool GuidIsNil (const Uuid & uuid);
|
||||
unsigned GuidHash (const Uuid & uuid);
|
||||
const wchar * GuidToString (const Uuid & uuid, wchar * dst, unsigned chars); // returns dst
|
||||
const char * GuidToString (const Uuid & uuid, char * dst, unsigned chars); // returns dst
|
||||
const wchar * GuidToHex (const Uuid & uuid, wchar * dst, unsigned chars); // returns dst
|
||||
bool GuidFromHex (const byte buf[], unsigned length, Uuid * uuid);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Uuid
|
||||
*
|
||||
***/
|
||||
|
||||
#include <PshPack1.h>
|
||||
struct Uuid {
|
||||
union {
|
||||
dword dwords[4];
|
||||
byte data[16];
|
||||
};
|
||||
|
||||
Uuid () {}
|
||||
Uuid (const wchar str[]);
|
||||
Uuid (const byte buf[], unsigned length);
|
||||
operator bool () const { return !GuidIsNil(*this); }
|
||||
inline bool operator ! () const { return GuidIsNil(*this); }
|
||||
inline bool operator < (const Uuid & rhs) const { return GuidCompare(*this, rhs) < 0; }
|
||||
inline bool operator == (const Uuid & rhs) const { return GuidsAreEqual(*this, rhs); }
|
||||
inline bool operator == (int rhs) const { REF(rhs); ASSERT(!rhs); return GuidsAreEqual(*this, kNilGuid); }
|
||||
inline bool operator != (const Uuid & rhs) const { return !GuidsAreEqual(*this, rhs); }
|
||||
inline bool operator != (int rhs) const { REF(rhs); ASSERT(!rhs); return !GuidsAreEqual(*this, kNilGuid); }
|
||||
};
|
||||
#include <PopPack.h>
|
||||
|
||||
|
Reference in New Issue
Block a user