Пример #1
0
void CEsperEngine::MsgEsperRead (const SArchonMessage &Msg)

//	MsgEsperRead
//
//	Requests a read on the given connection. If we fail, we return an error
//	to the caller.

	{
	CDatum dConnection = Msg.dPayload.GetElement(0);

	CString sError;
	if (!m_Connections.BeginRead(Msg, dConnection, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_READ_FAILED, sError), Msg);
		if (m_bLogTrace)
			LogTrace(strPattern("[%x] Read failed: %s", CEsperInterface::ConnectionToFriendlyID(dConnection), sError));

		return;
		}

#ifdef DEBUG_SOCKET_OPS
	if (m_bLogTrace)
		LogTrace(strPattern("[%x] Read", CEsperInterface::ConnectionToFriendlyID(dConnection)));
#endif

	//	We reply when the async operation completes (or we get an error).
	}
Пример #2
0
void CEsperEngine::MsgEsperWrite (const SArchonMessage &Msg)

//	MsgEsperWrite
//
//	Requests a write on the given connection.

	{
	CDatum dConnection = Msg.dPayload.GetElement(0);
	const CString &sData = Msg.dPayload.GetElement(1);

	CString sError;
	if (!m_Connections.BeginWrite(Msg, dConnection, sData, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_WRITE_FAILED, sError), Msg);
		if (m_bLogTrace)
			LogTrace(strPattern("[%x] Write failed (%d bytes): %s", CEsperInterface::ConnectionToFriendlyID(dConnection), sData.GetLength(), sError));

		return;
		}

#ifdef DEBUG_SOCKET_OPS
	if (m_bLogTrace)
		LogTrace(strPattern("[%x] Write %d bytes", CEsperInterface::ConnectionToFriendlyID(dConnection), sData.GetLength()));
#endif

	//	We reply when the async operation completes (or we get an error).
	}
Пример #3
0
bool CHyperionScheduler::IsSignalStop (const CString &sTask, CString *retsMessage)

//	IsSignalStop
//
//	Returns TRUE if the task has been signalled to stop.

	{
	CSmartLock Lock(m_cs);
	STask *pTask = m_Tasks.GetAt(sTask);
	if (pTask == NULL || !pTask->bRunning)
		return false;

	//	If the user signalled stop, then we should stop

	if (pTask->bSignalStop)
		{
		if (retsMessage) *retsMessage = strPattern(ERR_RUN_STOPPED, sTask);
		return true;
		}

	//	If the task has exceeded its max run time, then stop it.

	CDateTime Now(CDateTime::Now);
	CDateTime StopAt = timeAddTime(pTask->LastRun, CTimeSpan(0, MAX_RUN_TIME));
	if (StopAt <= Now)
		{
		if (retsMessage) *retsMessage = strPattern(ERR_RUN_TOO_LONG, sTask);
		return true;
		}

	//	Otherwise, stop is not signalled

	return false;
	}
