/*
* File: xfile.h
* Purpose: General Purpose File Class
*/
/*
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it
CxFile version 2.00 23/Aug/2002
CxFile version 2.10 16/Dec/2007
Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes
Covered code is provided under this license on an "as is" basis, without warranty
of any kind, either expressed or implied, including, without limitation, warranties
that the covered code is free of defects, merchantable, fit for a particular purpose
or non-infringing. The entire risk as to the quality and performance of the covered
code is with you. Should any covered code prove defective in any respect, you (not
the initial developer or any other contributor) assume the cost of any necessary
servicing, repair or correction. This disclaimer of warranty constitutes an essential
part of this license. No use of any covered code is authorized hereunder except under
this disclaimer.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, including commercial applications,
freely and without fee, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--------------------------------------------------------------------------------
*/
#if !defined(__xfile_h)
#define __xfile_h
#if defined (WIN32) || defined (_WIN32_WCE)
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "ximadef.h"
class DLL_EXP CxFile
{
public:
CxFile(void) { };
virtual ~CxFile() { };
virtual bool Close() = 0;
virtual size_t Read(void *buffer, size_t size, size_t count) = 0;
virtual size_t Write(const void *buffer, size_t size, size_t count) = 0;
virtual bool Seek(long offset, int origin) = 0;
virtual long Tell() = 0;
virtual long Size() = 0;
virtual bool Flush() = 0;
virtual bool Eof() = 0;
virtual long Error() = 0;
virtual bool PutC(unsigned char c)
{
// Default implementation
size_t nWrote = Write(&c, 1, 1);
return (bool)(nWrote == 1);
}
virtual long GetC() = 0;
virtual char * GetS(char *string, int n) = 0;
virtual long Scanf(const char *format, void* output) = 0;
};
#endif //__xfile_h
#if !defined(__xiofile_h)
#define __xiofile_h
#include "xfile.h"
//#include <TCHAR.h>
class DLL_EXP CxIOFile : public CxFile
{
public:
CxIOFile(FILE* fp = NULL)
{
m_fp = fp;
m_bCloseFile = (bool)(fp==0);
}
~CxIOFile()
{
Close();
}
//
bool Open(LPCTSTR filename, LPCTSTR mode)
{
if (m_fp) return false; // Can't re-open without closing first
m_fp = _tfopen(filename, mode);
if (!m_fp) return false;
m_bCloseFile = true;
return true;
}
//
virtual bool Close()
{
int iErr = 0;
if ( (m_fp) && (m_bCloseFile) ){
iErr = fclose(m_fp);
m_fp = NULL;
}
return (bool)(iErr==0);
}
//
virtual size_t Read(void *buffer, size_t size, size_t count)
{
if (!m_fp) return 0;
return fread(buffer, size, count, m_fp);
}
//
virtual size_t Write(const void *buffer, size_t size, size_t count)
{
if (!m_fp) return 0;
return fwrite(buffer, size, count, m_fp);
}
//
virtual bool Seek(long offset, int origin)
{
if (!m_fp) return false;
return (bool)(fseek(m_fp, offset, origin) == 0);
}
//
virtual long Tell()
{
if (!m_fp) return 0;
return ftell(m_fp);
}
//
virtual long Size()
{
if (!m_fp) return -1;
long pos,size;
pos = ftell(m_fp);
fseek(m_fp, 0, SEEK_END);
size = ftell(m_fp);
fseek(m_fp, pos,SEEK_SET);
return size;
}
//
virtual bool Flush()
{
if (!m_fp) return false;
return (bool)(fflush(m_fp) == 0);
}
//
virtual bool Eof()
{
if (!m_fp) return true;
return (bool)(feof(m_fp) != 0);
}
//
virtual long Error()
{
if (!m_fp) return -1;
return ferror(m_fp);
}
//
virtual bool PutC(unsigned char c)
{
if (!m_fp) return false;
return (bool)(fputc(c, m_fp) == c);
}
//
virtual long GetC()
{
if (!m_fp) return EOF;
return getc(m_fp);
}
//
virtual char * GetS(char *string, int n)
{
if (!m_fp) return NULL;
return fgets(string,n,m_fp);
}
//
virtual long Scanf(const char *format, void* output)
{
if (!m_fp) return EOF;
return fscanf(m_fp, format, output);
}
//
protected:
FILE *m_fp;
bool m_bCloseFile;
};
#endif
#if !defined(__xmemfile_h)
#define __xmemfile_h
#include "xfile.h"
//
class DLL_EXP CxMemFile : public CxFile
{
public:
CxMemFile(BYTE* pBuffer = NULL, DWORD size = 0);
~CxMemFile();
bool Open();
BYTE* GetBuffer(bool bDetachBuffer = true);
virtual bool Close();
virtual size_t Read(void *buffer, size_t size, size_t count);
virtual size_t Write(const void *buffer, size_t size, size_t count);
virtual bool Seek(long offset, int origin);
virtual long Tell();
virtual long Size();
virtual bool Flush();
virtual bool Eof();
virtual long Error();
virtual bool PutC(unsigned char c);
virtual long GetC();
virtual char * GetS(char *string, int n);
virtual long Scanf(const char *format, void* output);
protected:
bool Alloc(DWORD nBytes);
void Free();
BYTE* m_pBuffer;
DWORD m_Size;
bool m_bFreeOnClose;
long m_Position; //current position
long m_Edge; //buffer size
};
#endif
#include "xmemfile.h"
//
CxMemFile::CxMemFile(BYTE* pBuffer, DWORD size)
{
m_pBuffer = pBuffer;
m_Position = 0;
m_Size = m_Edge = size;
m_bFreeOnClose = (bool)(pBuffer==0);
}
//
CxMemFile::~CxMemFile()
{
Close();
}
//
bool CxMemFile::Close()
{
if ( (m_pBuffer) && (m_bFreeOnClose) ){
free(m_pBuffer);
m_pBuffer = NULL;
m_Size = 0;
}
return true;
}
//
bool CxMemFile::Open()
{
if (m_pBuffer) return false; // Can't re-open without closing first
m_Position = m_Size = m_Edge = 0;
m_pBuffer=(BYTE*)malloc(1);
m_bFreeOnClose = true;
return (m_pBuffer!=0);
}
//
BYTE* CxMemFile::GetBuffer(bool bDetachBuffer)
{
//can only detach, avoid inadvertantly attaching to
// memory that may not be ours [Jason De Arte]
if( bDetachBuffer )
m_bFreeOnClose = false;
return m_pBuffer;
}
//
size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
{
if (buffer==NULL) return 0;
if (m_pBuffer==NULL) return 0;
if (m_Position >= (long)m_Size) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
long nRead;
if (m_Position + nCount > (long)m_Size)
nRead = (m_Size - m_Position);
else
nRead = nCount;
memcpy(buffer, m_pBuffer + m_Position, nRead);
m_Position += nRead;
return (size_t)(nRead/size);
}
//
size_t CxMemFile::Write(const void *buffer, size_t size, size_t count)
{
if (m_pBuffer==NULL) return 0;
if (buffer==NULL) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
if (m_Position + nCount > m_Edge){
if (!Alloc(m_Position + nCount)){
return false;
}
}
memcpy(m_pBuffer + m_Position, buffer, nCount);
m_Position += nCount;
if (m_Position > (long)m_Size) m_Size = m_Position;
return count;
}
//
bool CxMemFile::Seek(long offset, int origin)
{
if (m_pBuffer==NULL) return false;
long lNewPos = m_Position;
if (origin == SEEK_SET) lNewPos = offset;
else if (origin == SEEK_CUR) lNewPos += offset;
else if (origin == SEEK_END) lNewPos = m_Size + offset;
else return false;
if (lNewPos < 0) lNewPos = 0;
m_Position = lNewPos;
return true;
}
//
long CxMemFile::Tell()
{
if (m_pBuffer==NULL) return -1;
return m_Position;
}
//
long CxMemFile::Size()
{
if (m_pBuffer==NULL) return -1;
return m_Size;
}
//
bool CxMemFile::Flush()
{
if (m_pBuffer==NULL) return false;
return true;
}
//
bool CxMemFile::Eof()
{
if (m_pBuffer==NULL) return true;
return (m_Position >= (long)m_Size);
}
//
long CxMemFile::Error()
{
if (m_pBuffer==NULL) return -1;
return (m_Position > (long)m_Size);
}
//
bool CxMemFile::PutC(unsigned char c)
{
if (m_pBuffer==NULL) return false;
if (m_Position >= m_Edge){
if (!Alloc(m_Position + 1)){
return false;
}
}
m_pBuffer[m_Position++] = c;
if (m_Position > (long)m_Size) m_Size = m_Position;
return true;
}
//
long CxMemFile::GetC()
{
if (Eof()) return EOF;
return *(BYTE*)((BYTE*)m_pBuffer + m_Position++);
}
//
char * CxMemFile::GetS(char *string, int n)
{
n--;
long c,i=0;
while (i<n){
c = GetC();
if (c == EOF) return 0;
string[i++] = (char)c;
if (c == '\n') break;
}
string[i] = 0;
return string;
}
//
long CxMemFile::Scanf(const char *format, void* output)
{
return 0;
}
//
bool CxMemFile::Alloc(DWORD dwNewLen)
{
if (dwNewLen > (DWORD)m_Edge)
{
// find new buffer size
DWORD dwNewBufferSize = (DWORD)(((dwNewLen>>16)+1)<<16);
// allocate new buffer
if (m_pBuffer == NULL) m_pBuffer = (BYTE*)malloc(dwNewBufferSize);
else m_pBuffer = (BYTE*)realloc(m_pBuffer, dwNewBufferSize);
// I own this buffer now (caller knows nothing about it)
m_bFreeOnClose = true;
m_Edge = dwNewBufferSize;
}
return (m_pBuffer!=0);
}
//
void CxMemFile::Free()
{
Close();
}
//