*** Merged Code from Multiplayer Branch Revision 2960 ***

- Virtual File System (VFS) by birdflu. This is needed for Multiplayer and is also used for Single Player. Very neat system :-)
- Multiplayer Version 1.1 + some additional features and bugfixes
* INFO: If you compile a new EXE and want to test, be sure to also use the latest SVN GameDir files in your JA2 install directory *




git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@2961 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2009-06-04 21:01:45 +00:00
parent 17f44f63e8
commit 47db604b50
301 changed files with 76701 additions and 1843 deletions
+187
View File
@@ -0,0 +1,187 @@
#include "vfs_dir_file.h"
#include "../Interface/vfs_directory_interface.h"
#include "../iteratedir.h"
vfs::Path vfs::CVFSFile::GetFullPath()
{
if(_pLoc_)
{
return _pLoc_->GetFullPath() + m_sFileName;
}
else
{
return m_sFileName;
}
}
bool vfs::CVFSFile::Delete()
{
Close();
vfs::Path fname;
if(_pLoc_)
{
fname = static_cast<IDirectory<CVFSFile::write_type>*>(_pLoc_)->GetRealPath() + m_sFileName;
}
else
{
fname = m_sFileName;
}
return os::DeleteRealFile(fname);
}
bool vfs::CVFSFile::OpenRead()
{
// std::cout << "[CVFSFile::OpenRead] open file <" << m_sFileName() << ">\n" ;
if( !m_oFile.good() )
{
std::cout << "ERROR" << std::endl;
return false;
}
if(m_bIsOpen_read)
{
return true;
}
std::ios::openmode Mode;
vfs::Path sFileName;
if(_pLoc_)
{
sFileName = static_cast<IDirectory<CFile::write_type>*>(_pLoc_)->GetRealPath() + m_sFileName;
}
else
{
sFileName = m_sFileName;
}
// try to open
Mode = std::ios::in|std::ios::binary;
#ifdef WIN32
m_oFile.open(sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_read = m_oFile.is_open()) )
{
m_oFile.clear();
return false;
}
return m_oFile.good();
}
bool vfs::CVFSFile::OpenWrite(bool bCreateWhenNotExist, bool bTruncate)
{
// std::cout << "[CVFSFile::OpenWrite] opening file <" << m_sFileName << "> .. ";
if(!m_oFile.good())
{
// std::cout << "ERROR" << std::endl;
return false;
}
if(m_bIsOpen_write)
{
// std::cout << "already open" << std::endl;
return m_oFile.good();
}
vfs::Path sFileName;
if(_pLoc_)
{
sFileName = static_cast<IDirectory<CFile::write_type>*>(_pLoc_)->GetRealPath() + m_sFileName;
}
else
{
sFileName = m_sFileName;
}
std::ios::openmode Mode;
Mode = std::ios::in|std::ios::out|std::ios::binary;
if(bTruncate)
{
Mode |= std::ios::trunc;
}
#ifdef WIN32
m_oFile.open(sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
m_oFile.clear();
if(bCreateWhenNotExist)
{
// create file
Mode = std::ios::out|std::ios::binary;
if(bTruncate)
{
Mode |= std::ios::trunc;
}
#ifdef WIN32
m_oFile.open(sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
return false;
}
m_oFile.close();
Mode |= std::ios::in;
#ifdef WIN32
m_oFile.open(sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
return false;
}
}
else
{
return false;
}
}
return m_oFile.good();
}
vfs::Path vfs::CVFSTextFile::GetFullPath()
{
if(_pLoc_)
{
return static_cast<IDirectory<CFile::write_type>*>(_pLoc_)->GetRealPath() + m_sFileName;
}
else
{
return m_sFileName;
}
}
bool vfs::CVFSTextFile::OpenRead()
{
if( !m_oFile.good() )
{
return false;
}
if(m_bIsOpen_read)
{
return true;
}
vfs::Path sFileName;
if(_pLoc_)
{
sFileName = static_cast<IDirectory<CFile::write_type>*>(_pLoc_)->GetRealPath() + m_sFileName;
}
else
{
sFileName = m_sFileName;
}
std::ios::openmode Mode;
Mode = std::ios::in;
#ifdef WIN32
m_oFile.open(sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_read = m_oFile.is_open()) )
{
m_oFile.clear();
return false;
}
return m_oFile.good();
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef _VFS_DIR_FILE_H_
#define _VFS_DIR_FILE_H_
#include "vfs_file.h"
#include "../Interface/vfs_file_interface.h"
#include "../Interface/vfs_location_aware_file_interface.h"
#include "../Interface/vfs_location_interface.h"
namespace vfs
{
class CVFSFile : public vfs::CFile, public vfs::ILocationAware<vfs::IReadable, vfs::IWriteable>
{
public:
CVFSFile(vfs::Path const& sFileName, vfs::IDirectory<vfs::CFile::write_type> *pDirectory)
: vfs::CFile(sFileName), vfs::ILocationAware<vfs::IReadable, vfs::IWriteable>(pDirectory)
{};
virtual ~CVFSFile()
{};
virtual vfs::Path GetFullPath();
virtual bool Delete();
virtual bool OpenRead();
virtual bool OpenWrite(bool bCreateWhenNotExist = false, bool bTruncate = false);
};
class CVFSTextFile : public vfs::CTextFile, public vfs::ILocationAware<vfs::CFile::read_type, vfs::CFile::write_type>
{
public:
CVFSTextFile(vfs::Path const& sFileName, vfs::IDirectory<vfs::CFile::write_type> *pDirectory)
: vfs::CTextFile(sFileName), vfs::ILocationAware<vfs::CFile::read_type, vfs::CFile::write_type>(pDirectory)
{};
virtual ~CVFSTextFile()
{};
virtual vfs::Path GetFullPath();
virtual bool OpenRead();
};
} // end namespace
#endif // _VFS_DIR_FILE_H_
+414
View File
@@ -0,0 +1,414 @@
#include "vfs_file.h"
#include <cassert>
#include <sys/stat.h>
vfs::CFile::CFile(vfs::Path const& sFileName)
: vfs::IFileTemplate<vfs::IReadable,vfs::IWriteable>(sFileName), m_bIsOpen_read(false), m_bIsOpen_write(false)
{
}
vfs::CFile::~CFile()
{
m_oFile.clear();
if(m_bIsOpen_read || m_bIsOpen_write)
{
this->Close();
}
}
bool vfs::CFile::Delete()
{
Close();
if(remove(m_sFileName().utf8().c_str()) == 0)
{
return true;
}
return false;
}
bool vfs::CFile::Close()
{
m_oFile.clear();
if( (m_bIsOpen_read || m_bIsOpen_write) && m_oFile.good() )
{
m_oFile.close();
m_bIsOpen_read = false;
m_bIsOpen_write = false;
}
return m_oFile.good();
}
bool vfs::CFile::IsOpenRead()
{
return m_bIsOpen_read;
}
bool vfs::CFile::OpenRead()
{
if(!m_oFile.good())
{
return false;
}
if(m_bIsOpen_read)
{
return true;
}
std::ios::openmode Mode;
// try to open
Mode = std::ios::in|std::ios::binary;
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(), Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(), Mode);
#endif
m_bIsOpen_read = m_oFile.is_open() && m_oFile.good();
return m_bIsOpen_read;
}
bool vfs::CFile::Read(vfs::Byte* pData, vfs::UInt32 uiBytesToRead, vfs::UInt32& uiBytesRead)
{
uiBytesRead = 0;
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
m_oFile.read(static_cast<char*>(pData),uiBytesToRead);
uiBytesRead = m_oFile.gcount();
return m_oFile.good();
}
vfs::UInt32 vfs::CFile::GetReadLocation()
{
return m_oFile.tellg();
}
bool vfs::CFile::SetReadLocation(vfs::UInt32 uiPositionInBytes)
{
if(m_oFile.good())
{
if(m_bIsOpen_read || this->OpenRead())
{
m_oFile.seekg(uiPositionInBytes);
}
}
return m_oFile.good();
}
bool vfs::CFile::SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir)
{
if(!m_bIsOpen_read && !OpenRead())
{
return false;
}
std::ios::seekdir ioSeekDir;
if(eSeekDir == IBaseFile::SD_BEGIN)
{
ioSeekDir = std::ios::beg;
}
else if(eSeekDir == IBaseFile::SD_CURRENT)
{
ioSeekDir = std::ios::cur;
}
else if(eSeekDir == IBaseFile::SD_END)
{
ioSeekDir = std::ios::end;
}
else
{
return m_oFile.good();
}
m_oFile.seekg(uiOffsetInBytes,ioSeekDir);
return m_oFile.good();
}
bool vfs::CFile::IsOpenWrite()
{
return m_bIsOpen_write;
}
bool vfs::CFile::OpenWrite(bool bCreateWhenNotExist, bool bTruncate)
{
if(!m_oFile.good())
{
return false;
}
if(m_bIsOpen_write)
{
return true;
}
std::ios::openmode Mode;
Mode = std::ios::in|std::ios::out|std::ios::binary;
if(bTruncate)
{
Mode |= std::ios::trunc;
}
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
m_oFile.clear();
if(bCreateWhenNotExist)
{
// create file
Mode = std::ios::out|std::ios::binary;
if(bTruncate)
{
Mode |= std::ios::trunc;
}
//m_oFile.open(VfsString(sFileName).AsString().c_str(),Mode);
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
return false;
}
m_oFile.close();
Mode |= std::ios::in;
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if( !(m_bIsOpen_write = m_oFile.is_open()) )
{
return false;
}
}
else
{
return false;
}
}
return m_oFile.good();
}
bool vfs::CFile::Write(const vfs::Byte* pData, vfs::UInt32 uiBytesToWrite, vfs::UInt32& uiBytesWritten)
{
uiBytesWritten = 0;
// expect file to be opened (if not, should i open it? with what parameters?)
if(!m_bIsOpen_write && !this->OpenWrite(true))
{
return false;
}
vfs::UInt64 start = m_oFile.tellp();
if(!m_oFile.write(pData,uiBytesToWrite))
{
return false;
}
vfs::UInt64 end = m_oFile.tellp();
uiBytesWritten = end-start;
if(uiBytesWritten != uiBytesToWrite)
{
return false;
}
return m_oFile.good();
}
vfs::UInt32 vfs::CFile::GetWriteLocation()
{
return m_oFile.tellp();
}
bool vfs::CFile::SetWriteLocation(vfs::Int32 uiPositionInBytes)
{
if(m_oFile.good())
{
if(!m_bIsOpen_write && !this->OpenWrite(true))
{
return false;
}
m_oFile.seekp(uiPositionInBytes);
}
return m_oFile.good();
}
bool vfs::CFile::SetWriteLocation(Int32 uiOffsetInBytes, vfs::IBaseFile::ESeekDir eSeekDir)
{
if(m_oFile.good())
{
if(!m_bIsOpen_write && !this->OpenWrite(true))
{
return false;
}
std::ios::seekdir ioSeekDir;
if(eSeekDir == IBaseFile::SD_BEGIN)
{
ioSeekDir = std::ios::beg;
}
else if(eSeekDir == IBaseFile::SD_CURRENT)
{
ioSeekDir = std::ios::cur;
}
else if(eSeekDir == IBaseFile::SD_END)
{
ioSeekDir = std::ios::end;
}
else
{
return false;
}
m_oFile.seekp(uiOffsetInBytes,ioSeekDir);
}
return m_oFile.good();
}
bool vfs::CFile::GetFileSize(UInt32& uiFileSize)
{
uiFileSize = 0;
if(!m_oFile.good())
{
return false;
}
bool closeAtExit = !m_bIsOpen_read;
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
// save the current position
std::ios::pos_type current_position = m_oFile.tellg();
// move to end of the file
m_oFile.seekg(0,std::ios::end);
std::ios::pos_type file_size = m_oFile.tellg();
// move to old position
m_oFile.seekg(current_position,std::ios::beg);
assert(current_position == m_oFile.tellg());
uiFileSize = file_size;
if(closeAtExit)
{
this->Close();
}
return m_oFile.good();
}
/******************************************************************/
/******************************************************************/
bool vfs::CTextFile::OpenRead()
{
if(m_bIsOpen_read)
{
return true;
}
std::ios::openmode Mode;
Mode = std::ios::in;
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if(!(m_bIsOpen_read = m_oFile.is_open()))
{
return false;
}
return m_bIsOpen_read && m_oFile.good();
}
bool vfs::CTextFile::OpenWrite(bool bCreateWhenNotExist, bool bTruncate)
{
if(m_oFile.good())
{
if(m_bIsOpen_write)
{
return true;
}
std::ios::openmode Mode;
Mode = std::ios::out|std::ios::app;
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if(!m_oFile.is_open())
{
m_oFile.clear();
if(bCreateWhenNotExist)
{
// create file
Mode = std::ios::out;
Mode |= bTruncate ? std::ios::trunc : std::ios::app;
#ifdef WIN32
m_oFile.open(m_sFileName().c_wcs().c_str(),Mode);
#else
m_oFile.open(m_sFileName().utf8().c_str(),Mode);
#endif
if(!m_oFile.is_open())
{
return false;
}
}
else
{
m_bIsOpen_write = false;
return false;
}
}
m_bIsOpen_write = true;
}
return m_oFile.good();
}
bool vfs::CTextFile::ReadLine(std::string &sLine, UInt32 uiMaxNumChars)
{
if(!m_bIsOpen_read && !OpenRead())
{
return false;
}
if(!m_oFile.good())
{
return false;
}
if(!m_oFile.eof())
{
char *text = new char[uiMaxNumChars+1];
m_oFile.getline(text,uiMaxNumChars);
sLine.assign(text);
delete[] text;
return m_oFile.good();
}
return false;
}
bool vfs::CTextFile::Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead)
{
if(!m_bIsOpen_read)
{
OpenRead();
}
if(!m_oFile.good())
{
return false;
}
if(!m_oFile.eof())
{
m_oFile.getline((char*)pData,uiBytesToRead);
uiBytesRead = m_oFile.gcount();
return m_oFile.good();
}
return false;
}
bool vfs::CTextFile::Write(const Byte* pData, UInt32 uiBytesToWrite, UInt32& uiBytesWritten)
{
// TODO
return false;
}
bool vfs::CTextFile::WriteLine(std::string const& sLine)
{
UInt32 uiWritten, uiToWrite=sLine.size();
return CFile::Write(sLine.c_str(), uiToWrite ,uiWritten) && (uiWritten == uiToWrite);
}
+72
View File
@@ -0,0 +1,72 @@
#ifndef _VFS_FILE_H_
#define _VFS_FILE_H_
#include "../vfs_types.h"
#include "../Interface/vfs_file_interface.h"
#include <fstream>
typedef std::basic_fstream<wchar_t> wfstream;
namespace vfs
{
/******************************************************************/
/******************************************************************/
class CFile : public vfs::IFileTemplate<IReadable,IWriteable>
{
public :
CFile(vfs::Path const& sFileName);
virtual ~CFile();
virtual bool Close();
virtual bool GetFileSize(UInt32& uiFileSize);
virtual bool IsOpenRead();
virtual bool OpenRead();
virtual bool Read(vfs::Byte* pData, vfs::UInt32 uiBytesToRead, vfs::UInt32& uiBytesRead);
virtual vfs::UInt32 GetReadLocation();
virtual bool SetReadLocation(UInt32 uiPositionInBytes);
virtual bool SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool IsOpenWrite();
virtual bool OpenWrite(bool bCreateWhenNotExist = false, bool bTruncate = false);
virtual bool Write(const vfs::Byte* pData, vfs::UInt32 uiBytesToWrite, vfs::UInt32& uiBytesWritten);
virtual vfs::UInt32 GetWriteLocation();
virtual bool SetWriteLocation(Int32 uiPositionInBytes);
virtual bool SetWriteLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool Delete();
protected:
std::fstream m_oFile;
bool m_bIsOpen_read, m_bIsOpen_write;
};
/******************************************************************/
/******************************************************************/
class CTextFile : public CFile
{
public:
CTextFile(vfs::Path const& sFileName)
: CFile(sFileName)
{};
virtual ~CTextFile()
{};
virtual bool OpenRead();
virtual bool OpenWrite(bool bCreateWhenNotExist = false, bool bTruncate = false);
virtual bool Read(Byte* pData, vfs::UInt32 uiBytesToRead, vfs::UInt32& uiBytesRead);
virtual bool ReadLine(std::string &sLine, vfs::UInt32 uiMaxNumChars);
virtual bool Write(const vfs::Byte* pData, vfs::UInt32 uiBytesToWrite, vfs::UInt32& uiBytesWritten);
virtual bool WriteLine(std::string const& sLine);
};
} // end namespace
#endif // _VFS_FILE_H_
+131
View File
@@ -0,0 +1,131 @@
#include "vfs_lib_file.h"
#include "../vfs.h"
ObjBlockAllocator<vfs::CLibFile>* vfs::CLibFile::_lfile_pool = NULL;
vfs::CLibFile* vfs::CLibFile::Create(vfs::Path const& sFileName,
vfs::IVFSLocation<vfs::IReadable,vfs::IWriteType> *pLocation,
ILibrary *pLibrary,
ObjBlockAllocator<vfs::CLibFile>* allocator)
{
#if 0
vfs::CLibFile* pFile = new vfs::CLibFile();
#else
vfs::CLibFile* pFile;
if(allocator)
{
pFile = allocator->New();
}
else
{
if(!_lfile_pool)
{
_lfile_pool = new ObjBlockAllocator<vfs::CLibFile>();
CFileAllocator::RegisterAllocator(_lfile_pool);
}
pFile = _lfile_pool->New();
}
#endif
pFile->m_sFileName = sFileName;
pFile->_pLoc_ = pLocation;
pFile->m_pLibrary = pLibrary;
return pFile;
}
vfs::CLibFile::CLibFile()
: vfs::IFileTemplate<IReadable,IWriteType>(L""),
vfs::ILocationAware<vfs::IReadable,vfs::IWriteType>(NULL),
m_bIsOpen_read(false),
m_pLibrary(NULL)
{
};
vfs::CLibFile::~CLibFile()
{
}
bool vfs::CLibFile::Close()
{
if(m_bIsOpen_read)
{
m_bIsOpen_read = !m_pLibrary->Close(this);
return m_bIsOpen_read;
}
return false;
}
vfs::Path vfs::CLibFile::GetFullPath()
{
if(_pLoc_)
{
return _pLoc_->GetFullPath() + m_sFileName;
}
else
{
return m_sFileName;
}
}
bool vfs::CLibFile::IsOpenRead()
{
return m_bIsOpen_read;
}
bool vfs::CLibFile::OpenRead()
{
if(!m_bIsOpen_read)
{
if(!(m_bIsOpen_read = m_pLibrary->OpenRead(this)))
{
return false;
}
}
return true;
}
bool vfs::CLibFile::Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
bool success = m_pLibrary->Read(this,pData,uiBytesToRead,uiBytesRead);
return success;
}
vfs::UInt32 vfs::CLibFile::GetReadLocation()
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return -1;
}
return m_pLibrary->GetReadLocation(this);
}
bool vfs::CLibFile::SetReadLocation(vfs::UInt32 uiPositionInBytes)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
bool success = m_pLibrary->SetReadLocation(this,uiPositionInBytes);
return success;
}
bool vfs::CLibFile::SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
return m_pLibrary->SetReadLocation(this,uiOffsetInBytes,eSeekDir);
}
bool vfs::CLibFile::GetFileSize(vfs::UInt32& uiFileSize)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
return m_pLibrary->GetFileSize(this,uiFileSize);
}
+51
View File
@@ -0,0 +1,51 @@
#ifndef _VFS_LIB_FILE_H_
#define _VFS_LIB_FILE_H_
#include "../Interface/vfs_file_interface.h"
#include "../Interface/vfs_location_interface.h"
#include "../Interface/vfs_location_aware_file_interface.h"
#include "../Interface/vfs_library_interface.h"
namespace vfs
{
class ILibrary;
class CLibFile : public vfs::IFileTemplate<vfs::IReadable,vfs::IWriteType>, public vfs::ILocationAware<vfs::IReadable,vfs::IWriteType>
{
typedef vfs::IFileTemplate<vfs::IReadable,vfs::IWriteType> tBaseType;
public:
static CLibFile* Create(vfs::Path const& sFileName,
vfs::IVFSLocation<vfs::IReadable,vfs::IWriteType> *pLocation,
ILibrary *pLibrary,
ObjBlockAllocator<CLibFile>* allocator = NULL);
// don't delete objects that YOU have not created with 'new'
// dtor has to remain public to be usable at all
virtual ~CLibFile();
virtual bool Close();
virtual vfs::Path GetFullPath();
virtual bool IsOpenRead();
virtual bool OpenRead();
virtual bool Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead);
virtual UInt32 GetReadLocation();
virtual bool SetReadLocation(UInt32 uiPositionInBytes);
virtual bool SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool GetFileSize(UInt32& uiFileSize);
protected:
bool m_bIsOpen_read;
ILibrary* m_pLibrary;
private:
friend class std::vector<CLibFile>;
CLibFile();
static ObjBlockAllocator<CLibFile>* _lfile_pool;
};
} // end namespace
#endif // _VFS_LIB_FILE_H_
+222
View File
@@ -0,0 +1,222 @@
#include "vfs_memory_file.h"
#include "vfs_file_raii.h"
#include <vector>
vfs::CMemoryFile::CMemoryFile()
: vfs::IFileTemplate<vfs::IReadable,vfs::IWriteable>(vfs::Path()), m_bIsOpen_read(false), m_bIsOpen_write(false)
{
m_ssBuffer.str("");
}
vfs::CMemoryFile::CMemoryFile(vfs::Path const& sFileName)
: vfs::IFileTemplate<vfs::IReadable,vfs::IWriteable>(sFileName), m_bIsOpen_read(false), m_bIsOpen_write(false)
{
m_ssBuffer.str("");
}
vfs::CMemoryFile::~CMemoryFile()
{
m_ssBuffer.str("");
m_ssBuffer.clear();
}
bool vfs::CMemoryFile::Close()
{
m_ssBuffer.clear();
m_bIsOpen_read = false;
m_bIsOpen_write = false;
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::GetFileSize(UInt32& uiFileSize)
{
uiFileSize = 0;
if(!m_ssBuffer.good())
{
return false;
}
std::ios::pos_type current_position = 0;
if(!m_ssBuffer.str().empty())
{
current_position = m_ssBuffer.tellg();
m_ssBuffer.seekg(0,std::ios::end);
uiFileSize = m_ssBuffer.tellg();
m_ssBuffer.seekg(current_position,std::ios::beg);
}
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::IsOpenRead()
{
return m_bIsOpen_read;
}
bool vfs::CMemoryFile::OpenRead()
{
m_bIsOpen_read = m_ssBuffer.good();
return m_bIsOpen_read;
}
bool vfs::CMemoryFile::Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
m_ssBuffer.read(static_cast<Byte*>(pData),uiBytesToRead);
uiBytesRead = m_ssBuffer.gcount();
return m_ssBuffer.good();
}
vfs::UInt32 vfs::CMemoryFile::GetReadLocation()
{
if(!m_bIsOpen_read && this->OpenRead())
{
return false;
}
return m_ssBuffer.tellg();
}
bool vfs::CMemoryFile::SetReadLocation(UInt32 uiPositionInBytes)
{
if(!m_ssBuffer.good())
{
return false;
}
m_ssBuffer.seekg(uiPositionInBytes);
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir)
{
if(!m_bIsOpen_read && !this->OpenRead())
{
return false;
}
std::ios::seekdir ioSeekDir;
if(eSeekDir == IBaseFile::SD_BEGIN)
{
ioSeekDir = std::ios::beg;
}
else if(eSeekDir == IBaseFile::SD_CURRENT)
{
ioSeekDir = std::ios::cur;
}
else if(eSeekDir == IBaseFile::SD_END)
{
ioSeekDir = std::ios::end;
}
else
{
return false;
}
m_ssBuffer.seekg(uiOffsetInBytes,ioSeekDir);
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::IsOpenWrite()
{
return m_bIsOpen_write;
}
bool vfs::CMemoryFile::OpenWrite(bool bCreateWhenNotExist, bool bTruncate)
{
if(bTruncate)
{
m_ssBuffer.str("");
m_ssBuffer.clear();
}
m_bIsOpen_write = m_ssBuffer.good();
return m_bIsOpen_write;
}
bool vfs::CMemoryFile::Write(const Byte* pData, UInt32 uiBytesToWrite, UInt32& uiBytesWritten)
{
if(!m_bIsOpen_write && !this->OpenWrite())
{
return false;
}
vfs::UInt64 start = 0;
if(!m_ssBuffer.str().empty())
{
start = m_ssBuffer.tellp();
}
m_ssBuffer.write(pData,uiBytesToWrite);
vfs::UInt64 end = m_ssBuffer.tellp();
uiBytesWritten = end-start;
if(uiBytesWritten != uiBytesToWrite)
{
return false;
}
return m_ssBuffer.good();
}
vfs::UInt32 vfs::CMemoryFile::GetWriteLocation()
{
return m_ssBuffer.tellp();
}
bool vfs::CMemoryFile::SetWriteLocation(Int32 uiPositionInBytes)
{
if(!m_bIsOpen_write && !this->OpenWrite())
{
return false;
}
m_ssBuffer.seekp(uiPositionInBytes);
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::SetWriteLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir)
{
if(!m_bIsOpen_write && !this->OpenWrite())
{
return false;
}
std::ios::seekdir ioSeekDir;
if(eSeekDir == IBaseFile::SD_BEGIN)
{
ioSeekDir = std::ios::beg;
}
else if(eSeekDir == IBaseFile::SD_CURRENT)
{
ioSeekDir = std::ios::cur;
}
else if(eSeekDir == IBaseFile::SD_END)
{
ioSeekDir = std::ios::end;
}
else
{
return false;
}
m_ssBuffer.seekp(uiOffsetInBytes,ioSeekDir);
return m_ssBuffer.good();
}
bool vfs::CMemoryFile::CopyToBuffer(vfs::tReadableFile& rFile)
{
bool needToClose = !rFile.IsOpenRead();
vfs::COpenReadFile readfile(&rFile);
if(!needToClose)
{
readfile.release();
}
vfs::UInt32 uiSize,uiIO;
uiSize = rFile.GetFileSize();
std::vector<Byte> vBuffer(uiSize);
if( rFile.Read(&vBuffer[0],uiSize,uiIO) && (uiSize == uiIO) )
{
if( this->Write(&vBuffer[0],uiSize,uiIO) && (uiSize == uiIO) )
{
return true;
}
}
return false;
}
bool vfs::CMemoryFile::Delete()
{
m_ssBuffer.clear();
m_ssBuffer.str("");
return m_ssBuffer.good();
}
+47
View File
@@ -0,0 +1,47 @@
#ifndef _VFS_MEMORY_FILE_H_
#define _VFS_MEMORY_FILE_H_
#include "../Interface/vfs_file_interface.h"
#include <sstream>
namespace vfs
{
class CMemoryFile : public vfs::IFileTemplate<vfs::IReadable,vfs::IWriteable>
{
public :
CMemoryFile();
CMemoryFile(vfs::Path const& sFileName);
virtual ~CMemoryFile();
virtual bool Close();
virtual bool GetFileSize(UInt32& uiFileSize);
virtual bool IsOpenRead();
virtual bool OpenRead();
virtual bool Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead);
virtual UInt32 GetReadLocation();
virtual bool SetReadLocation(UInt32 uiPositionInBytes);
virtual bool SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool IsOpenWrite();
virtual bool OpenWrite(bool bCreateWhenNotExist = false, bool bTruncate = false);
virtual bool Write(const Byte* pData, UInt32 uiBytesToWrite, UInt32& uiBytesWritten);
virtual UInt32 GetWriteLocation();
virtual bool SetWriteLocation(Int32 uiPositionInBytes);
virtual bool SetWriteLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool Delete();
// convenience method
bool CopyToBuffer(vfs::tReadableFile& rFile);
protected:
std::stringstream m_ssBuffer;
bool m_bIsOpen_read, m_bIsOpen_write;
};
} // end namespace
#endif // _VFS_MEMORY_FILE_H_