obs/OBSApi/Utility/XFile.h

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;
};