#include <cdevContextMap.h>

// *****************************************************************************
// * cdevContextMap::cdevContextMap :
// *	This is the constructor for the class and it initializes all 
// *	data items to 0 or NULL...
// *****************************************************************************
cdevContextMap::cdevContextMap  ( void ) 
	: entries(NULL), maximum(0), cnt(0) 
	{}

// *****************************************************************************
// * cdevContextMap::~cdevContextMap :
// *	This is the destructor for the class and it will delete any
// *	cdevData objects that have been allocated using new and will
// *	then free the array that was allocated using malloc or realloc.
// *****************************************************************************
cdevContextMap::~cdevContextMap ( void )
	{
	if(entries!=NULL)
		{
		for(int i=0; i<maximum; i++) if(entries[i]!=NULL) delete entries[i];
		free(entries);
		}
	entries = NULL;
	maximum = 0;
	cnt     = 0;
	}


// *****************************************************************************
// * cdevContextMap::resize :
// *	This method is called to double the number of pointers that 
// *	are available to store context items in...
// *****************************************************************************
void cdevContextMap::resize ( void )
	{
	if(maximum<=0)
		{
		maximum = 64;
		entries = (cdevData **)malloc(maximum * sizeof(cdevData *));
		memset(entries, 0, maximum*sizeof(cdevData *));
		}
	else	{
		entries = (cdevData **)realloc(entries, 2*maximum*sizeof(cdevData *));
		memset(&entries[maximum], 0, maximum*sizeof(cdevData *));
		maximum *= 2;
		}
	}

// *****************************************************************************
// * cdevContextMap::insert :
// *	This method is used to add a new cdevData object to the
// *	cdevContextMap table... If a matching cdevData object already
// *	exists in the class, then its identifier will be returned...
// *	otherwise, a new cdevData object will be added to the list and 
// *	the index of the new item will be returned...
// ***************************************************************************** 
int cdevContextMap::insert ( cdevData & context )
	{
	int i;
	int found = 0;

	for(i=0; 
	    i<cnt && (entries[i]==NULL || !(found=(*entries[i]==context)));
	    i++);

	if(!found)
		{
		if(i>=maximum) resize();
		entries[i] = new cdevData(context);
		cnt++;
		}
	return i;
	}


// *****************************************************************************
// * cdevContextMap::find :
// *	This method allows the caller to obtain the index of a context
// *	cdevData object that matches the cdevData object he provides...
// *	If a matching context object cannot be found, then -1 will be
// *	returned.
// *****************************************************************************
int cdevContextMap::find ( cdevData & context )
	{
	int i;
	int found;

	for(i=0; 
	    i<cnt && (entries[i]==NULL || !(found=(*entries[i]==context)));
	    i++);
	    
	return (i<cnt)?i:-1;
	}

// *****************************************************************************
// * cdevContextMap::asciiDump :
// *	This is a diagnostic method that allows the caller to dump the
// *	contents of the cdevContextMap table to a file descriptor...
// *****************************************************************************
void cdevContextMap::asciiDump ( FILE * fp )
	{
	fprintf(fp, "----------------------------------------------------------\n");
	fprintf(fp, "           Diagnostic Dump of CDEV Context Map\n");
	fprintf(fp, "----------------------------------------------------------\n");
	fprintf(fp, "Number of Entries           : %i\n", cnt);
	fprintf(fp, "Allocated Maximum Entries   : %i\n", maximum);

	for(int i=0; i<cnt; i++)
		{
		fprintf(fp, "\n\t------------------------------------------------\n");
		fprintf(fp, "\tContext at Entry Number %i\n", i);
		fprintf(fp, "\t------------------------------------------------\n");
		if(entries[i]==NULL) fprintf(fp, "\t(not specified)\n");
		else                 entries[i]->asciiDump(fp);
		fflush(fp);
		}
	fprintf(fp, "----------------------------------------------------------\n");
	fprintf(fp, "        End of Diagnostic Dump of CDEV Context Map\n");
	fprintf(fp, "----------------------------------------------------------\n\n");
	fflush(fp);
	}
