/*==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 . 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 static inline void IReadValue (T * value, byte ** buffer, unsigned * bufsz) { ASSERT(*bufsz >= sizeof(T)); *value = *(T *)*buffer; *buffer += sizeof(T); *bufsz -= sizeof(T); } //============================================================================ template 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 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 static inline void IWriteValue (const T & value, ARRAY(byte) * buffer) { T * ptr = (T *) buffer->New(sizeof(T)); *ptr = value; } //============================================================================ template 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 static inline void IWriteString (const T str[], ARRAY(byte) * buffer) { IWriteArray(str, StrLen(str) + 1, buffer); } //============================================================================ template static inline bool ICompareValue (const T & lhs, const T & rhs) { return lhs == rhs; } //============================================================================ template 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 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[]) { return false; } //============================================================================ template static inline void ICopyValue (T * plhs, const T & rhs) { *plhs = rhs; } //============================================================================ template 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 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(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(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(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; }