You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1217 lines
41 KiB
1217 lines
41 KiB
/*==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/pnNetProtocol/Private/pnNpCommon.cpp |
|
* |
|
***/ |
|
|
|
#include "../Pch.h" |
|
#pragma hdrstop |
|
|
|
|
|
|
|
namespace pnNpCommon { |
|
|
|
// Verify our qword constants were properly inited as such. |
|
COMPILER_ASSERT(NetVaultNode::kBlob_2); |
|
|
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* Local data |
|
* |
|
***/ |
|
|
|
const unsigned kNumBlobFields = 4; |
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* Internal functions |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IReadValue (T * value, byte ** buffer, unsigned * bufsz) { |
|
ASSERT(*bufsz >= sizeof(T)); |
|
*value = *(T *)*buffer; |
|
*buffer += sizeof(T); |
|
*bufsz -= sizeof(T); |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IReadArray (T ** buf, unsigned * elems, byte ** buffer, unsigned * bufsz) { |
|
dword bytes; |
|
IReadValue(&bytes, buffer, bufsz); |
|
ASSERT(bytes % sizeof(T) == 0); |
|
*elems = bytes / sizeof(T); |
|
T * src = (T *)*buffer; |
|
DEL(*buf); |
|
*buf = (T *)ALLOC(bytes); |
|
MemCopy(*buf, src, bytes); |
|
*buffer += bytes; |
|
*bufsz -= bytes; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IReadString (T ** buf, byte ** buffer, unsigned * bufsz) { |
|
unsigned elems; |
|
IReadArray(buf, &elems, buffer, bufsz); |
|
// ensure the string is null-terminated |
|
if (elems) |
|
(*buf)[elems-1] = 0; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IWriteValue (const T & value, ARRAY(byte) * buffer) { |
|
T * ptr = (T *) buffer->New(sizeof(T)); |
|
*ptr = value; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IWriteArray (const T buf[], unsigned elems, ARRAY(byte) * buffer) { |
|
unsigned bytes = elems * sizeof(T); |
|
IWriteValue(bytes, buffer); |
|
T * dst = (T *) buffer->New(bytes); |
|
MemCopy(dst, buf, bytes); |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void IWriteString (const T str[], ARRAY(byte) * buffer) { |
|
IWriteArray(str, StrLen(str) + 1, buffer); |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline bool ICompareValue (const T & lhs, const T & rhs) { |
|
return lhs == rhs; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline bool ICompareString (const T lhs[], const T rhs[]) { |
|
if (!lhs && !rhs) |
|
return true; |
|
if (!lhs || !rhs) |
|
return false; |
|
return 0 == StrCmp(lhs, rhs); |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline bool ICompareStringI (const T lhs[], const T rhs[]) { |
|
if (!lhs && !rhs) |
|
return true; |
|
if (!lhs || !rhs) |
|
return false; |
|
return 0 == StrCmpI(lhs, rhs); |
|
} |
|
|
|
//============================================================================ |
|
static inline bool ICompareArray (const byte lhs[], const byte rhs[]) { |
|
REF(lhs); |
|
REF(rhs); |
|
return false; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void ICopyValue (T * plhs, const T & rhs) { |
|
*plhs = rhs; |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static inline void ICopyString (T ** plhs, const T rhs[]) { |
|
FREE(*plhs); |
|
if (rhs) |
|
*plhs = StrDup(rhs); |
|
else |
|
*plhs = StrDup(""); |
|
} |
|
|
|
//============================================================================ |
|
static inline void ICopyString (wchar ** plhs, const wchar rhs[]) { |
|
FREE(*plhs); |
|
if (rhs) |
|
*plhs = StrDup(rhs); |
|
else |
|
*plhs = StrDup(L""); |
|
} |
|
|
|
//============================================================================ |
|
template <typename T> |
|
static bool IStrSqlEscape (const T src[], T * dst, unsigned dstChars) { |
|
|
|
// count the number of ' chars |
|
unsigned ticks = 0; |
|
{ |
|
const T * cur = src; |
|
while (*cur) { |
|
if (*cur == L'\'') |
|
++ticks; |
|
cur++; |
|
} |
|
} |
|
|
|
unsigned reqChars = StrLen(src) + ticks + 1; |
|
|
|
if (dstChars < reqChars) |
|
// failure! |
|
return false; |
|
|
|
T * cur = dst; |
|
|
|
// copy src to dst, escaping ' chars |
|
while (*src) { |
|
if (*src == L'\'') { |
|
*cur++ = L'\''; |
|
*cur++ = *src++; |
|
continue; |
|
} |
|
*cur++ = *src++; |
|
} |
|
|
|
// null-terminate dst string |
|
*cur = 0; |
|
|
|
// success! |
|
return true; |
|
} |
|
|
|
|
|
} using namespace pnNpCommon; |
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* NetGameScore |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
unsigned NetGameScore::Read(const byte inbuffer[], unsigned bufsz, byte** end) { |
|
|
|
byte * buffer = const_cast<byte *>(inbuffer); |
|
byte * start = buffer; |
|
|
|
wchar* tempstr = nil; |
|
|
|
IReadValue(&scoreId, &buffer, &bufsz); |
|
IReadValue(&ownerId, &buffer, &bufsz); |
|
IReadValue(&createdTime, &buffer, &bufsz); |
|
IReadValue(&gameType, &buffer, &bufsz); |
|
IReadValue(&value, &buffer, &bufsz); |
|
IReadString(&tempstr, &buffer, &bufsz); |
|
|
|
StrCopy(gameName, tempstr, arrsize(gameName)); |
|
DEL(tempstr); |
|
|
|
if (end) |
|
*end = buffer; |
|
|
|
return buffer - start; |
|
} |
|
|
|
//============================================================================ |
|
unsigned NetGameScore::Write(ARRAY(byte) * buffer) const { |
|
|
|
unsigned pos = buffer->Count(); |
|
|
|
IWriteValue(scoreId, buffer); |
|
IWriteValue(ownerId, buffer); |
|
IWriteValue(createdTime, buffer); |
|
IWriteValue(gameType, buffer); |
|
IWriteValue(value, buffer); |
|
IWriteString(gameName, buffer); |
|
|
|
return buffer->Count() - pos; |
|
} |
|
|
|
//============================================================================ |
|
void NetGameScore::CopyFrom(const NetGameScore & score) { |
|
scoreId = score.scoreId; |
|
ownerId = score.ownerId; |
|
createdTime = score.createdTime; |
|
gameType = score.gameType; |
|
value = score.value; |
|
StrCopy(gameName, score.gameName, arrsize(gameName)); |
|
} |
|
|
|
/***************************************************************************** |
|
* |
|
* NetGameRank |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
unsigned NetGameRank::Read(const byte inbuffer[], unsigned bufsz, byte** end) { |
|
|
|
byte * buffer = const_cast<byte *>(inbuffer); |
|
byte * start = buffer; |
|
|
|
wchar* tempstr = nil; |
|
|
|
IReadValue(&rank, &buffer, &bufsz); |
|
IReadValue(&score, &buffer, &bufsz); |
|
IReadString(&tempstr, &buffer, &bufsz); |
|
|
|
StrCopy(name, tempstr, arrsize(name)); |
|
DEL(tempstr); |
|
|
|
if (end) |
|
*end = buffer; |
|
|
|
return buffer - start; |
|
} |
|
|
|
//============================================================================ |
|
unsigned NetGameRank::Write(ARRAY(byte) * buffer) const { |
|
|
|
unsigned pos = buffer->Count(); |
|
|
|
IWriteValue(rank, buffer); |
|
IWriteValue(score, buffer); |
|
IWriteString(name, buffer); |
|
|
|
return buffer->Count() - pos; |
|
} |
|
|
|
//============================================================================ |
|
void NetGameRank::CopyFrom(const NetGameRank & fromRank) { |
|
rank = fromRank.rank; |
|
score = fromRank.score; |
|
StrCopy(name, fromRank.name, arrsize(name)); |
|
} |
|
|
|
/***************************************************************************** |
|
* |
|
* NetVaultNode |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
static void DeallocNodeFields (NetVaultNode * node) { |
|
for (qword fieldFlag = 1; fieldFlag; fieldFlag <<= 1) { |
|
if (fieldFlag > node->fieldFlags) |
|
break; |
|
|
|
#define DELFIELD(f, v) case (qword)(NetVaultNode::f): DEL(node->v); node->v = nil; break |
|
switch (fieldFlag & node->fieldFlags) { |
|
DELFIELD(kCreateAgeName, createAgeName); |
|
DELFIELD(kString64_1, string64_1); |
|
DELFIELD(kString64_2, string64_2); |
|
DELFIELD(kString64_3, string64_3); |
|
DELFIELD(kString64_4, string64_4); |
|
DELFIELD(kString64_5, string64_5); |
|
DELFIELD(kString64_6, string64_6); |
|
DELFIELD(kIString64_1, istring64_1); |
|
DELFIELD(kIString64_2, istring64_2); |
|
DELFIELD(kText_1, text_1); |
|
DELFIELD(kText_2, text_2); |
|
DELFIELD(kBlob_1, blob_1); |
|
DELFIELD(kBlob_2, blob_2); |
|
default: break; |
|
} |
|
} |
|
} |
|
|
|
//============================================================================ |
|
NetVaultNode::NetVaultNode () { |
|
ASSERTMSG(!fieldFlags, "NetVaultNode instances must be allocated with NEWZERO"); |
|
} |
|
|
|
//============================================================================ |
|
NetVaultNode::~NetVaultNode () { |
|
DeallocNodeFields(this); |
|
} |
|
|
|
//============================================================================ |
|
unsigned NetVaultNode::Read_LCS (const byte inbuffer[], unsigned bufsz, unsigned rwOpts) { |
|
|
|
DeallocNodeFields(this); |
|
|
|
byte * buffer = const_cast<byte *>(inbuffer); |
|
byte * start = buffer; |
|
|
|
IReadValue(&fieldFlags, &buffer, &bufsz); |
|
|
|
for (qword bit = 1; bit; bit <<= 1) { |
|
|
|
// if we've passed all fields on the node then bail |
|
if (bit > fieldFlags) |
|
break; |
|
|
|
// if this field isn't in the set to be read, then continue to next |
|
if (!(bit & fieldFlags)) |
|
continue; |
|
|
|
#define READ(flag, func, varptr) case flag: func(varptr, &buffer, &bufsz); break |
|
#define READARR(flag, func, varptr, lenptr) case flag: func(varptr, lenptr, &buffer, &bufsz); break |
|
switch (bit) { |
|
READ(kNodeId, IReadValue, &nodeId); |
|
READ(kCreateTime, IReadValue, &createTime); |
|
READ(kModifyTime, IReadValue, &modifyTime); |
|
READ(kCreateAgeName,IReadString, &createAgeName); |
|
READ(kCreateAgeUuid,IReadValue, &createAgeUuid); |
|
READ(kCreatorAcct, IReadValue, &creatorAcct); |
|
READ(kCreatorId, IReadValue, &creatorId); |
|
READ(kNodeType, IReadValue, &nodeType); |
|
READ(kInt32_1, IReadValue, &int32_1); |
|
READ(kInt32_2, IReadValue, &int32_2); |
|
READ(kInt32_3, IReadValue, &int32_3); |
|
READ(kInt32_4, IReadValue, &int32_4); |
|
READ(kUInt32_1, IReadValue, &uint32_1); |
|
READ(kUInt32_2, IReadValue, &uint32_2); |
|
READ(kUInt32_3, IReadValue, &uint32_3); |
|
READ(kUInt32_4, IReadValue, &uint32_4); |
|
READ(kUuid_1, IReadValue, &uuid_1); |
|
READ(kUuid_2, IReadValue, &uuid_2); |
|
READ(kUuid_3, IReadValue, &uuid_3); |
|
READ(kUuid_4, IReadValue, &uuid_4); |
|
READ(kString64_1, IReadString, &string64_1); |
|
READ(kString64_2, IReadString, &string64_2); |
|
READ(kString64_3, IReadString, &string64_3); |
|
READ(kString64_4, IReadString, &string64_4); |
|
READ(kString64_5, IReadString, &string64_5); |
|
READ(kString64_6, IReadString, &string64_6); |
|
READ(kIString64_1, IReadString, &istring64_1); |
|
READ(kIString64_2, IReadString, &istring64_2); |
|
READ(kText_1, IReadString, &text_1); |
|
READ(kText_2, IReadString, &text_2); |
|
READARR(kBlob_1, IReadArray, &blob_1, &blob_1Length); |
|
READARR(kBlob_2, IReadArray, &blob_2, &blob_2Length); |
|
DEFAULT_FATAL(bit); |
|
} |
|
#undef READARR |
|
#undef READ |
|
} |
|
|
|
if (rwOpts & kRwUpdateDirty) |
|
dirtyFlags = fieldFlags; |
|
else |
|
dirtyFlags = 0; |
|
|
|
return buffer - start; |
|
} |
|
|
|
//============================================================================ |
|
unsigned NetVaultNode::Write_LCS (ARRAY(byte) * buffer, unsigned rwOpts) { |
|
|
|
unsigned pos = buffer->Count(); |
|
|
|
qword flags = fieldFlags; |
|
|
|
if (rwOpts & kRwDirtyOnly) |
|
flags &= dirtyFlags; |
|
|
|
if (!flags) |
|
return 0; |
|
|
|
IWriteValue(flags, buffer); |
|
|
|
for (qword bit = 1; bit; bit <<= 1) { |
|
|
|
// if we've passed all fields on the node then bail |
|
if (bit > flags) |
|
break; |
|
|
|
// if this field isn't in the set to be written, then continue to next |
|
if (!(bit & flags)) |
|
continue; |
|
|
|
#define WRITE(flag, func, var) case flag: func(var, buffer); break |
|
#define WRITEARR(flag, func, var, len) case flag: func(var, len, buffer); break |
|
switch (bit) { |
|
WRITE(kNodeId, IWriteValue, nodeId ); |
|
WRITE(kCreateTime, IWriteValue, createTime ); |
|
WRITE(kModifyTime, IWriteValue, modifyTime ); |
|
WRITE(kCreateAgeName, IWriteString, createAgeName ? createAgeName : L"" ); |
|
WRITE(kCreateAgeUuid, IWriteValue, createAgeUuid ); |
|
WRITE(kCreatorAcct, IWriteValue, creatorAcct ); |
|
WRITE(kCreatorId, IWriteValue, creatorId ); |
|
WRITE(kNodeType, IWriteValue, nodeType ); |
|
WRITE(kInt32_1, IWriteValue, int32_1 ); |
|
WRITE(kInt32_2, IWriteValue, int32_2 ); |
|
WRITE(kInt32_3, IWriteValue, int32_3 ); |
|
WRITE(kInt32_4, IWriteValue, int32_4 ); |
|
WRITE(kUInt32_1, IWriteValue, uint32_1 ); |
|
WRITE(kUInt32_2, IWriteValue, uint32_2 ); |
|
WRITE(kUInt32_3, IWriteValue, uint32_3 ); |
|
WRITE(kUInt32_4, IWriteValue, uint32_4 ); |
|
WRITE(kUuid_1, IWriteValue, uuid_1 ); |
|
WRITE(kUuid_2, IWriteValue, uuid_2 ); |
|
WRITE(kUuid_3, IWriteValue, uuid_3 ); |
|
WRITE(kUuid_4, IWriteValue, uuid_4 ); |
|
WRITE(kString64_1, IWriteString, string64_1 ? string64_1 : L"" ); |
|
WRITE(kString64_2, IWriteString, string64_2 ? string64_2 : L"" ); |
|
WRITE(kString64_3, IWriteString, string64_3 ? string64_3 : L"" ); |
|
WRITE(kString64_4, IWriteString, string64_4 ? string64_4 : L"" ); |
|
WRITE(kString64_5, IWriteString, string64_5 ? string64_5 : L"" ); |
|
WRITE(kString64_6, IWriteString, string64_6 ? string64_6 : L"" ); |
|
WRITE(kIString64_1, IWriteString, istring64_1 ? istring64_1 : L"" ); |
|
WRITE(kIString64_2, IWriteString, istring64_2 ? istring64_2 : L"" ); |
|
WRITE(kText_1, IWriteString, text_1 ? text_1 : L"" ); |
|
WRITE(kText_2, IWriteString, text_2 ? text_2 : L"" ); |
|
WRITEARR(kBlob_1, IWriteArray, blob_1, blob_1Length); |
|
WRITEARR(kBlob_2, IWriteArray, blob_2, blob_2Length); |
|
DEFAULT_FATAL(bit); |
|
} |
|
#undef WRITEARR |
|
#undef WRITE |
|
} |
|
|
|
if (rwOpts & kRwUpdateDirty) |
|
dirtyFlags = 0; |
|
// else, preserve existing dirtyFlags value |
|
|
|
return buffer->Count() - pos; |
|
} |
|
|
|
//============================================================================ |
|
bool NetVaultNode::Matches (const NetVaultNode * other) { |
|
for (qword bit = 1; bit; bit <<= 1) { |
|
// if bit has gone past all set fields on the other node without failing, return true |
|
if (bit > other->fieldFlags) |
|
return true; |
|
|
|
// if the other node does not have the field, then continue to next field |
|
if (!(bit & other->fieldFlags)) |
|
continue; |
|
|
|
// if we don't have the field (but the other node does), then return false |
|
if (!(bit & fieldFlags)) |
|
return false; |
|
|
|
#define COMPARE(flag, func, var) case flag: if (!func(var, other->var)) return false; break |
|
switch (bit) { |
|
COMPARE(kNodeId, ICompareValue, nodeId); |
|
COMPARE(kCreateTime, ICompareValue, createTime); |
|
COMPARE(kModifyTime, ICompareValue, modifyTime); |
|
COMPARE(kCreateAgeName, ICompareStringI, createAgeName); |
|
COMPARE(kCreateAgeUuid, ICompareValue, createAgeUuid); |
|
COMPARE(kCreatorAcct, ICompareValue, creatorAcct); |
|
COMPARE(kCreatorId, ICompareValue, creatorId); |
|
COMPARE(kNodeType, ICompareValue, nodeType); |
|
COMPARE(kInt32_1, ICompareValue, int32_1); |
|
COMPARE(kInt32_2, ICompareValue, int32_2); |
|
COMPARE(kInt32_3, ICompareValue, int32_3); |
|
COMPARE(kInt32_4, ICompareValue, int32_4); |
|
COMPARE(kUInt32_1, ICompareValue, uint32_1); |
|
COMPARE(kUInt32_2, ICompareValue, uint32_2); |
|
COMPARE(kUInt32_3, ICompareValue, uint32_3); |
|
COMPARE(kUInt32_4, ICompareValue, uint32_4); |
|
COMPARE(kUuid_1, ICompareValue, uuid_1); |
|
COMPARE(kUuid_2, ICompareValue, uuid_2); |
|
COMPARE(kUuid_3, ICompareValue, uuid_3); |
|
COMPARE(kUuid_4, ICompareValue, uuid_4); |
|
COMPARE(kString64_1, ICompareString, string64_1); |
|
COMPARE(kString64_2, ICompareString, string64_2); |
|
COMPARE(kString64_3, ICompareString, string64_3); |
|
COMPARE(kString64_4, ICompareString, string64_4); |
|
COMPARE(kString64_5, ICompareString, string64_5); |
|
COMPARE(kString64_6, ICompareString, string64_6); |
|
COMPARE(kIString64_1, ICompareStringI, istring64_1); |
|
COMPARE(kIString64_2, ICompareStringI, istring64_2); |
|
COMPARE(kText_1, ICompareString, text_1); |
|
COMPARE(kText_2, ICompareString, text_2); |
|
COMPARE(kBlob_1, ICompareArray, blob_1); |
|
COMPARE(kBlob_2, ICompareArray, blob_2); |
|
DEFAULT_FATAL(bit); |
|
} |
|
#undef COMPARE |
|
} |
|
return true; |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::CopyFrom (const NetVaultNode * other, unsigned copyOpts) { |
|
if (this == other) |
|
return; |
|
|
|
qword origDirtyFlags = dirtyFlags; |
|
|
|
for (qword bit = 1; bit; bit <<= 1) { |
|
// we already have a value for this field... |
|
if (bit & fieldFlags) { |
|
if (!(copyOpts & kCopyOverwrite)) |
|
continue; // don't overwrite our field value |
|
} |
|
|
|
// other does not have a value for this field... |
|
if (!(bit & other->fieldFlags)) { |
|
// clear our field? |
|
if (!(copyOpts & kCopyClear)) |
|
continue; |
|
// clear our field. |
|
if (bit & fieldFlags) { |
|
#define _ZERO(flag, func, var, z) case flag: func(bit, this, &var, z); break |
|
#define _ZEROSTRING(flag, func, var, z) case flag: func(bit, this, &var, z, kMaxVaultNodeStringLength); break |
|
#define _ZEROCLOB(flag, func, var, z) case flag: func(bit, this, &var, z, (unsigned)-1); break |
|
#define _ZEROARR(flag, func, var, varlen) case flag: func(bit, this, &var, &varlen, nil, 0); break |
|
switch (bit) { |
|
_ZERO(kNodeId, IVaultNodeSetValue, nodeId, (unsigned)0); |
|
_ZERO(kCreateTime, IVaultNodeSetValue, createTime, (unsigned)0); |
|
_ZERO(kModifyTime, IVaultNodeSetValue, modifyTime, (unsigned)0); |
|
_ZEROSTRING(kCreateAgeName, IVaultNodeSetString, createAgeName, L""); |
|
_ZERO(kCreateAgeUuid, IVaultNodeSetValue, createAgeUuid, kNilGuid); |
|
_ZERO(kCreatorAcct, IVaultNodeSetValue, creatorAcct, kNilGuid); |
|
_ZERO(kCreatorId, IVaultNodeSetValue, creatorId, (unsigned)0); |
|
_ZERO(kNodeType, IVaultNodeSetValue, nodeType, (unsigned)0); |
|
_ZERO(kInt32_1, IVaultNodeSetValue, int32_1, (signed)0); |
|
_ZERO(kInt32_2, IVaultNodeSetValue, int32_2, (signed)0); |
|
_ZERO(kInt32_3, IVaultNodeSetValue, int32_3, (signed)0); |
|
_ZERO(kInt32_4, IVaultNodeSetValue, int32_4, (signed)0); |
|
_ZERO(kUInt32_1, IVaultNodeSetValue, uint32_1, (unsigned)0); |
|
_ZERO(kUInt32_2, IVaultNodeSetValue, uint32_2, (unsigned)0); |
|
_ZERO(kUInt32_3, IVaultNodeSetValue, uint32_3, (unsigned)0); |
|
_ZERO(kUInt32_4, IVaultNodeSetValue, uint32_4, (unsigned)0); |
|
_ZERO(kUuid_1, IVaultNodeSetValue, uuid_1, kNilGuid); |
|
_ZERO(kUuid_2, IVaultNodeSetValue, uuid_2, kNilGuid); |
|
_ZERO(kUuid_3, IVaultNodeSetValue, uuid_3, kNilGuid); |
|
_ZERO(kUuid_4, IVaultNodeSetValue, uuid_4, kNilGuid); |
|
_ZEROSTRING(kString64_1, IVaultNodeSetString, string64_1, L""); |
|
_ZEROSTRING(kString64_2, IVaultNodeSetString, string64_2, L""); |
|
_ZEROSTRING(kString64_3, IVaultNodeSetString, string64_3, L""); |
|
_ZEROSTRING(kString64_4, IVaultNodeSetString, string64_4, L""); |
|
_ZEROSTRING(kString64_5, IVaultNodeSetString, string64_5, L""); |
|
_ZEROSTRING(kString64_6, IVaultNodeSetString, string64_6, L""); |
|
_ZEROSTRING(kIString64_1, IVaultNodeSetString, istring64_1, L""); |
|
_ZEROSTRING(kIString64_2, IVaultNodeSetString, istring64_2, L""); |
|
_ZEROCLOB(kText_1, IVaultNodeSetString, text_1, L""); |
|
_ZEROCLOB(kText_2, IVaultNodeSetString, text_2, L""); |
|
_ZEROARR(kBlob_1, IVaultNodeSetBlob, blob_1, blob_1Length); |
|
_ZEROARR(kBlob_2, IVaultNodeSetBlob, blob_2, blob_2Length); |
|
DEFAULT_FATAL(bit); |
|
} |
|
#undef _ZEROARR |
|
#undef _ZEROCLOB |
|
#undef _ZEROSTRING |
|
#undef _ZERO |
|
} |
|
} |
|
|
|
#define COPY(flag, func, var) case flag: func(bit, this, &var, other->var); break |
|
#define COPYSTRING(flag, func, var) case flag: func(bit, this, &var, other->var, kMaxVaultNodeStringLength); break |
|
#define COPYCLOB(flag, func, var) case flag: func(bit, this, &var, other->var, (unsigned)-1); break |
|
#define COPYARR(flag, func, var, varlen) case flag: func(bit, this, &var, &varlen, other->var, other->varlen); break |
|
switch (bit) { |
|
COPY(kNodeId, IVaultNodeSetValue, nodeId ); |
|
COPY(kCreateTime, IVaultNodeSetValue, createTime ); |
|
COPY(kModifyTime, IVaultNodeSetValue, modifyTime ); |
|
COPYSTRING(kCreateAgeName, IVaultNodeSetString, createAgeName ); |
|
COPY(kCreateAgeUuid, IVaultNodeSetValue, createAgeUuid ); |
|
COPY(kCreatorAcct, IVaultNodeSetValue, creatorAcct ); |
|
COPY(kCreatorId, IVaultNodeSetValue, creatorId ); |
|
COPY(kNodeType, IVaultNodeSetValue, nodeType ); |
|
COPY(kInt32_1, IVaultNodeSetValue, int32_1 ); |
|
COPY(kInt32_2, IVaultNodeSetValue, int32_2 ); |
|
COPY(kInt32_3, IVaultNodeSetValue, int32_3 ); |
|
COPY(kInt32_4, IVaultNodeSetValue, int32_4 ); |
|
COPY(kUInt32_1, IVaultNodeSetValue, uint32_1 ); |
|
COPY(kUInt32_2, IVaultNodeSetValue, uint32_2 ); |
|
COPY(kUInt32_3, IVaultNodeSetValue, uint32_3 ); |
|
COPY(kUInt32_4, IVaultNodeSetValue, uint32_4 ); |
|
COPY(kUuid_1, IVaultNodeSetValue, uuid_1 ); |
|
COPY(kUuid_2, IVaultNodeSetValue, uuid_2 ); |
|
COPY(kUuid_3, IVaultNodeSetValue, uuid_3 ); |
|
COPY(kUuid_4, IVaultNodeSetValue, uuid_4 ); |
|
COPYSTRING(kString64_1, IVaultNodeSetString, string64_1 ); |
|
COPYSTRING(kString64_2, IVaultNodeSetString, string64_2 ); |
|
COPYSTRING(kString64_3, IVaultNodeSetString, string64_3 ); |
|
COPYSTRING(kString64_4, IVaultNodeSetString, string64_4 ); |
|
COPYSTRING(kString64_5, IVaultNodeSetString, string64_5 ); |
|
COPYSTRING(kString64_6, IVaultNodeSetString, string64_6 ); |
|
COPYSTRING(kIString64_1, IVaultNodeSetString, istring64_1 ); |
|
COPYSTRING(kIString64_2, IVaultNodeSetString, istring64_2 ); |
|
COPYCLOB(kText_1, IVaultNodeSetString, text_1 ); |
|
COPYCLOB(kText_2, IVaultNodeSetString, text_2 ); |
|
COPYARR(kBlob_1, IVaultNodeSetBlob, blob_1, blob_1Length); |
|
COPYARR(kBlob_2, IVaultNodeSetBlob, blob_2, blob_2Length); |
|
DEFAULT_FATAL(bit); |
|
} |
|
#undef COPYARR |
|
#undef COPYCLOB |
|
#undef COPYSTRING |
|
#undef COPY |
|
} |
|
|
|
if (!(copyOpts & kCopySetDirty)) |
|
dirtyFlags = origDirtyFlags; |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetNodeId (unsigned v) { |
|
IVaultNodeSetValue(kNodeId, this, &nodeId, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetCreateTime (unsigned v) { |
|
IVaultNodeSetValue(kCreateTime, this, &createTime, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetModifyTime (unsigned v) { |
|
IVaultNodeSetValue(kModifyTime, this, &modifyTime, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetCreateAgeName (const wchar v[]) { |
|
IVaultNodeSetString(kCreateAgeName, this, &createAgeName, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetCreateAgeUuid (const Uuid & v) { |
|
IVaultNodeSetValue(kCreateAgeUuid, this, &createAgeUuid, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetCreatorAcct (const Uuid & v) { |
|
IVaultNodeSetValue(kCreatorAcct, this, &creatorAcct, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetCreatorId (unsigned v) { |
|
IVaultNodeSetValue(kCreatorId, this, &creatorId, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetNodeType (unsigned v) { |
|
IVaultNodeSetValue(kNodeType, this, &nodeType, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetInt32_1 (int v) { |
|
IVaultNodeSetValue(kInt32_1, this, &int32_1, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetInt32_2 (int v) { |
|
IVaultNodeSetValue(kInt32_2, this, &int32_2, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetInt32_3 (int v) { |
|
IVaultNodeSetValue(kInt32_3, this, &int32_3, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetInt32_4 (int v) { |
|
IVaultNodeSetValue(kInt32_4, this, &int32_4, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUInt32_1 (unsigned v) { |
|
IVaultNodeSetValue(kUInt32_1, this, &uint32_1, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUInt32_2 (unsigned v) { |
|
IVaultNodeSetValue(kUInt32_2, this, &uint32_2, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUInt32_3 (unsigned v) { |
|
IVaultNodeSetValue(kUInt32_3, this, &uint32_3, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUInt32_4 (unsigned v) { |
|
IVaultNodeSetValue(kUInt32_4, this, &uint32_4, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUuid_1 (const Uuid & v) { |
|
IVaultNodeSetValue(kUuid_1, this, &uuid_1, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUuid_2 (const Uuid & v) { |
|
IVaultNodeSetValue(kUuid_2, this, &uuid_2, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUuid_3 (const Uuid & v) { |
|
IVaultNodeSetValue(kUuid_3, this, &uuid_3, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetUuid_4 (const Uuid & v) { |
|
IVaultNodeSetValue(kUuid_4, this, &uuid_4, v); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_1 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_1, this, &string64_1, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_2 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_2, this, &string64_2, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_3 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_3, this, &string64_3, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_4 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_4, this, &string64_4, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_5 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_5, this, &string64_5, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetString64_6 (const wchar v[]) { |
|
IVaultNodeSetString(kString64_6, this, &string64_6, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetIString64_1 (const wchar v[]) { |
|
IVaultNodeSetString(kIString64_1, this, &istring64_1, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetIString64_2 (const wchar v[]) { |
|
IVaultNodeSetString(kIString64_2, this, &istring64_2, v, kMaxVaultNodeStringLength); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetText_1 (const wchar v[]) { |
|
IVaultNodeSetString(kText_1, this, &text_1, v, (unsigned)-1); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetText_2 (const wchar v[]) { |
|
IVaultNodeSetString(kText_2, this, &text_2, v, (unsigned)-1); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetBlob_1 (const byte v[], unsigned len) { |
|
IVaultNodeSetBlob(kBlob_1, this, &blob_1, &blob_1Length, v, len); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetBlob_2 (const byte v[], unsigned len) { |
|
IVaultNodeSetBlob(kBlob_2, this, &blob_2, &blob_2Length, v, len); |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetText (qword fieldFlag, const wchar v[]) { |
|
switch (fieldFlag) { |
|
case kText_1: SetText_1(v); break; |
|
case kText_2: SetText_2(v); break; |
|
DEFAULT_FATAL(fieldFlag); |
|
} |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNode::SetBlob (qword fieldFlag, const byte v[], unsigned len) { |
|
switch (fieldFlag) { |
|
case kBlob_1: SetBlob_1(v, len); break; |
|
case kBlob_2: SetBlob_2(v, len); break; |
|
DEFAULT_FATAL(fieldFlag); |
|
} |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* NetVaultNodeFieldArray |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
NetVaultNodeFieldArray::NetVaultNodeFieldArray (NetVaultNode * node) |
|
: node(node) |
|
{ |
|
node->IncRef("FieldArray"); |
|
fields.Add(Field(&node->nodeId, L"NodeId")); |
|
fields.Add(Field(&node->createTime, L"CreateTime")); |
|
fields.Add(Field(&node->modifyTime, L"ModifyTime")); |
|
fields.Add(Field(&node->createAgeName, L"CreateAgeName")); |
|
fields.Add(Field(&node->createAgeUuid, L"CreateAgeUuid")); |
|
fields.Add(Field(&node->creatorAcct, L"CreatorAcctId")); |
|
fields.Add(Field(&node->creatorId, L"CreatorId")); |
|
fields.Add(Field(&node->nodeType, L"NodeType")); |
|
fields.Add(Field(&node->int32_1, L"Int32_1")); |
|
fields.Add(Field(&node->int32_2, L"Int32_2")); |
|
fields.Add(Field(&node->int32_3, L"Int32_3")); |
|
fields.Add(Field(&node->int32_4, L"Int32_4")); |
|
fields.Add(Field(&node->uint32_1, L"UInt32_1")); |
|
fields.Add(Field(&node->uint32_2, L"UInt32_2")); |
|
fields.Add(Field(&node->uint32_3, L"UInt32_3")); |
|
fields.Add(Field(&node->uint32_4, L"UInt32_4")); |
|
fields.Add(Field(&node->uuid_1, L"Uuid_1")); |
|
fields.Add(Field(&node->uuid_2, L"Uuid_2")); |
|
fields.Add(Field(&node->uuid_3, L"Uuid_3")); |
|
fields.Add(Field(&node->uuid_4, L"Uuid_4")); |
|
fields.Add(Field(&node->string64_1, L"String64_1")); |
|
fields.Add(Field(&node->string64_2, L"String64_2")); |
|
fields.Add(Field(&node->string64_3, L"String64_3")); |
|
fields.Add(Field(&node->string64_4, L"String64_4")); |
|
fields.Add(Field(&node->string64_5, L"String64_5")); |
|
fields.Add(Field(&node->string64_6, L"String64_6")); |
|
fields.Add(Field(&node->istring64_1, L"IString64_1")); |
|
fields.Add(Field(&node->istring64_2, L"IString64_2")); |
|
fields.Add(Field(&node->text_1, L"Text_1")); |
|
fields.Add(Field(&node->text_2, L"Text_2")); |
|
fields.Add(Field(&node->blob_1, L"Blob_1")); |
|
fields.Add(Field(&node->blob_2, L"Blob_2")); |
|
} |
|
|
|
//============================================================================ |
|
NetVaultNodeFieldArray::~NetVaultNodeFieldArray () { |
|
fields.Clear(); |
|
node->DecRef("FieldArray"); |
|
} |
|
|
|
//============================================================================ |
|
void * NetVaultNodeFieldArray::GetFieldAddress (qword bit) { |
|
ASSERT(bit); |
|
|
|
unsigned index = 0; |
|
for (qword b = bit; b > 1; b >>= 1) |
|
++index; |
|
|
|
// do not return blob fields |
|
if (index < fields.Count() - kNumBlobFields) |
|
return fields[index].addr; |
|
else |
|
return nil; |
|
} |
|
|
|
//============================================================================ |
|
const wchar * NetVaultNodeFieldArray::GetFieldName (qword bit) { |
|
ASSERT(bit); |
|
|
|
unsigned index = 0; |
|
for (qword b = bit; b > 1; b >>= 1) |
|
++index; |
|
|
|
ASSERT(index < fields.Count()); |
|
return fields[index].name; |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNodeFieldArray::GetFieldValueString_LCS ( |
|
qword bit, |
|
wchar * dst, |
|
unsigned dstChars |
|
) { |
|
void * fieldAddr = GetFieldAddress(bit); |
|
|
|
switch (bit) { |
|
case NetVaultNode::kNodeId: |
|
case NetVaultNode::kCreatorId: |
|
case NetVaultNode::kCreateTime: |
|
case NetVaultNode::kModifyTime: |
|
case NetVaultNode::kNodeType: |
|
case NetVaultNode::kUInt32_1: |
|
case NetVaultNode::kUInt32_2: |
|
case NetVaultNode::kUInt32_3: |
|
case NetVaultNode::kUInt32_4: |
|
StrPrintf(dst, dstChars, L"%u", *(unsigned *)fieldAddr); |
|
break; |
|
|
|
case NetVaultNode::kInt32_1: |
|
case NetVaultNode::kInt32_2: |
|
case NetVaultNode::kInt32_3: |
|
case NetVaultNode::kInt32_4: |
|
StrPrintf(dst, dstChars, L"%i", *(int *)fieldAddr); |
|
break; |
|
|
|
case NetVaultNode::kCreateAgeUuid: |
|
case NetVaultNode::kCreatorAcct: |
|
case NetVaultNode::kUuid_1: |
|
case NetVaultNode::kUuid_2: |
|
case NetVaultNode::kUuid_3: |
|
case NetVaultNode::kUuid_4: { |
|
wchar tmp[64]; |
|
GuidToHex(*(Uuid *)fieldAddr, tmp, arrsize(tmp)); |
|
StrPrintf(dst, dstChars, L"hextoraw('%s')", tmp); |
|
} |
|
break; |
|
|
|
case NetVaultNode::kCreateAgeName: |
|
case NetVaultNode::kString64_1: |
|
case NetVaultNode::kString64_2: |
|
case NetVaultNode::kString64_3: |
|
case NetVaultNode::kString64_4: |
|
case NetVaultNode::kString64_5: |
|
case NetVaultNode::kString64_6: |
|
case NetVaultNode::kIString64_1: |
|
case NetVaultNode::kIString64_2: { |
|
wchar * tmp = ALLOCA(wchar, dstChars); |
|
IStrSqlEscape(*(wchar **)fieldAddr, tmp, dstChars); |
|
StrPrintf(dst, dstChars, L"'%s'", tmp); |
|
} |
|
break; |
|
|
|
// FIELD(Text_1); |
|
// FIELD(Text_2); |
|
// FIELD(Blob_1); |
|
// FIELD(Blob_2); |
|
DEFAULT_FATAL(bit); |
|
} |
|
} |
|
|
|
//============================================================================ |
|
void NetVaultNodeFieldArray::BuildWhereClause_LCS ( |
|
EWhereCondition condition, |
|
wchar * dst, |
|
unsigned dstChars |
|
) { |
|
if (!dstChars) |
|
return; |
|
|
|
dst[0] = 0; |
|
|
|
static const wchar * s_conditionStrs[] = { |
|
L" AND ", |
|
L" OR " |
|
}; |
|
|
|
unsigned fieldCount = 0; |
|
for (qword bit = 1; bit; bit <<= 1) { |
|
if (!(bit & node->fieldFlags)) |
|
continue; |
|
|
|
if (fieldCount++) |
|
StrPack(dst, s_conditionStrs[condition], dstChars); |
|
|
|
wchar str[256]; |
|
GetFieldValueString_LCS(bit, str, arrsize(str)); |
|
|
|
StrPack(dst, GetFieldName(bit), dstChars); |
|
StrPack(dst, L"=", dstChars); |
|
StrPack(dst, str, dstChars); |
|
} |
|
} |
|
|
|
//============================================================================ |
|
NetVaultNodeFieldArray::ESqlType NetVaultNodeFieldArray::GetSqlType_LCS (qword bit) { |
|
switch (bit) { |
|
case NetVaultNode::kNodeId: |
|
case NetVaultNode::kCreatorId: |
|
case NetVaultNode::kCreateTime: |
|
case NetVaultNode::kModifyTime: |
|
case NetVaultNode::kNodeType: |
|
case NetVaultNode::kUInt32_1: |
|
case NetVaultNode::kUInt32_2: |
|
case NetVaultNode::kUInt32_3: |
|
case NetVaultNode::kUInt32_4: |
|
return kSqlUInt32; |
|
|
|
case NetVaultNode::kInt32_1: |
|
case NetVaultNode::kInt32_2: |
|
case NetVaultNode::kInt32_3: |
|
case NetVaultNode::kInt32_4: |
|
return kSqlInt32; |
|
|
|
case NetVaultNode::kCreateAgeUuid: |
|
case NetVaultNode::kCreatorAcct: |
|
case NetVaultNode::kUuid_1: |
|
case NetVaultNode::kUuid_2: |
|
case NetVaultNode::kUuid_3: |
|
case NetVaultNode::kUuid_4: |
|
return kSqlUuid; |
|
|
|
case NetVaultNode::kCreateAgeName: |
|
case NetVaultNode::kString64_1: |
|
case NetVaultNode::kString64_2: |
|
case NetVaultNode::kString64_3: |
|
case NetVaultNode::kString64_4: |
|
case NetVaultNode::kString64_5: |
|
case NetVaultNode::kString64_6: |
|
case NetVaultNode::kIString64_1: |
|
case NetVaultNode::kIString64_2: |
|
return kSqlString; |
|
|
|
case NetVaultNode::kText_1: |
|
case NetVaultNode::kText_2: |
|
return kSqlCLob; |
|
|
|
// case NetVaultNode::kBlob_1: |
|
// case NetVaultNode::kBlob_1: |
|
// return kSqlBlob: |
|
|
|
default: |
|
return kSqlInvalid; |
|
} |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* CSrvPackBuffer |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
CSrvPackBuffer::CSrvPackBuffer (unsigned bytes) { |
|
m_data = (byte *)ALLOC(bytes); |
|
m_pos = m_data; |
|
m_end = m_pos + bytes; |
|
} |
|
|
|
//============================================================================ |
|
void * CSrvPackBuffer::Alloc (unsigned bytes) { |
|
ASSERT((signed) bytes >= 0); |
|
ASSERT(m_pos + bytes <= m_end); |
|
|
|
byte * pos = m_pos; |
|
m_pos += bytes; |
|
return pos; |
|
} |
|
|
|
//============================================================================ |
|
void CSrvPackBuffer::AddData (const void * ptr, unsigned bytes) { |
|
MemCopy(Alloc(bytes), ptr, bytes); |
|
} |
|
|
|
//============================================================================ |
|
void CSrvPackBuffer::AddString (const wchar str[]) { |
|
AddData(str, StrBytes(str)); |
|
} |
|
|
|
//============================================================================ |
|
void CSrvPackBuffer::AddDWordArray (const dword * arr, unsigned count) { |
|
// Don't let large counts cause pointer wrap |
|
count &= 0x00ffffff; |
|
AddData(arr, count * sizeof(arr[0])); |
|
} |
|
|
|
//============================================================================ |
|
void CSrvPackBuffer::AddDWordArray (const unsigned * arr, unsigned count) { |
|
COMPILER_ASSERT(sizeof(unsigned) == sizeof(dword)); |
|
// Don't let large counts cause pointer wrap |
|
count &= 0x00ffffff; |
|
AddData(arr, count * sizeof(arr[0])); |
|
} |
|
|
|
//============================================================================ |
|
unsigned CSrvPackBuffer::Size () { |
|
return m_pos - m_data; |
|
} |
|
|
|
|
|
/***************************************************************************** |
|
* |
|
* CSrvUnpackBuffer |
|
* |
|
***/ |
|
|
|
//============================================================================ |
|
CSrvUnpackBuffer::CSrvUnpackBuffer (const void * buffer, unsigned count) { |
|
m_pos = (const byte *) buffer; |
|
m_end = m_pos + count; |
|
} |
|
|
|
//============================================================================ |
|
const void * CSrvUnpackBuffer::GetData (unsigned bytes) { |
|
for (;;) { |
|
const byte * result = m_pos; |
|
m_pos += bytes; |
|
|
|
if (m_pos < result) |
|
break; |
|
if (m_pos > m_end) |
|
break; |
|
|
|
return result; |
|
} |
|
|
|
m_end = nil; |
|
return nil; |
|
} |
|
|
|
//============================================================================ |
|
const wchar * CSrvUnpackBuffer::GetString () { |
|
|
|
if (m_end) { |
|
const wchar * end = (const wchar *) (m_end - sizeof(wchar) + 1); |
|
for (const wchar * cur = (const wchar *) m_pos; cur < end; ) { |
|
if (*cur++) |
|
continue; |
|
|
|
const wchar * pos = (const wchar *) m_pos; |
|
m_pos = (const byte *) cur; |
|
return pos; |
|
} |
|
} |
|
|
|
m_end = NULL; |
|
return NULL; |
|
} |
|
|
|
//============================================================================ |
|
const dword * CSrvUnpackBuffer::GetDWordArray (unsigned count) { |
|
// Don't let large counts cause pointer wrap |
|
if (count & 0x00ffffff) |
|
return (const dword *)GetData(count * sizeof(dword)); |
|
|
|
m_end = nil; |
|
return nil; |
|
} |
|
|
|
//============================================================================ |
|
unsigned CSrvUnpackBuffer::BytesLeft () { |
|
return m_end ? m_end - m_pos : 0; |
|
} |
|
|
|
//============================================================================ |
|
bool CSrvUnpackBuffer::ParseError () { |
|
return !m_end; |
|
}
|
|
|