Пример #4
0
void CAeonEngine::MsgFileDirectory (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgFileDirectory
//
//	Aeon.fileDirectory {filePath} {requestedFields} {options}

	{
	CString sError;

	//	Get the filePath

	CString sTable;
	CString sFilePath;
	if (!CAeonTable::ParseFilePath(Msg.dPayload.GetElement(0), &sTable, &sFilePath, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_PARSING_FILE_PATH, sError), Msg);
		return;
		}

	//	Make sure we are allowed access to this table

	if (!ValidateTableAccess(Msg, pSecurityCtx, sTable))
		return;

	//	Convert the filepath to a key

	CString sDirKey = CRowKey::FilePathToKey(sFilePath);

	//	Get the table

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return;
		}

	//	Get the set of requested fields and options

	CDatum dRequestedFields = Msg.dPayload.GetElement(1);
	CDatum dOptions = Msg.dPayload.GetElement(2);

	//	Do it

	CDatum dResult;
	if (!pTable->FileDirectory(sDirKey, dRequestedFields, dOptions, &dResult, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Reply

	SendMessageReply(MSG_REPLY_DATA, dResult, Msg);
	}
Пример #5
0
void CAeonEngine::MsgFileGetDesc (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgFileGetDesc
//
//	Aeon.fileGetDesc {filePath}

	{
	CString sError;

	//	Get the filePath

	CString sTable;
	CString sFilePath;
	if (!CAeonTable::ParseFilePath(Msg.dPayload.GetElement(0), &sTable, &sFilePath, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_PARSING_FILE_PATH, sError), Msg);
		return;
		}

	//	Make sure we are allowed access to this table

	if (!ValidateTableAccess(Msg, pSecurityCtx, sTable))
		return;

	//	Get the table

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return;
		}

	//	Get the descriptor

	CDatum dFileDesc;
	if (!pTable->GetFileDesc(sFilePath, &dFileDesc, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Prepare the descriptor for return

	CDatum dNewFileDesc = CAeonTable::PrepareFileDesc(sTable, sFilePath, dFileDesc);

	//	Done

	SendMessageReply(MSG_REPLY_DATA, dNewFileDesc, Msg);
	}
Пример #6
0
bool CAeonEngine::GetKeyRange (const SArchonMessage &Msg, const CString &sTable, int iCount)

//	GetKeyRange
//
//	Processes a getKeyRange message

	{
	//	If the table doesn't exist, then we can't continue

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return false;
		}

	//	Create an iterator

	CDatum dResult;
	CString sError;
	if (!pTable->GetKeyRange(iCount, &dResult, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return false;
		}

	//	Reply

	SendMessageReply(MSG_AEON_RESULT_KEYS, dResult, Msg);
	return true;
	}
Пример #7
0
bool CAeonEngine::FlushTableRows (void)

//	FlushTableRows
//
//	Save all in-memory rows to disk

	{
	int i;

	//	Get a list of all tables

	TArray<CAeonTable *> AllTables;
	GetTables(&AllTables);

	//	Loop over each table

	bool bAllSucceeded = true;
	for (i = 0; i < AllTables.GetCount(); i++)
		{
		CString sError;
		if (!AllTables[i]->Save(&sError))
			{
			Log(MSG_LOG_ERROR, strPattern("Unable to save table %s: %s", AllTables[i]->GetName(), sError));
			bAllSucceeded = false;
			//	Continue saving other tables
			}
		}
	
	//	Done

	return bAllSucceeded;
	}
Пример #8
0
bool CAeonEngine::ValidateTableAccess (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx, const CString &sTable)

//	ValidateTableAccess
//
//	Returns TRUE if the security context allows access to the given table.

	{
	//	If we're not ready, then error

	if (!m_bReady)
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_NOT_READY, Msg);
		return false;
		}

	//	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;
		}

	return true;
	}
Пример #9
0
bool CHexeMarkupEvaluator::ProcessEval (SHTTPRequestCtx &Ctx, TagTypes iDirective, const CString &sCode)

//	ProcessEval
//
//	Process an evaluation.

	{
	//	Remember what we're processing in case we need RPC.

	m_iProcessing = iDirective;

	//	Compile the body into a function call

	CDatum dCode;
	CString sError;
	if (!CHexeDocument::ParseLispExpression(sCode, &dCode, &sError))
		{
		m_Output.Write(strPattern("ERROR: %s", sError));
		return true;
		}

	//	Run

	CDatum dResult;
	CHexeProcess::ERunCodes iRun = m_pProcess->Run(dCode, &dResult);

	//	Process the result

	if (!ProcessResult(Ctx, iRun, dResult))
		return false;

	//	Done

	return true;
	}
Пример #10
0
void CMnemosynthDb::RemoveMachineEndpoints (const CString &sName)

