/***********************************************************************\
Common class providing a multiple-result interface in all Convert objects
Copyright (C) 1993 David John Burrowes

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

The author, David John Burrowes, can be reached at:
	davidjohn@kira.net.netcom.com
	David John Burrowes
	1926 Ivy #10
	San Mateo, CA 94403-1367
\***********************************************************************/

/*
====================================================================
This is the implementation file for the ResultObject class.  Full documentation for this class can be found in the ResultObject.rtf file.  I will not duplicate all that fine information here.
	This is $Revision: 1.4 $ of this file
	It was last modified by $Author: death $ on $Date: 93/04/04 23:45:10 $
Note that this file was created while using the New Century Schoolbook Roman typeface.  You may find that some things line up strangely if you don't use that family.
$Log:	ResultObject.m,v $
Revision 1.4  93/04/04  23:45:10  death
Sun Apr  4 23:45:09 PDT 1993

Revision 1.3  93/01/10  15:08:44  death
Sun Jan 10 15:08:44 PST 1993

Revision 1.2  92/07/26  13:59:14  death
Update of the result object...

====================================================================
*/

//
//	Import our own definition
//
#import "ResultObject.h"
#import <strings.h>
#import <stdlib.h>
#import <memory.h>

@implementation ResultObject






//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		CopyCString:
//	Parameters:	a string that we want to copy and store
//	Returns:		self
//	Description:
//		Stores the specified string in the first storage area for returned data.  The
//		string is copied first.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) CopyCString: (CString) data
{
	return [self CopyCString: data Into: FIRST_RESULT];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		CopyCString:Into:
//	Parameters:	a string, and location to store it
//	Returns:		self
//	Description:
//		Attempts to make a copy of the string.  If we succeed, we store it in the requested
//		position, otherwise, we do nothing but post an error!!!.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) CopyCString: (CString) data Into: (Integer) reference
{
	GenericType	theData;
	Integer	status;
	CString	tempStr;
	
	tempStr = (char*) malloc(strlen(data)+1);
	if (tempStr == NullCString)
		status = ERR_CANTSTORE;
	else
	{
		strcpy(tempStr, data);
		theData.cstring = tempStr;
		[self PutData: theData WithType: TYPE_CSTRING  Into: reference DoIOwn: YES];
		status = [self GetMyError];
		if (status != ERR_OK)
			free(tempStr);
	}
	[self StoreMyError: status];
	return self;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		CopyPointer:WithLength:
//	Parameters:	a pointer, and the length of its data
//	Returns:		self
//	Description:
//		Stores the specified data in the first storage area.  Copies the data that the
//		pointer points to, first..
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) CopyPointer: (Pointer) data WithLength: (PositiveInteger) length 
{
	return [self CopyPointer: data WithLength: length Into: FIRST_RESULT];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		CopyPointer:WithLength:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) CopyPointer: (Pointer) data WithLength: (PositiveInteger) length Into: (Integer) reference
{
	GenericType	theData;
	Integer	status;
	Pointer	tempPtr;
	
	tempPtr = (Pointer) malloc(length);
	if (tempPtr == NullPointer)
		status = ERR_CANTSTORE;
	else
	{
		bcopy(data, tempPtr, length);
		theData.pointer = tempPtr;
		[self PutData: theData WithType: TYPE_POINTER  Into: reference DoIOwn: YES];
		status = [self GetMyError];
		if (status != ERR_OK)
			free(tempPtr);
	}
	[self StoreMyError: status];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		init
//	Parameters:	none
//	Returns:		self
//	Description:
//		This initalizes this object.  What this means is simply that we call the parent
//		to init, and then clear all our storage areas
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) init
{
	Integer	index;
	StorageArea*	SA;	// pointer to the storage area we want to work on.

	[super init];
	//
	//	Now, clear our storage areas.  We can't use ResetResults, because if there is
	//	junk somewhere in there, it might try to free some string or ptr that doesn't exist...
	//
	for (index = 0; index < MAXAREAS; index++)
	{
		SA = &ReturnVals[index];	// Esentially doing a pascal WITH ReturnVals[index]...
		SA->StoredData.type = TYPE_NONE;
		SA->StoredData.data.integer = 0;
		SA->IOwnData = NO;
	}
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		free
//	Parameters:	none
//	Returns:		self
//	Description:
//		Clears anything about us, then asks the parent to clear themselves too...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- free
{
	[self ResetResults];
	[super free];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetBoolean
//	Parameters:	none
//	Returns:		a boolean value
//	Description:
//		Retrieves the boolean value, if any, from the first storage area, and returns it.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Boolean) GetBoolean
{
	return [self GetBooleanFrom: FIRST_RESULT];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetBooleanFrom:
//	Parameters:	an integer indicating which storage area to retrieve from
//	Returns:		a Boolean value
//	Description:
//		Retrieves the boolean value, if any, from the storage area specified.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Boolean) GetBooleanFrom: (Integer) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_BOOLEAN From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.boolean;
		else return NO;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetCharacter
//	Parameters:	none
//	Returns:		a character value
//	Description:
//		Retrieves the character value, if any, from the first storage area, and returns it.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Character) GetCharacter
{
	return [self GetCharacterFrom: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetCharacterFrom:
//	Parameters:	an integer indicating which storage area to retrieve from
//	Returns:		a character value
//	Description:
//		Retrieves the character value, if any, from the storage area specified.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Character) GetCharacterFrom: (Integer) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_CHARACTER From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.character;
		else return (Character) 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetCString
//	Parameters:	none
//	Returns:		a Cstring value
//	Description:
//		Retrieves the cstring value, if any, from the first storage area, and returns it.
//		This assumes that GetCString has already made a copy of the data to return
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (CString) GetCString
{
	return [self GetCStringFrom: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetCStringFrom
//	Parameters:	a number indicating which storage area to retrieve from
//	Returns:		a Cstring value
//	Description:
//		Retrieves the cstring value, if any, from the specified storage area, and returns it.
//		We always make a copy of the string and then return the copy.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (CString) GetCStringFrom: (Integer) reference
{
	GenericType data;
	CString tempStr = NullCString;
	
	data = [self GetDataWithType: TYPE_CSTRING From: reference];
	if ([self GetMyError] == ERR_OK)
	{
		tempStr = (CString) malloc(strlen(data.cstring)+1);
		if (tempStr == NullCString)
		{
			[self StoreMyError: ERR_CANTSTORE];
			free(tempStr);
			tempStr = NullCString;
		}
		else
			strcpy(tempStr, data.cstring);
	}
	return tempStr;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetDataWithType:From:
//	Parameters:	none
//	Returns:		a generic type value
//	Description:
//		Locates a data value in the storage area specified by storage.  If it matches
//		the requested type, return it.  Otherwise, post an error.
//		At present, we ignore the owning flag...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (GenericType) GetDataWithType: (Integer) theType From: (Integer) storage;
{
	Integer status;
	GenericType theData;
	
	if ((storage > MAXAREAS -1) || (storage < 0))
		status = ERR_NOSUCHAREA;
	else
	{
		if (ReturnVals[storage].StoredData.type != theType)
		{
			status = ERR_NOSUCHTYPE;
			theData.integer = 0;
		}
		else
		{
			theData = ReturnVals[storage].StoredData.data;
			status = ERR_OK;
		}
	}
	[self StoreMyError: status];
	return theData;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetErrorCode
//	Parameters:	none
//	Returns:		an integer value
//	Description:
//		Retrieves an error code from the main error code storage area.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer) GetErrorCode
{
	return [self GetIntegerFrom: ERRORCODE_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetErrorText
//	Parameters:	none
//	Returns:		a CString value
//	Description:
//		Retrieves a string from the error string result area, and returns it to the
//		caller.  Note that this does mean it retrieves and returns a copy..
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (CString) GetErrorText
{
	return [self GetCStringFrom: ERRORTEXT_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetInteger
//	Parameters:	none
//	Returns:		an integer value
//	Description:
//		Retrieves the integer value, if any, from the first storage area.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer) GetInteger
{
	return [self GetIntegerFrom: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetIntegerFrom:
//	Parameters:	an integer indicating which storage area to retrieve from
//	Returns:		a Boolean value
//	Description:
//		Retrieves the boolean value, if any, from the storage area specified.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer) GetIntegerFrom: (Integer) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_INTEGER From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.integer;
		else return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetMyError
//	Parameters:	none
//	Returns:		an error value
//	Description:
//		Retrieves the error code that the methods that make up this class will
//		generate, in case they had any problems while working.  At the moment, only
//		GetDataWithType:From:  and PutDataWithType: Into:DoIOwn: store error
//		codes..  oh, and so do the two Copy methods..
//		Note that we must access the info directly, and not call GetData, otherwise
//		we'll be mutually recursing for a brief time before we crash.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer) GetMyError
{	
	return ReturnVals[MYERROR_RESULT].StoredData.data.integer;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetObject
//	Parameters:	none
//	Returns:		an Object value
//	Description:
//		Retrieves the Object value, if any, from the first storage area.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) GetObject
{
	return [self GetObjectFrom: FIRST_RESULT];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetObjectFrom:
//	Parameters:	a reference to the storagearea we want to retrieve the value from
//	Returns:		an Object value
//	Description:
//		Retrieves the Object value, if any, from the specified storage area
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) GetObjectFrom: (Integer) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_INSTANCE From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.instance;
		else return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetPointer
//	Parameters:	none
//	Returns:		a pointer value
//	Description:
//		Retrieves the pointer value, if any, from the first storage area.  It does NOT
//		make a copy of the pointer data.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Pointer) GetPointer
{
	return [self GetPointerFrom: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetPointerFrom:
//	Parameters:	an integer indicating what storage area to retrieve from
//	Returns:		a pointer value
//	Description:
//		Retrieves the pointer value, if any, from the specified storage are.  It does NOT
//		make a copy of the pointer data.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Pointer) GetPointerFrom: (Integer) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_POINTER From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.pointer;
		else return NullPointer;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetPositiveInteger
//	Parameters:	none
//	Returns:		a positive integer value
//	Description:
//		Retrieves the positiveinteger value, if any, from the first storage area.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (PositiveInteger) GetPositiveInteger
{
	return [self GetPositiveIntegerFrom: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		GetPositiveIntegerFrom:
//	Parameters:	an integer indicating which storage area to retrieve from
//	Returns:		a PositiveInteger value
//	Description:
//		Retrieves the integer value, if any, from the storage area specified.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (PositiveInteger) GetPositiveIntegerFrom: (PositiveInteger) reference
{
	GenericType data;
	
	data = [self GetDataWithType: TYPE_POSITIVEINTEGER From: reference];
	if ([self GetMyError] == ERR_OK)
		return data.positiveinteger;
		else return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutBoolean:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutBoolean: (Boolean) data Into: (Integer) reference
{
	GenericType	theData;

	theData.boolean = data;
	[self PutData: theData WithType: TYPE_BOOLEAN  Into: reference DoIOwn: YES];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutCharacter:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutCharacter: (Character) data Into: (Integer) reference
{
	GenericType	theData;

	theData.character = data;
	[self PutData: theData WithType: TYPE_CHARACTER  Into: reference DoIOwn: YES];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutCString:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutCString: (CString) data Into: (Integer) reference
{
	GenericType	theData;

	theData.cstring = data;
	[self PutData: theData WithType: TYPE_CSTRING  Into: reference DoIOwn: NO];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutData:Into:DoIOwn:
//	Parameters:	data to be stored, which storage area to put it in, and whether we own it
//	Returns:		self
//	Description:
//		If we are trying to store in an area that we shouldn't be, then return an error and
//		don't store anything.  Otherwise copy our information into the storage area.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutData: (GenericType) theData WithType: (Integer) theType
	Into: (Integer) storage DoIOwn: (Boolean) ownit
{
	Integer status;
	
	if ((storage > MAXAREAS -1) || (storage < 0))
		status = ERR_NOSUCHAREA;
	else
	{
		ReturnVals[storage].IOwnData = ownit;
		ReturnVals[storage].StoredData.data= theData;
		ReturnVals[storage].StoredData.type= theType;
		status = ERR_OK;
	}
	[self StoreMyError: status];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutInteger:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutInteger: (Integer) data Into: (Integer) reference
{
	GenericType	theData;

	theData.integer = data;
	 [self PutData: theData WithType: TYPE_INTEGER  Into: reference DoIOwn: YES];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutObject:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutObject: (Instance) data Into: (Integer) reference
{
	GenericType	theData;

	theData.instance = data;
	[self PutData: theData WithType: TYPE_INSTANCE  Into: reference DoIOwn: NO];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutPointer:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutPointer: (Pointer) data Into: (Integer) reference
{
	GenericType	theData;

	theData.pointer = data;
	[self PutData: theData WithType: TYPE_POINTER Into: reference DoIOwn: NO];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		PutPositiveInteger:Into:
//	Parameters:	data item, and location to store it
//	Returns:		self
//	Description:
//		Stores the specified data in the specified storage area.  To do this, we build
//	a data type with our data and its type, and then we ask to store it properly.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) PutPositiveInteger: (PositiveInteger) data Into: (Integer) reference
{
	GenericType	theData;
	
	theData.positiveinteger = data;
	[self PutData: theData WithType: TYPE_POSITIVEINTEGER Into: reference DoIOwn: YES];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		ResetResults
//	Parameters:	none
//	Returns:		self
//	Description:
//		This clears all the result storage areas.  This is accomplished by:
//			(1) Freeing any strings or pointers we own
//			(2) Setting all data items to a type of TYPE_NONE
//			(3) (this is redundant) putting 0 into each storage data item
//		This is accomplished by first checking if we own the data, and if so, if it is a poiner
//		or a CString. If so, then we take the data, and implicitly cast it as a char* and free it.
//		In any case, we then set the type of the data storage area to no data type, and clear
//		the data item (again, implicitly casting the data item to do this).  This implicit
//		casting can be done because the ultimate data item is a union with multiple types
//		unioned in it.  =)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) ResetResults
{
	Integer	index;
	StorageArea*	SA;	// pointer to the storage area we want to work on.
	
	for (index = 0; index < MAXAREAS; index++)
	{
		SA = &ReturnVals[index];	// Esentially doing a pascal WITH ReturnVals[index]...
		if ((SA->IOwnData == YES) &&
			((SA->StoredData.type == TYPE_CSTRING) ||
			(SA->StoredData.type == TYPE_POINTER)))
			free(SA->StoredData.data.cstring);
		SA->StoredData.type = TYPE_NONE;
		SA->StoredData.data.integer = 0;
		SA->IOwnData = NO;
	}
	//
	//	Special case.  put a empty CString into the error text, to allow for sloppy
	//	programming.
	//
	[self PutCString: "" Into: ERRORTEXT_RESULT];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreErrorCode:AndText:
//	Parameters:	an error code and an error string to be stored for the callser to find
//	Returns:		self
//	Description:
//		This stores the error code and error string into the result areas reserved for
//		them, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreErrorCode: (Integer) code AndText: (CString) text
{
	[self PutInteger: code Into: ERRORCODE_RESULT];
	[self PutCString: text Into: ERRORTEXT_RESULT];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreErrorCode:AndCopyOfText:
//	Parameters:	an error code and an error string to be stored for the callser to find
//	Returns:		self
//	Description:
//		This stores its the error code, and a full copy of the error text in the result
//		areas reserved for these purposes..
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreErrorCode: (Integer) code AndCopyOfText: (CString) text
{
	[self PutInteger: code Into: ERRORCODE_RESULT];
	[self CopyCString: text Into: ERRORTEXT_RESULT];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreBoolean:
//	Parameters:	a Boolean
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreBoolean: (Boolean) data
{
	return [self PutBoolean: data Into: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreCharacter:
//	Parameters:	a Character
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreCharacter: (Character) data
	{ return [self PutCharacter: data Into: FIRST_RESULT]; }


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreCString:
//	Parameters:	a CString
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreCString: (CString) data
{
	return [self PutCString: data Into: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreInteger:
//	Parameters:	an Integer
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreInteger: (Integer) data
{
	return [self PutInteger: data Into: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreMyError:
//	Parameters:	an Integer
//	Returns:		self
//	Description:
//		This stores its data into the the error register used for our own error generation
//		Note that this must do this nasty work itself, rather than using, say,
//		PutInteger:Into:, cause otherwise it's very likely you'll have an infinite loop
//		on your hand...  nasty
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreMyError: (Integer) data
{
	ReturnVals[MYERROR_RESULT].IOwnData = YES;
	ReturnVals[MYERROR_RESULT].StoredData.data.integer= data;
	ReturnVals[MYERROR_RESULT].StoredData.type= TYPE_INTEGER;
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StoreObject:
//	Parameters:	an Object
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StoreObject: (Instance) data
{
	return [self PutObject: data Into: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StorePointer:
//	Parameters:	a Pointer
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StorePointer: (Pointer) data
{
	return [self PutPointer: data Into: FIRST_RESULT];
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Routine:		StorePositiveInteger:
//	Parameters:	a PositiveInteger
//	Returns:		self
//	Description:
//		This stores its data into the first result storage area, and returns self.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Instance) StorePositiveInteger: (PositiveInteger) data
{
	return [self PutPositiveInteger: data Into: FIRST_RESULT];
}
@end
