//===========================================================================//
// File:    storage.cpp                                                     
// Project: LabRat                                                 		 
// Contents: 				  
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 07/9/96   JSE  Initial coding.                                             
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//





#include "stdafx.h"
#include "storage.hpp"

#include "new.h"
#include "math.h"


//#ifdef _DEBUG
//#define new DEBUG_NEW
//#undef THIS_FILE
//static char THIS_FILE[] = __FILE__;
//#endif

//
// All new types must be registered in these functions.
//

/////////////////////////////////////////////////////////////////////////////

TraceStorage *
	TraceStorage::FindElement(CObarrayHolder *data_holder, int element)
{

	TraceStorage *trace_str;
	switch (data_holder->traceType)
	{
		case CLabRatDoc::LogicalTraceType:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(ToggleTraceStorage)*element);
			break;
			
		case CLabRatDoc::IntegerTraceType:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(IntegerTraceStorage)*element);
			break;
		
		case CLabRatDoc::ScalarTraceType:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(ScalarTraceStorage)*element);
			break;
		
		case CLabRatDoc::MarkerTraceType:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(MarkerTraceStorage)*element);
			break;

		case CLabRatDoc::ReceiverMessageTraceType:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(ReceiverMessageTraceStorage)*element);
			break;

		default:
			trace_str = data_holder->data;
			*((char **)(&trace_str)) += (sizeof(TraceStorage)*element);
			break;
	}
	
	return trace_str;
}

/////////////////////////////////////////////////////////////////////////////

TraceLine *
	TraceStorage::CreateTraceLine(int trace_type)
{

	TraceLine *trace_line;
	switch (trace_type)
	{
		case CLabRatDoc::LogicalTraceType:
			trace_line =
				(TraceLine*)new ToggleTraceLine;
			break;

		case CLabRatDoc::IntegerTraceType:
			trace_line =
				(TraceLine*)new IntegerTraceLine;
			break;
		
		case CLabRatDoc::ScalarTraceType:
			trace_line =
				(TraceLine*)new ScalarTraceLine;
			break;
		
		case CLabRatDoc::MarkerTraceType:
			trace_line =
				(TraceLine*)new MarkerTraceLine;
			break;

		case CLabRatDoc::ReceiverMessageTraceType:
			trace_line =
				(TraceLine*)new ReceiverMessageTraceLine;
			break;

		default:
			trace_line =
				new TraceLine;

	}

	return trace_line;
}



/////////////////////////////////////////////////////////////////////////////

void
	TraceStorage::AllocateStorage(CObarrayHolder *data_holder)
{

	if (data_holder->traceEntryCount == 0)
	{
		data_holder->size = 0;
		return;
	}

	LPVOID mem_pointer;

	int i;

	TraceStorage *init_mem;

	switch (data_holder->traceType)
	{

		case CLabRatDoc::LogicalTraceType:
			data_holder->size = sizeof(ToggleTraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 

			 init_mem = (TraceStorage *)mem_pointer;

			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {	
				init_mem = (TraceStorage *)new(init_mem) ToggleTraceStorage;
				*((char **)(&init_mem)) += sizeof(ToggleTraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;

			break;
		
		case CLabRatDoc::IntegerTraceType:
			data_holder->size = sizeof(IntegerTraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 init_mem = (TraceStorage *)mem_pointer;
			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {
				
				init_mem = (TraceStorage *)new(init_mem) IntegerTraceStorage;
				*((char **)(&init_mem)) += sizeof(IntegerTraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;

			break;
		
		case CLabRatDoc::ScalarTraceType:
			data_holder->size = sizeof(ScalarTraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 init_mem = (TraceStorage *)mem_pointer;
			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {
				
				init_mem = (TraceStorage *)new(init_mem) ScalarTraceStorage;
				*((char **)(&init_mem)) += sizeof(ScalarTraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;


			break;
	
		case CLabRatDoc::MarkerTraceType:
			data_holder->size = sizeof(MarkerTraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 
			 init_mem = (TraceStorage *)mem_pointer;
			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {
				
				init_mem = (TraceStorage *)new(init_mem) MarkerTraceStorage;
				*((char **)(&init_mem)) += sizeof(MarkerTraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;


			break;

		case CLabRatDoc::ReceiverMessageTraceType:
			data_holder->size = sizeof(ReceiverMessageTraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 
			 init_mem = (TraceStorage *)mem_pointer;
			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {
				
				init_mem = (TraceStorage *)new(init_mem) ReceiverMessageTraceStorage;
				*((char **)(&init_mem)) += sizeof(ReceiverMessageTraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;


			break;

		default:
			data_holder->size = sizeof(TraceStorage) * data_holder->traceEntryCount;
	
			mem_pointer = 
				VirtualAlloc(NULL, data_holder->size, 
				MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
			
			 
			 init_mem = (TraceStorage *)mem_pointer;
			 for ( i = 0;  i < data_holder->traceEntryCount; ++i)
			 {
				
				init_mem = (TraceStorage *)new(init_mem) TraceStorage;
				*((char **)(&init_mem)) += sizeof(TraceStorage);
			 }

			 data_holder->data = (TraceStorage *)mem_pointer;


			break;

	}
}

/////////////////////////////////////////////////////////////////////////////



void
	TraceStorage::LoadData(
		CArchive& /*ar*/, CObarrayHolder * /*data_holder*/, BYTE /*edge_flag*/)
{
	
}


/////////////////////////////////////////////////////////////////////////////

void
	ToggleTraceStorage::LoadData(
		CArchive& /*ar*/, CObarrayHolder * /*data_holder*/ , BYTE edge_flag)
{
	if (edge_flag == CLabRatDoc::GoingDownFlag)
	{
		SetPosition(FALSE);
	}
	else
	{
		SetPosition(TRUE);
	}
}

/////////////////////////////////////////////////////////////////////////////

void
	IntegerTraceStorage::LoadData(
		CArchive& ar, CObarrayHolder * /*data_holder*/, BYTE /*edge_flag*/)
{
	ar >> position;
	BigEndianConvert(position);
}

/////////////////////////////////////////////////////////////////////////////

void
	ScalarTraceStorage::LoadData(
		CArchive& ar, CObarrayHolder * /*data_holder*/, BYTE /*edge_flag*/)
{
	ar >> position;
	BigEndianConvert(position);
}

/////////////////////////////////////////////////////////////////////////////


void
	ReceiverMessageTraceStorage::LoadData(
		CArchive& ar, CObarrayHolder *data_holder, BYTE edge_flag)
{
	
	ScalarTraceStorage::LoadData(ar, data_holder, edge_flag);

	if (edge_flag == CLabRatDoc::Queing)
	{
		edgeFlag = messageQue;
	}
	else if (edge_flag == CLabRatDoc::Dispatching)
	{
		edgeFlag = messageDispatch;
	}

	ar >> messagePriority;
	BYTE throwaway;

	if (BigEndian)
	{
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
	}

	ar >> classID;
	if (BigEndian)
	{
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
	}
	
	ar >> messageID;
	
	BigEndianConvert(messagePriority);
	BigEndianConvert(classID);
	BigEndianConvert(messageID);
	
}