//	RemoveMachineEndpoints
//
//	Removes all endpoints for the given machine.

	{
	CSmartLock Lock(m_cs);
	int i;

	//	Look for endpoints that start with the machine name

	CString sPattern = strPattern("%s/", sName);

	//	Delete them. We always start at 1 because the first endpoint is us
	//	and can never be deleted.

	for (i = 1; i < m_Endpoints.GetCount(); i++)
		if (strStartsWith(m_Endpoints[i].sName, sPattern))
			{
#ifdef DEBUG_MNEMOSYNTH
			printf("[CMnemosynthDb::RemoveMachineEndpoints]: Remove %s\n", (LPSTR)m_Endpoints[i].sName);
#endif
			m_Endpoints.Delete(i);
			i--;
			}
	}
Пример #11
0
bool CHyperionScheduler::SetSignalStop (const CString &sTask, CString *retsError)

//	SetSignalStop
//
//	Tells the task to stop running.

	{
	CSmartLock Lock(m_cs);
	STask *pTask = m_Tasks.GetAt(sTask);
	if (pTask == NULL)
		{
		if (retsError) *retsError = strPattern(ERR_UNKNOWN_TASK, sTask);
		return false;
		}

	//	If we're not running, then nothing to do.

	if (!pTask->bRunning)
		return true;

	//	Set the state

	pTask->bSignalStop = true;
	return true;
	}
Пример #12
0
void CBlackBox::Log (const CString &sLine)

//	Log
//
//	Log a line

	{
	CDateTime Now(CDateTime::Now);
	CString sOutput = strPattern("%s %s\r\n",
			Now.Format(CDateTime::dfShort, CDateTime::tfLong24),
			sLine);

	if (m_File.IsOpen())
		{
		int iWritten = m_File.Write(sOutput);

		//	LATER: Handle out of disk space

		//	In Debug mode, we always output.

#ifdef DEBUG
		printf(sOutput);
#endif
		}
	else if (m_bConsoleOut)
		{
		//	Write out to console
		//	NOTE: We rely on the fact that we called SetConsoleOutputCP(65001),
		//	which is UTF8.

		printf(sOutput);
		}
	}
Пример #13
0
void CEsperEngine::DeleteListener (const SArchonMessage &Msg)

//	DeleteListener
//
//	Deletes the listener

	{
	CSmartLock Lock(m_cs);

	//	Get the name

	CString sName = Msg.dPayload.GetElement(0);

	//	Find the listener

	int iIndex;
	if (!FindListener(sName, &iIndex))
		{
		//	If we're in shutdown, then it is OK that we can't find
		//	a listener. Otherwise we return an error

		if (!m_bShutdown)
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_LISTENER_NOT_FOUND, sName), Msg);
		return;
		}

	//	Ask the listener to stop

	m_Listeners[iIndex]->SignalShutdown();

	//	Done (we will reply when the thread shuts down)
	}
Пример #14
0
void CEsperEngine::MsgEsperAMP1 (const SArchonMessage &Msg)

