Files
source/VFS/File/vfs_memory_file.cpp
T
Wanne 14750c6903 **********************************************************
** Big Maps Projects code (incl. Multiplayer v1.5 **
**********************************************************
- Merged Big Maps Project code from BMP+MP trunk (Revision: 3340)
o Complete SVN Revision history: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- Before THIS merge, I made a branch of the existing 1.13 source
o SVN Branch: https://81.169.133.124/source/ja2/branches/JA2_rev.3336/src
- Removed old VS 6.0 and VS 2003 project and solutions files, because compilation is broken long time ago
- I will add VS 2010 projects and solution file in the next few days

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@3341 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2010-02-28 18:38:52 +00:00

239 lines
5.5 KiB
C++

#include "vfs_memory_file.h"
#include "../vfs_file_raii.h"
#include <vector>
#define ERROR_FILE(msg) BuildString().add(L"[").add(this->getPath()).add(L"] - ").add(msg).get()
#ifdef _DEBUG
#define IS_FILE_VALID() THROWIFFALSE( m_buffer.good(), ERROR_FILE(L"invalid file object") );
#else
#define IS_FILE_VALID() THROWIFFALSE( m_buffer.good(), ERROR_FILE(L"invalid file object") );
#endif
static inline std::ios::seekdir _seekDir(vfs::IBaseFile::ESeekDir seekDir)
{
if(seekDir == vfs::IBaseFile::SD_BEGIN)
{
return std::ios::beg;
}
else if(seekDir == vfs::IBaseFile::SD_CURRENT)
{
return std::ios::cur;
}
else if(seekDir == vfs::IBaseFile::SD_END)
{
return std::ios::end;
}
THROWEXCEPTION(BuildString().add(L"Unknown seek direction [").add(seekDir).add(L"]").get());
}
///////////////////////////////////////////////////
vfs::CMemoryFile::CMemoryFile()
: tBaseClass(vfs::Path()), m_isOpen_read(false), m_isOpen_write(false)
{
m_buffer.str("");
}
vfs::CMemoryFile::CMemoryFile(vfs::Path const& fileName)
: tBaseClass(fileName), m_isOpen_read(false), m_isOpen_write(false)
{
m_buffer.str("");
}
vfs::CMemoryFile::~CMemoryFile()
{
m_buffer.str("");
m_buffer.clear();
}
vfs::FileAttributes vfs::CMemoryFile::getAttributes()
{
return vfs::FileAttributes(vfs::FileAttributes::ATTRIB_NORMAL, vfs::FileAttributes::LT_NONE);
}
void vfs::CMemoryFile::close()
{
m_buffer.clear();
m_isOpen_read = false;
m_isOpen_write = false;
IS_FILE_VALID();
}
vfs::size_t vfs::CMemoryFile::getSize()
{
IS_FILE_VALID();
std::streampos size = 0;
if(!m_buffer.str().empty())
{
std::streampos current_position = m_buffer.tellg();
m_buffer.seekg(0,std::ios::end);
size = m_buffer.tellg();
m_buffer.seekg(current_position,std::ios::beg);
}
IS_FILE_VALID();
return (vfs::size_t)size;
}
bool vfs::CMemoryFile::isOpenRead()
{
return m_isOpen_read;
}
bool vfs::CMemoryFile::openRead()
{
if(!m_buffer.good())
{
return false;
}
return m_isOpen_read = true;
}
vfs::size_t vfs::CMemoryFile::read(vfs::Byte* data, vfs::size_t bytesToRead)
{
if(!m_buffer.eof())
{
IS_FILE_VALID();
THROWIFFALSE(m_isOpen_read || this->openRead(), ERROR_FILE(L"open error"));
m_buffer.read(static_cast<Byte*>(data), bytesToRead);
std::streamsize bytesRead = m_buffer.gcount();
THROWIFFALSE( m_buffer.good() || m_buffer.eof(), ERROR_FILE(L"read error") );
return (vfs::size_t)bytesRead;
}
return 0;
}
vfs::size_t vfs::CMemoryFile::getReadPosition()
{
IS_FILE_VALID();
THROWIFFALSE(m_isOpen_read || this->openRead(), ERROR_FILE(L"open error"));
return (vfs::size_t)m_buffer.tellg();
}
void vfs::CMemoryFile::setReadPosition(vfs::size_t positionInBytes)
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_read || this->openRead(), ERROR_FILE(L"open error") );
m_buffer.seekg((std::streamoff)positionInBytes);
IS_FILE_VALID();
}
void vfs::CMemoryFile::setReadPosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_read || this->openRead(), ERROR_FILE(L"open error") );
std::ios::seekdir ioSeekDir;
TRYCATCH_RETHROW(ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
m_buffer.seekg(offsetInBytes, ioSeekDir);
IS_FILE_VALID();
}
bool vfs::CMemoryFile::isOpenWrite()
{
return m_isOpen_write;
}
bool vfs::CMemoryFile::openWrite(bool bCreateWhenNotExist, bool bTruncate)
{
if( !m_buffer.good() )
return false;
if( m_isOpen_write )
return true;
if(bTruncate)
{
m_buffer.str("");
m_buffer.clear();
}
m_isOpen_write = m_buffer.good();
return m_isOpen_write;
}
vfs::size_t vfs::CMemoryFile::write(const vfs::Byte* data, vfs::size_t bytesToWrite)
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
std::streampos start = 0;
if(!m_buffer.str().empty())
{
start = m_buffer.tellp();
}
THROWIFFALSE( m_buffer.write(data, bytesToWrite), ERROR_FILE(L"write error") );
std::streampos bytesWritten = m_buffer.tellp() - start;
IS_FILE_VALID();
return (vfs::size_t)bytesWritten;
}
vfs::size_t vfs::CMemoryFile::getWritePosition()
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
return (vfs::size_t)m_buffer.tellp();
}
void vfs::CMemoryFile::setWritePosition(vfs::size_t positionInBytes)
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
m_buffer.seekp((std::streamoff)positionInBytes);
IS_FILE_VALID();
}
void vfs::CMemoryFile::setWritePosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
IS_FILE_VALID();
THROWIFFALSE( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
std::ios::seekdir ioSeekDir;
TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error") );
m_buffer.seekp(offsetInBytes, ioSeekDir);
IS_FILE_VALID();
}
void vfs::CMemoryFile::copyToBuffer(vfs::tReadableFile& rFile)
{
try
{
bool needToClose = !rFile.isOpenRead();
vfs::COpenReadFile readfile(&rFile);
if(!needToClose)
{
readfile.release();
}
typedef std::vector<vfs::Byte> tByteVector;
vfs::size_t size = rFile.getSize();
tByteVector vBuffer(size);
rFile.read(&vBuffer[0], size);
this->write(&vBuffer[0], size);
}
catch(CBasicException& ex)
{
RETHROWEXCEPTION(ERROR_FILE(L""), &ex);
}
}
bool vfs::CMemoryFile::deleteFile()
{
m_buffer.clear();
m_buffer.str("");
return m_buffer.good();
}