本文整理汇总了C++中CDatum::GetCount方法的典型用法代码示例。如果您正苦于以下问题:C++ CDatum::GetCount方法的具体用法?C++ CDatum::GetCount怎么用?C++ CDatum::GetCount使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CDatum
的用法示例。
在下文中一共展示了CDatum::GetCount方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ExecuteScript
int ExecuteScript (const SOptions &Options)
{
int i, j;
// Load the script file
CDatum dScript;
CString sError;
if (!CDatum::CreateFromFile(Options.sScriptFile, CDatum::formatAEONScript, &dScript, &sError))
{
printf("ERROR: %s\n", (LPSTR)sError);
return 1;
}
// Get the server to connect to
CString sServer = dScript.GetElement(FIELD_SERVER);
if (sServer.IsEmpty())
sServer = Options.sServer;
// Connect
CSocket theSocket;
if (!ConnectToArcology(STR_ARC_CONSOLE, sServer, Options, &theSocket))
return 1;
// Run the script
CDatum dCommands = dScript.GetElement(FIELD_COMMANDS);
for (i = 0; i < dCommands.GetCount(); i++)
{
CDatum dCommand = dCommands.GetElement(i);
// Generate a command-line from the command
CStringBuffer Buffer;
for (j = 0; j < dCommand.GetCount(); j++)
{
if (j != 0)
Buffer.Write(" ", 1);
dCommand.Serialize(CDatum::formatAEONScript, Buffer);
}
// Run
printf("%s\n", (LPSTR)(const CString &)Buffer);
CString sResult = ExecuteArcologyCommand(theSocket, Buffer);
PrintUTF8(sResult);
printf("\n");
}
// Done
return 0;
}
示例2:
CComplexArray::CComplexArray (CDatum dSrc)
// ComplexArray constructor
{
int i;
if (dSrc.GetBasicType() == CDatum::typeStruct)
{
InsertEmpty(1);
SetElement(0, dSrc);
}
else
{
int iCount = dSrc.GetCount();
// Clone from another complex array
if (iCount > 0)
{
InsertEmpty(iCount);
for (i = 0; i < iCount; i++)
SetElement(i, dSrc.GetElement(i));
}
}
}
示例3: CreateSecondaryData
void CAeonView::CreateSecondaryData (const CTableDimensions &PrimaryDims, const CRowKey &PrimaryKey, CDatum dFullData, SEQUENCENUMBER RowID, CDatum *retdData)
// CreateSecondaryData
//
// Creates the data for a secondary view row.
{
int i, j;
CComplexStruct *pData = new CComplexStruct;
// If the list of columns is empty then we just add the primary key
if (m_Columns.GetCount() == 0)
pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims));
// Otherwise we add all the fields listed in the columns array
else
{
for (i = 0; i < m_Columns.GetCount(); i++)
{
// The special string "primaryKey" means that we insert the
// primary key as a special field.
if (strEquals(m_Columns[i], FIELD_PRIMARY_KEY))
pData->SetElement(FIELD_PRIMARY_KEY, PrimaryKey.AsDatum(PrimaryDims));
// The special string "*" means that we insert all existing
// fields.
else if (strEquals(m_Columns[i], STR_ALL_COLUMNS))
{
for (j = 0; j < dFullData.GetCount(); j++)
{
CDatum dKey = dFullData.GetKey(j);
CDatum dValue = dFullData.GetElement(j);
if (!dValue.IsNil())
pData->SetElement(dKey, dValue);
}
}
// Add the field by name.
else
{
CDatum dColData = dFullData.GetElement(m_Columns[i]);
if (!dColData.IsNil())
pData->SetElement(m_Columns[i], dColData);
}
}
}
// Done
*retdData = CDatum(pData);
}
示例4: DeserializeAEONScript
bool IComplexDatum::DeserializeAEONScript (CDatum::ESerializationFormats iFormat, const CString &sTypename, CCharStream *pStream)
// DeserializeAEONScript
//
// Deserialize AEONScript
{
int i;
DWORD dwFlags = OnGetSerializeFlags();
// If we have an open brace then we've stored everything as a structure.
if (pStream->GetChar() == '{')
{
// Object must support this
if (!(dwFlags & FLAG_SERIALIZE_AS_STRUCT))
return false;
// Parse the structure
CAEONScriptParser Parser(pStream);
CDatum dData;
CAEONScriptParser::ETokens iToken = Parser.ParseToken(&dData);
if (iToken != CAEONScriptParser::tkDatum)
return false;
// Take all the fields in the structure and apply them to our object
// (our descendants will do the right thing).
for (i = 0; i < dData.GetCount(); i++)
SetElement(dData.GetKey(i), dData.GetElement(i));
}
// Otherwise we expect base64 encoded data
else
{
// Backup one character because we want the OnDeserialize call to read it.
pStream->UnreadChar();
// Deserialize
CBase64Decoder Decoder(pStream->GetByteStream());
if (!OnDeserialize(iFormat, sTypename, Decoder))
return false;
// Read the next character into the stream
pStream->RefreshStream();
pStream->ReadChar();
}
return true;
}
示例5: AppendStruct
void CComplexStruct::AppendStruct (CDatum dDatum)
// AppendStruct
//
// Appends the element of the given structure
{
int i;
if (dDatum.GetBasicType() == CDatum::typeStruct)
{
for (i = 0; i < dDatum.GetCount(); i++)
SetElement(dDatum.GetKey(i), dDatum.GetElement(i));
}
}
示例6: OutputDatum
void CHexeMarkupEvaluator::OutputDatum (CDatum dValue)
// OutputDatum
//
// Outputs a datum to the resulting HTML page. NOTE: We expect the values to be
// HTML compatible (i.e., caller is responsible for escaping).
{
int i;
if (dValue.GetBasicType() == CDatum::typeArray)
{
for (i = 0; i < dValue.GetCount(); i++)
OutputDatum(dValue.GetElement(i));
}
else
{
m_Output.Write(dValue.AsString());
}
}
示例7: CreateSanitizedUserRecord
CDatum CUserInfoSession::CreateSanitizedUserRecord (CDatum dRecord)
// CreateSanitizedUserRecord
//
// Creates a user record suitable for returning to clients. In partincular,
// we remove the authentication information.
{
int i;
// Create a destination
CComplexStruct *pDest = new CComplexStruct;
// Copy all appropriate fields
for (i = 0; i < dRecord.GetCount(); i++)
{
// If this is an auth field, then skip it
if (strEquals(dRecord.GetKey(i), FIELD_AUTH_DESC))
;
else if (strEndsWith(dRecord.GetKey(i), FIELD_AUTH_DESC_SUFFIX))
;
// Otherwise, copy it
else
pDest->SetElement(dRecord.GetKey(i), dRecord.GetElement(i));
}
// Done
return CDatum(pDest);
}
示例8: ExecuteUpgrade
CString ExecuteUpgrade (CSocket &theSocket, const CString &sCmd)
{
int i;
CString sRoot = fileGetPath(fileGetExecutableFilespec());
// Make a list of all executable files to upgrade
TArray<CString> FileList;
if (!fileGetFileList(sRoot, NULL_STR, CString("*.exe"), FFL_FLAG_RELATIVE_FILESPEC, &FileList))
return CString("ERROR: Unable to obtain a list of executable files to upgrade.");
// Prepare a request upgrade command
CStringBuffer Output;
Output.Write("requestUpgrade (", 16);
for (i = 0; i < FileList.GetCount(); i++)
{
CString sFilespec = fileAppend(sRoot, FileList[i]);
// Version
SFileVersionInfo Info;
if (!fileGetVersionInfo(sFilespec, &Info))
{
printf("ERROR: Unable to get file version: %s\n", (LPSTR)sFilespec);
continue;
}
CIPInteger Version(Info.dwProductVersion);
CString sVersion = Version.AsString();
// Checksum
DWORD dwChecksum = fileChecksumAdler32(sFilespec);
if (dwChecksum == 0)
{
printf("ERROR: Unable to get file checksum: %s\n", (LPSTR)sFilespec);
continue;
}
CString sOutput = strPattern("{filename:\"%s\" version:%s checksum:%d} ", FileList[i], sVersion, dwChecksum);
Output.Write(sOutput);
}
Output.Write(")", 1);
// Send the command
CString sSend = CString::CreateFromHandoff(Output);
CString sResult;
CDatum dResult;
ExecuteArcologyCommand(theSocket, sSend, &sResult, &dResult);
if (strEquals(sResult, CString("ERROR")))
return dResult.AsString();
// Show all the files to upgrade
CDatum dUpgradeDesc = dResult.GetElement(0).GetElement(FIELD_UPGRADE_DESC);
for (i = 0; i < dUpgradeDesc.GetCount(); i++)
{
CDatum dFileDesc = dUpgradeDesc.GetElement(i);
printf("Upgrading %s\n", (LPSTR)dFileDesc.GetElement(FIELD_FILENAME).AsString());
}
// Confirm
CString sConfirm = GetInputLine(CString("\nAre you sure you want to upgrade the arcology? [y/n] : "));
if (*sConfirm.GetParsePointer() != 'y' && *sConfirm.GetParsePointer() != 'Y')
return NULL_STR;
// Upload the new files.
for (i = 0; i < dUpgradeDesc.GetCount(); i++)
{
CDatum dFileDesc = dUpgradeDesc.GetElement(i);
const CString &sFilename = dFileDesc.GetElement(FIELD_FILENAME);
CString sFilespec = fileAppend(sRoot, sFilename);
CString sResult = UploadFile(theSocket, CMD_UPLOAD_UPGRADE, sFilename, sFilespec);
printf("%s\n", (LPSTR)sResult);
}
// Complete the upgrade
return ExecuteArcologyCommand(theSocket, CMD_COMPLETE_UPGRADE);
}
示例9: InitAsSecondaryView
bool CAeonView::InitAsSecondaryView (CDatum dDesc, CHexeProcess &Process, const CString &sRecoveryFilespec, bool bForceUpdate, CString *retsError)
// InitAsSecondaryView
//
// Initializes a secondary view.
{
int i;
ASSERT(m_Dims.GetCount() == 0);
// Get the name
m_sName = dDesc.GetElement(FIELD_NAME);
m_bUsesListKeys = false;
// Parse the x dimension
CDatum dimDesc = dDesc.GetElement(FIELD_X);
if (!dimDesc.IsNil())
{
SDimensionDesc *pDimDesc = m_Dims.Insert();
CDatum *pKey = m_Keys.Insert();
if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
{
m_bInvalid = true;
return false;
}
if (pDimDesc->iKeyType == keyListUTF8)
m_bUsesListKeys = true;
// Parse the y dimension
dimDesc = dDesc.GetElement(FIELD_Y);
if (!dimDesc.IsNil())
{
pDimDesc = m_Dims.Insert();
pKey = m_Keys.Insert();
if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
{
m_bInvalid = true;
return false;
}
if (pDimDesc->iKeyType == keyListUTF8)
m_bUsesListKeys = true;
// Parse z dimension
dimDesc = dDesc.GetElement(FIELD_Z);
if (!dimDesc.IsNil())
{
pDimDesc = m_Dims.Insert();
pKey = m_Keys.Insert();
if (!CAeonTable::ParseDimensionDescForSecondaryView(dimDesc, Process, pDimDesc, pKey, retsError))
{
m_bInvalid = true;
return false;
}
if (pDimDesc->iKeyType == keyListUTF8)
m_bUsesListKeys = true;
}
}
}
// If we don't have at least one dimension then this is an error
else
{
*retsError = ERR_DIMENSIONS_REQUIRED;
m_bInvalid = true;
return false;
}
// Secondary views always have an extra dimension. We use the rowID as a
// way to break ties in the other parts of the key (since secondary keys
// need not be unique).
SDimensionDesc *pDimDesc = m_Dims.Insert();
pDimDesc->iKeyType = keyInt64;
pDimDesc->iSort = AscendingSort;
// Parse columns
CDatum dColumns = dDesc.GetElement(FIELD_COLUMNS);
for (i = 0; i < dColumns.GetCount(); i++)
{
const CString &sCol = dColumns.GetElement(i);
if (!sCol.IsEmpty())
m_Columns.Insert(sCol);
}
// Computed columns
m_ComputedColumns = dDesc.GetElement(FIELD_COMPUTED_COLUMNS);
// We need to set the global environment because it got loaded under a
//.........这里部分代码省略.........
示例10: CreatePermutedKeys
void CAeonView::CreatePermutedKeys (const TArray<CDatum> &KeyData, int iDim, const TArray<CDatum> &PrevKey, SEQUENCENUMBER RowID, TArray<CRowKey> *retKeys)
// CreatePermutedKeys
//
// Adds keys to retKeys by permuting any list values.
{
int i;
// If we're done, then add the key
if (iDim == KeyData.GetCount())
{
CRowKey *pNewKey = retKeys->Insert();
CRowKey::CreateFromDatumAndRowID(m_Dims, PrevKey, RowID, pNewKey);
}
// Otherwise, we generate the keys just for the current dimension and
// recurse.
else
{
switch (m_Dims[iDim].iKeyType)
{
// For list keys, add all the values of the list as separate keys
case keyListUTF8:
{
CDatum dList = KeyData[iDim];
// If nil, just add as a single nil key
if (dList.IsNil())
{
TArray<CDatum> NewKey(PrevKey);
NewKey.Insert(dList);
CreatePermutedKeys(KeyData, iDim + 1, NewKey, RowID, retKeys);
}
// Otherwise, add all values
else
{
TArray<CDatum> NewKey(PrevKey);
NewKey.Insert(CDatum());
for (i = 0; i < dList.GetCount(); i++)
{
NewKey[iDim] = dList.GetElement(i);
CreatePermutedKeys(KeyData, iDim + 1, NewKey, RowID, retKeys);
}
}
break;
}
// For non-list keys we just continue adding them
default:
{
TArray<CDatum> NewKey(PrevKey);
NewKey.Insert(KeyData[iDim]);
CreatePermutedKeys(KeyData, iDim + 1, NewKey, RowID, retKeys);
}
}
}
}
示例11: ParseTableAndView
bool CAeonEngine::ParseTableAndView (const SArchonMessage &Msg,
const CHexeSecurityCtx *pSecurityCtx,
CDatum dTableAndView,
CAeonTable **retpTable,
DWORD *retdwViewID,
CDatum dKey,
CRowKey *retKey)
// ParseTableAndView
//
// Parses a datum as follows:
//
// If a single string, it specifies a table and the default view.
// If an array with two strings, the first is the table name; the second is the view name.
{
CString sError;
// If we're not ready, then error
if (!m_bReady)
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_NOT_READY, Msg);
return false;
}
// Parse the table names
CString sTable;
CString sView;
if (dTableAndView.GetCount() < 2)
sTable = dTableAndView.AsString();
else
{
sTable = dTableAndView.GetElement(0).AsString();
sView = dTableAndView.GetElement(1).AsString();
}
// Make sure we have access
if (pSecurityCtx && !pSecurityCtx->IsNamespaceAccessible(sTable))
{
SendMessageReplyError(MSG_ERROR_NOT_ALLOWED, strPattern(ERR_NOT_IN_SANDBOX, sTable, pSecurityCtx->GetSandboxName()), Msg);
return false;
}
// Get the table
CAeonTable *pTable;
if (!FindTable(sTable, &pTable))
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
return false;
}
// Get the view. If we want a key, take this opportunity to parse it.
DWORD dwViewID;
if (retKey)
{
if (!pTable->FindViewAndPath(sView, &dwViewID, dKey, retKey, &sError))
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
return false;
}
}
// Otherwise just get the view.
else
{
if (!pTable->FindView(sView, &dwViewID))
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_UNKNOWN_VIEW, sTable, sView), Msg);
return false;
}
}
// Done
if (retpTable)
*retpTable = pTable;
if (retdwViewID)
*retdwViewID = dwViewID;
return true;
}
示例12: ProcessResult
bool CHexeMarkupEvaluator::ProcessResult (SHTTPRequestCtx &Ctx, CHexeProcess::ERunCodes iRun, CDatum dResult)
// ProcessResult
//
// Process the result of an evaluation. Returns TRUE if processing should
// continue; FALSE if we need RPC or are done processing.
{
// If we have more async calls then return
if (iRun == CHexeProcess::runAsyncRequest)
{
Ctx.iStatus = pstatRPCReady;
Ctx.sRPCAddr = dResult.GetElement(0);
Ctx.RPCMsg.sMsg = dResult.GetElement(1);
Ctx.RPCMsg.dPayload = dResult.GetElement(2);
Ctx.RPCMsg.dwTicket = 0;
Ctx.RPCMsg.sReplyAddr = NULL_STR;
return false;
}
// Otherwise, process the result based on the directive that we're
// evaluating.
bool bResult = true;
switch (m_iProcessing)
{
case tagEval:
OutputDatum(dResult);
break;
case tagFile:
// If this is an error, then we return with 404
if (iRun == CHexeProcess::runError)
{
Ctx.iStatus = pstatResponseReady;
Ctx.Response.InitResponse(http_NOT_FOUND, dResult.AsString());
bResult = false;
}
// If the result is a list then we expect a fileDesc and fileData.
else if (dResult.GetCount() >= 2)
{
Ctx.iStatus = pstatFileDataReady;
Ctx.dFileDesc = dResult.GetElement(0);
Ctx.dFileData = dResult.GetElement(1);
Ctx.AdditionalHeaders = m_Headers;
bResult = false;
}
// Otherwise we expect a filePath
else
{
Ctx.iStatus = pstatFilePathReady;
Ctx.sFilePath = dResult;
Ctx.AdditionalHeaders = m_Headers;
bResult = false;
}
break;
case tagHeader:
bResult = ProcessHeader(Ctx, dResult);
break;
case tagIf:
m_iIfLevel++;
if (dResult.IsNil())
m_iIfLevelEnd = m_iIfLevel;
break;
case tagRedirect:
// If this is an error, then we return with 404
if (iRun == CHexeProcess::runError)
{
Ctx.iStatus = pstatResponseReady;
Ctx.Response.InitResponse(http_NOT_FOUND, dResult.AsString());
bResult = false;
}
// Otherwise, we expect a string containing the new address.
else if (!dResult.IsNil())
{
m_dwResponseCode = http_MOVED_PERMANENTLY;
m_sResponseMsg = STR_MOVED_PERMANENTLY;
AddHeader(HEADER_LOCATION, dResult);
}
break;
default:
ASSERT(false);
}
//.........这里部分代码省略.........
示例13: DefaultCompare
int CDatum::DefaultCompare (void *pCtx, const CDatum &dKey1, const CDatum &dKey2)
// DefaultCompare
//
// Default comparison routine used for sorting. Returns:
//
// -1: If dKey1 < dKey2
// 0: If dKey1 == dKey2
// 1: If dKey1 > dKey2
//
// NOTES:
//
// Nil == ""
// Nil == {}
// Nil == ()
// "abc" != "ABC"
{
int i;
// If both are the same datatype, then compare
CDatum::Types iType1 = dKey1.GetBasicType();
CDatum::Types iType2 = dKey2.GetBasicType();
// If both types are equal, then compare
if (iType1 == iType2)
{
switch (iType1)
{
case CDatum::typeNil:
case CDatum::typeTrue:
return 0;
case CDatum::typeInteger32:
if ((int)dKey1 > (int)dKey2)
return 1;
else if ((int)dKey1 < (int)dKey2)
return -1;
else
return 0;
case CDatum::typeInteger64:
if ((DWORDLONG)dKey1 > (DWORDLONG)dKey2)
return 1;
else if ((DWORDLONG)dKey1 < (DWORDLONG)dKey2)
return -1;
else
return 0;
case CDatum::typeDouble:
if ((double)dKey1 > (double)dKey2)
return 1;
else if ((double)dKey1 < (double)dKey2)
return -1;
else
return 0;
case CDatum::typeIntegerIP:
return KeyCompare((const CIPInteger &)dKey1, (const CIPInteger &)dKey2);
case CDatum::typeString:
return KeyCompare((const CString &)dKey1, (const CString &)dKey2);
case CDatum::typeDateTime:
return ((const CDateTime &)dKey1).Compare((const CDateTime &)dKey2);
case CDatum::typeArray:
if (dKey1.GetCount() > dKey2.GetCount())
return 1;
else if (dKey1.GetCount() < dKey2.GetCount())
return -1;
else
{
for (i = 0; i < dKey1.GetCount(); i++)
{
CDatum dItem1 = dKey1.GetElement(i);
CDatum dItem2 = dKey2.GetElement(i);
int iItemCompare = CDatum::DefaultCompare(pCtx, dItem1, dItem2);
if (iItemCompare != 0)
return iItemCompare;
}
return 0;
}
case CDatum::typeStruct:
if (dKey1.GetCount() > dKey2.GetCount())
return 1;
else if (dKey1.GetCount() < dKey2.GetCount())
return -1;
else
{
for (i = 0; i < dKey1.GetCount(); i++)
{
CString sItemKey1 = dKey1.GetKey(i);
CString sItemKey2 = dKey2.GetKey(i);
int iKeyCompare = KeyCompare(sItemKey1, sItemKey2);
if (iKeyCompare != 0)
//.........这里部分代码省略.........
示例14: MsgGetRows
void CAeonEngine::MsgGetRows (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)
// MsgGetRows
//
// Aeon.getRows {tableAndView} {key} {count}
// Aeon.getMoreRows {tableAndView} {lastKey} {count}
{
int i;
CAeonTable *pTable;
DWORD dwViewID;
if (!ParseTableAndView(Msg, pSecurityCtx, Msg.dPayload.GetElement(0), &pTable, &dwViewID))
return;
// Get the row limits
int iRowCount;
TArray<int> Limits;
CDatum dLimits = Msg.dPayload.GetElement(2);
if (dLimits.IsNil())
iRowCount = -1;
else if (dLimits.GetCount() <= 1)
{
iRowCount = (int)dLimits.GetElement(0);
if (iRowCount <= 0)
iRowCount = -1;
}
else
{
iRowCount = (int)dLimits.GetElement(0);
if (iRowCount <= 0)
iRowCount = -1;
Limits.InsertEmpty(dLimits.GetCount() - 1);
for (i = 1; i < dLimits.GetCount(); i++)
Limits[i - 1] = (int)dLimits.GetElement(i);
}
// Set up flags and options
DWORD dwFlags = 0;
dwFlags |= (strEquals(Msg.sMsg, MSG_AEON_GET_ROWS) ? 0 : CAeonTable::FLAG_MORE_ROWS);
CDatum dOptions = Msg.dPayload.GetElement(3);
for (i = 0; i < dOptions.GetCount(); i++)
{
if (strEquals(dOptions.GetElement(i), OPTION_INCLUDE_KEY))
dwFlags |= CAeonTable::FLAG_INCLUDE_KEY;
else if (strEquals(dOptions.GetElement(i), OPTION_NO_KEY))
dwFlags |= CAeonTable::FLAG_NO_KEY;
else
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_INVALID_GET_ROWS_OPTION, Msg.sMsg, dOptions.GetElement(i).AsString()), Msg);
return;
}
}
// Ask the table
CDatum dResult;
CString sError;
if (!pTable->GetRows(dwViewID, Msg.dPayload.GetElement(1), iRowCount, Limits, dwFlags, &dResult, &sError))
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
return;
}
// Done
SendMessageReply(MSG_REPLY_DATA, dResult, Msg);
}
示例15: OnProcessMessage
bool CUserInfoSession::OnProcessMessage (const SArchonMessage &Msg)
// OnProcessMessage
//
// We received a reply from Aeon
{
int i;
// If this is an error, then we return the error back to the client
if (IsError(Msg))
{
SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, Msg.dPayload);
return false;
}
// If we're waiting for the user record, then see if we can process it now.
if (m_iState == stateWaitingForUserRecord)
{
// Cryptosaur.getUser
if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_GET_USER))
{
CDatum dUserData = Msg.dPayload;
// If the user does not exist, then we return Nil
if (dUserData.IsNil())
{
SendMessageReply(MSG_REPLY_DATA, CDatum());
return false;
}
// Generate a sanitized user record
CComplexStruct *pReply = new CComplexStruct;
pReply->SetElement(FIELD_USERNAME, dUserData.GetElement(FIELD_USERNAME));
// Sanitize rights
CDatum dRights = dUserData.GetElement(FIELD_RIGHTS);
if (!m_sScope.IsEmpty())
{
CComplexArray *pRights = new CComplexArray;
for (i = 0; i < dRights.GetCount(); i++)
if (strStartsWith(dRights.GetElement(i), m_sScope))
pRights->Insert(dRights.GetElement(i));
pReply->SetElement(FIELD_RIGHTS, CDatum(pRights));
}
else
pReply->SetElement(FIELD_RIGHTS, dRights);
// Done
SendMessageReply(MSG_REPLY_DATA, CDatum(pReply));
return false;
}
// If we get back nil then the user does not exist.
else if (Msg.dPayload.IsNil())
{
SendMessageReplyError(MSG_ERROR_DOES_NOT_EXIST, strPattern(ERR_UNKNOWN_USERNAME, m_sUsername));
return false;
}
// Otherwise, we handle the result based on the original message
else if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_CHECK_PASSWORD_SHA1))
{
// Get the parameters from the original message
CDatum dChallenge = GetOriginalMsg().dPayload.GetElement(1);
CDatum dResponse = GetOriginalMsg().dPayload.GetElement(2);
// Get the password has from the response
CDatum dAuthDesc = Msg.dPayload.GetElement(FIELD_AUTH_DESC);
CDatum dPasswordHash = dAuthDesc.GetElement(FIELD_CREDENTIALS);
// Create a response to the challenge based on the password hash that
// we have stored.
CDatum dCorrect = CAI1Protocol::CreateSHAPasswordChallengeResponse(dPasswordHash, dChallenge);
// Compare the correct response to the actual
if ((const CIPInteger &)dResponse == (const CIPInteger &)dCorrect)
return UpdateLoginSuccess(stateWaitingForSuccessUpdate);
else
return UpdateLoginFailure();
}
// Cryptosaur.hasRights
else if (strEquals(GetOriginalMsg().sMsg, MSG_CRYPTOSAUR_HAS_RIGHTS))
//.........这里部分代码省略.........