//	MsgEsperAMP1
//
//	Esper.amp1 {machine-address} {command} {data}

	{
	CString sFullAddress = Msg.dPayload.GetElement(0);
	CString sCommand = Msg.dPayload.GetElement(1);
	CDatum dData = Msg.dPayload.GetElement(2);
	CString sAuthName = Msg.dPayload.GetElement(3);
	CIPInteger AuthKey = Msg.dPayload.GetElement(4);

	//	Don't log, because we might recurse when sending a log message

#if 0
#ifdef DEBUG
	Log(MSG_LOG_DEBUG, strPattern("Send AMP1 %s to %s.", sCommand, sFullAddress));
#endif
#endif

	CString sError;
	if (!m_Connections.BeginAMP1Request(Msg, sFullAddress, sCommand, dData, sAuthName, AuthKey, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	We reply when the async operation completes (or we get an error).
	}
Пример #15
0
CString CAeonInterface::EncodeFilePathComponent (const CString &sValue)

//	EncodeFilePathComponent
//
//	Encodes a file path component by replacing any invalid characters with ~hh
//	(where hh is the hexcode).

	{
	char *pPos = sValue.GetParsePointer();
	char *pEndPos = pPos + sValue.GetLength();
	CStringBuffer Output;

	while (pPos < pEndPos)
		{
		if (!strIsASCIIAlpha(pPos)					//	alpha
				&& !strIsDigit(pPos)				//	numbers
				&& *pPos != '-'
				&& *pPos != '_'
				&& *pPos != '.'
				&& *pPos != '~'
				&& !strIsASCIIHigh(pPos))			//	unicode characters
			{
			CString sChar = strPattern("~%x", (DWORD)(BYTE)*pPos);
			Output.Write(sChar);
			}
		else
			Output.Write(pPos, 1);

		pPos++;
		}

	//	Done

	return CString::CreateFromHandoff(Output);
	}
Пример #16
0
bool CXMLElement::ParseEntityTable (IMemoryBlock &Stream, CExternalEntityTable *retEntityTable, CString *retsError)

//	ParseEntityTable
//
//	This function parses only the entity table

	{
	//	Initialize context

	ParserCtx Ctx(Stream, NULL);

	//	Parse the prologue

	if (!ParsePrologue(&Ctx))
		{
		*retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError);
		return false;
		}

	//	Done

	if (retEntityTable)
		retEntityTable->AddTable(Ctx.EntityTable);

	return true;
	}
Пример #17
0
void CBlackBox::Boot (const CString &sPath)

//	Boot
//
//	Prepare the log file

	{
	ASSERT(!m_File.IsOpen());

	//	Generate a filename using the current date and time

	CDateTime Now(CDateTime::Now);
	CString sFilename = strPattern("BlackBox_%04d%02d%02d_%02d%02d%02d.log",
			Now.Year(),
			Now.Month(),
			Now.Day(),
			Now.Hour(),
			Now.Minute(),
			Now.Second());

	//	Create the file

	CString sError;
	if (!m_File.Create(fileAppend(sPath, sFilename), CFile::FLAG_CREATE_ALWAYS, &sError))
		//	LATER: Handle error somehow.
		NULL;
	}
Пример #18
0
bool CCryptosaurEngine::ValidateAuthDescCreate (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx, CDatum dAuthDesc)

//	ValidateAuthDescCreate
//
//	Make sure that the authDesc structure has the proper fields for creating
//	a new user (either admin or not).

	{
	if (!strEquals(dAuthDesc.GetElement(FIELD_TYPE), AUTH_TYPE_SHA1))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_INVALID_AUTHDESC_TYPE, dAuthDesc.GetElement(FIELD_TYPE).AsString()), Msg);
		return false;
		}

	if (dAuthDesc.GetElement(FIELD_CREDENTIALS).IsNil())
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_CREDENTIALS_REQUIRED, Msg);
		return false;
		}

	if (dAuthDesc.GetElement(FIELD_ACTUAL).IsNil())
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_ACTUAL_REQUIRED, Msg);
		return false;
		}

	return true;
	}
Пример #19
0
bool CXMLElement::ParseXML (IMemoryBlock &Stream, 
							   IXMLParserController *pController,
							   CXMLElement **retpElement, 
							   CString *retsError,
							   CExternalEntityTable *retEntityTable)

//	ParseXML
//
//	Parses the block and returns an XML element

	{
	//	Initialize context

	ParserCtx Ctx(Stream, pController);

	//	Parse the prologue

	if (!ParsePrologue(&Ctx))
		{
		*retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError);
		return false;
		}

	//	Next token must be an element open tag

	if (Ctx.iToken != tkTagOpen)
		{
		*retsError = strPattern("Line(%d): root element expected.", Ctx.iLine);
		return false;
		}

	//	Parse the root element

	if (!ParseElement(&Ctx, retpElement))
		{
		*retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError);
		return false;
		}

	//	Done

	if (retEntityTable)
		retEntityTable->AddTable(Ctx.EntityTable);

	return true;
	}
