www.pudn.com > acdx.rar > TransactionFile.cpp


// TransactionFile.cpp: implementation of the TransactionFile class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "StdAfx.h" 
#include "TransactionFile.h" 
 
 
#include  
using namespace std; 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
///////////////////////////////////////////////////////////// 
// operator << 
// 
// Purpose:		stream operators for file 
 
void operator << ( stringstream & strm, TransactionFile & file ) 
{ 
	// get buffer 
	long	sz     = file.size(); 
	TCHAR * buffer = new TCHAR[sz+1]; 
	if ( !buffer ) 
		return; 
 
	// if read in, put buffer into stream 
	if ( file.read(buffer,sz) ) 
	{ 
		buffer[sz] = '\0'; 
		strm << buffer; 
	} 
 
	// release buffer 
	delete buffer; 
} 
 
void operator << ( TransactionFile & file, stringstream & strm ) 
{ 
	// get buffer 
	long    sz     = strm.str().size(); 
	TCHAR * buffer = (TCHAR *) strm.str().c_str(); 
	if ( !buffer ) 
		return; 
 
	// write buffer to file 
	file.write(buffer,sz); 
} 
 
 
///////////////////////////////////////////////////////////// 
// TransactionFile 
 
 
 
//##ModelId=424BB63F0289 
TransactionFile::TransactionFile () : 
	Lock(), 
	SysEvent(), 
	m_hFile(0),						// handle to file 
	m_readOffset(0),				// current read offset 
	m_writeOffset(0),				// current write offset 
	m_readWait(INFINITE),			// time (ms) to wait after read 
	m_writeWait(INFINITE),			// time (ms) to wait after write 
	m_openFlags(0),					// flags used to open file 
	m_name("")						// name of file 
 
{ 
	SysEvent::create(); 
} 
 
//##ModelId=424BB63F0298 
TransactionFile::~TransactionFile ()  
{ 
	destroyLock(); 
	SysEvent::release(); 
	close(); 
} 
 
 
//##ModelId=424BB63F0299 
void TransactionFile::showLastError () 
{ 
	LPVOID lpMsgBuf; 
	DWORD  error = GetLastError(); 
	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |  
				   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,     
				   NULL, 
				   error, 
				   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 
				   (LPTSTR) &lpMsgBuf,    0,    NULL );		  // Process any inserts in lpMsgBuf. 
 
	// Display the string. 
	AtlTrace("%s\n",(const char *) lpMsgBuf); 
 
	// Free the buffer. 
	LocalFree( lpMsgBuf ); 
} 
 
 
 
//##ModelId=424BB63F029A 
bool TransactionFile::invalidFile () 
{ 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return true; 
	else 
		return false; 
} 
 
//##ModelId=424BB63F029B 
bool TransactionFile::create ( string & fileName ) 
{ 
	DWORD openFlags = CREATE_ALWAYS; 
	return open(fileName,openFlags); 
} 
 
//##ModelId=424BB63F02A8 
bool TransactionFile::open ( string & fileName ) 
{ 
	DWORD openFlags = OPEN_ALWAYS; 
	return open(fileName,openFlags); 
} 
 
 
//##ModelId=424BB63F02AA 
bool TransactionFile::openAlways ( string & fileName ) 
{ 
	DWORD openFlags = OPEN_ALWAYS; 
	return open(fileName,openFlags); 
} 
 
//##ModelId=424BB63F02B8 
bool TransactionFile::open ( string & fileName, DWORD openFlags ) 
{ 
	if ( !lock() ) 
		return false; 
 
	// open the file 
	m_hFile =  
	CreateFile( fileName.c_str(), 
				GENERIC_READ | GENERIC_WRITE, 
				FILE_SHARE_READ | FILE_SHARE_WRITE, 
				NULL, 
				openFlags, 
				FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,  
				0 ); 
 
	unlock(); 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
	{ 
		showLastError(); 
		return false; 
	} 
 
	// store file info 
	m_openFlags = openFlags; 
	m_name = fileName; 
	m_readOffset = 0; 
	m_writeOffset = 0; 
 
	return true; 
} 
 
