/******************************************************************************
 *
 * 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.
 *
 *
 *	File.cpp
 *
 *****************************************************************************/

// SOL++2000

#include <sol\File.h>


File::File() 
{
	mode = NULL;
	fh   = INVALID_HANDLE_VALUE;
}

File::~File()
{
	close();
}

BOOL File::create(const char* name) 
{
	mode = OF_CREATE;
	BOOL result = TRUE;
	fh = ::CreateFile(name,			//  name of the file 
    		GENERIC_READ|GENERIC_WRITE,	// access mode 
    		0,						// share mode 
    		NULL,					// security descriptor 
    		CREATE_ALWAYS,			// how to create 
    		FILE_ATTRIBUTE_NORMAL,	// file attributes 
    		NULL); 					// attributes to copy  
	if(fh == INVALID_HANDLE_VALUE) 
		result = FALSE;	
	return result;
}


BOOL File::create(const char* name, 
		DWORD access, DWORD share,
    	SECURITY_ATTRIBUTES*  securityAttrs, 
    	DWORD  howToCreate,	
    	DWORD  attrsAndFlags, 
    	HANDLE  hTemplateFile)
{
	BOOL result = TRUE;
	fh = ::CreateFile(name, 
			access, share,
    		securityAttrs, 
    		howToCreate,	
    		attrsAndFlags, 
    		hTemplateFile);

	if(fh == INVALID_HANDLE_VALUE)
		result = FALSE;
	return result;
} 				
	

		
void File::close() 
{
	if(fh != INVALID_HANDLE_VALUE) {
		::FlushFileBuffers(fh);
		::CloseHandle(fh);

		fh = INVALID_HANDLE_VALUE;
	}
}


long File::fileLength() 
{
	return (long)::GetFileSize(fh, NULL);
}

void File::flush() 
{
	if(fh != INVALID_HANDLE_VALUE) {
		::FlushFileBuffers(fh);
		//fh = INVALID_HANDLE_VALUE;
	}
}


BOOL File::isExistent(const char* fileName) 
{
	// 1999.08.22 Modifed to open in sharing mode(1).
	BOOL result = openReadOnly(fileName, 1);
	if(result)
		close();
	return result;
}


BOOL  File::openReadOnly(const char* name, int shareMode) 
{
	mode = OF_READ;		
	BOOL result = TRUE;
	fh = ::CreateFile(name,			//  name of the file 
    		GENERIC_READ,			// access mode 
    		shareMode,				// share mode 
    		NULL,					// security descriptor 
    		OPEN_EXISTING,			// how to create 
    		FILE_ATTRIBUTE_READONLY,	// file attributes 
    		NULL); 					// attributes to copy
   	if(fh == INVALID_HANDLE_VALUE)
   		result = FALSE;  

	return result;
}


BOOL File::openReadWrite(const char* name) 
{
	mode = OF_READWRITE;
	BOOL result = TRUE;
	fh = ::CreateFile(name,		//  name of the file 
    		GENERIC_READ|GENERIC_WRITE,	// access mode 
    		0,						// share mode 
    		NULL,					// security descriptor 
    		OPEN_EXISTING,			// how to create 
    		FILE_ATTRIBUTE_NORMAL,	// file attributes 
    		NULL 					// attributes to copy  
   		);	
	if(fh == INVALID_HANDLE_VALUE)
		result = FALSE;

	return result;
}


BOOL File::openWriteOnly(const char* name) 
{
	mode = OF_WRITE;			// Added
	BOOL result = TRUE;
	fh = ::CreateFile(name,		//  name of the file 
    	GENERIC_WRITE,			// access mode 
    	0,						// share mode 
    	NULL,					// security descriptor 
    	OPEN_EXISTING,			// how to create 
    	FILE_ATTRIBUTE_NORMAL,	// file attributes 
    	NULL); 					// attributes to copy  
 	if(fh == INVALID_HANDLE_VALUE)
		result = FALSE;

	return result;
}


BOOL File::remove(const char* name) 
{
	BOOL result;
	result = ::DeleteFile(name);
	return result;
}


// dir FILE_BEGIN/FILE_CURRENT/FILE_END
long File::seek(long pos, int dir) 
{
	long npos = 0;
	npos = ::SetFilePointer(fh, pos, NULL, dir);
	return npos;
}

unsigned long  File::read(char* buffer, unsigned long size) 
{
	unsigned long len = 0;

	::ReadFile(fh, buffer, size, (unsigned long*)&len, NULL);
	return len;
}


unsigned long File::write(char* buffer, unsigned long size) 
{
	unsigned long len = 0;
	::WriteFile(fh, buffer, size, (unsigned long*)&len, NULL);
	return len;
}


BOOL File::getCreationTime(FILETIME& creation) 
{
	FILETIME lastAccess;
	FILETIME lastWrite;
	return ::GetFileTime(fh, &creation, &lastAccess, &lastWrite);
}

BOOL File::getLastAccessTime(FILETIME& lastAccess) 
{
	FILETIME creation;
	FILETIME lastWrite;
	return ::GetFileTime(fh, &creation, &lastAccess, &lastWrite);
}


BOOL File::getLastWriteTime(FILETIME& lastWrite) 
{
	FILETIME creation;
	FILETIME lastAccess;
	return ::GetFileTime(fh, &creation, &lastAccess, &lastWrite);
}

