#include "stdafx.h"
#include "Protocol.h"


/**********************************************************************************************
** Statische Funktionen                                                                      **
**********************************************************************************************/

static Protocol *pStaticProtocol = 0;

Protocol *GetStaticProtocolObject ()
{
	if (!pStaticProtocol) {
		pStaticProtocol = new Protocol();
	}
	return pStaticProtocol;
}


/**********************************************************************************************
** class ProtocolRoot                                                                        **
**********************************************************************************************/

ProtocolRoot::ProtocolRoot (int hasSemaphore)
{
	if (hasSemaphore) hSem = CreateSemaphore (0,1,1,0);
	count = alloc = 0;
	ppColl = 0;
	pParentObject = 0;
	start_time = time (0);
}

ProtocolRoot::~ProtocolRoot ()
{
	if (hSem) CloseHandle (hSem);
	if (ppColl) {
		unsigned int i;
		for (i = 0; i < count; i++) delete ppColl[i];
		delete ppColl;
	}
}

void ProtocolRoot::EnterCS ()
{
	if (hSem) WaitForSingleObject (hSem, INFINITE);
}

void ProtocolRoot::LeaveCS ()
{
	if (hSem) ReleaseSemaphore (hSem, 1, 0);
}

void ProtocolRoot::CollAdd (ProtocolRoot *pNew)
{
	if (count == alloc) {
		ProtocolRoot **ppOld = ppColl;
		ppColl = new ProtocolRoot * [alloc += PROTOCOL_EXTEND];
		if (ppOld) {
			memcpy (ppColl, ppOld, sizeof (ProtocolRoot *) * count);
			delete ppOld;
		}
	}
	ppColl[count++] = pNew;
	pNew->SetParent (this);
}

unsigned int ProtocolRoot::CollGetCount () const
{
	return count;
}

ProtocolRoot *ProtocolRoot::CollGet (unsigned int nr) const
{
	if (nr < count) return ppColl[nr];
	else return 0;
}

void ProtocolRoot::SetParent (ProtocolRoot *pParent)
{
	pParentObject = pParent;
}


/**********************************************************************************************
** class Protocol                                                                            **
**********************************************************************************************/

Protocol::Protocol (void) : ProtocolRoot (1)
{
}

Protocol::~Protocol (void)
{
}

void Protocol::SaveAddObject (ProtocolObject *pObject)
{
	EnterCS ();
	CollAdd (pObject);
	LeaveCS ();
}


/**********************************************************************************************
** class ProtocolObject                                                                      **
**********************************************************************************************/

ProtocolObject::ProtocolObject () : ProtocolRoot (0)
{
}

ProtocolObject::~ProtocolObject ()
{
}

void ProtocolObject::SaveClose ()
{
	pParentObject->EnterCS ();
	opened = 0;
	end_time = time (0);
	pParentObject->LeaveCS ();
}

void ProtocolObject::SaveAddCall (ProtocolCall *pCall)
{
	pParentObject->EnterCS ();
	CollAdd (pCall);
	pParentObject->LeaveCS ();
}

unsigned int ProtocolObject::GetLine (unsigned int id, char *buffer, unsigned int buflen) const
{
	char buf[256];

	if (opened)
		sprintf (buf, "%04d: %08X open     %s", id, (unsigned int) start_time, "Object");
	else
		sprintf (buf, "%04d: %08X %08x %s", id, (unsigned int) start_time, (unsigned int) end_time, "Object");

	strncpy (buffer, buf, buflen);
	return (unsigned int) strlen (buf);

}



/**********************************************************************************************
** class ProtocolCall                                                                        **
**********************************************************************************************/

ProtocolCall::ProtocolCall (const char *call, const char *parameters) : ProtocolRoot (0)
{
	strncpy (sCall, call, PROTOCOL_CALL_SIZE);
	sCall[PROTOCOL_CALL_SIZE-1] = 0;
	strncpy (sParameters, parameters, PROTOCOL_CALL_PARAMETERS);
	sParameters[PROTOCOL_CALL_PARAMETERS-1] = 0;
}

ProtocolCall::~ProtocolCall ()
{
}

void ProtocolCall::SetResult (const char *result)
{
	strncpy (sResult, result, PROTOCOL_CALL_RESULT);
	sResult[PROTOCOL_CALL_RESULT-1] = 0;
	end_time = time (0);
}

unsigned int ProtocolCall::GetLine (unsigned int object_id, unsigned int id, char *buffer, unsigned int buflen) const
{
	char buf[512];
	sprintf (buf, "%4d:%4d: %08X %08x %-20.20s %-50.50s %-30.30s", object_id, id, start_time, end_time, sCall, sParameters, sResult);
	strncpy (buffer, buf, buflen);
	return (unsigned int) strlen (buf);
}
