#include <math.h>
#include <cdevData.h>
#include "equal.h"

typedef int (*cdevTest)(cdevData & data);

int tagTest         ( cdevData & data );
int scalarTest      ( cdevData & data );
int byteArrayTest   ( cdevData & data );
int shortArrayTest  ( cdevData & data );
int ushortArrayTest ( cdevData & data );
int intArrayTest    ( cdevData & data );
int uintArrayTest   ( cdevData & data );
int longArrayTest   ( cdevData & data );
int ulongArrayTest  ( cdevData & data );
int floatArrayTest  ( cdevData & data );
int doubleArrayTest ( cdevData & data );
int stringArrayTest ( cdevData & data );
int asciiDumpTest   ( cdevData & data );
int copyTest        ( cdevData & data );
int assignmentTest  ( cdevData & data );
int removeTest      ( cdevData & data );
int findTest        ( cdevData & data );
int xdrTest         ( cdevData & data );

enum testTags
	{
	TAGTEST = 0,
	SCALARTEST,
	BYTEARRAYTEST,
	SHORTARRAYTEST,
	USHORTARRAYTEST,
	INTARRAYTEST,
	UINTARRAYTEST,
	LONGARRAYTEST,
	ULONGARRAYTEST,
	FLOATARRAYTEST,
	DOUBLEARRAYTEST,
	STRINGARRAYTEST,
	COPYTEST,
	ASSIGNTEST,
	FINDTEST,
	XDRTEST,
	ASCIIDUMPTEST,
	REMOVETEST,
	MAXTESTS	
	};

cdevTest testFunctions[MAXTESTS] =
	{
	tagTest,
	scalarTest,
	byteArrayTest,
	shortArrayTest,
	ushortArrayTest,
	intArrayTest,
	uintArrayTest,
	longArrayTest,
	ulongArrayTest,
	floatArrayTest,
	doubleArrayTest,
	stringArrayTest,
	copyTest,
	assignmentTest,
	findTest,
	xdrTest,
	asciiDumpTest,
	removeTest,
	};
	
char * testNames[MAXTESTS] = 
	{
	"Tag Insertion/Extraction Test",
	"Scalar Insertion/Extraction Test",
	"Byte Array Insertion/Extraction Test",
	"Short Array Insertion/Extraction Test",
	"Unsigned Short Array Insert/Extract Test",
	"Int Array Insert/Extract Test",
	"Unsigned Int Array Insert/Extract Test",
	"Long Array Insert/Extract Test",
	"Unsigned Long Array Insert/Extract Test",
	"Float Array Insert/Extract Test",
	"Double Array Insert/Extract Test",
	"String Insert/Extract Test",
	"Copy Constructor Test",
	"Assignment Operator Copy Test",
	"Tagged Item Find Test",
	"XDR Import/Export Facility Test",
	"ASCII Dump Test",
	"Tagged Item Deletion Test",
	};
	

int testResults[MAXTESTS];


int main()
{
int i;
cdevData data;

for(i=0; i<MAXTESTS; i++) testResults[i]=CDEV_SUCCESS;

for(i=0; i<MAXTESTS && testFunctions[i]!=NULL; i++)
	{
	fprintf(stdout, "******************************************************\n");
	fprintf(stdout, "* Beginning : %-38.38s *\n", testNames[i]);
	testResults[i] = testFunctions[i](data);
	fprintf(stdout, "* Completing: %-38.38s *\n", testNames[i]);
	fprintf(stdout, "* Status    : %-38.38s *\n", testResults[i]?"FAILURE":"SUCCESS");
	fprintf(stdout, "******************************************************\n\n");
	}
fprintf(stdout, "\n\nFINAL RESULTS\n");
for(i=0; i<MAXTESTS; i++)
	{
	fprintf(stdout, "\t%-50.50s %s\n", testNames[i], testResults[i]?"FAILURE":"SUCCESS");
	}
fprintf(stdout, "\n");
return 0;
}