//##ModelId=424BB63F02C6 
void TransactionFile::close () 
{ 
	if ( !lock() ) 
		return; 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return; 
 
	::CloseHandle(m_hFile); 
	m_hFile = INVALID_HANDLE_VALUE; 
 
	unlock(); 
} 
 
 
//##ModelId=424BB63F02D7 
bool TransactionFile::offsetPosition ( DWORD offset, bool read ) 
{ 
	if ( !lock() ) 
		return false; 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return false; 
 
	if ( read ) 
		m_readOffset  += offset; 
	else 
		m_writeOffset += offset; 
 
	unlock(); 
	return true; 
} 
 
 
//##ModelId=424BB63F02C7 
bool TransactionFile::setPosition ( DWORD position, bool read ) 
{ 
	if ( !lock() ) 
		return false; 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return false; 
 
	if ( read ) 
		m_readOffset  = position; 
	else 
		m_writeOffset = position; 
 
	unlock(); 
	return true; 
} 
 
 
//##ModelId=424BB63F02E6 
void TransactionFile::clear () 
{ 
	if ( !lock() ) 
		return; 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return; 
 
	::CloseHandle(m_hFile); 
	DeleteFile( m_name.c_str() ); 
 
	bool success =  
	open(m_name,m_openFlags); 
 
	unlock(); 
} 
 
//##ModelId=424BB63F02D6 
long TransactionFile::size () 
{ 
	if ( !lock() ) 
		return 0; 
 
	if ( m_hFile == INVALID_HANDLE_VALUE ) 
		return 0; 
 
	DWORD dwSize = 
	::GetFileSize(m_hFile, NULL); 
 
	unlock(); 
	return dwSize; 
} 
 
//##ModelId=424BB63F02E7 
bool TransactionFile::write ( LPTSTR pBuffer, DWORD noToWrite, bool wait ) 
{ 
	if ( !lock() ) 
		return false; 
 
	// set overlap for write 
	OVERLAPPED overlap; 
 
	HANDLE hEvent      = getEvent(); 
	overlap.hEvent     = hEvent; 
	overlap.Offset     = m_writeOffset; 
	overlap.OffsetHigh = 0; 
 
	bool success = false; 
	try 
	{ 
		// write to file 
		DWORD noWritten = 0; 
		if ( WriteFile(m_hFile,(LPVOID)pBuffer,noToWrite,&noWritten,&overlap) != 0 ) 
			success = true; 
 
		if ( wait && m_writeWait > 0 ) 
		{ 
			DWORD result = WaitForSingleObject( hEvent, m_writeWait ); 
			switch ( result ) 
			{ 
				case WAIT_OBJECT_0: 
					break; 
 
				case WAIT_ABANDONED: 
				case WAIT_TIMEOUT: 
				default: 
					return false; 
 
			} 
		} 
 
		// if write success update write offset 
		if ( noWritten == noToWrite ) 
			m_writeOffset += noWritten; 
 
	} 
	catch(...) 
	{} 
 
 
	unlock(); 
 
	return success; 
} 
 
//##ModelId=424BB63F02F6 
bool TransactionFile::read ( LPTSTR pBuffer, DWORD noToRead, bool wait ) 
{ 
	//if ( !lock() ) 
	//	return false; 
 
	// set overlap for write 
	OVERLAPPED overlap; 
 
	HANDLE hEvent      = getEvent(); 
	overlap.hEvent     = hEvent; 
	overlap.Offset     = m_readOffset; 
	overlap.OffsetHigh = 0; 
 
	bool success = false; 
	try 
	{ 
		// read from file 
		DWORD noRead; 
		DWORD result = ReadFile(m_hFile,(LPVOID)pBuffer,noToRead,&noRead,&overlap); 
		if ( result != 0 ) 
			success = true; 
 
		if ( wait && m_readWait > 0 ) 
		{ 
			DWORD result = WaitForSingleObject( hEvent, m_readWait ); 
			switch ( result ) 
			{ 
				case WAIT_OBJECT_0: 
					break; 
 
				case WAIT_ABANDONED: 
				case WAIT_TIMEOUT: 
				default: 
					return false; 
 
			} 
		} 
 
		// if read success update read offset  
		if ( noRead == noToRead ) 
			m_readOffset += noRead; 
 
	} 
	catch(...) 
	{} 
 
	unlock(); 
 
	return success; 
}