Пример #20
0
void CAeonEngine::MsgMutate (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgMutate
//
//	Aeon.mutate {tableName} {rowPath} {data} {mutationDesc}

	{
	AEONERR error;

	const CString &sTable = Msg.dPayload.GetElement(0);
	CDatum dRowPath = Msg.dPayload.GetElement(1);
	CDatum dData = Msg.dPayload.GetElement(2);
	CDatum dMutateDesc = Msg.dPayload.GetElement(3);

	//	Make sure we are allowed access to this table

	if (!ValidateTableAccess(Msg, pSecurityCtx, sTable))
		return;

	//	If the table doesn't exist, then we can't continue

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return;
		}

	//	Parse the path
	//
	//	NOTE: We don't need to validate that this is a valid path for create
	//	because we do that later inside Mutate. [Because Mutate accepts a nil
	//	path when generating a unique key.]

	CString sError;
	CRowKey Path;
	if (!pTable->ParseDimensionPath(NULL_STR, dRowPath, &Path, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Mutate

	CDatum dResult;
	if (error = pTable->Mutate(Path, dData, dMutateDesc, &dResult, &sError))
		{
		if (error == AEONERR_OUT_OF_DATE)
			SendMessageReplyError(MSG_ERROR_OUT_OF_DATE, sError, Msg);
		else
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Done

	SendMessageReply(MSG_REPLY_DATA, dResult, Msg);
	}
Пример #21
0
void CComplexDateTime::Serialize (CDatum::ESerializationFormats iFormat, IByteStream &Stream) const

//	Serialize
//
//	Serialize to the given format.

	{
	switch (iFormat)
		{
		case CDatum::formatAEONScript:
		case CDatum::formatAEONLocal:
			{
			CString sDate = strPattern("#%d-%02d-%02dT%02d:%02d:%02d.%04d",
					m_DateTime.Year(),
					m_DateTime.Month(),
					m_DateTime.Day(),
					m_DateTime.Hour(),
					m_DateTime.Minute(),
					m_DateTime.Second(),
					m_DateTime.Millisecond());

			Stream.Write(sDate);
			break;
			}

		case CDatum::formatJSON:
			{
			CString sDate = strPattern("\"%d-%02d-%02dT%02d:%02d:%02d.%04d\"",
					m_DateTime.Year(),
					m_DateTime.Month(),
					m_DateTime.Day(),
					m_DateTime.Hour(),
					m_DateTime.Minute(),
					m_DateTime.Second(),
					m_DateTime.Millisecond());

			Stream.Write(sDate);
			break;
			}

		default:
			IComplexDatum::Serialize(iFormat, Stream);
			break;
		}
	}
Пример #22
0
CString CAeonInterface::CreateTableFilePath (const CString &sTable, const CString &sFilePath)

//	CreateTableFilePath
//
//	Composes a full filepath.

	{
	return strPattern("/%s/%s", sTable, sFilePath);
	}
Пример #23
0
CString CMnemosynthDb::GenerateEndpointName (const CString &sMachine, const CString &sModule)

//	GenerateEndpointName
//
//	Generates an endpoint name from machine and module

	{
	return strPattern("%s/%s", sMachine, sModule);
	}
Пример #24
0
bool CArchonProcess::SendMessage (const CString &sAddress, const SArchonMessage &Msg)

//	SendMessage
//
//	Sends a message to the given address. If we fail, we reply as appropriate.

	{
	bool bSuccess;

	CMessagePort *pPort = Bind(sAddress);
	if (pPort)
		{
		bSuccess = pPort->SendMessage(Msg);
		}
	else
		{
		Log(MSG_LOG_ERROR, strPattern(ERR_CANT_BIND, sAddress));
		bSuccess = false;
		}

	//	If we failed to send the message, then we might want to reply to the 
	//	client.

	if (!bSuccess)
		{
		//	If this is a notification port then we ignore the error (it just
		//	means that no one is listening).

		if (!strEndsWith(sAddress, STR_NOTIFY_SUFFIX) 
				&& !strStartsWith(Msg.sMsg, MSG_ERROR_PREFIX))
			{
			//	Reply to client, if necessary

			if (!CMessagePort::IsNullAddr(Msg.sReplyAddr))
				SendMessageCommand(Msg.sReplyAddr, MSG_ERROR_UNABLE_TO_COMPLY, NULL_STR, Msg.dwTicket, CDatum(strPattern(ERR_CANT_SEND_TO, sAddress)));
			else
				Log(MSG_LOG_ERROR, strPattern("Failed sending message to: %s.", sAddress));
			}
		}

	//	Done

	return bSuccess;
	}
Пример #25
0
bool CDatum::CreateFromFile (const CString &sFilespec, ESerializationFormats iFormat, CDatum *retdDatum, CString *retsError)

//	CreateFromFile
//
//	Loads a datum from a file.

	{
	//	Open the file

	CFileBuffer theFile;
	if (!theFile.OpenReadOnly(sFilespec))
		{
		*retsError = strPattern(ERR_CANT_OPEN_FILE, sFilespec);
		return false;
		}

	//	If unknown format, see if we can detect the format

	if (iFormat == formatUnknown)
		{
		if (!DetectFileFormat(sFilespec, theFile, &iFormat, retsError))
			return false;

		//	If format unknown, then error.

		if (iFormat == formatUnknown)
			{
			*retsError = strPattern(ERR_UNKNOWN_FORMAT, sFilespec);
			return false;
			}
		}

	//	Parse it

	if (!Deserialize(iFormat, theFile, retdDatum))
		{
		*retsError = strPattern(ERR_DESERIALIZE_ERROR, sFilespec);
		return false;
		}

	//	Done

	return true;
	}
Пример #26
0
bool CXMLElement::ParseRootElement (IMemoryBlock &Stream, CXMLElement **retpRoot, CExternalEntityTable *retEntityTable, CString *retsError)

//	ParseRootElement
//
//	Parses the entity definitions and the root element (but not the contents
//	of the root element).

	{
	//	Initialize context

	ParserCtx Ctx(Stream, NULL);

	//	Parse the prologue

	if (!ParsePrologue(&Ctx))
		{
		*retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError);
		return false;
		}

	//	Next token must be an element open tag

	if (Ctx.iToken != tkTagOpen)
		{
		*retsError = strPattern("Line(%d): Root element expected.", Ctx.iLine);
		return false;
		}

	//	Parse the root element

	Ctx.m_bParseRootElement = true;
	if (!ParseElement(&Ctx, retpRoot))
		{
		*retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError);
		return false;
		}

	//	Done

	if (retEntityTable)
		retEntityTable->AddTable(Ctx.EntityTable);

	return true;
	}
Пример #27
0
bool CHexeMarkupEvaluator::EvalInit (SHTTPRequestCtx &Ctx,
									 const CHexeProcess &ProcessTemplate, 
									 const CHexeSecurityCtx &SecurityCtx,
									 const TArray<CDatum> &HexeDefinitions,
									 CDatum dFileDesc,
									 CDatum dData)

//	EvalInit
//
//	Initializes evaluation. Return TRUE if the message is ready; FALSE if we 
//	need to wait for an RPC result.

	{
	CleanUp();

	//	Initialize the process that we'll use for evaluation

	m_pProcess = new CHexeProcess;

	//	Clone from the template

	m_pProcess->InitFrom(ProcessTemplate);

	//	Set some context

	m_pProcess->SetLibraryCtx(LIBRARY_HYPERION, Ctx.pSession->GetEngine());
	m_pProcess->SetLibraryCtx(LIBRARY_SESSION, Ctx.pSession);
	m_pProcess->SetLibraryCtx(LIBRARY_SESSION_HTTP_BODY_BUILDER, &Ctx.BodyBuilder);
	m_pProcess->SetLibraryCtx(LIBRARY_SESSION_HTTP_REQUEST, &Ctx.Request);
	m_pProcess->SetSecurityCtx(SecurityCtx);

	//	Definitions

	CString sError;
	if (!m_pProcess->LoadHexeDefinitions(HexeDefinitions, &sError))
		{
		m_Output.Write(strPattern("<!DOCTYPE html><html lang='en'><body><h1>%s</h1></body></html>", htmlWriteText(sError)));
		return ComposeResponse(Ctx);
		}

	//	Initialize parsing

	const CString &sData = dData;
	m_Parser.Init(sData.GetParsePointer(), sData.GetLength());

	//	Initialize state

	m_iProcessing = tagNone;
	m_iIfLevel = 0;
	m_iIfLevelEnd = 0;

	//	Parse until we need to process an RPC message

	return ParseUntilRPC(Ctx);
	}
Пример #28
0
void CArchonTimer::LogTime (IArchonProcessCtx *pProcess, const CString &sText, DWORDLONG dwMinTime) const

//	LogTime
//
//	Logs a time

	{
	DWORDLONG dwTime = ::sysGetTicksElapsed(m_dwStart);
	if (dwTime >= dwMinTime)
		pProcess->Log(MSG_LOG_INFO, strPattern("%s (%s ms)", sText, strFormatInteger((int)dwTime, -1, FORMAT_THOUSAND_SEPARATOR)));
	}
Пример #29
0
void CAeonEngine::MsgInsertNew (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx)

//	MsgInsertNew
//
//	Aeon.insertNew {tableName} {rowPath} {data}
//
//	{rowPath} is an array with as many elements as the table dimensions

	{
	AEONERR error;

	const CString &sTable = Msg.dPayload.GetElement(0);
	CDatum dRowPath = Msg.dPayload.GetElement(1);
	CDatum dData = Msg.dPayload.GetElement(2);

	//	Make sure we are allowed access to this table

	if (!ValidateTableAccess(Msg, pSecurityCtx, sTable))
		return;

	//	If the table doesn't exist, then we can't continue

	CAeonTable *pTable;
	if (!FindTable(sTable, &pTable))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg);
		return;
		}

	//	Parse the path

	CString sError;
	CRowKey Path;
	if (!pTable->ParseDimensionPathForCreate(dRowPath, &Path, &sError))
		{
		SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Insert

	if (error = pTable->Insert(Path, dData, true, &sError))
		{
		if (error == AEONERR_ALREADY_EXISTS)
			SendMessageReplyError(MSG_ERROR_ALREADY_EXISTS, sError, Msg);
		else
			SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg);
		return;
		}

	//	Done

	SendMessageReply(MSG_OK, CDatum(), Msg);
	}