int globalTags[20] = 
	{
	101, 102, 103, 104, 105,
	106, 107, 108, 109, 110,
	111, 112, 113, 114, 115, 
	116, 117, 118, 119, 120
	};
char *globalTagNames[20] = 
	{
	"tag01", "tag02", "tag03",  "tag04", "tag05",
	"tag06", "tag07", "tag08",  "tag09", "tag10",
	"tag11", "tag12", "tag13",  "tag14", "tag15",
	"tag16", "tag17", "tag18",  "tag19", "tag20"
	};
	
int tagTest ( cdevData & data )
{
int i;
int    localTags[20];
char * localTagNames[20];

for(i=0; i<20; i++) data.insertTag(globalTags[i], globalTagNames[i]);
for(i=0; i<20; i++) data.tagC2I   (globalTagNames[i], &localTags[i]);
for(i=0; i<20; i++) data.tagI2C   (globalTags[i], localTagNames[i]);
for(i=0; i<20; i++)
	{
	if(localTags[i]!=globalTags[i]) return -1;
	if(strcmp(localTagNames[i], globalTagNames[i])) return -1;
	}
return 0;
}

int scalarTest ( cdevData & data )
{
int result = 0;

BYTE           c   = 1, C[10];
short          s   = 2, S[10];
unsigned short us  = 3, US[10];
int            i   = 4, I[10];
unsigned int   ui  = 5, UI[10];
long           l   = 6, L[10];
unsigned long  ul  = 7, UL[10];
float          f   = 8.0, F[10];
double         d   = 9.0, D[10];
char *         str = "10.11", STR[10][32];

data.insert(globalTagNames[0], c);
data.insert(globalTagNames[1], s);
data.insert(globalTagNames[2], us);
data.insert(globalTagNames[3], i);
data.insert(globalTagNames[4], ui);
data.insert(globalTagNames[5], l);
data.insert(globalTagNames[6], ul);
data.insert(globalTagNames[7], f);
data.insert(globalTagNames[8], d);
data.insert(globalTagNames[9], str);

for(int x=0; x<10; x++)
	{
	data.get(globalTagNames[x], &C[x]);
	data.get(globalTagNames[x], &S[x]);
	data.get(globalTagNames[x], &US[x]);
	data.get(globalTagNames[x], &I[x]);
	data.get(globalTagNames[x], &UI[x]);
	data.get(globalTagNames[x], &L[x]);
	data.get(globalTagNames[x], &UL[x]);
	data.get(globalTagNames[x], &F[x]);
	data.get(globalTagNames[x], &D[x]);
	data.get(globalTagNames[x], STR[x], 32);
	}

if(c!=(BYTE)C[0]     || C[0]!=(BYTE)S[0]  || 
   C[0]!=(BYTE)US[0] || C[0]!=(BYTE)I[0]  ||
   C[0]!=(BYTE)UI[0] || C[0]!=(BYTE)L[0]  ||
   C[0]!=(BYTE)UL[0] || C[0]!=(BYTE)F[0]  || 
   C[0]!=(BYTE)D[0]  || C[0]!=(BYTE)atof(STR[0]))  
   	{
   	fprintf(stdout, "* ERROR IN BYTE INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(s!=(short)S[1]     || C[1]!=(BYTE)S[1]  || 
   S[1]!=(short)US[1] || S[1]!=(short)I[1]  ||
   S[1]!=(short)UI[1] || S[1]!=(short)L[1]  ||
   S[1]!=(short)UL[1] || S[1]!=(short)F[1]  || 
   S[1]!=(short)D[1]  || S[1]!=(short)atof(STR[1]))  
   	{
   	fprintf(stdout, "* ERROR IN SHORT INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(us!=(unsigned short)US[2]    || C[2]!=(BYTE)US[2]  || 
   S[2]!=(short)US[2]           || US[2]!=(unsigned short)I[2]  ||
   US[2]!=(unsigned short)UI[2] || US[2]!=(unsigned short)L[2]  ||
   US[2]!=(unsigned short)UL[2] || US[2]!=(unsigned short)F[2]  || 
   US[2]!=(unsigned short)D[2]  || US[2]!=(unsigned short)atof(STR[2]))  
   	{
   	fprintf(stdout, "* ERROR IN UNSIGNED SHORT INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(i!=(int)I[3]       || C[3]!=(BYTE)I[3]  || 
   S[3]!=(short)I[3]  || US[3]!=(unsigned short)I[3]  ||
   I[3]!=(int)UI[3]   || I[3]!=(int)L[3]  ||
   I[3]!=(int)UL[3]   || I[3]!=(int)F[3]  || 
   I[3]!=(int)D[3]    || I[3]!=(int)atof(STR[3]))  
   	{
   	fprintf(stdout, "* ERROR IN INT INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(ui!=(unsigned int)UI[4]    || C[4]!=(BYTE)UI[4]  || 
   S[4]!=(short)UI[4]         || US[4]!=(unsigned short)UI[4]  ||
   I[4]!=(int)UI[4]           || UI[4]!=(unsigned int)L[4]  ||
   UI[4]!=(unsigned int)UL[4] || UI[4]!=(unsigned int)F[4]  || 
   UI[4]!=(unsigned int)D[4]  || UI[4]!=(unsigned int)atof(STR[4]))  
   	{
   	fprintf(stdout, "* ERROR IN UNSIGNED INT INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(l!=(long)L[5]      || C[5]!=(BYTE)L[5]  || 
   S[5]!=(short)L[5]  || US[5]!=(unsigned short)L[5]  ||
   I[5]!=(int)L[5]    || UI[5]!=(unsigned int)L[5]  ||
   L[5]!=(long)UL[5]  || L[5]!=(long)F[5]  || 
   L[5]!=(long)D[5]   || L[5]!=(long)atof(STR[5])) 
   	{
   	fprintf(stdout, "* ERROR IN LONG INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(ul!=(unsigned long)UL[6]   || C[6]!=(BYTE)UL[6]  || 
   S[6]!=(short)UL[6]         || US[6]!=(unsigned short)UL[6]  ||
   I[6]!=(int)UL[6]           || UI[6]!=(unsigned int)UL[6]  ||
   L[6]!=(long)UL[6]          || UL[6]!=(unsigned long)F[6]  || 
   UL[6]!=(unsigned long)D[6] || UL[6]!=(unsigned long)atof(STR[6])) 
   	{
   	fprintf(stdout, "* ERROR IN UNSIGNED LONG INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(f!=(float)F[7]    || C[7]!=(BYTE)F[7]  || 
   S[7]!=(short)F[7] || US[7]!=(unsigned short)F[7]  ||
   I[7]!=(int)F[7]   || UI[7]!=(unsigned int)F[7]  ||
   L[7]!=(long)F[7]  || UL[7]!=(unsigned long)F[7]  || 
   F[7]!=(float)D[7] || F[7]!=(float)atof(STR[7])) 
   	{
   	fprintf(stdout, "* ERROR IN FLOAT INSERTION/EXTRACTION\n");
   	result = -1;
	} 
	
if(d!=(double)D[8]    || C[8]!=(BYTE)D[8]  || 
   S[8]!=(short)D[8] || US[8]!=(unsigned short)D[8]  ||
   I[8]!=(int)D[8]   || UI[8]!=(unsigned int)D[8]  ||
   L[8]!=(long)D[8]  || UL[8]!=(unsigned long)D[8]  || 
   F[8]!=(float)D[8] || D[8]!=(double)atof(STR[8])) 
   	{
   	fprintf(stdout, "* ERROR IN DOUBLE INSERTION/EXTRACTION\n");
   	result = -1;
	} 

if(strcmp(str, STR[9])       || C[9]!=(BYTE)atof(STR[9]) || 
   S[9]!=(short)atof(STR[9]) || US[9]!=(unsigned short)atof(STR[9]) ||
   I[9]!=(int)atof(STR[9])   || UI[9]!=(unsigned int)atof(STR[9])  ||
   L[9]!=(long)atof(STR[9])  || UL[9]!=(unsigned long)atof(STR[9]) || 
   fabs(F[9]-(float)atof(STR[9]))>0.0001 || D[9]!=(double)atof(STR[9])) 
   	{
   	fprintf(stdout, "* ERROR IN STRING INSERTION/EXTRACTION\n");
   	result = -1;
	}
return result;
}


int byteArrayTest ( cdevData & data )
{
int  LOCALTAG = 10;
int  result = 0, bresult = 0;
int  x;
BYTE input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 10;
bounds[1].offset = 0;
bounds[1].length = 10;
bounds[2].offset = 0;
bounds[2].length = 10;

for(x=0; x<1000; x++) input[x] = (BYTE)x;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if(input[x]!=(BYTE)C[x]  || input[x]!=(BYTE)S[x] ||
	   input[x]!=(BYTE)US[x] || input[x]!=(BYTE)I[x] ||
	   input[x]!=(BYTE)UI[x] || input[x]!=(BYTE)L[x] ||
	   input[x]!=(BYTE)UL[x] || input[x]!=(BYTE)F[x] || 
	   input[x]!=(BYTE)D[x]  || input[x]!=(BYTE)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int shortArrayTest ( cdevData & data )
{
int  LOCALTAG = 11;
int  result = 0, bresult = 0;
int  x;
short input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (short)x*2;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || input[x]!=(short)S[x] ||
	   input[x]!=(short)US[x] || input[x]!=(short)I[x] ||
	   input[x]!=(short)UI[x] || input[x]!=(short)L[x] ||
	   input[x]!=(short)UL[x] || input[x]!=(short)F[x] || 
	   input[x]!=(short)D[x]  || input[x]!=(short)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int ushortArrayTest ( cdevData & data )
{
int  LOCALTAG = 12;
int  result = 0, bresult = 0;
int  x;
unsigned short input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (unsigned short)x*3;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   input[x]!=(unsigned short)US[x] || input[x]!=(unsigned short)I[x] ||
	   input[x]!=(unsigned short)UI[x] || input[x]!=(unsigned short)L[x] ||
	   input[x]!=(unsigned short)UL[x] || input[x]!=(unsigned short)F[x] || 
	   input[x]!=(unsigned short)D[x]  || input[x]!=(unsigned short)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int intArrayTest ( cdevData & data )
{
int  LOCALTAG = 13;
int  result = 0, bresult = 0;
int  x;
int input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (int)x*4;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   (unsigned short)input[x]!=US[x] || input[x]!=(int)I[x] ||
	   input[x]!=(int)UI[x] || input[x]!=(int)L[x] ||
	   input[x]!=(int)UL[x] || input[x]!=(int)F[x] || 
	   input[x]!=(int)D[x]  || input[x]!=(int)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int uintArrayTest ( cdevData & data )
{
int  LOCALTAG = 14;
int  result = 0, bresult = 0;
int  x;
unsigned int input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (unsigned int)x*5;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   (unsigned short)input[x]!=US[x] || (int)input[x]!=I[x] ||
	   input[x]!=(unsigned int)UI[x] || input[x]!=(unsigned int)L[x] ||
	   input[x]!=(unsigned int)UL[x] || input[x]!=(unsigned int)F[x] || 
	   input[x]!=(unsigned int)D[x]  || input[x]!=(unsigned int)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}


int longArrayTest ( cdevData & data )
{
int  LOCALTAG = 15;
int  result = 0, bresult = 0;
int  x;
long input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (long)x*6;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   (unsigned short)input[x]!=US[x] || (int)input[x]!=I[x] ||
	   (unsigned int)input[x]!=UI[x] || input[x]!=(long)L[x] ||
	   input[x]!=(long)UL[x] || input[x]!=(long)F[x] || 
	   input[x]!=(long)D[x]  || input[x]!=(long)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int ulongArrayTest ( cdevData & data )
{
int  LOCALTAG = 16;
int  result = 0, bresult = 0;
int  x;
unsigned long input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (unsigned long)x*7;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   (unsigned short)input[x]!=US[x] || (int)input[x]!=I[x] ||
	   (unsigned int)input[x]!=UI[x] || (long)input[x]!=L[x] ||
	   input[x]!=(unsigned long)UL[x] || input[x]!=(unsigned long)F[x] || 
	   input[x]!=(unsigned long)D[x]  || input[x]!=(unsigned long)atof(STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int floatArrayTest ( cdevData & data )
{
int  LOCALTAG = 17;
int  result = 0, bresult = 0;
int  x;
float input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (float)2.1 * x;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)input[x]!=C[x] || (short)input[x]!=S[x] ||
	   (unsigned short)input[x]!=US[x] || (int)input[x]!=I[x] ||
	   (unsigned int)input[x]!=UI[x] || (long)input[x]!=L[x] ||
	   (unsigned long)input[x]!=UL[x] || input[x]!=(float)F[x] || 
	   input[x]!=(float)D[x]  || !equal(input[x], (float)atof(STR[x])))
		{
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int doubleArrayTest ( cdevData & data )
{
int  LOCALTAG = 18;
int  result = 0, bresult = 0;
int  x;
double input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) input[x] = (double)5.1111112*x;
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000 && !result; x++)
	{
	if((BYTE)input[x]!=C[x]               || 
	   (short)input[x]!=S[x]              ||
	   (unsigned short)input[x]!=US[x]    || 
	   (int)input[x]!=I[x]                ||
	   (unsigned int)input[x]!=UI[x]      || 
	   (long)input[x]!=L[x]               ||
	   (unsigned long)input[x]!=UL[x]     || 
	   !equal((float)input[x],F[x])       || 
	   !equal(input[x],(double)D[x])      || 
	   !equal(input[x],(double)atof(STR[x])))
		{
		if((BYTE)input[x]!=C[x])                 fprintf(stdout, "* Byte %c != %c\n",           (BYTE)input[x], C[x]);
		if((short)input[x]!=S[x])                fprintf(stdout, "* Short %i != %i\n",          (short)input[x], S[x]);
		if((unsigned short)input[x]!=US[x])      fprintf(stdout, "* Unsigned short %i != %i\n", (unsigned short)input[x], US[x]); 
		if((int)input[x]!=I[x])                  fprintf(stdout, "* Int %i != %i\n",            (int)input[x], I[x]);
		if((unsigned int)input[x]!=UI[x])        fprintf(stdout, "* Unsigned int %i != %i\n",   (unsigned int)input[x], UI[x]); 
		if((long)input[x]!=L[x])                 fprintf(stdout, "* Long %i != %i\n",           (long)input[x], L[x]);
		if((unsigned long)input[x]!=UL[x])       fprintf(stdout, "* Unsigned long %i != %i\n",  (unsigned long)input[x], UL[x]); 
		if(!equal((float)input[x],(double)F[x])) fprintf(stdout, "* Float %f != %f\n",          (float)input[x], F[x]); 
		if(!equal(input[x],D[x]))                fprintf(stdout, "* Double %f != %f\n",         input[x], D[x]);
		if(!equal(input[x],atof(STR[x])))        fprintf(stdout, "* String %f != %f\n",         input[x], atof(STR[x]));
		result = -1;
		}
	delete STR[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}

int stringArrayTest ( cdevData & data )
{
int  LOCALTAG = 19;
int  result = 0, bresult = 0;
int  x;
char * input[1000];
cdevBounds bounds[3];
cdevBounds obounds[3];

BYTE            C[1000];
short           S[1000];
unsigned short US[1000];
int             I[1000];
unsigned int   UI[1000];
long            L[1000];
unsigned long  UL[1000];
float           F[1000];
double          D[1000];
char *        STR[1000];

bounds[0].offset = 0;
bounds[0].length = 5;
bounds[1].offset = 0;
bounds[1].length = 2;
bounds[2].offset = 0;
bounds[2].length = 100;

for(x=0; x<1000; x++) 
	{
	input[x] = new char[32];
	sprintf(input[x], "%i.%i", x, x);
	}
	
data.insert(globalTags[LOCALTAG], input, 1000, 3);
data.setBounds(globalTags[LOCALTAG], bounds, 3);
data.getBounds(globalTags[LOCALTAG], obounds, 3);
for(x=0; x<3; x++)
	{
	if(bounds[x].offset!=obounds[x].offset) bresult = -1;
	}
if(bresult!=0) fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SPECIFIED AND BOUNDS READ\n");

data.get(globalTags[LOCALTAG], C);
data.get(globalTags[LOCALTAG], S);
data.get(globalTags[LOCALTAG], US);
data.get(globalTags[LOCALTAG], I);
data.get(globalTags[LOCALTAG], UI);
data.get(globalTags[LOCALTAG], L);
data.get(globalTags[LOCALTAG], UL);
data.get(globalTags[LOCALTAG], F);
data.get(globalTags[LOCALTAG], D);
data.get(globalTags[LOCALTAG], STR);

for(x=0; x<1000; x++)
	{
	if((BYTE)atof(input[x])!=C[x]            || 
	   (short)atof(input[x])!=S[x]           ||
	   (unsigned short)atof(input[x])!=US[x] || 
	   (int)atof(input[x])!=I[x]             ||
	   (unsigned int)atof(input[x])!=UI[x]   || 
	   (long)atof(input[x])!=L[x]            ||
	   (unsigned long)atof(input[x])!=UL[x]  || 
	   !equal(atof(input[x]),(double)F[x])   || 
	   !equal(atof(input[x]),D[x])           || 
	   strcmp(input[x],STR[x]))
		{
		result = -1;
		}
	delete STR[x];
	delete input[x];
	}

if(result) fprintf(stdout, "* MISMATCH BETWEEN SPECIFIED DATA AND RETRIEVED DATA\n");

if(result || bresult) return -1;
return 0;
}


int asciiDumpTest ( cdevData & data )
{
data.asciiDump(stdout);
return 0;
}

int copyTest ( cdevData & data )
{
int result = 0;
cdevData data2(data);
char Val1[64], Val2[64];
char * val1[1000], * val2[1000];
int i, x;
size_t dim1, dim2;


for(i=0; i<10; i++)
	{
	data.getDim(globalTags[i], &dim1);
	data2.getDim(globalTags[i], &dim2);

	if(dim1!=dim2) 
		{
		fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
		result = -1;
		}
	else if(data.getType(globalTags[i]) !=
	        data2.getType(globalTags[i])) 
	        	{
			fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
	        	result = -1;
			}
	data.get(globalTags[i], Val1, 64);
	data2.get(globalTags[i], Val2, 64);
	if(strcmp(Val1, Val2))
		{
		result = -1;
		}
	}
	
for(i=10; i<20; i++)
	{
	memset(val1, 0, 1000*sizeof(char *));
	memset(val2, 0, 1000*sizeof(char *));
	
	if(!data.get(globalTags[i], val1) &&
	   !data2.get(globalTags[i], val2)) 
	   	{
		data.getDim(globalTags[i], &dim1);
		data2.getDim(globalTags[i], &dim2);

		if(dim1!=dim2) 
			{
			fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
			result = -1;
			}
		else if(data.getType(globalTags[i]) !=
		        data2.getType(globalTags[i])) 
		        	{
				fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
		        	result = -1;
		        	}
		else if(dim1)
			{
			cdevBounds * bounds1 = new cdevBounds[dim1];
			cdevBounds * bounds2 = new cdevBounds[dim2];
			data.getBounds(globalTags[i], bounds1, dim1);
			data2.getBounds(globalTags[i], bounds2, dim2);
			for(x=0; x<(int)dim1; x++)
				{
				if(bounds1[x].offset != bounds2[x].offset ||
				   bounds1[x].length != bounds2[x].length)
				   	{
				   	result = -1;
					fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SIZES ON %s\n", globalTagNames[i]);
				   	}
				}
			delete bounds1;
			delete bounds2;
			}

		for(x=0; x<1000; x++)
			{
			if(strcmp(val1[x], val2[x])) 
				{
				fprintf(stdout, "* VALUE MISMATCH ON %s\n", globalTagNames[i]);
				result = -1;
				}
			delete val1[x];
			delete val2[x];
			}
	   	}
	   else 
	   	{
		fprintf(stdout, "* FAILURE TO READ DATA ON %s\n", globalTagNames[i]);
	   	for(x=0; x<1000; x++)
	   		{
	   		if(val1[x]!=NULL) delete val1[x];
	   		if(val2[x]!=NULL) delete val2[x];
	   		}
	   	result = -1;
	   	}
	}
return result;
}



int removeTest (cdevData & data )
{
int result = 0;
int removedCnt = 0;
int goneCnt    = 0;
int i;

for(i=0; i<20; i+=3)
	{
	data.remove(globalTags[i]);
	removedCnt++;
	}

for(i=0; i<20; i++)
	{
	if(data.getType(globalTags[i])==CDEV_INVALID) goneCnt++;
	}

if(goneCnt!=removedCnt) return -1;

for(i=0; i<20; i+=3)
	{
	if(data.getType(globalTags[i])!=CDEV_INVALID) return -1;
	}
return 0;
}


int findTest ( cdevData & data )
{
int result = 0;
int x;

// Test finding scalar value first
BYTE c1, * c2;
data.get (globalTags[0], &c1);
data.find(globalTags[0], (void * &)c2);
if(c1 != *c2) result = -1;

// Test finding an array of values next
int i1[1000], *i2;
data.get(globalTags[13], i1);
data.find(globalTags[13], (void * &)i2);
for(x=0; x<1000; x++)
	{
	if(i1[x]!=i2[x]) result = -1;
	}
	
// Test finding a single character string next
char s1[100], *s2;
data.get(globalTags[9], s1, 100);
data.find(globalTags[9], (void * &)s2);
if(strcmp(s1, s2)) result = -1;

// Test finding an array of character strings
char *S1[1000], ** S2;
data.get(globalTags[19], S1);
data.find(globalTags[19], (void * &)S2);
for(x=0; x<1000; x++)
	{
	if(strcmp(S1[x], S2[x])) result = -1;
	delete S1[x];
	}
return result;
}


int xdrTest ( cdevData & data )
{
int    result = 0;
char * buf;
size_t bufLen;
cdevData data2;

data.xdrExport(&buf, &bufLen);
data2.xdrImport(buf, bufLen);

char Val1[64], Val2[64];
char * val1[1000], * val2[1000];
int i, x;
size_t dim1, dim2;


for(i=0; i<10; i++)
	{
	data.getDim(globalTags[i], &dim1);
	data2.getDim(globalTags[i], &dim2);

	if(dim1!=dim2) 
		{
		fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
		result = -1;
		}
	else if(data.getType(globalTags[i]) !=
	        data2.getType(globalTags[i])) 
	        	{
			fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
	        	result = -1;
			}
	data.get(globalTags[i], Val1, 64);
	data2.get(globalTags[i], Val2, 64);
	if(strcmp(Val1, Val2))
		{
		result = -1;
		}
	}
	
for(i=10; i<20; i++)
	{
	memset(val1, 0, 1000*sizeof(char *));
	memset(val2, 0, 1000*sizeof(char *));
	
	if(!data.get(globalTags[i], val1) &&
	   !data2.get(globalTags[i], val2)) 
	   	{
		data.getDim(globalTags[i], &dim1);
		data2.getDim(globalTags[i], &dim2);

		if(dim1!=dim2) 
			{
			fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
			result = -1;
			}
		else if(data.getType(globalTags[i]) !=
		        data2.getType(globalTags[i])) 
		        	{
				fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
		        	result = -1;
		        	}
		else if(dim1)
			{
			cdevBounds * bounds1 = new cdevBounds[dim1];
			cdevBounds * bounds2 = new cdevBounds[dim2];
			data.getBounds(globalTags[i], bounds1, dim1);
			data2.getBounds(globalTags[i], bounds2, dim2);
			for(x=0; x<(int)dim1; x++)
				{
				if(bounds1[x].offset != bounds2[x].offset ||
				   bounds1[x].length != bounds2[x].length)
				   	{
				   	result = -1;
					fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SIZES ON %s\n", globalTagNames[i]);
				   	}
				}
			delete bounds1;
			delete bounds2;
			}

		for(x=0; x<1000; x++)
			{
			if(strcmp(val1[x], val2[x])) 
				{
				fprintf(stdout, "* VALUE MISMATCH ON %s\n", globalTagNames[i]);
				result = -1;
				}
			delete val1[x];
			delete val2[x];
			}
	   	}
	   else 
	   	{
		fprintf(stdout, "* FAILURE TO READ DATA ON %s\n", globalTagNames[i]);
	   	for(x=0; x<1000; x++)
	   		{
	   		if(val1[x]!=NULL) delete val1[x];
	   		if(val2[x]!=NULL) delete val2[x];
	   		}
	   	result = -1;
	   	}
	}
return result;
}


int assignmentTest ( cdevData & data )
{
int result = 0;
cdevData data2;
char Val1[64], Val2[64];
char * val1[1000], * val2[1000];
int i, x;
size_t dim1, dim2;

data2 = data;

for(i=0; i<10; i++)
	{
	data.getDim(globalTags[i], &dim1);
	data2.getDim(globalTags[i], &dim2);

	if(dim1!=dim2) 
		{
		fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
		result = -1;
		}
	else if(data.getType(globalTags[i]) !=
	        data2.getType(globalTags[i])) 
	        	{
			fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
	        	result = -1;
			}
	data.get(globalTags[i], Val1, 64);
	data2.get(globalTags[i], Val2, 64);
	if(strcmp(Val1, Val2))
		{
		result = -1;
		}
	}
	
for(i=10; i<20; i++)
	{
	memset(val1, 0, 1000*sizeof(char *));
	memset(val2, 0, 1000*sizeof(char *));
	
	if(!data.get(globalTags[i], val1) &&
	   !data2.get(globalTags[i], val2)) 
	   	{
		data.getDim(globalTags[i], &dim1);
		data2.getDim(globalTags[i], &dim2);

		if(dim1!=dim2) 
			{
			fprintf(stdout, "* MISMATCH BETWEEN DIMENSION SIZES ON %s\n", globalTagNames[i]);
			result = -1;
			}
		else if(data.getType(globalTags[i]) !=
		        data2.getType(globalTags[i])) 
		        	{
				fprintf(stdout, "* MISMATCH BETWEEN DATA TYPES SIZES ON %s\n", globalTagNames[i]);
		        	result = -1;
		        	}
		else if(dim1)
			{
			cdevBounds * bounds1 = new cdevBounds[dim1];
			cdevBounds * bounds2 = new cdevBounds[dim2];
			data.getBounds(globalTags[i], bounds1, dim1);
			data2.getBounds(globalTags[i], bounds2, dim2);
			for(x=0; x<(int)dim1; x++)
				{
				if(bounds1[x].offset != bounds2[x].offset ||
				   bounds1[x].length != bounds2[x].length)
				   	{
				   	result = -1;
					fprintf(stdout, "* MISMATCH BETWEEN BOUNDS SIZES ON %s\n", globalTagNames[i]);
				   	}
				}
			delete bounds1;
			delete bounds2;
			}

		for(x=0; x<1000; x++)
			{
			if(strcmp(val1[x], val2[x])) 
				{
				fprintf(stdout, "* VALUE MISMATCH ON %s\n", globalTagNames[i]);
				result = -1;
				}
			delete val1[x];
			delete val2[x];
			}
	   	}
	   else 
	   	{
		fprintf(stdout, "* FAILURE TO READ DATA ON %s\n", globalTagNames[i]);
	   	for(x=0; x<1000; x++)
	   		{
	   		if(val1[x]!=NULL) delete val1[x];
	   		if(val2[x]!=NULL) delete val2[x];
	   		}
	   	result = -1;
	   	}
	}
return result;
}
