/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	FileStream.cpp
 *
 *****************************************************************************/

// SOL++2000

//#include <stdarg.h>
#include <sol\FileStream.h>
#include <sol\stdio.h>

FileStream::FileStream()
{
	offset	 = 0L;
	buffsize = 1024;
	buffer   = new char[buffsize];
	pos      = 0;
	charNum  = 0;
}


FileStream::FileStream(int n)
{
	offset	 = 0L;
	buffsize = n;
	buffer   = new char[buffsize];
	pos      = 0;
	charNum  = 0;
}


FileStream::~FileStream()
{
	delete [] buffer;	// 
}


BOOL FileStream::create(const char* fileName)
{
	pos      = 0;
	charNum  = 0;
	offset	 = 0L;
	return File::create(fileName);
}


BOOL FileStream::openReadOnly(const char* fileName)
{
	pos     = 0;
	charNum = 0;
	offset  = 0L;
	return File::openReadOnly(fileName);
}


BOOL FileStream::openReadWrite(const char* fileName)
{
	pos     = 0;
	charNum = 0;
	offset  = 0L;	
	return File::openReadWrite(fileName);
}


BOOL FileStream::openWriteOnly(const char* fileName)
{
	pos     = 0;
	charNum = 0;
	offset  = 0L;	
	return File::openWriteOnly(fileName);
}


int FileStream::readMultiLines()
{
	if(seek(offset, 0) == -1L) {
		return -1;
	}
	charNum = read(buffer, buffsize);
	if(charNum == -1) {
		return -1;
	}
	int next = getNextPosition();
	if(next == -1)	{
		return -1;
	}
	charNum = next;
	offset += next;

	return 1;
}


int FileStream::writeMultiLines()
{
	if(seek(offset, 0) == -1L) {
		return -1;
	}
	int num = write(buffer, charNum);
	offset += charNum;

	return num;
}


int FileStream::getNextPosition()
{
	int i = charNum - 1;

	while(i > 0) {
		if(buffer[i-1] == 0xd && buffer[i] == 0xa) {
			return i+1;
		}
		i--;
	}
	return -1;
}


int FileStream::getLine(char* string, int num)
{
	int ret = 0;
	if(pos >= charNum) {
		pos = 0;
		ret = readMultiLines();
	}
	if(ret == -1) {
		return FALSE;
	}

	int i = pos;
	int j = 0;

	while(i < charNum) {
		if(j == num) {
			break;
		}
		if(buffer[i] == 0xd && buffer[i+1] == 0xa) {
			pos = i+2;
			break;
		}
		string[j++] = buffer[i++];
	}
	string[j] = NULL;
	return TRUE;
}


int FileStream::putLine(const char* line)
{
	int len  = strlen(line);

	int num = 0;
	if(pos + len >= buffsize) {
		charNum = pos;
		num     = writeMultiLines();
		pos = 0;
	}
	int i = pos;
	int j = 0;
	while(j <= len) {
		if(line[j] == NULL) {
			pos     = i;
			charNum = pos;
			break;
		}
		buffer[i++] = line[j++];
	}
	return num;
}


int FileStream::putLineWithCR(const char* line)
{
	int n = putLine(line);
	int m = putLine("\r\n");
	return n + m;
}


int FileStream::printFWithCR(char* format,...)
{
	static char buffer[512];
	va_list pos;
	va_start(pos, format);
	vsprintf(buffer, format, pos);
	va_end(pos);

	return putLineWithCR(buffer);
}


void FileStream::flush()
{
	if(charNum >0) 	writeMultiLines();
	pos     = 0;
	charNum = 0;

	offset = NULL;
}


void FileStream::close()
{
	int mode = getMode();
	if((mode == OF_WRITE) || (mode == OF_CREATE)) {
		flush();
	}
	pos     = 0;	// 
	charNum = 0;	//
	offset	= 0L;	//

	File::close();
}

