//	Zinc Application Framework - Z_STORE1.CPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#include <z_store.hpp>
#include <z_string.hpp>
#include <z_utils.hpp>

// ----- ZafStorageFile -----------------------------------------------------

#define DEFAULT_BUFFER_SIZE		60

ZafStorageFile::ZafStorageFile(ZafFileMode newMode, char *initData, int initDataSize) :
	ZafFile(newMode),
	destroyable(true), changed(false), bufferSize(DEFAULT_BUFFER_SIZE), position(0)
{
	// Allocate and initialize the data buffer.
	if (initData)
	{
		dataBuffer = initData;
		bufferSize = length = initDataSize;
	}
	else
	{
		dataBuffer = new char[(int)bufferSize];
		length = 0;
	}
}

ZafStorageFile::~ZafStorageFile(void)
{
	// Destroy the buffer.
	if (destroyable)
		delete []dataBuffer;
}

// ----- Search functions ---------------------------------------------------

ZafOffset ZafStorageFile::Length(void) const
{
	// Return the current length.
	return (length);
}

int ZafStorageFile::Seek(ZafOffset offset, ZafSeek location)
{
	// Determine the actual buffer offset.
	if (location == ZAF_SEEK_START)
		position = (int)offset;
	else if (location == ZAF_SEEK_CURRENT)
		position += (int)offset;
	else if (location == ZAF_SEEK_END)
		position = length + (int)offset;

	// Check against absolute constraints.
	if (position > length)
		position = length;
	else if (position < 0)
		position = 0;
	return (0);
}

ZafOffset ZafStorageFile::Tell(void) const
{
	// Return the current offset.
	return (position);
}

// ----- I/O functions ------------------------------------------------------

int ZafStorageFile::ReadData(void *buffer, int size)
{
	// Read the data.
	int readSize = ZafMin((int)(length - position), size);
	if (readSize > 0)
	{
#if defined(ZAF_MACINTOSH)
		memcpy(buffer, &dataBuffer[(int)position], (unsigned long)readSize);
#else
		memcpy(buffer, &dataBuffer[(int)position], readSize);
#endif
		position += readSize;
	}
	return (readSize);
}

int ZafStorageFile::WriteData(const void *buffer, int size)
{
	// size could be less than 0 if too large a value is passed.
	if (size <= 0)
		return (size);

	// Test for writing beyond the end of the data buffer.
	if (position + size > bufferSize)
	{
		// Re-allocate the data buffer.
		while (position + size > bufferSize)
			bufferSize *= 2;
		char *tempBuffer = dataBuffer;
		dataBuffer = new char[(unsigned int)bufferSize];
		memcpy(dataBuffer, tempBuffer, (unsigned int)length);
		delete []tempBuffer;
	}

	// Write the data.
#if defined(ZAF_MACINTOSH)
	memcpy(&dataBuffer[(unsigned int)position], buffer, (unsigned long)size);
#else
	memcpy(&dataBuffer[(unsigned int)position], buffer, size);
#endif
	position += size;
	if (length < position)
		length = position;
	changed = true;
	return (size);	
}

