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)); } } }
bool CDatum::IsEqual (CDatum dValue) const // IsEqual // // Returns TRUE if the values are equal { switch (GetBasicType()) { case typeNil: return dValue.IsNil(); case typeTrue: return !dValue.IsNil(); case typeInteger32: case typeInteger64: case typeIntegerIP: case typeDouble: return (dValue.IsNumber() && CNumberValue(*this).Compare(dValue) == 0); case typeString: return (dValue.GetBasicType() == typeString && strEquals(*this, dValue)); case typeDateTime: return (dValue.GetBasicType() == typeDateTime && ((const CDateTime &)*this == (const CDateTime &)dValue)); // LATER case typeArray: case typeBinary: case typeStruct: case typeSymbol: return false; default: ASSERT(false); return false; } }
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)); } }
bool CRunSession::OnStartSession (const SArchonMessage &Msg, DWORD dwTicket) // OnStartSession // // Start the session { CDatum dCode = Msg.dPayload.GetElement(0); // Initialize the process m_Process.LoadLibrary(LIBRARY_CORE); // Parse into an expression (depending on the type of input) CDatum dExpression; if (dCode.GetBasicType() == CDatum::typeString) { CString sError; if (!CHexeDocument::ParseLispExpression(dCode, &dExpression, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_COMPILER, sError)); return false; } } // Otherwise we don't know how to parse the input else { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_UNABLE_TO_PARSE_CODE); return false; } // Run the code CDatum dResult; CHexeProcess::ERunCodes iRun = m_Process.Run(dExpression, &dResult); // Deal with the result return HandleResult(iRun, dResult); }
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()); } }
void CHexeMarkupEvaluator::AddHeader (const CString &sField, CDatum dValue) // AddHeader // // Adds the header { CHTTPMessage::SHeader *pNewHeader; switch (dValue.GetBasicType()) { case CDatum::typeString: pNewHeader = m_Headers.Insert(); pNewHeader->sField = sField; pNewHeader->sValue = dValue; break; default: pNewHeader = m_Headers.Insert(); pNewHeader->sField = sField; pNewHeader->sValue = dValue.AsString(); } }
bool CHexeMarkupEvaluator::ProcessHeader (SHTTPRequestCtx &Ctx, CDatum dResult) // ProcessHeader // // Outputs the given header { // Check for error if (dResult.IsError()) { m_Output.Write(strPattern(ERR_PROCESSING_HEADER, dResult.AsString())); return true; } // Processing depends on result type switch (dResult.GetBasicType()) { case CDatum::typeNil: return true; // If this is a string or anything else, we expect both field and value // are in the same string and we need to parse it. default: { CString sData = dResult.AsString(); // Parse into field and value char *pPos = sData.GetParsePointer(); while (strIsWhitespace(pPos)) pPos++; // Look for the field name char *pStart = pPos; while (*pPos != ':' && *pPos != '\0') pPos++; CString sField(pStart, pPos - pStart); if (sField.IsEmpty()) { m_Output.Write(strPattern(ERR_NO_HEADER_FIELD, sData)); return true; } // Look for the value CString sValue; if (*pPos == ':') { pPos++; while (strIsWhitespace(pPos)) pPos++; sValue = CString(pPos); } // Done CHTTPMessage::SHeader *pNewHeader = m_Headers.Insert(); pNewHeader->sField = sField; pNewHeader->sValue = sValue; } } return true; }
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) return iKeyCompare; CDatum dItem1 = dKey1.GetElement(i); CDatum dItem2 = dKey2.GetElement(i); int iItemCompare = CDatum::DefaultCompare(pCtx, dItem1, dItem2); if (iItemCompare != 0) return iItemCompare; } return 0; } // LATER: Not yet supported default: return 0; } } // If one of the types is nil, then compare else if (iType1 == CDatum::typeNil || iType2 == CDatum::typeNil) { CDatum dNonNil; int iResult; if (iType2 == CDatum::typeNil) { dNonNil = dKey1; Swap(iType1, iType2); iResult = 1; } else { dNonNil = dKey2; iResult = -1; } switch (iType2) { case CDatum::typeString: if (((const CString &)dNonNil).IsEmpty()) return 0; else return iResult; case CDatum::typeArray: case CDatum::typeStruct: if (dNonNil.GetCount() == 0) return 0; else return iResult; default: // nil is always less return iResult; } } // If one of the types is a number, then compare as numbers else if (dKey1.IsNumber() || dKey2.IsNumber()) { CNumberValue Number1(dKey1); CNumberValue Number2(dKey2); if (Number1.IsValidNumber() && Number2.IsValidNumber()) return Number1.Compare(Number2); else if (Number1.IsValidNumber()) return 1; else if (Number2.IsValidNumber()) return -1; else return 0; } // Otherwise, cannot compare else return 0; }