269 lines
6.4 KiB
C++
269 lines
6.4 KiB
C++
/********************************************************************************
|
|
XFile.h: The truth is out there
|
|
Copyright (C) 2001-2012 Hugh Bailey <obs.jim@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
********************************************************************************/
|
|
|
|
|
|
#pragma once
|
|
|
|
#define XFILE_ERROR 0xFFFFFFFF
|
|
|
|
#define XFILE_READ 0x1
|
|
#define XFILE_WRITE 0x2
|
|
#define XFILE_SHARED 0x4
|
|
|
|
#define XFILE_CREATENEW 1
|
|
#define XFILE_CREATEALWAYS 2
|
|
#define XFILE_OPENEXISTING 3
|
|
#define XFILE_OPENALWAYS 4
|
|
|
|
#define XFILE_BEGIN 1
|
|
#define XFILE_CURPOS 2
|
|
#define XFILE_END 3
|
|
|
|
|
|
class BASE_EXPORT XFile
|
|
{
|
|
HANDLE hFile;
|
|
QWORD qwPos;
|
|
BOOL bHasWritten;
|
|
|
|
public:
|
|
XFile();
|
|
XFile(CTSTR lpFile, DWORD dwAccess, DWORD dwCreationDisposition);
|
|
|
|
~XFile() {Close();}
|
|
|
|
BOOL Open(CTSTR lpFile, DWORD dwAccess, DWORD dwCreationDisposition);
|
|
BOOL IsOpen();
|
|
DWORD Read(LPVOID lpBuffer, DWORD dwBytes);
|
|
DWORD Write(const void *lpBuffer, DWORD dwBytes);
|
|
DWORD WriteStr(LPCSTR lpBuffer);
|
|
DWORD WriteStr(CWSTR lpBuffer);
|
|
DWORD WriteAsUTF8(CTSTR lpBuffer, DWORD dwElements=0);
|
|
|
|
void FlushFileBuffers();
|
|
|
|
inline void ReadFileToString(String &strIn)
|
|
{
|
|
if(!IsOpen())
|
|
return;
|
|
|
|
SetPos(0, XFILE_BEGIN);
|
|
DWORD dwFileSize = (DWORD)GetFileSize();
|
|
LPSTR lpFileDataUTF8 = (LPSTR)Allocate(dwFileSize+1);
|
|
lpFileDataUTF8[dwFileSize] = 0;
|
|
Read(lpFileDataUTF8, dwFileSize);
|
|
|
|
strIn = String(lpFileDataUTF8);
|
|
Free(lpFileDataUTF8);
|
|
}
|
|
|
|
BOOL SetFileSize(DWORD dwSize);
|
|
QWORD GetFileSize() const;
|
|
QWORD SetPos(INT64 iPos, DWORD dwMoveMethod);
|
|
inline QWORD GetPos() const {return qwPos;}
|
|
void Close();
|
|
};
|
|
|
|
BASE_EXPORT String GetPathFileName(CTSTR lpPath, BOOL bExtention=FALSE);
|
|
BASE_EXPORT String GetPathDirectory(CTSTR lpPath);
|
|
BASE_EXPORT String GetPathWithoutExtension(CTSTR lpPath);
|
|
BASE_EXPORT String GetPathExtension(CTSTR lpPath);
|
|
|
|
class BASE_EXPORT XFileInputSerializer : public Serializer
|
|
{
|
|
public:
|
|
XFileInputSerializer() {bufferSize = 0; bufferPos = 0;}
|
|
~XFileInputSerializer() {Close();}
|
|
|
|
BOOL IsLoading() {return TRUE;}
|
|
|
|
BOOL Open(CTSTR lpFile)
|
|
{
|
|
bufferPos = bufferSize = 0;
|
|
if(!file.Open(lpFile, XFILE_READ, XFILE_OPENEXISTING))
|
|
return FALSE;
|
|
fileSize = file.GetFileSize();
|
|
return TRUE;
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
file.Close();
|
|
}
|
|
|
|
void Serialize(LPVOID lpData, DWORD length)
|
|
{
|
|
assert(lpData);
|
|
|
|
LPBYTE lpTemp = (LPBYTE)lpData;
|
|
|
|
while(length)
|
|
{
|
|
if(!bufferSize || (bufferSize == bufferPos))
|
|
Cache();
|
|
|
|
DWORD dwReadSize = MIN(length, bufferSize-bufferPos);
|
|
|
|
if(!dwReadSize)
|
|
return;
|
|
|
|
mcpy(lpTemp, Buffer+bufferPos, dwReadSize);
|
|
|
|
lpTemp += dwReadSize;
|
|
bufferPos += dwReadSize;
|
|
|
|
length -= dwReadSize;
|
|
}
|
|
}
|
|
|
|
UINT64 Seek(INT64 offset, DWORD seekType=SERIALIZE_SEEK_START)
|
|
{
|
|
QWORD ret;
|
|
|
|
if(seekType == SERIALIZE_SEEK_START)
|
|
ret = file.SetPos(INT64(offset), XFILE_BEGIN);
|
|
else if(seekType == SERIALIZE_SEEK_CURRENT)
|
|
ret = file.SetPos(INT64(GetPos())+offset, XFILE_BEGIN);
|
|
else if(seekType == SERIALIZE_SEEK_END)
|
|
ret = file.SetPos(offset, XFILE_END);
|
|
|
|
Cache();
|
|
|
|
return ret;
|
|
}
|
|
|
|
UINT64 GetPos() const
|
|
{
|
|
return (file.GetPos()-bufferSize)+bufferPos;
|
|
}
|
|
|
|
BOOL DataPending()
|
|
{
|
|
return file.GetPos() < fileSize;
|
|
}
|
|
|
|
const XFile& GetFile() const {return file;}
|
|
|
|
private:
|
|
void Cache()
|
|
{
|
|
bufferSize = file.Read(Buffer, 2048);
|
|
bufferPos = 0;
|
|
}
|
|
|
|
XFile file;
|
|
|
|
DWORD bufferPos, bufferSize;
|
|
UINT64 fileSize;
|
|
BYTE Buffer[2048];
|
|
};
|
|
|
|
|
|
class XFileOutputSerializer : public Serializer
|
|
{
|
|
public:
|
|
XFileOutputSerializer() {bufferPos = 0;}
|
|
|
|
BOOL IsLoading() {return FALSE;}
|
|
|
|
BOOL Open(CTSTR lpFile, DWORD dwCreationDisposition, DWORD bufferSize=(1024*64))
|
|
{
|
|
if(!bufferSize) bufferSize = 1024*64;
|
|
|
|
this->bufferSize = bufferSize;
|
|
Buffer = (LPBYTE)Allocate(bufferSize);
|
|
totalWritten = bufferPos = 0;
|
|
return file.Open(lpFile, XFILE_WRITE, dwCreationDisposition);
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
Flush();
|
|
file.Close();
|
|
Free(Buffer);
|
|
}
|
|
|
|
void Serialize(LPVOID lpData, DWORD length)
|
|
{
|
|
assert(lpData);
|
|
|
|
LPBYTE lpTemp = (LPBYTE)lpData;
|
|
|
|
totalWritten += length;
|
|
|
|
while(length)
|
|
{
|
|
if(bufferPos == bufferSize)
|
|
Flush();
|
|
|
|
DWORD dwWriteSize = MIN(length, (bufferSize-bufferPos));
|
|
|
|
assert(dwWriteSize);
|
|
|
|
if(!dwWriteSize)
|
|
return;
|
|
|
|
mcpy(Buffer+bufferPos, lpTemp, dwWriteSize);
|
|
|
|
lpTemp += dwWriteSize;
|
|
bufferPos += dwWriteSize;
|
|
|
|
length -= dwWriteSize;
|
|
}
|
|
}
|
|
|
|
UINT64 Seek(INT64 offset, DWORD seekType=SERIALIZE_SEEK_START)
|
|
{
|
|
Flush();
|
|
if(seekType == SERIALIZE_SEEK_START)
|
|
seekType = XFILE_BEGIN;
|
|
else if(seekType == SERIALIZE_SEEK_CURRENT)
|
|
seekType = XFILE_CURPOS;
|
|
else if(seekType == SERIALIZE_SEEK_END)
|
|
seekType = XFILE_END;
|
|
|
|
return file.SetPos(offset, seekType);
|
|
}
|
|
|
|
UINT64 GetPos() const
|
|
{
|
|
return file.GetPos()+bufferPos;
|
|
}
|
|
|
|
inline QWORD GetTotalWritten() {return totalWritten;}
|
|
|
|
private:
|
|
void Flush()
|
|
{
|
|
if(bufferPos)
|
|
{
|
|
file.Write(Buffer, bufferPos);
|
|
bufferPos = 0;
|
|
}
|
|
}
|
|
|
|
XFile file;
|
|
|
|
DWORD bufferPos;
|
|
DWORD bufferSize;
|
|
|
|
QWORD totalWritten;
|
|
LPBYTE Buffer;
|
|
};
|