Пример #30
0
bool CAeonEngine::OpenTableDefinitions (void)

//	OpenTableDefinitions
//
//	Opens and reads all tables in all volumes. Note that we have no idea what
//	could have happened since our last boot--someone could have copied files
//	all over the place. We make almost no assumptions.

	{
	CSmartLock Lock(m_cs);

	int i, j;
	CString sError;

	//	Loop over all volumes and end up with a list of tables and volumes

	TSortMap<CString, TArray<CString>> Tables;
	for (i = 0; i < m_LocalVolumes.GetCount(); i++)
		{
		CString sVolume = m_LocalVolumes.GetVolume(i);

		TArray<CString> Dirs;
		fileGetFileList(fileAppend(m_LocalVolumes.GetPath(i), FILESPEC_TABLE_DIR_FILTER), FFL_FLAG_DIRECTORIES_ONLY | FFL_FLAG_RELATIVE_FILESPEC, &Dirs);

		for (j = 0; j < Dirs.GetCount(); j++)
			{
			TArray<CString> *pList = Tables.SetAt(Dirs[j]);
			pList->Insert(sVolume);
			}
		}

	//	Open all tables

	for (i = 0; i < Tables.GetCount(); i++)
		{
		CString sName = Tables.GetKey(i);

		CAeonTable *pTable = new CAeonTable;
		if (!pTable->Open(GetProcessCtx(), &m_LocalVolumes, sName, Tables[i], &sError))
			{
			Log(MSG_LOG_ERROR, strPattern("Unable to load %s: %s", sName, sError));
			delete pTable;
			continue;
			}

		m_Tables.Insert(sName, pTable);
		}

	//	Done

	return true;
	}