*** 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_
+21
View File
@@ -0,0 +1,21 @@
#ifndef _VFS_DIRECTORY_INTERFACE_H_
#define _VFS_DIRECTORY_INTERFACE_H_
//#include "vfs_file_interface.h"
#include "vfs_location_interface.h"
namespace vfs
{
/**
* NOTE: declaration of 'IDirectory' is in file 'vfs_location_interface' because
* of msvc and gcc incompatibilities
*
template<class WriteType>
class IDirectory : public IVFSLocation<vfs::IReadable, WriteType>
*
*/
}
#endif // _VFS_DIRECTORY_INTERFACE_H_
+222
View File
@@ -0,0 +1,222 @@
#ifndef _VFS_FILE_INTERFACE_H_
#define _VFS_FILE_INTERFACE_H_
#include "../vfs_types.h"
namespace vfs
{
/**
* IBaseFile
*/
class IBaseFile
{
public:
enum ESeekDir
{
SD_BEGIN,
SD_CURRENT,
SD_END,
};
public:
IBaseFile(vfs::Path const& sFileName)
: m_sFileName(sFileName)
{};
virtual ~IBaseFile()
{};
vfs::Path const& GetFileName()
{
return m_sFileName;
};
virtual vfs::Path GetFullPath()
{
return GetFileName();
};
virtual bool IsWriteable() = 0;
virtual bool IsReadable() = 0;
virtual bool Close() = 0;
virtual bool GetFileSize(UInt32& uiFileSize) = 0;
UInt32 GetFileSize()
{
UInt32 size;
if(GetFileSize(size))
{
return size;
}
return 0;
};
protected:
vfs::Path m_sFileName;
};
/**
* IReadType , IReadable
*/
class IReadType{};
class IReadable : public vfs::IReadType
{
public:
virtual bool IsOpenRead() = 0;
virtual bool OpenRead() = 0;
virtual bool Read(Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead) = 0;
virtual UInt32 GetReadLocation() = 0;
virtual bool SetReadLocation(UInt32 uiPositionInBytes) = 0;
virtual bool SetReadLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir) = 0;
};
//class NonReadable : public IReadType{};
/**
* IWriteType , IWriteable
*/
class IWriteType{};
class IWriteable : public vfs::IWriteType
{
public:
virtual bool IsOpenWrite() = 0;
virtual bool OpenWrite(bool bCreateWhenNotExist = false, bool bTruncate = false) = 0;
virtual bool Write(const Byte* pData, UInt32 uiBytesToWrite, UInt32& uiBytesWritten) = 0;
virtual UInt32 GetWriteLocation() = 0;
virtual bool SetWriteLocation(Int32 uiPositionInBytes) = 0;
virtual bool SetWriteLocation(Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir) = 0;
virtual bool Delete() = 0;
};
//class NonWriteable: public IWriteType{};
/******************************************************************/
/******************************************************************/
/**
* IFileTemplate
*/
template<typename ReadType=vfs::IReadType, typename WriteType=vfs::IWriteType>
class IFileTemplate : public vfs::IBaseFile, public ReadType, public WriteType
{
public:
typedef ReadType read_type;
typedef WriteType write_type;
public:
IFileTemplate(vfs::Path const& sFileName)
: vfs::IBaseFile(sFileName), ReadType(), WriteType()
{};
virtual ~IFileTemplate()
{};
virtual bool IsWriteable()
{
return typeid(write_type) == typeid(vfs::IWriteable);
}
virtual bool IsReadable()
{
return typeid(read_type) == typeid(vfs::IReadable);
}
virtual vfs::IFileTemplate<read_type,vfs::IWriteable>* GetWriteable()
{
//if(IsWriteable()) TODO: test how this affects compatibility
{
return reinterpret_cast<vfs::IFileTemplate<read_type,vfs::IWriteable>*>(this);
}
return NULL;
}
virtual vfs::IFileTemplate<vfs::IReadable,write_type>* GetReadable()
{
if(IsReadable())
{
return reinterpret_cast<vfs::IFileTemplate<vfs::IReadable,write_type>*>(this);
}
return NULL;
}
};
/**
* IReadableFile
*/
template<class WriteType=vfs::IWriteType>
class IReadableFile : public vfs::IFileTemplate<IReadable,WriteType>
{
public:
template<typename T>
static IReadableFile* Cast(T* t)
{
vfs::IBaseFile* bf = t;
return Cast<IBaseFile>(bf);
}
template<>
static IReadableFile* Cast<IBaseFile>(IBaseFile* bf)
{
if(bf && bf->IsReadable())
{
return static_cast<IReadableFile*>(bf);
}
return NULL;
}
template<class T>
IReadableFile* operator=(T const& t)
{
return IReadableFile::Cast(t);
}
public:
IReadableFile(vfs::Path const& sFileName)
: vfs::IFileTemplate<vfs::IReadable,WriteType>(sFileName)
{};
virtual ~IReadableFile(){};
protected:
IReadableFile();
};
/**
* IWriteableFile
*/
template<class ReadType=IReadType>
class IWriteableFile : public vfs::IFileTemplate<ReadType,vfs::IWriteable>
{
public:
template<class T>
static IWriteableFile* Cast(T* t)
{
vfs::IBaseFile* bf = t;
return Cast<IBaseFile>(bf);
}
template<>
static IWriteableFile* Cast<IBaseFile>(IBaseFile* bf)
{
if(bf && bf->IsWriteable())
{
return static_cast<IWriteableFile*>(bf);
}
return NULL;
}
template<class T>
IWriteableFile& operator=(T const& t)
{
return *IWriteableFile::Cast(t);
}
public:
IWriteableFile(vfs::Path const& sFileName)
: vfs::IFileTemplate<ReadType,vfs::IWriteable>(sFileName)
{};
virtual ~IWriteableFile(){};
protected:
IWriteableFile();
};
/******************************************************************/
/******************************************************************/
/**
* typedef's
*/
typedef vfs::IReadableFile<vfs::IWriteType> tReadableFile;
typedef vfs::IWriteableFile<vfs::IReadable> tWriteableFile;
//typedef vfs::IWriteableFile<vfs::IReadType> tWriteableFile;
} // end namespace
#endif // _VFS_FILE_INTERFACE_H_
+50
View File
@@ -0,0 +1,50 @@
#ifndef _VFS_LIBRARY_INTERFACE_H_
#define _VFS_LIBRARY_INTERFACE_H_
#include "vfs_location_interface.h"
namespace vfs
{
class ILibrary : public vfs::IVFSLocation<vfs::IReadable,vfs::IWriteType>
{
public:
ILibrary(tReadableFile *pLibraryFile, vfs::Path const& sMountPoint, bool bOwnFile = false)
: vfs::IVFSLocation<vfs::IReadable,vfs::IWriteType>(sMountPoint), m_pLibraryFile(pLibraryFile), m_bOwnLibFile(bOwnFile)
{};
virtual ~ILibrary()
{
if(m_pLibraryFile && m_bOwnLibFile)
{
m_pLibraryFile->Close();
delete m_pLibraryFile;
m_pLibraryFile = NULL;
}
};
virtual bool Init() = 0;
virtual bool CloseLibrary() = 0;
virtual bool Close(tFileType *pFileHandle) = 0;
virtual bool OpenRead(tFileType *pFileHandle) = 0;
virtual bool Read(tFileType *pFileHandle, Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead) = 0;
virtual UInt32 GetReadLocation(tFileType *pFileHandle) = 0;
virtual bool SetReadLocation(tFileType *pFileHandle, UInt32 uiPositionInBytes) = 0;
virtual bool SetReadLocation(tFileType *pFileHandle, Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir) = 0;
virtual bool GetFileSize(tFileType *pFileHandle, UInt32& uiFileSize) = 0;
vfs::Path const& GetLibName()
{
return m_pLibraryFile->GetFileName();
}
protected:
vfs::tReadableFile* m_pLibraryFile;
bool m_bOwnLibFile;
};
}
#endif // _VFS_LIBRARY_INTERFACE_H_
@@ -0,0 +1,43 @@
#ifndef _VFS_LOCATION_AWARE_FILE_INTERFACE_H_
#define _VFS_LOCATION_AWARE_FILE_INTERFACE_H_
#include "vfs_file_interface.h"
namespace vfs
{
template<typename ReadType, typename WriteType>
class IVFSLocation;
template<class WriteType> class IDirectory;
class ILibrary;
/**
* ILocationAware
*/
template<typename ReadType, typename WriteType>
class ILocationAware
{
public:
typedef vfs::IVFSLocation<ReadType,WriteType> tLocationType;
public:
ILocationAware(vfs::IVFSLocation<ReadType,WriteType> *pLocation)
: _pLoc_(pLocation)
{};
virtual ~ILocationAware()
{};
protected:
tLocationType* _pLoc_;
};
/******************************************************************/
/******************************************************************/
}
#endif // _VFS_LOCATION_AWARE_FILE_INTERFACE_H_
+236
View File
@@ -0,0 +1,236 @@
#ifndef _VFS_LOCATION_INTERFACE_H_
#define _VFS_LOCATION_INTERFACE_H_
#include "../vfs_types.h"
#include "../vfs_debug.h"
#include "vfs_file_interface.h"
#include <map>
#include <list>
namespace vfs
{
class IBaseLocation
{
public:
class Iterator
{
public:
class IImplemetation
{
public:
virtual ~IImplemetation() {};
virtual vfs::IBaseFile* value() = 0;
virtual void next() = 0;
};
public:
Iterator() : _iter_impl(NULL), _file(NULL) {};
Iterator(IImplemetation* impl) : _iter_impl(impl), _file(NULL)
{
THROWIFFALSE(_iter_impl, L"EXCEPTION");
_file = _iter_impl->value();
}
~Iterator()
{
}
//////////////////////////////
vfs::IBaseFile* value()
{
return _file;
};
void next()
{
if(_iter_impl)
{
_iter_impl->next();
_file = _iter_impl->value();
if(!_file)
{
delete _iter_impl;
_iter_impl = NULL;
}
}
}
bool end()
{
return _file == NULL;
}
//////////////////////////////
private:
IImplemetation* _iter_impl;
vfs::IBaseFile* _file;
};
public:
virtual ~IBaseLocation()
{};
template<typename T>
T* Cast()
{
return dynamic_cast<T*>(this);
}
virtual bool IsWriteable() = 0;
virtual bool IsReadable() = 0;
virtual vfs::Path const& GetFullPath() = 0;
virtual bool FileExists(vfs::Path const& sFileName) = 0;
virtual vfs::IBaseFile* GetFile(vfs::Path const& sFileName) = 0;
virtual Iterator begin() = 0;
virtual void GetSubDirList(std::list<vfs::Path>& rlSubDirs) = 0;
};
/**
* IVFSLocation
*/
//template<typename ReadType=vfs::IReadType, typename WriteType=vfs::IWriteType>
template<typename ReadType, typename WriteType>
class IVFSLocation : public IBaseLocation
{
public:
typedef vfs::IVFSLocation<ReadType,WriteType> tClassType;
typedef vfs::IFileTemplate<ReadType,WriteType> tFileType;
typedef ReadType tReadType;
typedef WriteType tWriteType;
typedef std::list<std::pair<tFileType*,vfs::Path> > tListFilesWithPath;
public:
IVFSLocation(vfs::Path const& sMountPoint)
: m_sMountPoint(sMountPoint)
{};
virtual ~IVFSLocation()
{};
// has to be virtual , or the types of the caller (not the real object) will be tested
virtual bool IsWriteable()
{
return typeid(tWriteType) == typeid(vfs::IWriteable);
}
virtual bool IsReadable()
{
return typeid(tReadType) == typeid(vfs::IReadable);
}
virtual IVFSLocation<IReadType,IWriteable>* GetWriteable()
{
//if(IsWriteable()) TODO: test how this affects compatibility
{
return reinterpret_cast<IVFSLocation<vfs::IReadType,vfs::IWriteable>*>(this);
}
return NULL;
}
vfs::Path const& GetMountPoint()
{
return m_sMountPoint;
};
/**
* IVFSLocation interface
*/
virtual vfs::Path const& GetFullPath()
{
return m_sMountPoint;
}
virtual bool FileExists(vfs::Path const& sFileName) = 0;
virtual vfs::IBaseFile* GetFile(vfs::Path const& sFileName) = 0;
virtual tFileType* GetFileTyped(vfs::Path const& rFileName) = 0;
protected:
vfs::Path m_sMountPoint;
};
/**************************************************************************************/
/**************************************************************************************/
template<typename WriteType=vfs::IWriteType>
class IReadLocation : public IVFSLocation<IReadable,WriteType>
{
public:
template<typename T>
static IReadLocation* Cast(T* t)
{
// which file type does the to tested location contain
typename T::tFileType* _F=NULL;
// is it readable?
vfs::IReadable *rf = _F;
// is the write type compatible (probably redundant)
WriteType *wf = _F;
// it is readable and the write type fits
return reinterpret_cast<IReadLocation*>(t);
}
template<>
static IReadLocation* Cast<IBaseLocation>(IBaseLocation* bl)
{
return dynamic_cast<IReadLocation*>(bl);
}
public:
IReadLocation(vfs::Path const& sLocalPath)
: vfs::IVFSLocation<IReadable,WriteType>(sLocalPath)
{};
virtual ~IReadLocation(){};
};
typedef IReadLocation<vfs::IWriteType> tReadLocation;
template<typename ReadType=vfs::IReadType>
class IWriteLocation : public vfs::IVFSLocation<ReadType,vfs::IWriteable>
{
public:
template<class T>
static IWriteLocation* Cast(T* t)
{
// which file type does the to tested location contain
typename T::tFileType* _F=NULL;
// is it writeable?
vfs::IWriteable *wf = _F;
// is the read type compatible (probably redundant)
ReadType *rf = _F;
// is writeable and the read type fits
return reinterpret_cast<IWriteLocation*>(t);
}
template<>
static IWriteLocation* Cast<IBaseLocation>(IBaseLocation* bl)
{
return dynamic_cast<IWriteLocation*>(bl);
}
public:
IWriteLocation(vfs::Path const& sLocalPath)
: vfs::IVFSLocation<ReadType,vfs::IWriteable>(sLocalPath)
{};
virtual ~IWriteLocation(){};
};
typedef IWriteLocation<vfs::IReadType> tWriteLocation;
/**************************************************************************************/
/**************************************************************************************/
template<class WriteType>
class IDirectory : public vfs::IVFSLocation<vfs::IReadable, WriteType>
{
typedef typename vfs::IVFSLocation<vfs::IReadable, WriteType> tBaseType;
public:
IDirectory(vfs::Path const& sMountPoint, vfs::Path const& sRealPath)
: vfs::IVFSLocation<vfs::IReadable, WriteType>(sMountPoint), m_sRealPath(sRealPath)
{};
virtual ~IDirectory()
{};
vfs::Path const& GetRealPath()
{
return m_sRealPath;
}
virtual tBaseType::tFileType* AddFile(vfs::Path const& sFilename, bool bDeleteOldFile=false) = 0;
virtual bool AddFile( typename vfs::IVFSLocation<vfs::IReadable, WriteType>::tFileType* pFile, bool bDeleteOldFile=false) = 0;
virtual bool CreateSubDirectory(vfs::Path const& sSubDirPath) = 0;
virtual bool DeleteDirectory(vfs::Path const& sDirPath) = 0;
virtual bool DeleteFileFromDirectory(vfs::Path const& sFileName) = 0;
protected:
const vfs::Path m_sRealPath;
};
/**************************************************************************************/
/**************************************************************************************/
} // end namespace
#endif // _VFS_LOCATION_INTERFACE_H_
+215
View File
@@ -0,0 +1,215 @@
#include "vfs_7z_library.h"
#include "vfs_lib_dir.h"
#include "../File/vfs_lib_file.h"
#include "../vfs_file_raii.h"
namespace sz
{
extern "C"
{
#include "7zCrc.h"
#include "Archive/7z/7zAlloc.h"
#include "Archive/7z/7zExtract.h"
#include "Archive/7z/7zIn.h"
}
}
/********************************************************************************************/
/*** my 7z extensions ***/
/********************************************************************************************/
namespace szExt
{
typedef struct CSzVfsFile
{
vfs::tReadableFile* file;
} CSzVfsFile;
typedef struct CVfsFileInStream
{
sz::ISeekInStream s;
CSzVfsFile file;
} CVfsFileInStream;
static sz::SRes VfsFileInStream_Read(void *pp, void *buf, size_t *size)
{
CVfsFileInStream *p = (CVfsFileInStream *)pp;
vfs::UInt32 to_read = *size;
vfs::UInt32 has_read = 0;
sz::SRes res;
if(p->file.file->Read((vfs::Byte*)buf,to_read, has_read))
{
res = SZ_OK;
}
else
{
res = SZ_ERROR_READ;
}
*size = has_read;
return res;
}
static sz::SRes VfsFileInStream_Seek(void *pp, sz::Int64 *pos, sz::ESzSeek origin)
{
CVfsFileInStream *p = (CVfsFileInStream *)pp;
vfs::IBaseFile::ESeekDir eSD;
switch (origin)
{
case sz::SZ_SEEK_SET:
eSD = vfs::IBaseFile::SD_BEGIN;
break;
case sz::SZ_SEEK_CUR:
eSD = vfs::IBaseFile::SD_CURRENT;
break;
case sz::SZ_SEEK_END:
eSD = vfs::IBaseFile::SD_END;
break;
default:
return ERROR_INVALID_PARAMETER;
}
vfs::Int32 _pos = (vfs::Int32)(*pos); // only 32 bit
sz::SRes res;
if(p->file.file->SetReadLocation(_pos,eSD))
{
*pos = p->file.file->GetReadLocation();
res = SZ_OK;
}
else
{
res = SZ_ERROR_READ;
}
return res;
}
void VfsFileInStream_CreateVTable(CVfsFileInStream *p)
{
p->s.Read = VfsFileInStream_Read;
p->s.Seek = VfsFileInStream_Seek;
}
}; // end namespace szExt
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
#define k_Copy 0
sz::UInt64 GetSum(const sz::UInt64 *values, sz::UInt32 index)
{
sz::UInt64 sum = 0;
sz::UInt32 i;
for (i = 0; i < index; i++)
{
sum += values[i];
}
return sum;
}
bool vfs::CUncompressed7zLibrary::Init()
{
if(!m_pLibraryFile)
{
return false;
}
szExt::CVfsFileInStream archiveStream;
sz::CLookToRead lookStream;
sz::CSzArEx db;
sz::SRes res;
sz::ISzAlloc allocImp;
sz::ISzAlloc allocTempImp;
if(!m_pLibraryFile->OpenRead())
{
return false;
}
archiveStream.file.file = m_pLibraryFile;
szExt::VfsFileInStream_CreateVTable(&archiveStream);
sz::LookToRead_CreateVTable(&lookStream, False);
lookStream.realStream = &archiveStream.s;
sz::LookToRead_Init(&lookStream);
allocImp.Alloc = sz::SzAlloc;
allocImp.Free = sz::SzFree;
allocTempImp.Alloc = sz::SzAllocTemp;
allocTempImp.Free = sz::SzFreeTemp;
sz::CrcGenerateTable();
sz::SzArEx_Init(&db);
if( SZ_OK != (res = sz::SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp)) )
{
std::stringstream wss;
wss << "Could not open 7z archive [" << m_pLibraryFile->GetFullPath()().utf8() << "]";
THROWEXCEPTION(wss.str().c_str());
}
vfs::IDirectory<ILibrary::tWriteType>* pLD = NULL;
vfs::Path oDir, oFile;
vfs::Path oDirPath;
for(vfs::UInt32 i = 0; i < db.db.NumFiles; i++)
{
sz::CSzFileItem *f = db.db.Files + i;
if (f->IsDir)
{
continue;
}
vfs::Path sPath(f->Name);
sPath.SplitLast(oDir,oFile);
oDirPath = m_sMountPoint;
if(!oDir.empty())
{
oDirPath += oDir;
}
// determine offset and size
sz::UInt32 folderIndex = db.FileIndexToFolderIndexMap[i];
sz::CSzFolder *folder = db.db.Folders + folderIndex;
sz::UInt64 unpackSizeSpec = sz::SzFolder_GetUnpackSize(folder);
size_t unpackSize = (size_t)unpackSizeSpec;
sz::UInt64 startOffset = sz::SzArEx_GetFolderStreamPos(&db, folderIndex, 0);
const sz::UInt64 *packSizes = db.db.PackSizes + db.FolderStartPackStreamIndex[folderIndex];
//CSzCoderInfo *coder = &folder->Coders[0];
//if (coder->MethodID == k_Copy)
//{
// UInt32 si = 0;
// UInt64 offset;
// UInt64 inSize;
// offset = GetSum(packSizes, si);
// inSize = packSizes[si];
//}
// get or create according directory object
tDirCatalogue::iterator it = m_catDirs.find(oDirPath);
if(it != m_catDirs.end())
{
pLD = it->second;
}
else
{
pLD = new CLibDirectory(oDir,oDirPath);
m_catDirs.insert(std::make_pair(oDirPath,pLD));
}
// create file
vfs::CLibFile *pFile = vfs::CLibFile::Create(oFile,pLD,this,_allocator);
// add file to directory
if(!pLD->AddFile(pFile))
{
// something is wrong
m_pLibraryFile->Close();
return false;
}
// link file data struct to file object
m_mapLibData.insert(std::pair<tFileType*,sFileData>(pFile,sFileData(unpackSize, (UInt32)startOffset)));
}
return true;
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef _VFS_7Z_LIBRARY_H_
#define _VFS_7Z_LIBRARY_H_
#include "vfs_uncompressed_lib_base.h"
#include "File/vfs_lib_file.h"
namespace vfs
{
class CUncompressed7zLibrary : public vfs::CUncompressedLibraryBase
{
public:
CUncompressed7zLibrary(tReadableFile *pLibraryFile,
vfs::Path const& sMountPoint,
bool bOwnFile = false,
ObjBlockAllocator<vfs::CLibFile>* allocator=NULL)
: vfs::CUncompressedLibraryBase(pLibraryFile,sMountPoint,bOwnFile), _allocator(allocator)
{};
virtual ~CUncompressed7zLibrary()
{};
/**
* ILibrary interface
*/
virtual bool Init();
private:
ObjBlockAllocator<vfs::CLibFile>* _allocator;
};
} // end namespace
#endif // _VFS_7Z_LIBRARY_H_
+402
View File
@@ -0,0 +1,402 @@
//#define VFS_BASIC_TYPES
#include "../vfs_types.h"
#include "vfs_create_7z_library.h"
#include "../vfs_file_raii.h"
#include "../vfs_debug.h"
namespace sz
{
extern "C"
{
#include "7zCrc.h"
#include "Archive/7z/7zIn.h"
}
};
#include <vector>
#include <sstream>
/******************************************************************************************/
/******************************************************************************************/
/******************************************************************************************/
namespace szExt
{
inline vfs::UInt32 WRITEBYTE(std::ostream& out, sz::Byte const& value)
{
out.write((char*)&value,sizeof(sz::Byte));
return 1;
}
template<typename T>
inline vfs::UInt32 WRITEALL(std::ostream& out, T const& value)
{
out.write((char*)&value,sizeof(T));
return sizeof(T);
}
template<typename T>
inline vfs::UInt32 WRITEBUFFER(std::ostream& out, T* value, size_t num_elements)
{
out.write((char*)value,sizeof(T) * num_elements);
return num_elements*sizeof(T);
}
/**
* "compress" numbers by removing heading zero-bytes
* - add additional byte that represents a bit-vector of bytes within a 64-bit/8-byte number
* - if the number is smaller than 128, use the extra byte to store the value
*/
template<typename T>
inline vfs::UInt32 WRITE(std::ostream& out, T const& value)
{
vfs::UInt32 count = 0;
sz::Byte data[8];
sz::Byte firstByte = 0;
sz::Byte* b = (sz::Byte*)&value;
size_t SIZE = sizeof(T);
b+= SIZE-1;
vfs::Int32 i;
for(i=SIZE-1; i>=0; --i)
{
if( (*b & 0xFF) != 0)
{
break;
}
b--;
}
if(i < 0)
{
count += WRITEBYTE(out,0);
return count;
}
if(i == 0)
{
if(*b >= 0x80)
{
count += WRITEBYTE(out,0x80);
}
count += WRITEBYTE(out,*b);
return count;
}
vfs::Int32 num = 0;
for(;i >= 0; --i)
{
firstByte |= 1 << (8 - i - 1);
data[i] = *b--;
num++;
}
count += WRITEBYTE(out,firstByte);
count += WRITEBUFFER(out,data,num);
return count;
}
}
/******************************************************************************************/
/******************************************************************************************/
/******************************************************************************************/
vfs::CCreateUncompressed7zLibrary::CCreateUncompressed7zLibrary()
: m_pLibFile(NULL)
{
sz::CrcGenerateTable();
}
vfs::CCreateUncompressed7zLibrary::~CCreateUncompressed7zLibrary()
{
m_pLibFile = NULL;
m_lFileInfo.clear();
m_mapDirInfo.clear();
}
bool vfs::CCreateUncompressed7zLibrary::AddFile(vfs::tReadableFile* pFile)
{
if(!pFile)
{
// at least nothing bad happened
return true;
}
try
{
vfs::COpenReadFile infile(pFile);
}
catch(CBasicException &ex)
{
std::wstringstream wss;
wss << L"Could not open File \"" << pFile->GetFullPath()() << L"\"";
RETHROWEXCEPTION(wss.str().c_str(),&ex);
}
SFileInfo fi;
vfs::Path filename = pFile->GetFullPath();
fi.name = filename().c_wcs();
fi.size = pFile->GetFileSize();
if(m_lFileInfo.empty())
{
fi.offset = 0;
}
else
{
SFileInfo const& fic = m_lFileInfo.back();
fi.offset = fic.offset + fic.size;
}
std::vector<vfs::Byte> data(fi.size);
UInt32 ui_read;
pFile->Read(&data[0], fi.size, ui_read);
fi.CRC = sz::CrcCalc(&data[0],fi.size);
m_ssFileStream.write(&data[0],fi.size);
m_lFileInfo.push_back(fi);
vfs::Path path,dummy;
filename.SplitLast(path,dummy);
if(!path.empty())
{
tDirInfo::iterator it_find = m_mapDirInfo.find(path().c_wcs());
if(it_find == m_mapDirInfo.end())
{
SFileInfo dir;
dir.name = path().c_wcs();
dir.offset = 0;
dir.size = 0;
dir.time_creation = 0;
dir.time_last_access = 0;
dir.time_write = 0;
m_mapDirInfo.insert(std::make_pair(dir.name,dir));
}
}
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteLibrary(vfs::Path const& sLibName)
{
vfs::COpenWriteFile outfile(sLibName,true);
return WriteLibrary(&outfile.file());
}
bool vfs::CCreateUncompressed7zLibrary::WriteLibrary(vfs::tWriteableFile* pFile)
{
if(!pFile)
{
return false;
}
if(m_lFileInfo.empty())
{
return false;
}
m_pLibFile = pFile;
if(!m_pLibFile->IsOpenWrite() && !m_pLibFile->OpenWrite(true,true))
{
return false;
}
//
WriteNextHeader(m_ssInfoStream);
//
std::stringstream ssSigHeader;
WriteSignatureHeader(ssSigHeader);
//
UInt32 written;
//
m_pLibFile->Write(ssSigHeader.str().c_str(),ssSigHeader.str().length(), written);
//
m_pLibFile->Write(m_ssFileStream.str().c_str(),m_ssFileStream.str().length(), written);
//
m_pLibFile->Write(m_ssInfoStream.str().c_str(),m_ssInfoStream.str().length(), written);
return true;
}
/**************************************************************************************/
bool vfs::CCreateUncompressed7zLibrary::WriteSignatureHeader(std::ostream& out)
{
vfs::UInt32 count=0;
// #define k7zSignatureSize -> not in namespace sz
count += szExt::WRITEBUFFER(out, sz::k7zSignature, k7zSignatureSize);
sz::Byte Major = 0, Minor = 2;
count += szExt::WRITEALL(out, (sz::Byte)Major );
count += szExt::WRITEALL(out, (sz::Byte)Minor );
sz::UInt32 StartHeaderCRC, NextHeaderCRC;
SFileInfo const& fi = m_lFileInfo.back();
sz::UInt64 NextHeaderOffset = fi.offset + fi.size;
sz::UInt64 NextHeaderSize = m_ssInfoStream.str().length()*sizeof(char);
NextHeaderCRC = sz::CrcCalc(m_ssInfoStream.str().c_str(),(size_t)NextHeaderSize);
std::stringstream sstemp;
count += szExt::WRITEALL(sstemp, (sz::UInt64)NextHeaderOffset );
count += szExt::WRITEALL(sstemp, (sz::UInt64)NextHeaderSize );
count += szExt::WRITEALL(sstemp, (sz::UInt32)NextHeaderCRC );
StartHeaderCRC = sz::CrcCalc(sstemp.str().c_str(), sstemp.str().length()*sizeof(char));
count += szExt::WRITEALL(out, (sz::UInt32)StartHeaderCRC );
out << sstemp.str();
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteNextHeader(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdHeader);
// this->WriteArchiveProperties(out);
// this->WriteAdditionalStreamsInfo(out)
//
this->WriteMainStreamsInfo(out);
//
this->WriteFilesInfo(out);
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteMainStreamsInfo(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdMainStreamsInfo );
this->WritePackInfo(out);
this->WriteUnPackInfo(out);
this->WriteSubStreamsInfo(out);
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WritePackInfo(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdPackInfo );
szExt::WRITE(out, (sz::UInt64)0 ); // data offset
szExt::WRITE(out, (sz::UInt32)m_lFileInfo.size() );
szExt::WRITE(out, (sz::Byte)sz::k7zIdSize );
std::list<SFileInfo>::iterator it = m_lFileInfo.begin();
for(;it != m_lFileInfo.end(); ++it)
{
szExt::WRITE(out, (sz::UInt64)it->size );
}
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteUnPackInfo(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdUnpackInfo );
szExt::WRITE(out, (sz::Byte)sz::k7zIdFolder );
szExt::WRITE(out, (sz::UInt64)m_lFileInfo.size() );
szExt::WRITE(out, (sz::Byte)0 ); // External
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
for(;fit != m_lFileInfo.end(); ++fit)
{
this->WriteFolder(out);
}
szExt::WRITE(out, (sz::Byte)sz::k7zIdCodersUnpackSize );
fit = m_lFileInfo.begin();
for(;fit != m_lFileInfo.end(); ++fit)
{
szExt::WRITE(out, (sz::UInt64)fit->size );
}
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteSubStreamsInfo(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdSubStreamsInfo );
szExt::WRITE(out, (sz::Byte)sz::k7zIdCRC );
szExt::WRITE(out, (sz::Byte)1 ); // early out - all CRCs defined
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
for(;fit != m_lFileInfo.end(); ++fit )
{
szExt::WRITEALL(out, (sz::UInt32)fit->CRC);
}
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteFolder(std::ostream& out)
{
szExt::WRITE(out, (sz::UInt32)1 ); // NumCoders
szExt::WRITE(out, (sz::Byte)1 ); // MainByte
szExt::WRITE(out, (sz::Byte)0 ); // Methods
return true;
}
bool vfs::CCreateUncompressed7zLibrary::WriteFilesInfo(std::ostream& out)
{
szExt::WRITE(out, (sz::Byte)sz::k7zIdFilesInfo );
vfs::UInt64 num_files = (m_lFileInfo.size()+m_mapDirInfo.size());
szExt::WRITE(out, (sz::UInt64)num_files );
// empty stream -> pack info in bit-vector
szExt::WRITE(out, (sz::Byte)sz::k7zIdEmptyStream );
sz::UInt64 num_empty64 = num_files/8 + (num_files%8 == 0 ? 0 : 1);
size_t num_empty = (size_t)num_empty64;
THROWIFFALSE(num_empty == num_empty64, L"WTF");
sz::Byte *empty_vector = new sz::Byte[num_empty];
memset(empty_vector,0,num_empty);
for(vfs::UInt32 e=m_lFileInfo.size(); e < num_files; ++e)
{
size_t index = e / 8;
empty_vector[index] |= 1 << (7 - e%8);
}
szExt::WRITE(out, (sz::UInt64)num_empty ); // size
szExt::WRITEBUFFER(out, empty_vector, num_empty);
delete[] empty_vector;
// names
szExt::WRITE(out, (sz::Byte)sz::k7zIdName );
sz::UInt32 count = 0;
std::stringstream name_stream;
count += szExt::WRITE(name_stream, (sz::Byte)0 ); // switch
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
for(;fit != m_lFileInfo.end(); ++fit)
{
count += this->WriteFileName(name_stream, fit->name);
}
std::map<utf8string::str_t,SFileInfo>::iterator dit = m_mapDirInfo.begin();
for(;dit != m_mapDirInfo.end(); ++dit)
{
count += this->WriteFileName(name_stream, dit->second.name);
}
szExt::WRITE(out, (sz::UInt64)count ); // size
szExt::WRITEBUFFER(out, name_stream.str().c_str(), name_stream.str().length() );
//szExt::WRITE(out, (sz::Byte)sz::k7zIdEmptyFile );
//szExt::WRITE(out, (sz::Byte)sz::k7zIdCTime ); // create
//szExt::WRITE(out, (sz::Byte)sz::k7zIdATime ); // last access
//szExt::WRITE(out, (sz::Byte)sz::k7zIdMTime ); // write
//szExt::WRITE(out, (sz::Byte)sz::k7zIdWinAttributes );
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
return true;
}
vfs::UInt32 vfs::CCreateUncompressed7zLibrary::WriteFileName(std::ostream& out, utf8string const& filename)
{
vfs::UInt32 count = 0;
THROWIFFALSE(filename.length(), L"zero length name");
count += szExt::WRITEBUFFER(out, &filename.c_wcs().at(0), filename.length());
count += szExt::WRITE(out, (sz::Byte)0);
count += szExt::WRITE(out, (sz::Byte)0);
return count;
}
+64
View File
@@ -0,0 +1,64 @@
#ifndef _VFS_CREATE_7Z_LIBRARY_H_
#define _VFS_CREATE_7Z_LIBRARY_H_
//#include "Interface/vfs_library_interface.h"
//#include "Interface/vfs_directory_interface.h"
#include "../Interface/vfs_file_interface.h"
#include <sstream>
#include <map>
#include <list>
namespace vfs
{
class CCreateUncompressed7zLibrary
{
public:
CCreateUncompressed7zLibrary();
virtual ~CCreateUncompressed7zLibrary();
bool AddFile(vfs::tReadableFile* pFile);
bool WriteLibrary(vfs::Path const& sLibName);
bool WriteLibrary(vfs::tWriteableFile* pFile);
protected:
bool WriteSignatureHeader(std::ostream& out);
bool WriteNextHeader(std::ostream& out);
bool WriteMainStreamsInfo(std::ostream &out);
bool WritePackInfo(std::ostream& out);
bool WriteUnPackInfo(std::ostream& out);
bool WriteSubStreamsInfo(std::ostream& out);
bool WriteFolder(std::ostream& out);
bool WriteFilesInfo(std::ostream& out);
private:
unsigned int WriteFileName(std::ostream& out, utf8string const& filename);
protected:
vfs::tWriteableFile* m_pLibFile;
struct SFileInfo
{
SFileInfo()
: name(L""), CRC(0), offset(0), size(0), time_creation(0), time_last_access(0), time_write(0)
{};
//////
utf8string::str_t name;
UInt32 CRC;
UInt64 offset;
UInt64 size;
UInt64 time_creation,time_last_access,time_write;
};
typedef std::map<utf8string::str_t,SFileInfo> tDirInfo;
std::list<SFileInfo> m_lFileInfo;
tDirInfo m_mapDirInfo;
// keeping pointers to files to write their contents lates is not enough,
// as the file may only exist for a short time
std::stringstream m_ssFileStream;
std::stringstream m_ssInfoStream;
};
} // end namespace
#endif // _VFS_CREATE_7Z_LIBRARY_H_
+512
View File
@@ -0,0 +1,512 @@
#include "vfs_directory_tree.h"
#include "../File/vfs_dir_file.h"
#include "../Interface/vfs_location_aware_file_interface.h"
#include "../iteratedir.h"
#include <queue>
#include <list>
#include <set>
const utf8string::str_t CONST_EXT_TXT = L".TXT";
const utf8string::str_t CONST_EXT_LOG = L".LOG";
const utf8string::str_t CONST_EXT_INI = L".INI";
namespace vfs
{
class CSubDir : public vfs::IDirectory<vfs::CDirectoryTree::tWriteType>
{
typedef std::map<vfs::Path, tFileType*, vfs::Path::Less> tFileCatalogue;
class IterImpl : public tClassType::Iterator::IImplemetation
{
public:
IterImpl(CSubDir& dir);
virtual ~IterImpl();
virtual tFileType* value();
virtual void next();
private:
CSubDir& _dir;
tFileCatalogue::iterator _iter;
};
public:
CSubDir(vfs::Path const& sMountPoint, vfs::Path const& sRealPath)
: vfs::IDirectory<vfs::CDirectoryTree::tWriteType>(sMountPoint,sRealPath)
{};
virtual ~CSubDir();
virtual bool FileExists(vfs::Path const& rFileName);
virtual vfs::IBaseFile* GetFile(vfs::Path const& rFileName);
virtual tFileType* GetFileTyped(vfs::Path const& rFileName);
virtual tFileType* AddFile(vfs::Path const& sFilename, bool bDeleteOldFile=false);
virtual bool AddFile(tFileType* pFile, bool bDeleteOldFile=false);
virtual bool CreateSubDirectory(vfs::Path const& sSubDirPath);
virtual bool DeleteDirectory(vfs::Path const& sDirPath);
virtual bool DeleteFileFromDirectory(vfs::Path const& sFileName);
virtual void GetSubDirList(std::list<vfs::Path>& rlSubDirs);
virtual Iterator begin();
private:
tFileCatalogue m_mapFiles;
};
}
/********************************************************/
vfs::CSubDir::IterImpl::IterImpl(CSubDir& dir)
: _dir(dir)
{
_iter = _dir.m_mapFiles.begin();
}
vfs::CSubDir::IterImpl::~IterImpl()
{
}
vfs::CSubDir::tFileType* vfs::CSubDir::IterImpl::value()
{
if(_iter != _dir.m_mapFiles.end())
{
return _iter->second;
}
return NULL;
}
void vfs::CSubDir::IterImpl::next()
{
if(_iter != _dir.m_mapFiles.end())
{
_iter++;
}
}
/********************************************************/
vfs::CSubDir::~CSubDir()
{
tFileCatalogue::iterator it = m_mapFiles.begin();
for(; it != m_mapFiles.end(); ++it)
{
if(it->second)
{
it->second->Close();
delete it->second;
}
}
m_mapFiles.clear();
}
bool vfs::CSubDir::FileExists(vfs::Path const& sFileName)
{
tFileCatalogue::iterator it = m_mapFiles.find(sFileName);
bool success = (it != m_mapFiles.end()) && (it->second != NULL);
return success;
}
vfs::IBaseFile* vfs::CSubDir::GetFile(vfs::Path const& sFileName)
{
return GetFileTyped(sFileName);
}
vfs::CSubDir::tFileType* vfs::CSubDir::GetFileTyped(vfs::Path const& sFileName)
{
tFileCatalogue::iterator it = m_mapFiles.find(sFileName);
if(it != m_mapFiles.end())
{
CSubDir::tFileType* file = it->second;
return file;
}
return NULL;
}
vfs::CSubDir::tFileType* vfs::CSubDir::AddFile(vfs::Path const& sFilename, bool bDeleteOldFile)
{
#if 1
tFileType* pFile = m_mapFiles[sFilename];
#else
CSubDir::tFileCatalogue::iterator it;
tFileType* pFile = ((it=m_mapFiles.find(sFilename)) != m_mapFiles.end()) ? it->second : NULL;
#endif
if(pFile)
{
if(!bDeleteOldFile)
{
// not allowed to replace old file
return NULL;
}
delete pFile;
}
utf8string sExtension;
sFilename.Extension(sExtension);
if(sExtension == CONST_EXT_TXT || sExtension == CONST_EXT_LOG || sExtension == CONST_EXT_INI)
{
pFile = new vfs::CVFSTextFile(sFilename,this);
}
else
{
pFile = new vfs::CVFSFile(sFilename,this);
}
#if 1
m_mapFiles[sFilename] = pFile;
#else
m_mapFiles.insert(std::make_pair(sFilename,pFile));
#endif
return pFile;
}
bool vfs::CSubDir::AddFile(tFileType* pFile, bool bDeleteOldFile)
{
if(!pFile)
{
return false;
}
tFileType * pOldFile = m_mapFiles[pFile->GetFileName()];
if( pOldFile && (pOldFile != pFile) )
{
if(bDeleteOldFile)
{
pOldFile->Close();
delete pOldFile;
}
}
m_mapFiles[pFile->GetFileName()] = pFile;
return true;
}
bool vfs::CSubDir::DeleteDirectory(vfs::Path const& sDirPath)
{
if( !(m_sMountPoint == sDirPath) )
{
return false;
}
tFileCatalogue::iterator it = m_mapFiles.begin();
for(; it != m_mapFiles.end(); ++it)
{
tFileType* pFile = it->second;
if(pFile)
{
pFile->Close();
if(!pFile->Delete())
{
std::wstringstream wss;
wss << L"Could not delete file \"" << pFile->GetFullPath()() << L"\"";
THROWEXCEPTION(wss.str().c_str());
}
delete pFile;
}
}
m_mapFiles.clear();
return true;
}
bool vfs::CSubDir::DeleteFileFromDirectory(vfs::Path const& rFileName)
{
tFileCatalogue::iterator it = m_mapFiles.find(rFileName);
if( it != m_mapFiles.end() )
{
tFileType* pFile = it->second;
if(pFile)
{
pFile->Close();
THROWIFFALSE(pFile->Delete(), L"Could not delete file");
delete pFile;
}
m_mapFiles.erase(it);
return true;
}
return false;
}
bool vfs::CSubDir::CreateSubDirectory(vfs::Path const& sSubDirPath)
{
return false;
}
void vfs::CSubDir::GetSubDirList(std::list<vfs::Path>& rlSubDirs)
{
}
vfs::CSubDir::Iterator vfs::CSubDir::begin()
{
Iterator it;
{
it = Iterator(new IterImpl(*this));
}
return it;
}
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
vfs::CDirectoryTree::~CDirectoryTree()
{
tDirCatalogue::iterator it = m_catDirs.begin();
for(;it != m_catDirs.end(); ++it)
{
delete it->second;
it->second = NULL;
}
m_catDirs.clear();
}
bool vfs::CDirectoryTree::Init()
{
// contains local path
typedef std::pair<vfs::Path,CSubDir*> tDirs;
std::queue<tDirs> qSubDirs;
qSubDirs.push(tDirs(vfs::Path(vfs::Const::EMPTY()),new CSubDir(m_sMountPoint,m_sRealPath)));
m_catDirs[m_sMountPoint] = qSubDirs.front().second;
utf8string sFilename;
CSubDir *pCurrentDir;
vfs::Path oCurDir;
while(!qSubDirs.empty())
{
pCurrentDir = qSubDirs.front().second;
oCurDir = m_sRealPath;
if( !qSubDirs.front().first.empty())
{
oCurDir += qSubDirs.front().first;
}
try
{
os::CIterateDirectory::EFileAttribute eFA;
os::CIterateDirectory iterFS(oCurDir, vfs::Const::STAR());
while ( iterFS.NextFile(sFilename, eFA) )
{
if (StrCmp::Equal(vfs::Const::DOT(),sFilename) || StrCmp::Equal(vfs::Const::DOTDOT(),sFilename) || StrCmp::Equal(vfs::Const::DOTSVN(),sFilename) )
{
continue;
}
if (eFA == os::CIterateDirectory::FA_DIRECTORY)
{
vfs::Path sLocal = qSubDirs.front().first + sFilename;
vfs::Path temp = m_sMountPoint+sLocal;
CSubDir *pNewDir = new CSubDir(sLocal, m_sRealPath+sLocal);
qSubDirs.push(tDirs(sLocal,pNewDir));
m_catDirs[temp] = pNewDir;
}
else
{
pCurrentDir->AddFile(vfs::Path(sFilename));
}
}
}
catch(CBasicException &ex)
{
// probably directory doesn't exist. abort or continue???
// -> abort AND continue
return false;
}
qSubDirs.pop();
}
return true;
}
vfs::CDirectoryTree::tFileType* vfs::CDirectoryTree::AddFile(vfs::Path const& sFilename, bool bDeleteOldFile)
{
vfs::Path sDir,sFile;
sFilename.SplitLast(sDir,sFile);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it == m_catDirs.end())
{
vfs::Path sTemp,sCreateDir,sLeft,sRight = sDir;
while(sRight.SplitFirst(sLeft,sTemp))
{
sRight = sTemp;
sCreateDir += sLeft;
CreateSubDirectory(sCreateDir);
}
it = m_catDirs.find(sDir);
if(it == m_catDirs.end())
{
return NULL;
}
}
if(it->second)
{
vfs::CDirectoryTree::tFileType* file = it->second->AddFile(sFile,bDeleteOldFile);
return file;
}
return NULL;
}
bool vfs::CDirectoryTree::AddFile(tFileType* pFile, bool bDeleteOldFile)
{
// no files from outside
// these files are not connected with the correct directory object
return false;
}
bool vfs::CDirectoryTree::DeleteDirectory(vfs::Path const& sDirPath)
{
tDirCatalogue::iterator it = m_catDirs.find(sDirPath);
if(it == m_catDirs.end())
{
// no such directory
return false;
}
if(it->second)
{
return it->second->DeleteDirectory(sDirPath);
}
return false;
}
bool vfs::CDirectoryTree::DeleteFileFromDirectory(vfs::Path const& sFileName)
{
vfs::Path sDir,sFile;
sFileName.SplitLast(sDir,sFile);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it == m_catDirs.end())
{
// no such directory
return false;
}
if(it->second)
{
return it->second->DeleteFileFromDirectory(sFile);
}
return false;
}
/**
* IVFSLocation interface
*/
bool vfs::CDirectoryTree::FileExists(vfs::Path const& sFileName)
{
vfs::Path sDir, sFile;
sFileName.SplitLast(sDir, sFile);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it == m_catDirs.end())
{
// no such directory
return false;
}
if(it->second)
{
bool success = it->second->FileExists(sFile);
return success;
}
return false;
}
vfs::IBaseFile* vfs::CDirectoryTree::GetFile(vfs::Path const& sFileName)
{
return GetFileTyped(sFileName);
}
vfs::CDirectoryTree::tFileType* vfs::CDirectoryTree::GetFileTyped(vfs::Path const& sFileName)
{
vfs::Path sDir, sFile;
sFileName.SplitLast(sDir, sFile);
//tDirCatalogue::iterator it = m_catDirs.find(sDir);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it == m_catDirs.end())
{
// no such directory
return NULL;
}
if(it->second)
{
vfs::CDirectoryTree::tFileType* file = it->second->GetFileTyped(sFile);
return file;
}
return NULL;
}
bool vfs::CDirectoryTree::CreateSubDirectory(vfs::Path const& sSubDirPath)
{
if(os::CreateRealDirecory( m_sRealPath + sSubDirPath ))
{
if( m_catDirs[sSubDirPath] == NULL)
{
CSubDir *pNewDir = new CSubDir(sSubDirPath, m_sRealPath + sSubDirPath);
m_catDirs[sSubDirPath] = pNewDir;
}
return true;
}
return false;
}
void vfs::CDirectoryTree::GetSubDirList(std::list<vfs::Path>& rlSubDirs)
{
tDirCatalogue::iterator it = m_catDirs.begin();
for(;it != m_catDirs.end(); ++it)
{
rlSubDirs.push_back(it->first);
}
}
vfs::CDirectoryTree::Iterator vfs::CDirectoryTree::begin()
{
return Iterator(new IterImpl(*this));
}
/*****************************************************************************/
/*****************************************************************************/
vfs::CDirectoryTree::IterImpl::IterImpl(CDirectoryTree& tree)
: _tree(tree)
{
_subdir_iter = _tree.m_catDirs.begin();
if(_subdir_iter != _tree.m_catDirs.end())
{
CSubDir *sdir = dynamic_cast<CSubDir*>(_subdir_iter->second);
CSubDir::Iterator it = sdir->begin();
_file_iter = it;
if(_file_iter.end())
{
next();
}
}
}
vfs::CDirectoryTree::IterImpl::~IterImpl()
{
}
vfs::CDirectoryTree::tFileType* vfs::CDirectoryTree::IterImpl::value()
{
if(!_file_iter.end())
{
return static_cast<tFileType*>(_file_iter.value());
}
return NULL;
}
void vfs::CDirectoryTree::IterImpl::next()
{
if(!_file_iter.end())
{
_file_iter.next();
}
// need to loop for the case when one or many sub directories are empty
while(_file_iter.end())
{
if(_subdir_iter == _tree.m_catDirs.end())
{
break;
}
else
{
_subdir_iter++;
if(_subdir_iter != _tree.m_catDirs.end())
{
_file_iter = _subdir_iter->second->begin();
}
}
}
return;
}
+70
View File
@@ -0,0 +1,70 @@
#ifndef _VFS_DIRECTORY_H_
#define _VFS_DIRECTORY_H_
#include "../vfs_types.h"
//#include "Interface/vfs_location_interface.h"
#include "../Interface/vfs_file_interface.h"
#include "../Interface/vfs_directory_interface.h"
#include <map>
#include <vector>
namespace vfs
{
/**
* IDirectory<read,write>
*/
class CDirectoryTree : public vfs::IDirectory<vfs::IWriteable>
{
typedef std::map<vfs::Path, vfs::IDirectory<CDirectoryTree::tWriteType>*, vfs::Path::Less> tDirCatalogue;
class IterImpl : public tClassType::Iterator::IImplemetation
{
public:
IterImpl(CDirectoryTree& tree);
virtual ~IterImpl();
virtual tFileType* value();
virtual void next();
private:
CDirectoryTree& _tree;
tDirCatalogue::iterator _subdir_iter;
tClassType::Iterator _file_iter;
};
public:
CDirectoryTree(vfs::Path const& sMountPoint, vfs::Path const& sRealPath)
: vfs::IDirectory<vfs::IWriteable>(sMountPoint,sRealPath)
{};
virtual ~CDirectoryTree();
bool Init();
/**
* IDirectory interface
*/
virtual tFileType* AddFile(vfs::Path const& sFilename, bool bDeleteOldFile=false);
virtual bool AddFile(tFileType* pFile, bool bDeleteOldFile=false);
virtual bool CreateSubDirectory(vfs::Path const& sSubDirPath);
virtual bool DeleteDirectory(vfs::Path const& sDirPath);
virtual bool DeleteFileFromDirectory(vfs::Path const& sFileName);
/**
* IVFSLocation interface
*/
virtual bool FileExists(vfs::Path const& sFileName);
virtual vfs::IBaseFile* GetFile(vfs::Path const& sFileName);
virtual tFileType* GetFileTyped(vfs::Path const& sFileName);
virtual void GetSubDirList(std::list<vfs::Path>& rlSubDirs);
virtual Iterator begin();
protected:
tDirCatalogue m_catDirs;
};
} // end namespace
#endif // _VFS_DIRECTORY_H_
+151
View File
@@ -0,0 +1,151 @@
#include "vfs_lib_dir.h"
vfs::CLibDirectory::~CLibDirectory()
{
tFileCatalogue::iterator it = m_mapFiles.begin();
for(; it != m_mapFiles.end(); ++it)
{
// don't delete objects here
//delete it->second;
}
m_mapFiles.clear();
}
vfs::CLibDirectory::tFileType* vfs::CLibDirectory::AddFile(vfs::Path const& sFilename, bool bDeleteOldFile)
{
return NULL;
}
bool vfs::CLibDirectory::AddFile(tFileType* pFile, bool bDeleteOldFile)
{
if(!pFile)
{
return false;
}
vfs::Path const& sName = pFile->GetFileName();
tFileType* pFileOld = m_mapFiles[sName];
if(pFileOld && (pFileOld != pFile) )
{
if(bDeleteOldFile)
{
delete pFileOld;
m_mapFiles[sName] = pFile;
}
else
{
return false;
}
}
m_mapFiles[sName] = pFile;
return true;
}
bool vfs::CLibDirectory::DeleteDirectory(vfs::Path const& sDirPath)
{
if( !(m_sMountPoint == sDirPath) )
{
return false;
}
if(IsWriteable())
{
tFileCatalogue::iterator it = m_mapFiles.begin();
for(; it != m_mapFiles.end(); ++it)
{
delete it->second;
}
m_mapFiles.clear();
return true;
}
return false;
}
bool vfs::CLibDirectory::DeleteFileFromDirectory(vfs::Path const& sFileName)
{
if(IsWriteable())
{
tFileCatalogue::iterator it = m_mapFiles.find(sFileName);
if(it != m_mapFiles.end())
{
delete it->second;
m_mapFiles.erase(it);
return true;
}
}
return false;
}
bool vfs::CLibDirectory::FileExists(vfs::Path const& sFileName)
{
bool success = (m_mapFiles[sFileName] != NULL);
return success;
}
vfs::IBaseFile* vfs::CLibDirectory::GetFile(vfs::Path const& sFileName)
{
return GetFileTyped(sFileName);
}
vfs::CLibDirectory::tFileType* vfs::CLibDirectory::GetFileTyped(vfs::Path const& sFileName)
{
CLibDirectory::tFileType* file = m_mapFiles[sFileName];
return file;
}
bool vfs::CLibDirectory::CreateSubDirectory(vfs::Path const& sSubDirPath)
{
// libraries are readonly
return false;
}
void vfs::CLibDirectory::GetSubDirList(std::list<vfs::Path>& rlSubDirs)
{
}
vfs::CLibDirectory::Iterator vfs::CLibDirectory::begin()
{
return Iterator(new IterImpl(*this));
}
/***************************************************************************/
/***************************************************************************/
vfs::CLibDirectory::IterImpl::IterImpl(CLibDirectory& lib)
: _lib(lib)
{
_iter = _lib.m_mapFiles.begin();
}
vfs::CLibDirectory::IterImpl::~IterImpl()
{
}
vfs::CLibDirectory::tFileType* vfs::CLibDirectory::IterImpl::value()
{
if(_iter != _lib.m_mapFiles.end())
{
return _iter->second;
}
return NULL;
}
void vfs::CLibDirectory::IterImpl::next()
{
if(_iter != _lib.m_mapFiles.end())
{
_iter++;
}
}
/***************************************************************************/
/***************************************************************************/
static void tesst()
{
vfs::CLibDirectory *dir = new vfs::CLibDirectory(vfs::Path("test"), vfs::Path("test2"));
vfs::CLibDirectory::Iterator it = dir->begin();
while(!it.end())
{
vfs::CLibDirectory::tFileType* file = static_cast<vfs::CLibDirectory::tFileType*>(it.value());
it.next();
}
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef _VFS_LIB_DIR_H_
#define _VFS_LIB_DIR_H_
#include "../Interface/vfs_directory_interface.h"
namespace vfs
{
class CLibDirectory : public vfs::IDirectory<vfs::IWriteType>
{
typedef std::map<vfs::Path, tFileType*, vfs::Path::Less> tFileCatalogue;
class IterImpl : public tClassType::Iterator::IImplemetation
{
public:
IterImpl(CLibDirectory& lib);
virtual ~IterImpl();
virtual tFileType* value();
virtual void next();
private:
CLibDirectory& _lib;
tFileCatalogue::iterator _iter;
};
public:
CLibDirectory(vfs::Path const& sLocalPath, vfs::Path const& sRealPath)
: vfs::IDirectory<vfs::IWriteType>(sLocalPath,sRealPath)
{};
virtual ~CLibDirectory();
/**
* IDirectory interface
*/
virtual tFileType* AddFile(vfs::Path const& sFilename, bool bDeleteOldFile=false);
virtual bool AddFile(tFileType* pFile, bool bDeleteOldFile=false);
virtual bool DeleteFileFromDirectory(vfs::Path const& sFileName);
virtual bool CreateSubDirectory(vfs::Path const& sSubDirPath);
virtual bool DeleteDirectory(vfs::Path const& sDirPath);
/**
* IVFSLocation interface
*/
virtual bool FileExists(vfs::Path const& sFileName);
virtual vfs::IBaseFile* GetFile(vfs::Path const& sFileName);
virtual tFileType* GetFileTyped(vfs::Path const& sFileName);
virtual void GetSubDirList(std::list<vfs::Path>& rlSubDirs);
virtual Iterator begin();
protected:
tFileCatalogue m_mapFiles;
};
} // -end- namespace
#endif // _VFS_LIB_DIR_H_
+156
View File
@@ -0,0 +1,156 @@
#include "vfs_slf_library.h"
#include "../Interface/vfs_directory_interface.h"
#include "vfs_lib_dir.h"
#include "../File/vfs_lib_file.h"
namespace slf
{
// copy from WinDef.h
typedef unsigned long DWORD;
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
typedef void* HANDLE;
const vfs::UInt32 FILENAME_SIZE = 256;
const vfs::UInt32 PATH_SIZE = 80;
const vfs::UInt32 FILE_OK = 0;
const vfs::UInt32 FILE_DELETED = 0xff;
const vfs::UInt32 FILE_OLD = 1;
const vfs::UInt32 FILE_DOESNT_EXIST = 0xfe;
struct LIBHEADER
{
vfs::Byte sLibName[ FILENAME_SIZE ];
vfs::Byte sPathToLibrary[ FILENAME_SIZE ];
vfs::Int32 iEntries;
vfs::Int32 iUsed;
vfs::UInt16 iSort;
vfs::UInt16 iVersion;
vfs::UByte fContainsSubDirectories;
vfs::Int32 iReserved;
};
struct DIRENTRY
{
vfs::Byte sFileName[ FILENAME_SIZE ];
vfs::UInt32 uiOffset;
vfs::UInt32 uiLength;
vfs::UInt8 ubState;
vfs::UInt8 ubReserved;
FILETIME sFileTime;
vfs::UInt16 usReserved2;
};
}; // end namespace slf
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
vfs::CSLFLibrary::~CSLFLibrary()
{
}
bool vfs::CSLFLibrary::Init()
{
if(m_pLibraryFile)
{
if(!m_pLibraryFile->OpenRead())
{
return false;
}
slf::LIBHEADER LibFileHeader;
UInt32 uiNumBytesRead;
if(!m_pLibraryFile->Read((Byte*)&LibFileHeader,sizeof( slf::LIBHEADER ), uiNumBytesRead))
{
m_pLibraryFile->Close();
return false;
}
if( uiNumBytesRead != sizeof( slf::LIBHEADER ) )
{
//Error Reading the file database header.
m_pLibraryFile->Close();
return false;
}
vfs::Path oLibPath;
//if the library has a path
if( strlen( LibFileHeader.sPathToLibrary ) != 0 )
{
oLibPath = vfs::Path( LibFileHeader.sPathToLibrary );
}
else
{
//else the library name does not contain a path ( most likely either an error or it is the default path )
oLibPath = vfs::Path( vfs::Const::EMPTY() );
}
if(m_sMountPoint.empty())
{
m_sMountPoint = oLibPath;
}
else
{
m_sMountPoint += oLibPath;
}
//place the file pointer at the begining of the file headers ( they are at the end of the file )
m_pLibraryFile->SetReadLocation(-( LibFileHeader.iEntries * (Int32)sizeof(slf::DIRENTRY) ), vfs::IBaseFile::SD_END);
//loop through the library and determine the number of files that are FILE_OK
//ie. so we dont load the old or deleted files
slf::DIRENTRY DirEntry;
vfs::Path oDir, oFile;
vfs::Path oDirPath;
for(UInt32 uiLoop=0; uiLoop < (UInt32)LibFileHeader.iEntries; uiLoop++ )
{
//read in the file header
if(!m_pLibraryFile->Read((Byte*)&DirEntry, sizeof( slf::DIRENTRY ), uiNumBytesRead))
{
m_pLibraryFile->Close();
return false;
}
if( DirEntry.ubState == slf::FILE_OK )
{
vfs::Path sPath(utf8string::as_utf16(DirEntry.sFileName));
sPath.SplitLast(oDir,oFile);
oDirPath = m_sMountPoint;
if(!oDir.empty())
{
oDirPath += oDir;
}
// get or create according directory object
vfs::IDirectory<ILibrary::tWriteType>* pLD = NULL;
tDirCatalogue::iterator it = m_catDirs.find(oDirPath);
if(it != m_catDirs.end())
{
pLD = it->second;
}
else
{
pLD = new vfs::CLibDirectory(oDirPath,oDirPath);
m_catDirs.insert(std::make_pair(oDirPath,pLD));
}
// create file
vfs::CLibFile *pFile = vfs::CLibFile::Create(oFile,pLD,this);
// add file to directory
if(!pLD->AddFile(pFile))
{
m_pLibraryFile->Close();
return false;
}
// link file data struct to file object
m_mapLibData.insert(std::make_pair(pFile,sFileData(DirEntry.uiLength, DirEntry.uiOffset)));
} // end if
} // end for
m_pLibraryFile->Close();
return true;
} // end if
// no library file
return false;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef _VFS_SLF_LIBRARY_H_
#define _VFS_SLF_LIBRARY_H_
//#include "Interface/vfs_library_interface.h"
//#include "Interface/vfs_directory_interface.h"
#include "vfs_uncompressed_lib_base.h"
namespace vfs
{
class CSLFLibrary : public vfs::CUncompressedLibraryBase
{
public:
CSLFLibrary(tReadableFile *pLibraryFile, vfs::Path const& sMountPoint, bool bOwnFile = false)
: vfs::CUncompressedLibraryBase(pLibraryFile,sMountPoint,bOwnFile)
{};
virtual ~CSLFLibrary();
/**
* ILibrary interface
*/
virtual bool Init();
};
} // end namespace
#endif // _VFS_SLF_LIBRARY_H_
+267
View File
@@ -0,0 +1,267 @@
#include "vfs_uncompressed_lib_base.h"
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
vfs::CUncompressedLibraryBase::~CUncompressedLibraryBase()
{
this->CloseLibrary();
// delete sub dirs from catalogue
tDirCatalogue::iterator it = m_catDirs.begin();
for(; it != m_catDirs.end(); ++it)
{
delete it->second;
}
// LibData is invalid
// just clear it, since the file handles were deleted before
m_mapLibData.clear();
m_catDirs.clear();
}
bool vfs::CUncompressedLibraryBase::CloseLibrary()
{
bool success = true;
tLibData::iterator it = m_mapLibData.begin();
for(; it != m_mapLibData .end(); ++it)
{
success &= it->first->Close();
// what if closing of (at least) one file fails?? continue or not??
// in the end, these are not real files!
}
return success;
}
bool vfs::CUncompressedLibraryBase::FileExists(vfs::Path const& sFileName)
{
vfs::Path sDir,sFile;
sFileName.SplitLast(sDir,sFile);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it != m_catDirs.end())
{
return it->second->FileExists(sFile);
}
return false;
}
vfs::IBaseFile* vfs::CUncompressedLibraryBase::GetFile(vfs::Path const& sFileName)
{
return GetFileTyped(sFileName);
}
vfs::CUncompressedLibraryBase::tFileType* vfs::CUncompressedLibraryBase::GetFileTyped(vfs::Path const& sFileName)
{
vfs::Path sDir,sFile;
sFileName.SplitLast(sDir,sFile);
tDirCatalogue::iterator it = m_catDirs.find(sDir);
if(it != m_catDirs.end())
{
return it->second->GetFileTyped(sFile);
}
return NULL;
}
bool vfs::CUncompressedLibraryBase::Close(tFileType *pFileHandle)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return false;
}
// reset read position
// can't do this when opening file,
// because you could try to open a file when it is already open and would so reset the read position
it->second.uiCurrentReadPosition = 0;
if(m_uiNumberOfOpenedFiles > 0)
{
m_uiNumberOfOpenedFiles--;
if(m_uiNumberOfOpenedFiles == 0)
{
m_pLibraryFile->Close();
}
}
return true;
}
bool vfs::CUncompressedLibraryBase::OpenRead(tFileType *pFileHandle)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return false;
}
m_uiNumberOfOpenedFiles++;
if(m_uiNumberOfOpenedFiles == 1)
{
if(!m_pLibraryFile->IsOpenRead() && !m_pLibraryFile->OpenRead())
{
return false;
}
}
// already open
return true;
}
bool vfs::CUncompressedLibraryBase::Read(tFileType *pFileHandle, Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return false;
}
// if(m_pLibraryFile->IsOpen()) ... we could check it (*AGAIN*),
// but the file implementation does it already,
// and the user probably called 'OpenRead' too,
// so why do it over and over again
if( (it->second.uiCurrentReadPosition + uiBytesToRead) > it->second.uiFileSize )
{
// original implementation
uiBytesRead = 0;
return false;
// or you could adjust the number of bytes to read
uiBytesToRead = it->second.uiFileSize - it->second.uiCurrentReadPosition; // +-1 ???
}
// set lib-file's read-location to match location of virtual-file
m_pLibraryFile->SetReadLocation(it->second.uiFileOffset + it->second.uiCurrentReadPosition,IBaseFile::SD_BEGIN);
bool success = m_pLibraryFile->Read(pData,uiBytesToRead,uiBytesRead)
&& (uiBytesToRead == uiBytesRead);
if(success)
{
it->second.uiCurrentReadPosition += uiBytesRead;
}
// false if read operation failed
return success;
}
vfs::UInt32 vfs::CUncompressedLibraryBase::GetReadLocation(tFileType *pFileHandle)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return -1;
}
return it->second.uiCurrentReadPosition;
}
bool vfs::CUncompressedLibraryBase::SetReadLocation(tFileType *pFileHandle, vfs::UInt32 uiPositionInBytes)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return false;
}
if( (uiPositionInBytes < 0) || (uiPositionInBytes >= (vfs::Int32)(it->second.uiFileSize)) )
{
return false;
}
// uiCurrentReadPosition is offset to file-offset
it->second.uiCurrentReadPosition = uiPositionInBytes;
return true;
}
bool vfs::CUncompressedLibraryBase::SetReadLocation(tFileType *pFileHandle, Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
return false;
}
if( abs(uiOffsetInBytes) > (Int32)(it->second.uiFileSize) )
{
// cannot be corrent in any case
return false;
}
if(eSeekDir == IBaseFile::SD_BEGIN)
{
if(uiOffsetInBytes < 0)
{
return false;
}
it->second.uiCurrentReadPosition = uiOffsetInBytes;
return true;
}
else if(eSeekDir == IBaseFile::SD_CURRENT)
{
vfs::Int32 temp = it->second.uiCurrentReadPosition + uiOffsetInBytes;
if( (temp < 0) || (temp > (Int32)(it->second.uiFileSize)) )
{
return false;
}
it->second.uiCurrentReadPosition = temp;
return true;
}
else if(eSeekDir == IBaseFile::SD_END)
{
if(uiOffsetInBytes > 0)
{
return false;
}
it->second.uiCurrentReadPosition = it->second.uiFileSize - uiOffsetInBytes;
return true;
}
return false;
}
bool vfs::CUncompressedLibraryBase::GetFileSize(tFileType *pFileHandle, UInt32& uiFileSize)
{
tLibData::iterator it = m_mapLibData.find(pFileHandle);
if(it == m_mapLibData.end())
{
// wrong file handle
uiFileSize = 0;
return false;
}
uiFileSize = it->second.uiFileSize;
return true;
}
void vfs::CUncompressedLibraryBase::GetSubDirList(std::list<vfs::Path>& rlSubDirs)
{
tDirCatalogue::iterator it = m_catDirs.begin();
for(;it != m_catDirs.end(); ++it)
{
rlSubDirs.push_back(it->first);
}
}
vfs::CUncompressedLibraryBase::Iterator vfs::CUncompressedLibraryBase::begin()
{
return Iterator(new IterImpl(*this));
}
/************************************************************************/
/************************************************************************/
vfs::CUncompressedLibraryBase::IterImpl::IterImpl(vfs::CUncompressedLibraryBase &lib)
: _lib(&lib)
{
_iter = _lib->m_mapLibData.begin();
}
vfs::CUncompressedLibraryBase::IterImpl::~IterImpl()
{
}
vfs::CUncompressedLibraryBase::tFileType* vfs::CUncompressedLibraryBase::IterImpl::value()
{
if(_iter != _lib->m_mapLibData.end())
{
return _iter->first;
}
return NULL;
}
void vfs::CUncompressedLibraryBase::IterImpl::next()
{
if(_iter != _lib->m_mapLibData.end())
{
_iter++;
}
}
+74
View File
@@ -0,0 +1,74 @@
#ifndef _VFS_UNCOMPRESSED_LIB_BASE_H_
#define _VFS_UNCOMPRESSED_LIB_BASE_H_
#include "../Interface/vfs_library_interface.h"
#include "../Interface/vfs_directory_interface.h"
#include <sstream>
namespace vfs
{
class CUncompressedLibraryBase : public vfs::ILibrary
{
protected:
typedef std::map<vfs::Path, vfs::IDirectory<ILibrary::tWriteType>*, vfs::Path::Less> tDirCatalogue;
struct sFileData
{
sFileData(UInt32 const& fileSize, UInt32 const& fileOffset)
: uiFileSize(fileSize), uiFileOffset(fileOffset), uiCurrentReadPosition(0)
{};
UInt32 uiFileSize,uiFileOffset,uiCurrentReadPosition;
};
typedef std::map<tFileType*, sFileData> tLibData;
class IterImpl : public tClassType::Iterator::IImplemetation
{
public:
IterImpl(CUncompressedLibraryBase& lib);
virtual ~IterImpl();
virtual tFileType* value();
virtual void next();
private:
CUncompressedLibraryBase* _lib;
tLibData::iterator _iter;
};
public:
CUncompressedLibraryBase(tReadableFile *pLibraryFile, vfs::Path const& sMountPoint, bool bOwnFile = false)
: vfs::ILibrary(pLibraryFile,sMountPoint,bOwnFile), m_uiNumberOfOpenedFiles(0)
{};
virtual ~CUncompressedLibraryBase();
/**
* IVFSLocation interface
*/
virtual bool FileExists(vfs::Path const& sFileName);
virtual vfs::IBaseFile* GetFile(vfs::Path const& sFileName);
virtual tFileType* GetFileTyped(vfs::Path const& sFileName);
virtual void GetSubDirList(std::list<vfs::Path>& rlSubDirs);
/**
* ILibrary interface
*/
virtual bool Init() = 0;
virtual bool CloseLibrary();
virtual bool Close(tFileType *pFileHandle);
virtual bool OpenRead(tFileType *pFileHandle);
virtual bool Read(tFileType *pFileHandle, Byte* pData, UInt32 uiBytesToRead, UInt32& uiBytesRead);
virtual UInt32 GetReadLocation(tFileType *pFileHandle);
virtual bool SetReadLocation(tFileType *pFileHandle, UInt32 uiPositionInBytes);
virtual bool SetReadLocation(tFileType *pFileHandle, Int32 uiOffsetInBytes, IBaseFile::ESeekDir eSeekDir);
virtual bool GetFileSize(tFileType *pFileHandle, UInt32& uiFileSize);
virtual Iterator begin();
protected:
tDirCatalogue m_catDirs;
tLibData m_mapLibData;
UInt32 m_uiNumberOfOpenedFiles;
};
} // end namespace
#endif // _VFS_UNCOMPRESSED_LIB_BASE_H_
+40
View File
@@ -0,0 +1,40 @@
#include "HPTimer.h"
CHPTimer::CHPTimer()
{
#ifdef WIN32
QueryPerformanceFrequency(&ticksPerSecond);
#endif
}
CHPTimer::~CHPTimer()
{
}
void CHPTimer::StartTimer()
{
#ifdef WIN32
QueryPerformanceCounter(&tick);
#elif LINUX
gettimeofday(&t1,0);
#endif
}
void CHPTimer::StopTimer()
{
#ifdef WIN32
QueryPerformanceCounter(&tick2);
#elif LINUX
gettimeofday(&t2,0);
#endif
}
double CHPTimer::GetElapsedTimeInSeconds()
{
#ifdef WIN32
return (double)(tick2.QuadPart - tick.QuadPart)/(double)ticksPerSecond.QuadPart;
#elif LINUX
return (double)(t2.tv_usec - t1.tv_usec)/1000000.0;
#endif
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef _HPTIMER_
#define _HPTIMER_
#ifdef WIN32
#include <Windows.h>
#elif LINUX
#include <sys/time.h>
#endif
class CHPTimer
{
public:
CHPTimer();
~CHPTimer();
void StartTimer();
void StopTimer();
double GetElapsedTimeInSeconds();
protected:
#ifdef WIN32
LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER tick,tick2;
#elif LINUX
timeval t1,t2;
#endif
};
#endif // _HPTIMER_
+148
View File
@@ -0,0 +1,148 @@
#define NOMINMAX
#include "Prof.h"
#include "../vfs_types.h"
#include "../File/vfs_file.h"
#include <sstream>
CProf* g_Profiler = NULL;
class CProfileStarter
{
public:
CProfileStarter()
{
CProf::GetProf();
}
};
static CProfileStarter starter;
CProf* CProf::GetProf()
{
if(!g_Profiler)
{
g_Profiler = new CProf();
}
return g_Profiler;
}
CProf::CProf()
{
m_vMarker.resize(1024);
_nextMarker = 0;
}
void CProf::Clear()
{
for(unsigned int i = 0; i < _nextMarker; ++i)
{
m_vMarker[i].markername = "";
m_vMarker[i].time = 0;
m_vMarker[i].call_count = 0;
m_vMarker[i].success_count = 0;
m_vMarker[i].fail_count = 0;
}
_nextMarker = 0;
}
CProf::tMarkerID CProf::RegisterMarker(const char *marker)
{
m_vMarker[_nextMarker].markername = marker;
return _nextMarker++;
}
void CProf::StartMarker(tMarkerID id)
{
m_vMarker[id].timer.StartTimer();
}
void CProf::StopMarker(tMarkerID id, bool success)
{
m_vMarker[id].timer.StopTimer();
m_vMarker[id].time += m_vMarker[id].timer.GetElapsedTimeInSeconds();
m_vMarker[id].call_count++;
if(success) m_vMarker[id].success_count++;
else m_vMarker[id].fail_count++;
}
inline std::string MultChar(std::string::value_type c, unsigned int multiplicity)
{
std::string s;
s.resize(multiplicity);
for(unsigned int i=0; i<multiplicity; ++i)
{
s[i] = c;
}
return s;
}
inline long double perCent(unsigned long value, unsigned long ref)
{
return 100.0 * ((double)(value)/double(ref));
}
inline long double oneDigit(long double number)
{
unsigned long temp = (unsigned long)(number * 10);
return (temp / 10.0);
}
bool CProf::PrintProfilerState(vfs::Path const& file)
{
vfs::CFile oFile(file);
if(!oFile.OpenWrite(true,true))
{
return false;
}
// get largest value
long double max_time = 0;
unsigned int max_prefix = 0;
for(unsigned int i=0; i<m_vMarker.size(); ++i)
{
if(m_vMarker[i].time > max_time)
{
max_time = m_vMarker[i].time;
}
std::string::size_type prefix_length = m_vMarker[i].markername.length();
if(prefix_length > max_prefix)
{
max_prefix = prefix_length;
}
}
const unsigned int WIDTH = 40;
std::stringstream line;
long double ld_success, ld_failure;
for(unsigned int i=0; i<m_vMarker.size(); ++i)
{
if(m_vMarker[i].markername.empty())
{
break;
}
if(m_vMarker[i].markername.length() < WIDTH)
{
unsigned int space = WIDTH - m_vMarker[i].markername.length();
line << m_vMarker[i].markername << MultChar(' ',space) << " | ";
}
else
{
line << m_vMarker[i].markername.substr(0,WIDTH) << " | ";
}
if(max_time != 0)
{
unsigned int num_stars = (unsigned int)(WIDTH * (m_vMarker[i].time / max_time));
ld_success = perCent(m_vMarker[i].success_count,m_vMarker[i].call_count);
ld_failure = perCent(m_vMarker[i].fail_count,m_vMarker[i].call_count);
line << "[" << oneDigit(ld_success) << "|" << oneDigit(ld_failure) << "] "
<< MultChar('*', num_stars) << MultChar(' ', WIDTH - num_stars) << " | ";
}
line << "C: " << m_vMarker[i].call_count << ", T: " << m_vMarker[i].time << std::endl;
//line << std::endl;
}
vfs::UInt32 written;
std::string useless_copy = line.str();
oFile.Write(useless_copy.c_str(), useless_copy.length()*sizeof(std::string::value_type),written);
oFile.Close();
return true;
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef _PROF_H_
#define _PROF_H_
#include "HPTimer.h"
#include "../vfs_types.h"
#include <string>
#include <vector>
#define DO_PROFILE 1
#if DO_PROFILE
#define REGISTERMARKER(id,name) static CProf::tMarkerID id = g_Profiler->RegisterMarker(name)
#define STARTMARKER(id) (g_Profiler->StartMarker(id))
#define STOPMARKER(id,success) (g_Profiler->StopMarker(id,success))
#define DUMPPROFILERSTATSTOFILE(file) if(g_Profiler){g_Profiler->PrintProfilerState(file);}
#else
#define REGISTERMARKER(id,name)
#define STARTMARKER(id)
#define STOPMARKER(id,success)
#define DUMPPROFILERSTATSTOFILE(file)
#endif
class CProf
{
public:
typedef unsigned int tMarkerID;
static CProf* GetProf();
void Clear();
tMarkerID RegisterMarker(const char *marker);
void StartMarker(tMarkerID id);
void StopMarker(tMarkerID id, bool success);
bool PrintProfilerState(vfs::Path const& file);
private:
CProf();
struct MARKER
{
MARKER() : call_count(0), success_count(0), fail_count(0), time(0.0) {};
std::string markername;
long double time;
unsigned long call_count;
unsigned long success_count;
unsigned long fail_count;
CHPTimer timer;
};
std::vector<MARKER> m_vMarker;
unsigned int _nextMarker;
};
extern CProf* g_Profiler;
#endif // _PROF_H_
File diff suppressed because it is too large Load Diff
+218
View File
@@ -0,0 +1,218 @@
#ifndef _PROPERTY_CONTAINER_H_
#define _PROPERTY_CONTAINER_H_
#include "vfs_types.h"
#include "Interface/vfs_file_interface.h"
#include <map>
#include <string>
#include <list>
#include <set>
class CPropertyContainer
{
public:
class TagMap
{
typedef std::map<utf8string,utf8string> tTagMap;
public:
TagMap();
utf8string const& Container(utf8string::char_t* container = NULL);
utf8string const& Section(utf8string::char_t* section = NULL);
utf8string const& SectionID(utf8string::char_t* section_id = NULL);
utf8string const& Key(utf8string::char_t* key = NULL);
utf8string const& KeyID(utf8string::char_t* key_id = NULL);
private:
tTagMap _map;
};
public:
CPropertyContainer(){};
~CPropertyContainer(){};
void ClearContainer();
bool InitFromIniFile(vfs::Path const& sFileName);
bool InitFromIniFile(vfs::tReadableFile *pFile);
bool WriteToIniFile(vfs::Path const& sFileName, bool bCreateNew = false);
bool InitFromXMLFile(vfs::Path const& sFileName, TagMap& tagmap);
bool WriteToXMLFile(vfs::Path const& sFileName, TagMap& tagmap);
void PrintProperties();
//
utf8string const& GetStringProperty(utf8string const& sSection, utf8string const& sKey, utf8string const& sDefaultValue=L"");
bool GetStringProperty(utf8string const& sSection, utf8string const& sKey, utf8string& sValue, utf8string const& sDefaultValue=L"");
bool GetStringProperty(utf8string const& sSection, utf8string const& sKey, utf8string::char_t* sValue, vfs::UInt32 len, utf8string const& sDefaultValue=L"");
//
vfs::Int64 GetIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::Int64 iDefaultValue);
vfs::Int64 GetIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::Int64 iDefaultValue, vfs::Int64 iMinValue, vfs::Int64 iMaxValue);
//
vfs::UInt64 GetUIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::UInt64 iDefaultValue);
vfs::UInt64 GetUIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::UInt64 iDefaultValue, vfs::UInt64 iMinValue, vfs::UInt64 iMaxValue);
//
double GetFloatProperty(utf8string const& sSection, utf8string const& sKey, double fDefaultValue);
double GetFloatProperty(utf8string const& sSection, utf8string const& sKey, double fDefaultValue, double fMinValue, double fMaxValue);
//
bool GetBoolProperty(utf8string const& sSection, utf8string const& sKey, bool bDefaultValue);
//
bool GetStringListProperty(utf8string const& sSection, utf8string const& sKey, std::list<utf8string> &lValueList, utf8string sDefaultValue);
bool GetIntListProperty(utf8string const& sSection, utf8string const& sKey, std::list<vfs::Int64> &lValueList, vfs::Int64 iDefaultValue);
bool GetUIntListProperty(utf8string const& sSection, utf8string const& sKey, std::list<vfs::UInt64> &lValueList, vfs::UInt64 iDefaultValue);
bool GetFloatListProperty(utf8string const& sSection, utf8string const& sKey, std::list<double> &lValueList, double fDefaultValue);
bool GetBoolListProperty(utf8string const& sSection, utf8string const& sKey, std::list<bool> &lValueList, bool bDefaultValue);
//
void SetStringProperty(utf8string const& sSection, utf8string const& sKey, utf8string const& sValue);
//
void SetIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::Int64 const& iValue);
void SetUIntProperty(utf8string const& sSection, utf8string const& sKey, vfs::UInt64 const& iValue);
void SetFloatProperty(utf8string const& sSection, utf8string const& sKey, double const& fValue);
void SetBoolProperty(utf8string const& sSection, utf8string const& sKey, bool const& bValue);
//
void SetStringListProperty(utf8string const& sSection, utf8string const& sKey, std::list<utf8string> const& slValue);
void SetIntListProperty(utf8string const& sSection, utf8string const& sKey, std::list<vfs::Int64> const& ilValue);
void SetUIntListProperty(utf8string const& sSection, utf8string const& sKey, std::list<vfs::UInt64> const& ilValue);
void SetFloatListProperty(utf8string const& sSection, utf8string const& sKey, std::list<double> const& flValue);
void SetBoolListProperty(utf8string const& sSection, utf8string const& sKey, std::list<bool> const& blValue);
private:
enum EOperation
{
Error, Set, Add,
};
bool ExtractSection(utf8string::str_t const& readStr, size_t startPos, utf8string::str_t& sSection);
EOperation ExtractKeyValue(utf8string::str_t const &readStr, size_t startPos, utf8string::str_t& sKey, utf8string::str_t& sValue);
private:
class CSection
{
friend class CPropertyContainer;
typedef std::map<utf8string,utf8string, utf8string::Less> tProps;
public:
bool add(utf8string const& key, utf8string const& value);
bool value(utf8string const& key, utf8string& value);
utf8string& value(utf8string const& key);
void Print(std::ostream& out, utf8string::str_t sPrefix = L"");
void Clear();
private:
tProps mapProps;
};
typedef std::map<utf8string, CSection, utf8string::Less> tSections;
bool GetValueForKey(utf8string const& sSection, utf8string const& sKey, utf8string &sValue);
CSection& Section(utf8string const& sSection);
tSections m_mapProps;
};
/*************************************************************/
/*************************************************************/
class CTransferRules
{
public:
enum EAction
{
DENY,
ACCEPT,
};
public:
CTransferRules() : m_eDefaultAction(ACCEPT) {};
bool InitFromTxtFile(vfs::Path const& sPath);
bool InitFromTxtFile(vfs::tReadableFile* pFile);
void SetDefaultAction(EAction act);
EAction GetDefaultAction();
EAction ApplyRule(utf8string const& sStr);
private:
struct SRule
{
EAction action;
vfs::Path pattern;
};
typedef std::list<SRule> tPatternList;
tPatternList m_listRules;
EAction m_eDefaultAction;
};
/*************************************************************/
/*************************************************************/
template<typename CharType, typename ValueType>
std::basic_string<CharType> ToString(ValueType const& rVal)
{
std::basic_stringstream<CharType> tss;
if( !(tss << rVal))
{
return std::basic_string<CharType>();
}
return tss.str();
}
class CMemoryFile;
class CLog
{
public:
enum EFlushMode
{
FLUSH_ON_DELETE,
FLUSH_BUFFER,
FLUSH_IMMEDIATELY,
};
public:
CLog(vfs::Path fileName, bool append = false, EFlushMode flushMode = FLUSH_ON_DELETE);
~CLog();
static CLog* Create(vfs::Path fileName, bool append = false, EFlushMode flushMode = FLUSH_ON_DELETE);
static void FlushAll();
static void FlushFinally();
CLog& operator<<(unsigned int const& t);
CLog& operator<<(unsigned short const& t);
CLog& operator<<(unsigned char const& t);
CLog& operator<<(int const& t);
CLog& operator<<(short const& t);
CLog& operator<<(char const& t);
CLog& operator<<(float const& t);
CLog& operator<<(double const& t);
CLog& operator<<(const char* t);
CLog& operator<<(const wchar_t* t);
CLog& operator<<(std::string const& t);
CLog& operator<<(std::wstring const& t);
CLog& operator<<(utf8string const& t);
CLog& Endl();
static const char endl[];
void SetAppend(bool append = true);
void SetBufferSize(vfs::UInt32 bufferSize);
void Flush();
private:
void _test_flush(bool force=false);
template<typename T_>
CLog& PushNumber(T_ const& t)
{
_buffer << ToString<char>(t);
_buffer_size += sizeof(T_);
_test_flush();
return *this;
}
private:
vfs::Path _filename;
vfs::tWriteableFile* _file;
bool _own_file;
bool _first_write;
EFlushMode _flush_mode;
bool _append;
vfs::UInt32 _buffer_size, _buffer_test_size;
std::stringstream _buffer;
private:
static std::list<CLog*>& _logs();
};
#endif // _PROPERTY_CONTAINER_H_
+345
View File
@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="VFS"
ProjectGUID="{C63466D6-49B5-4C54-AA0D-864F6171FD9B}"
RootNamespace="Utils"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="0">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="0"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="TRUE"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="FALSE"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MapEditorD|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="0">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MapEditor|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="0"
WholeProgramOptimization="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="TRUE"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="FALSE"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Interface">
<File
RelativePath=".\Interface\vfs_directory_interface.h">
</File>
<File
RelativePath=".\Interface\vfs_file_interface.h">
</File>
<File
RelativePath=".\Interface\vfs_library_interface.h">
</File>
<File
RelativePath=".\Interface\vfs_location_aware_file_interface.h">
</File>
<File
RelativePath=".\Interface\vfs_location_interface.h">
</File>
</Filter>
<Filter
Name="Location">
<File
RelativePath=".\Location\vfs_7z_library.cpp">
</File>
<File
RelativePath=".\Location\vfs_7z_library.h">
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.cpp">
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.h">
</File>
<File
RelativePath=".\Location\vfs_directory_tree.cpp">
</File>
<File
RelativePath=".\Location\vfs_directory_tree.h">
</File>
<File
RelativePath=".\Location\vfs_lib_dir.cpp">
</File>
<File
RelativePath=".\Location\vfs_lib_dir.h">
</File>
<File
RelativePath=".\Location\vfs_slf_library.cpp">
</File>
<File
RelativePath=".\Location\vfs_slf_library.h">
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.cpp">
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.h">
</File>
</Filter>
<Filter
Name="File">
<File
RelativePath=".\File\vfs_dir_file.cpp">
</File>
<File
RelativePath=".\File\vfs_dir_file.h">
</File>
<File
RelativePath=".\File\vfs_file.cpp">
</File>
<File
RelativePath=".\File\vfs_file.h">
</File>
<File
RelativePath=".\File\vfs_lib_file.cpp">
</File>
<File
RelativePath=".\File\vfs_lib_file.h">
</File>
<File
RelativePath=".\File\vfs_memory_file.cpp">
</File>
<File
RelativePath=".\File\vfs_memory_file.h">
</File>
</Filter>
<Filter
Name="Profiler">
<File
RelativePath=".\Profiler\HPTimer.cpp">
</File>
<File
RelativePath=".\Profiler\HPTimer.h">
</File>
<File
RelativePath=".\Profiler\Prof.cpp">
</File>
<File
RelativePath=".\Profiler\Prof.h">
</File>
</Filter>
<File
RelativePath=".\iteratedir.cpp">
</File>
<File
RelativePath=".\iteratedir.h">
</File>
<File
RelativePath=".\PropertyContainer.cpp">
</File>
<File
RelativePath=".\PropertyContainer.h">
</File>
<File
RelativePath=".\stringicmp.h">
</File>
<File
RelativePath=".\vfs.cpp">
</File>
<File
RelativePath=".\vfs.h">
</File>
<File
RelativePath=".\vfs_debug.cpp">
</File>
<File
RelativePath=".\vfs_debug.h">
</File>
<File
RelativePath=".\vfs_file_raii.cpp">
</File>
<File
RelativePath=".\vfs_file_raii.h">
</File>
<File
RelativePath=".\vfs_init.cpp">
</File>
<File
RelativePath=".\vfs_init.h">
</File>
<File
RelativePath=".\vfs_profile.cpp">
</File>
<File
RelativePath=".\vfs_profile.h">
</File>
<File
RelativePath=".\vfs_types.cpp">
</File>
<File
RelativePath=".\vfs_types.h">
</File>
<File
RelativePath=".\vfs_vfile.cpp">
</File>
<File
RelativePath=".\vfs_vfile.h">
</File>
<File
RelativePath=".\vfs_vloc.cpp">
</File>
<File
RelativePath=".\vfs_vloc.h">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+499
View File
@@ -0,0 +1,499 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="VFS_2005Express"
ProjectGUID="{C63466D6-49B5-4C54-AA0D-864F6171FD9B}"
RootNamespace="Utils"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditorD|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditor|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Interface"
>
<File
RelativePath=".\Interface\vfs_directory_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_file_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_library_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_location_aware_file_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_location_interface.h"
>
</File>
</Filter>
<Filter
Name="Location"
>
<File
RelativePath=".\Location\vfs_7z_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_7z_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_directory_tree.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_directory_tree.h"
>
</File>
<File
RelativePath=".\Location\vfs_lib_dir.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_lib_dir.h"
>
</File>
<File
RelativePath=".\Location\vfs_slf_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_slf_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.h"
>
</File>
</Filter>
<Filter
Name="File"
>
<File
RelativePath=".\File\vfs_dir_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_dir_file.h"
>
</File>
<File
RelativePath=".\File\vfs_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_file.h"
>
</File>
<File
RelativePath=".\File\vfs_lib_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_lib_file.h"
>
</File>
<File
RelativePath=".\File\vfs_memory_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_memory_file.h"
>
</File>
</Filter>
<Filter
Name="Profiler"
>
<File
RelativePath=".\Profiler\HPTimer.cpp"
>
</File>
<File
RelativePath=".\Profiler\HPTimer.h"
>
</File>
<File
RelativePath=".\Profiler\Prof.cpp"
>
</File>
<File
RelativePath=".\Profiler\Prof.h"
>
</File>
</Filter>
<File
RelativePath=".\iteratedir.cpp"
>
</File>
<File
RelativePath=".\iteratedir.h"
>
</File>
<File
RelativePath=".\PropertyContainer.cpp"
>
</File>
<File
RelativePath=".\PropertyContainer.h"
>
</File>
<File
RelativePath=".\utf8string.cpp"
>
</File>
<File
RelativePath=".\utf8string.h"
>
</File>
<File
RelativePath=".\vfs.cpp"
>
</File>
<File
RelativePath=".\vfs.h"
>
</File>
<File
RelativePath=".\vfs_debug.cpp"
>
</File>
<File
RelativePath=".\vfs_debug.h"
>
</File>
<File
RelativePath=".\vfs_file_raii.cpp"
>
</File>
<File
RelativePath=".\vfs_file_raii.h"
>
</File>
<File
RelativePath=".\vfs_init.cpp"
>
</File>
<File
RelativePath=".\vfs_init.h"
>
</File>
<File
RelativePath=".\vfs_profile.cpp"
>
</File>
<File
RelativePath=".\vfs_profile.h"
>
</File>
<File
RelativePath=".\vfs_types.cpp"
>
</File>
<File
RelativePath=".\vfs_types.h"
>
</File>
<File
RelativePath=".\vfs_vfile.cpp"
>
</File>
<File
RelativePath=".\vfs_vfile.h"
>
</File>
<File
RelativePath=".\vfs_vloc.cpp"
>
</File>
<File
RelativePath=".\vfs_vloc.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+500
View File
@@ -0,0 +1,500 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="VFS"
ProjectGUID="{C63466D6-49B5-4C54-AA0D-864F6171FD9B}"
RootNamespace="Utils"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditorD|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditor|Win32"
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Interface"
>
<File
RelativePath=".\Interface\vfs_directory_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_file_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_library_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_location_aware_file_interface.h"
>
</File>
<File
RelativePath=".\Interface\vfs_location_interface.h"
>
</File>
</Filter>
<Filter
Name="Location"
>
<File
RelativePath=".\Location\vfs_7z_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_7z_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_create_7z_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_directory_tree.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_directory_tree.h"
>
</File>
<File
RelativePath=".\Location\vfs_lib_dir.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_lib_dir.h"
>
</File>
<File
RelativePath=".\Location\vfs_slf_library.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_slf_library.h"
>
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.cpp"
>
</File>
<File
RelativePath=".\Location\vfs_uncompressed_lib_base.h"
>
</File>
</Filter>
<Filter
Name="File"
>
<File
RelativePath=".\File\vfs_dir_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_dir_file.h"
>
</File>
<File
RelativePath=".\File\vfs_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_file.h"
>
</File>
<File
RelativePath=".\File\vfs_lib_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_lib_file.h"
>
</File>
<File
RelativePath=".\File\vfs_memory_file.cpp"
>
</File>
<File
RelativePath=".\File\vfs_memory_file.h"
>
</File>
</Filter>
<Filter
Name="Profiler"
>
<File
RelativePath=".\Profiler\HPTimer.cpp"
>
</File>
<File
RelativePath=".\Profiler\HPTimer.h"
>
</File>
<File
RelativePath=".\Profiler\Prof.cpp"
>
</File>
<File
RelativePath=".\Profiler\Prof.h"
>
</File>
</Filter>
<File
RelativePath=".\iteratedir.cpp"
>
</File>
<File
RelativePath=".\iteratedir.h"
>
</File>
<File
RelativePath=".\PropertyContainer.cpp"
>
</File>
<File
RelativePath=".\PropertyContainer.h"
>
</File>
<File
RelativePath=".\utf8string.cpp"
>
</File>
<File
RelativePath=".\utf8string.h"
>
</File>
<File
RelativePath=".\vfs.cpp"
>
</File>
<File
RelativePath=".\vfs.h"
>
</File>
<File
RelativePath=".\vfs_debug.cpp"
>
</File>
<File
RelativePath=".\vfs_debug.h"
>
</File>
<File
RelativePath=".\vfs_file_raii.cpp"
>
</File>
<File
RelativePath=".\vfs_file_raii.h"
>
</File>
<File
RelativePath=".\vfs_init.cpp"
>
</File>
<File
RelativePath=".\vfs_init.h"
>
</File>
<File
RelativePath=".\vfs_profile.cpp"
>
</File>
<File
RelativePath=".\vfs_profile.h"
>
</File>
<File
RelativePath=".\vfs_types.cpp"
>
</File>
<File
RelativePath=".\vfs_types.h"
>
</File>
<File
RelativePath=".\vfs_vfile.cpp"
>
</File>
<File
RelativePath=".\vfs_vfile.h"
>
</File>
<File
RelativePath=".\vfs_vloc.cpp"
>
</File>
<File
RelativePath=".\vfs_vloc.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+117
View File
@@ -0,0 +1,117 @@
//
// Snap: Implementation of the TReadDir class
// This class reads the contents of a directory file-by-file
//
#include "iteratedir.h"
#include "VFS/vfs_debug.h"
#include <sstream>
#include "utf8string.h"
#ifndef WIN32
int file_select(struct direct *entry)
{
/* if((strcmp(entry->d_name,".") == 0) || ( strcmp(entry->d_name,"..") == 0))
{
return (FALSE);
}
else
{
return (TRUE);
}*/
return (TRUE);
}
#endif
os::CIterateDirectory::CIterateDirectory(vfs::Path const& sPath, utf8string const& searchPattern)
{
#ifdef WIN32
fSearchHandle = FindFirstFileW((sPath+searchPattern)().c_wcs().c_str(), &fFileInfo);
if (fSearchHandle == INVALID_HANDLE_VALUE)
{
std::wstringstream wss;
wss << L"Path [" << (sPath+searchPattern)() << L"] does not exist";
THROWEXCEPTION(wss.str().c_str());
}
#else
count = scandir(sPath().utf8().c_str(),&files,NULL,NULL);
current_pos = 0;
#endif
fFirstRequest = true;
}
os::CIterateDirectory::~CIterateDirectory()
{
#ifdef WIN32
FindClose(fSearchHandle);
#else
#endif
}
bool os::CIterateDirectory::NextFile(utf8string &fileName, CIterateDirectory::EFileAttribute &attrib)
{
#ifdef WIN32
THROWIFFALSE(fSearchHandle != INVALID_HANDLE_VALUE, L"Invalid Handle Value");
if (fFirstRequest)
{
fFirstRequest = false;
}
else if ( !FindNextFileW(fSearchHandle, &fFileInfo) )
{
return false;
}
fileName.r_wcs().assign(fFileInfo.cFileName);
attrib = (fFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? CIterateDirectory::FA_DIRECTORY : CIterateDirectory::FA_FILE;
return true;
#else
if(current_pos < count)
{
struct dirent* entry = files[current_pos];
fileName.assign(VfsString(entry->d_name)());
attrib = (entry->d_type == DT_DIR) ? CIterateDir::FA_DIRECTORY : CIterateDir::FA_FILE;
current_pos++;
return true;
}
return false;
#endif
}
bool os::CreateRealDirecory(vfs::Path& sDir, bool bDoNotCreate)
{
#if WIN32
if(bDoNotCreate)
{
bool bDirExists = false;
WIN32_FIND_DATAW fd;
memset(&fd,0,sizeof(WIN32_FIND_DATAW));
HANDLE hFile = FindFirstFileW( sDir().c_wcs().c_str(), &fd);
bDirExists = fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY;
FindClose(hFile);
return bDirExists;
}
BOOL success;
success = CreateDirectoryW(sDir().c_wcs().c_str(),NULL);
if(success == 0)
{
DWORD error = GetLastError();
if(error == ERROR_ALREADY_EXISTS)
{
return true;
}
return false;
}
return true;
#else
#endif
}
bool os::DeleteRealFile(vfs::Path &sDir)
{
#ifdef WIN32
return (DeleteFileW( sDir().c_wcs().c_str() ) != FALSE);
#else
return (remove( sDir().utf8().c_str() ) == 0);
#endif
}
+52
View File
@@ -0,0 +1,52 @@
//
// Snap: Declaration of the TReadDir class
// This class reads the contents of a directory file-by-file
//
#ifndef _ITERATEDIR_H_
#define _ITERATEDIR_H_
#ifdef WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/dir.h>
#include <unistd.h>
#include <stdio.h>
#endif
#include "vfs_types.h"
namespace os
{
class CIterateDirectory
{
public:
enum EFileAttribute
{
FA_DIRECTORY,
FA_FILE
};
public:
CIterateDirectory(vfs::Path const& sPath, utf8string const& searchPattern);
~CIterateDirectory();
bool NextFile(utf8string &fileName, CIterateDirectory::EFileAttribute &attrib);
private:
#ifdef WIN32
HANDLE fSearchHandle;
WIN32_FIND_DATAW fFileInfo;
#else
struct direct **files;
int count, current_pos;
#endif
bool fFirstRequest;
};
bool CreateRealDirecory(vfs::Path &sDir, bool bDoNotCreate=false);
bool DeleteRealFile(vfs::Path &sDir);
}; // end namespace
#endif // #ifndef _ITERATEDIR_H_
+478
View File
@@ -0,0 +1,478 @@
#include "utf8string.h"
#include "utf8.h"
#include <vector>
#include <vfs_debug.h>
////////////////////////////////////////////////////////////////////
namespace _StrCmp
{
////////////////////////////////////////////////////////////////
inline void Advance( const char*& s1, const char*& s2 )
{
while (*s1 && *s2 && toupper(*s1) == toupper(*s2))
{
++s1;
++s2;
}
}
inline void Advance( const wchar_t*& s1, const wchar_t*& s2 )
{
// should be 'towupper'
while (*s1 && *s2 && toupper(*s1) == toupper(*s2))
{
++s1;
++s2;
}
}
template<typename CharType>
inline void AdvanceCase( const CharType*& s1, const CharType*& s2 )
{
while (*s1 && *s2 && (*s1 == *s2))
{
++s1;
++s2;
}
}
////////////////////////////////////////////////////////////////
template<typename CharType>
inline bool Equal( const CharType* s1, const CharType* s2 )
{
return !(*s1 || *s2);
}
////////////////////////////////////////////////////////////////
inline bool Less( const wchar_t* s1, const wchar_t* s2 )
{
if (!*s1) return *s2 != 0;
if (!*s2) return false;
// should be 'towupper'
return toupper(*s1) < toupper(*s2);
}
inline bool Less( const char* s1, const char* s2 )
{
if (!*s1) return *s2 != 0;
if (!*s2) return false;
return toupper(*s1) < toupper(*s2);
}
template<typename CharType>
inline bool LessCase( const CharType* s1, const CharType* s2 )
{
if (!*s1) return *s2 != 0;
if (!*s2) return false;
return (*s1) < (*s2);
}
}
////////////////////////////////////////////////////////////////////
bool utf8string::lessCase(utf8string const& s1, utf8string const& s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
const utf8string::char_t *p2 = s2._str.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::LessCase(p1,p2);
}
bool utf8string::less(utf8string const& s1, utf8string const& s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
const utf8string::char_t *p2 = s2._str.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Less(p1,p2);
}
bool utf8string::equalCase(utf8string const& s1, const utf8string& s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
const utf8string::char_t *p2 = s2._str.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool utf8string::equalCase(utf8string const& s1, const utf8string::str_t& s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
const utf8string::char_t *p2 = s2.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool utf8string::equalCase(utf8string const& s1, const utf8string::char_t* s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
_StrCmp::AdvanceCase(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool utf8string::equal(utf8string const& s1, utf8string const& s2)
{
const utf8string::char_t *p1 = s1._str.c_str();
const utf8string::char_t *p2 = s2._str.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
////////////////////////////////////////////////////////////////////
/// class constructors
////////////////////////////////////////////////////////////////////
utf8string::utf8string()
{
}
utf8string::utf8string(const char* str)
{
utf8string::as_utf16(str,_str);
}
utf8string::utf8string(std::string const& str)
{
utf8string::as_utf16(str,_str);
}
utf8string::utf8string(const wchar_t* str)
{
_str.assign(str);
}
utf8string::utf8string(std::wstring const& str)
{
_str.assign(str);
}
////////////////////////////////////////////////////////////////////
/// static class methods
////////////////////////////////////////////////////////////////////
utf8string::str_t utf8string::as_utf16(std::string const& str)
{
utf8string::str_t s;
utf8string::as_utf16(str, s);
return s;
}
void utf8string::as_utf16(std::string const& str, utf8string::str_t &str16)
{
try
{
int d = utf8::distance(str.begin(), str.end());
str16.resize(d);
utf8::utf8to16(str.begin(), str.end(), &str16[0]);
}
catch(utf8::invalid_utf8& ex)
{
std::wstringstream wss;
utf8::uint8_t c = ex.utf8_octet();
wss << L"Invalid UTF8 character '" << (wchar_t)c << L"'=" << (unsigned char)c;
THROWEXCEPTION(wss.str().c_str());
}
catch(utf8::not_enough_room &ex)
{
THROWEXCEPTION(L"Incomplete UTF8 string");
}
}
utf8string::str_t utf8string::as_utf16(const char* str)
{
utf8string::str_t s;
utf8string::as_utf16(str, s);
return s;
}
void utf8string::as_utf16(const char* str, utf8string::str_t &str16)
{
try
{
int len = strlen(str);
int d = utf8::distance(str,str+len);
str16.resize(d);
utf8::utf8to16(str, str+len, &str16[0]);
}
catch(utf8::invalid_utf8& ex)
{
std::wstringstream wss;
utf8::uint8_t c = ex.utf8_octet();
wss << L"Invalid UTF8 character '" << (wchar_t)c << L"'=" << (unsigned char)c;
THROWEXCEPTION(wss.str().c_str());
}
catch(utf8::not_enough_room &ex)
{
THROWEXCEPTION(L"Incomplete UTF8 string");
}
}
std::string utf8string::as_utf8(utf8string const& str)
{
return str.utf8();
}
std::string utf8string::as_utf8(std::wstring const& str)
{
#if 0
std::string s;
utf8::utf16to8(str.begin(), str.end(), std::back_inserter(s));
#else
static std::vector<char> buffer;
buffer.resize(std::max<int>(buffer.size(), str.length()*3));
char* end = utf8::utf16to8(str.begin(), str.end(), &buffer[0]);
std::string s(&buffer[0],end);
#endif
return s;
}
// if 'strlen' is 0, length is determined automatically
std::string utf8string::as_utf8(const wchar_t* str, unsigned int strlength)
{
std::string s;
size_t len = strlength;
if(len == 0)
{
len = wcslen(str);
}
utf8::utf16to8(str,str+len,std::back_inserter(s));
return s;
}
// convenience method, for the case it should be used in generic code (overloading)
std::string utf8string::as_utf8(std::string const& str)
{
return str;
}
////////////////////////////////////////////////////////////////////
/// get string methods
////////////////////////////////////////////////////////////////////
std::string utf8string::utf8() const
{
return as_utf8(_str);
}
std::wstring const& utf8string::c_wcs() const
{
return _str;
}
std::wstring& utf8string::r_wcs()
{
return _str;
}
////////////////////////////////////////////////////////////////////
bool utf8string::empty() const
{
return _str.empty();
}
utf8string::size_t utf8string::length() const
{
return _str.length();
}
utf8string utf8string::operator+(utf8string const& str)
{
return utf8string(_str + str._str);
}
utf8string utf8string::operator+=(utf8string const& str)
{
_str += str._str;
return utf8string(_str);
}
////////////////////////////////////////////////////////////////
bool operator<(utf8string const& s1, utf8string const& s2)
{
return s1._str < s2._str;
}
std::wstringstream& operator<<(std::wstringstream& out, utf8string const& str)
{
out.write(str.c_wcs().c_str(), str.length());
return out;
}
std::wstringstream& operator<<(std::wstringstream& out, utf8string::str_t const& str)
{
out.write(str.c_str(), str.length());
return out;
}
std::wstringstream& operator<<(std::wstringstream& out, const utf8string::char_t* str)
{
out.write(str, wcslen(str));
return out;
}
/*****************************************************************************************/
/*****************************************************************************************/
class StrAccess
{
public:
StrAccess(utf8string const& s) : str(s._str) {};
std::wstring const& str;
};
// case IN-sensitive
bool StrCmp::Equal(const char* s1, const char* s2)
{
_StrCmp::Advance(s1,s2);
return _StrCmp::Equal(s1,s2);
}
bool StrCmp::Equal(std::string const& s1, std::string const& s2)
{
const char* p1 = s1.c_str();
const char* p2 = s2.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::Equal(std::string const& s1, const char* s2)
{
const char* p1 = s1.c_str();
_StrCmp::Advance(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::Equal(const char* s1, std::string const& s2)
{
const char* p2 = s2.c_str();
_StrCmp::Advance(s1,p2);
return _StrCmp::Equal(s1,p2);
}
//
bool StrCmp::Equal(const wchar_t* s1, const wchar_t* s2)
{
_StrCmp::Advance(s1,s2);
return _StrCmp::Equal(s1,s2);
}
bool StrCmp::Equal(std::wstring const& s1, std::wstring const& s2)
{
const wchar_t* p1 = s1.c_str();
const wchar_t* p2 = s2.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::Equal(std::wstring const& s1, const wchar_t* s2)
{
const wchar_t* p1 = s1.c_str();
_StrCmp::Advance(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::Equal(const wchar_t* s1, std::wstring const& s2)
{
const wchar_t* p2 = s2.c_str();
_StrCmp::Advance(s1,p2);
return _StrCmp::Equal(s1,p2);
}
//
bool StrCmp::Equal(utf8string const& s1, utf8string const& s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::Equal(utf8string const& s1, std::wstring const& s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
const wchar_t* p2 = s2.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::Equal(std::wstring const& s1, utf8string const& s2)
{
const wchar_t* p1 = s1.c_str();
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::Advance(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::Equal(utf8string const& s1, const wchar_t* s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
_StrCmp::Advance(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::Equal(const wchar_t* s1, utf8string const& s2)
{
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::Advance(s1,p2);
return _StrCmp::Equal(s1,p2);
}
// case Sensitive
bool StrCmp::EqualCase(const char* s1, const char* s2)
{
_StrCmp::AdvanceCase(s1,s2);
return _StrCmp::Equal(s1,s2);
}
bool StrCmp::EqualCase(std::string const& s1, std::string const& s2)
{
const char* p1 = s1.c_str();
const char* p2 = s2.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::EqualCase(std::string const& s1, const char* s2)
{
const char* p1 = s1.c_str();
_StrCmp::AdvanceCase(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::EqualCase(const char* s1, std::string const& s2)
{
const char* p2 = s2.c_str();
_StrCmp::AdvanceCase(s1,p2);
return _StrCmp::Equal(s1,p2);
}
//
bool StrCmp::EqualCase(const wchar_t* s1, const wchar_t* s2)
{
_StrCmp::AdvanceCase(s1,s2);
return _StrCmp::Equal(s1,s2);
}
bool StrCmp::EqualCase(std::wstring const& s1, std::wstring const& s2)
{
const wchar_t* p1 = s1.c_str();
const wchar_t* p2 = s2.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::EqualCase(std::wstring const& s1, const wchar_t* s2)
{
const wchar_t* p1 = s1.c_str();
_StrCmp::AdvanceCase(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::EqualCase(const wchar_t* s1, std::wstring const& s2)
{
const wchar_t* p2 = s2.c_str();
_StrCmp::AdvanceCase(s1,p2);
return _StrCmp::Equal(s1,p2);
}
//
bool StrCmp::EqualCase(utf8string const& s1, utf8string const& s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::EqualCase(utf8string const& s1, std::wstring const& s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
const wchar_t* p2 = s2.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::EqualCase(std::wstring const& s1, utf8string const& s2)
{
const wchar_t* p1 = s1.c_str();
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::AdvanceCase(p1,p2);
return _StrCmp::Equal(p1,p2);
}
bool StrCmp::EqualCase(utf8string const& s1, const wchar_t* s2)
{
const wchar_t* p1 = StrAccess(s1).str.c_str();
_StrCmp::AdvanceCase(p1,s2);
return _StrCmp::Equal(p1,s2);
}
bool StrCmp::EqualCase(const wchar_t* s1, utf8string const& s2)
{
const wchar_t* p2 = StrAccess(s2).str.c_str();
_StrCmp::AdvanceCase(s1,p2);
return _StrCmp::Equal(s1,p2);
}
+125
View File
@@ -0,0 +1,125 @@
#ifndef _UTF8STRING_H_
#define _UTF8STRING_H_
#include <string>
#include <sstream>
// simple UTF8 wrapper, uses utf8 implementation from http://utfcpp.sourceforge.net/
class utf8string
{
friend bool operator<(utf8string const& s1, utf8string const& s2);
friend class StrAccess;
public:
typedef std::wstring str_t;
typedef std::wstring::value_type char_t;
typedef std::wstring::value_type* ptr_t;
typedef std::wstring::size_type size_t;
////////////////////////////////////////////////////////////////////
static bool less(utf8string const& s1, const utf8string& s2);
static bool equal(utf8string const& s1, const utf8string& s2);
static bool equal(utf8string const& s1, const utf8string::str_t& s2);
static bool equal(utf8string const& s1, const utf8string::char_t* s2);
// case sensitive
static bool lessCase(utf8string const& s1, utf8string const& s2);
static bool equalCase(utf8string const& s1, const utf8string& s2);
static bool equalCase(utf8string const& s1, const utf8string::str_t& s2);
static bool equalCase(utf8string const& s1, const utf8string::char_t* s2);
template<bool (*funName)(utf8string const& s1, utf8string const& s2)>
class Op{
public:
bool operator()(utf8string const& s1, utf8string const& s2) const
{
return funName(s1,s2);
}
};
typedef Op<utf8string::less> Less;
typedef Op<utf8string::lessCase> LessCase;
typedef Op<utf8string::equal> Equal;
typedef Op<utf8string::equalCase> EqualCase;
public:
utf8string();
utf8string(const char* str);
utf8string(std::string const& str);
utf8string(const wchar_t* str);
utf8string(std::wstring const& str);
////////////////////////////////////////////////////////////////////
static utf8string::str_t as_utf16(const char* str);
static void as_utf16(const char* str, utf8string::str_t &str16);
static utf8string::str_t as_utf16(std::string const& str);
static void as_utf16(std::string const& str, utf8string::str_t &str16);
// fast conversion without creating an internal copy
static std::string as_utf8(utf8string const& str);
static std::string as_utf8(std::wstring const& str);
// if 'strlen' is 0, length is determined automatically
static std::string as_utf8(const wchar_t* str, unsigned int strlength=0);
//
// convenience method, for the case it should be used in generic code (overloading)
static std::string as_utf8(std::string const& str);
////////////////////////////////////////////////////////////////////
// convert string to UTF8 encoding
inline std::string utf8() const;
// returns const reference to copy or compare string
inline std::wstring const& c_wcs() const;
// returns reference to modify string
std::wstring& r_wcs();
////////////////////////////////////////////////////////////////////
bool empty() const;
inline utf8string::size_t length() const;
////////////////////////////////////////////////////////////////////
utf8string operator+(utf8string const& str);
utf8string operator+=(utf8string const& str);
private:
std::wstring _str;
};
bool operator<(utf8string const& s1, utf8string const& s2);
std::wstringstream& operator<<(std::wstringstream& out, utf8string const& str);
std::wstringstream& operator<<(std::wstringstream& out, utf8string::str_t const& str);
std::wstringstream& operator<<(std::wstringstream& out, const utf8string::char_t* str);
// explicit compare
namespace StrCmp
{
// case IN-sensitive
bool Equal(const char* s1, const char* s2);
bool Equal(std::string const& s1, std::string const& s2);
bool Equal(std::string const& s1, const char* s2);
bool Equal(const char* s1, std::string const& s2);
//
bool Equal(const wchar_t* s1, const wchar_t* s2);
bool Equal(std::wstring const& s1, std::wstring const& s2);
bool Equal(std::wstring const& s1, const wchar_t* s2);
bool Equal(const wchar_t* s1, std::wstring const& s2);
//
bool Equal(utf8string const& s1, utf8string const& s2);
bool Equal(utf8string const& s1, std::wstring const& s2);
bool Equal(std::wstring const& s1, utf8string const& s2);
bool Equal(utf8string const& s1, const wchar_t* s2);
bool Equal(const wchar_t* s1, utf8string const& s2);
// case Sensitive
bool EqualCase(const char* s1, const char* s2);
bool EqualCase(std::string const& s1, std::string const& s2);
bool EqualCase(std::string const& s1, const char* s2);
bool EqualCase(const char* s1, std::string const& s2);
//
bool EqualCase(const wchar_t* s1, const wchar_t* s2);
bool EqualCase(std::wstring const& s1, std::wstring const& s2);
bool EqualCase(std::wstring const& s1, const wchar_t* s2);
bool EqualCase(const wchar_t* s1, std::wstring const& s2);
//
bool EqualCase(utf8string const& s1, utf8string const& s2);
bool EqualCase(utf8string const& s1, std::wstring const& s2);
bool EqualCase(std::wstring const& s1, utf8string const& s2);
bool EqualCase(utf8string const& s1, const wchar_t* s2);
bool EqualCase(const wchar_t* s1, utf8string const& s2);
}
#endif // _UTF8STRING_H_
+590
View File
@@ -0,0 +1,590 @@
#include "vfs_types.h"
#include "vfs.h"
#include "Interface/vfs_file_interface.h"
#include "File/vfs_file.h"
#include "File/vfs_dir_file.h"
#include "File/vfs_lib_file.h"
#include "vfs_file_raii.h"
#include "vfs_vfile.h"
#include "PropertyContainer.h"
#include <stack>
std::vector<BasicAllocator*> CFileAllocator::_valloc;
void CFileAllocator::RegisterAllocator(BasicAllocator* allocator)
{
_valloc.push_back(allocator);
}
void CFileAllocator::Clear()
{
std::vector<BasicAllocator*>::iterator it = _valloc.begin();
for(; it != _valloc.end(); ++it)
{
delete *it;
*it = NULL;
}
_valloc.clear();
}
/********************************************************************/
/********************************************************************/
vfs::CVirtualFileSystem::CRegularIterator::CRegularIterator(vfs::CVirtualFileSystem& rVFS)
: vfs::CVirtualFileSystem::Iterator::IImplemetation(), m_rVFS(rVFS)
{
_vloc_iter = m_rVFS.m_mapFS.begin();
if(_vloc_iter != m_rVFS.m_mapFS.end())
{
_vfile_iter = _vloc_iter->second->iterate();
}
}
vfs::CVirtualFileSystem::CRegularIterator::~CRegularIterator()
{
}
vfs::tReadableFile* vfs::CVirtualFileSystem::CRegularIterator::value()
{
bool bExclusiveVLoc = false;
if(_vloc_iter != m_rVFS.m_mapFS.end())
{
bExclusiveVLoc = _vloc_iter->second->GetIsExclusive();
}
if(!_vfile_iter.end())
{
vfs::CVirtualFile* pVFile = _vfile_iter.value();
if(pVFile)
{
if(bExclusiveVLoc)
{
return vfs::tReadableFile::Cast(pVFile->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE));
}
else
{
return vfs::tReadableFile::Cast(pVFile->File(vfs::CVirtualFile::SF_TOP));
}
}
}
return NULL;
}
void vfs::CVirtualFileSystem::CRegularIterator::next()
{
if(!_vfile_iter.end())
{
_vfile_iter.next();
}
while(_vfile_iter.end())
{
if(_vloc_iter != m_rVFS.m_mapFS.end())
{
_vloc_iter++;
if(_vloc_iter != m_rVFS.m_mapFS.end())
{
_vfile_iter = _vloc_iter->second->iterate();
}
}
else
{
return;
}
}
}
/********************************************************************/
/********************************************************************/
vfs::CVirtualFileSystem::CMatchingIterator::CMatchingIterator(vfs::Path const& sPattern, vfs::CVirtualFileSystem& rVFS)
: vfs::CVirtualFileSystem::Iterator::IImplemetation(), m_rVFS(rVFS)
{
if(sPattern() == vfs::Const::STAR())
{
m_sLocPattern = vfs::Path(vfs::Const::STAR());
m_sFilePattern = vfs::Path(vfs::Const::STAR());
}
else
{
sPattern.SplitLast(m_sLocPattern,m_sFilePattern);
}
_vloc_iter = m_rVFS.m_mapFS.begin();
while(_vloc_iter != m_rVFS.m_mapFS.end())
{
if( MatchPattern(m_sLocPattern(),_vloc_iter->second->Path()) )
{
bool bExclusiveVLoc = _vloc_iter->second->GetIsExclusive();
_vfile_iter = _vloc_iter->second->iterate();
while(!_vfile_iter.end())
{
vfs::IBaseFile* pFile = NULL;
if(bExclusiveVLoc)
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
else
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_TOP);
}
if(pFile)
{
vfs::Path const& filename = pFile->GetFileName();
if( MatchPattern(m_sFilePattern(),filename()) )
{
return;
}
}
_vfile_iter.next();
}
}
_vloc_iter++;
}
}
vfs::CVirtualFileSystem::CMatchingIterator::~CMatchingIterator()
{
}
vfs::tReadableFile* vfs::CVirtualFileSystem::CMatchingIterator::value()
{
bool bExclusiveVLoc = false;
if( _vloc_iter != m_rVFS.m_mapFS.end() )
{
bExclusiveVLoc = _vloc_iter->second->GetIsExclusive();
}
if(!_vfile_iter.end())
{
vfs::CVirtualFile* pVFile = _vfile_iter.value();
if(pVFile)
{
vfs::IBaseFile* pFile = NULL;
if(bExclusiveVLoc)
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
else
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_TOP);
}
return vfs::tReadableFile::Cast(pFile);
}
}
return NULL;
}
bool vfs::CVirtualFileSystem::CMatchingIterator::nextLocationMatch()
{
while(_vloc_iter != m_rVFS.m_mapFS.end())
{
_vloc_iter++;
if(_vloc_iter != m_rVFS.m_mapFS.end())
{
if(MatchPattern(m_sLocPattern(),_vloc_iter->second->Path()))
{
return true;
}
}
}
return false;
}
bool vfs::CVirtualFileSystem::CMatchingIterator::nextFileMatch()
{
bool bExclusiveVLoc = false;
if( _vloc_iter != m_rVFS.m_mapFS.end() )
{
bExclusiveVLoc = _vloc_iter->second->GetIsExclusive();
}
while(!_vfile_iter.end())
{
_vfile_iter.next();
if(!_vfile_iter.end())
{
vfs::IBaseFile* pFile = NULL;
if(bExclusiveVLoc)
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
else
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_TOP);
}
if(pFile)
{
vfs::Path const& filename = pFile->GetFileName();
if(MatchPattern(m_sFilePattern(),filename()))
{
return true;
}
}
}
}
return false;
}
void vfs::CVirtualFileSystem::CMatchingIterator::next()
{
if(nextFileMatch())
{
return;
}
while(nextLocationMatch())
{
_vfile_iter = _vloc_iter->second->iterate();
if(!_vfile_iter.end())
{
bool bExclusiveVLoc = _vloc_iter->second->GetIsExclusive();
vfs::IBaseFile* pFile = NULL;
if(bExclusiveVLoc)
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
else
{
pFile = _vfile_iter.value()->File(vfs::CVirtualFile::SF_TOP);
}
if(pFile && MatchPattern(m_sFilePattern(),pFile->GetFileName()()))
{
return;
}
else if(nextFileMatch())
{
return;
}
}
}
}
/********************************************************************/
/********************************************************************/
vfs::CVirtualFileSystem::Iterator::Iterator()
: _iter_impl(NULL), _file(NULL)
{};
vfs::CVirtualFileSystem::Iterator::Iterator(vfs::CVirtualFileSystem::Iterator::IImplemetation* impl)
: _iter_impl(impl), _file(NULL)
{
THROWIFFALSE(_iter_impl, L"EXCEPTION");
_file = _iter_impl->value();
}
vfs::CVirtualFileSystem::Iterator::~Iterator()
{
}
vfs::tReadableFile* vfs::CVirtualFileSystem::Iterator::value()
{
return _file;
};
void vfs::CVirtualFileSystem::Iterator::next()
{
if(_iter_impl)
{
_iter_impl->next();
_file = _iter_impl->value();
if(!_file)
{
delete _iter_impl;
_iter_impl = NULL;
}
}
}
bool vfs::CVirtualFileSystem::Iterator::end()
{
return _file == NULL;
}
/********************************************************************/
/********************************************************************/
vfs::CVirtualFileSystem* GetVFS()
{
return vfs::CVirtualFileSystem::GetVFS();
}
vfs::CVirtualFileSystem* vfs::CVirtualFileSystem::m_pSingleton = NULL;
vfs::CVirtualFileSystem* vfs::CVirtualFileSystem::GetVFS()
{
if(!m_pSingleton)
{
m_pSingleton = new CVirtualFileSystem();
}
return m_pSingleton;
}
void vfs::CVirtualFileSystem::ShutdownVFS()
{
if(m_pSingleton)
{
delete m_pSingleton;
m_pSingleton = NULL;
}
}
vfs::CVirtualFileSystem::CVirtualFileSystem()
{
}
vfs::CVirtualFileSystem::~CVirtualFileSystem()
{
tVFS::iterator it = m_mapFS.begin();
for(; it != m_mapFS.end(); ++it)
{
delete it->second;
}
m_mapFS.clear();
}
vfs::CProfileStack* vfs::CVirtualFileSystem::GetProfileStack()
{
return &m_oProfileStack;
}
vfs::CVirtualFileSystem::Iterator vfs::CVirtualFileSystem::begin()
{
return Iterator(new vfs::CVirtualFileSystem::CRegularIterator(*this));
}
vfs::CVirtualFileSystem::Iterator vfs::CVirtualFileSystem::begin(vfs::Path const& sPattern)
{
return Iterator(new vfs::CVirtualFileSystem::CMatchingIterator(sPattern,*this));
}
bool vfs::CVirtualFileSystem::AddLocation(vfs::IBaseLocation* pLocation, utf8string const& sProfileName, bool bIsWriteable)
{
vfs::CVirtualProfile *pProf = m_oProfileStack.GetProfile(sProfileName);
if(!pProf)
{
pProf = new vfs::CVirtualProfile(sProfileName, bIsWriteable);
m_oProfileStack.PushProfile(pProf);
}
pProf->AddLocation(pLocation);
std::list<vfs::Path> lSubDirs;
pLocation->GetSubDirList(lSubDirs);
std::list<vfs::Path>::const_iterator sd_cit = lSubDirs.begin();
for(;sd_cit != lSubDirs.end(); ++sd_cit)
{
this->GetVirtualLocation(*sd_cit, true);
}
vfs::IBaseLocation::Iterator it = pLocation->begin();
for(; !it.end(); it.next())
{
vfs::IBaseFile *pFile = it.value();
vfs::Path const& sPath = pFile->GetFullPath();
vfs::Path dir,file;
sPath.SplitLast(dir,file);
CVirtualLocation* pLoc = this->GetVirtualLocation(dir,true);
pLoc->AddFile(pFile,sProfileName);
}
return true;
}
vfs::tReadableFile* vfs::CVirtualFileSystem::GetRFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF)
{
return vfs::tReadableFile::Cast(this->GetFile(rLocalFilePath,eSF));
}
vfs::tWriteableFile* vfs::CVirtualFileSystem::GetWFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF)
{
return vfs::tWriteableFile::Cast(this->GetFile(rLocalFilePath,eSF));
}
vfs::IBaseFile* vfs::CVirtualFileSystem::GetFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF)
{
vfs::Path sDir,sFile;
rLocalFilePath.SplitLast(sDir,sFile);
vfs::CVirtualLocation* pVLoc = this->GetVirtualLocation(sDir);
if(pVLoc)
{
vfs::CVirtualFile *pVFile = pVLoc->GetVFile(sFile);
if(pVFile)
{
if(pVLoc->GetIsExclusive())
{
return pVFile->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
return pVFile->File(eSF);
}
}
return NULL;
}
vfs::tReadableFile* vfs::CVirtualFileSystem::GetRFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName)
{
return vfs::tReadableFile::Cast(this->GetFile(rLocalFilePath, sProfileName));
}
vfs::tWriteableFile* vfs::CVirtualFileSystem::GetWFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName)
{
return vfs::tWriteableFile::Cast(this->GetFile(rLocalFilePath, sProfileName));
}
vfs::IBaseFile* vfs::CVirtualFileSystem::GetFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName)
{
vfs::Path sDir,sFile;
rLocalFilePath.SplitLast(sDir,sFile);
tVFS::iterator it_loc = m_mapFS.find(sDir);
if(it_loc == m_mapFS.end())
{
return NULL;
}
vfs::CVirtualLocation* pVLoc = it_loc->second;
if(pVLoc)
{
return pVLoc->GetFile(sFile,sProfileName);
}
return NULL;
}
bool vfs::CVirtualFileSystem::FileExists(vfs::Path const& rLocalFilePath, std::string const& sProfileName)
{
return GetFile(rLocalFilePath, sProfileName) != NULL;
}
bool vfs::CVirtualFileSystem::FileExists(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF)
{
return GetFile(rLocalFilePath, eSF) != NULL;
}
vfs::CVirtualLocation* vfs::CVirtualFileSystem::GetVirtualLocation(vfs::Path const& sPath, bool bCreate)
{
tVFS::iterator it = m_mapFS.find(sPath);
if(it == m_mapFS.end())
{
if(bCreate)
{
vfs::CVirtualLocation* pVLoc = new vfs::CVirtualLocation(sPath);
m_mapFS.insert(std::make_pair(sPath,pVLoc));
return pVLoc;
}
return NULL;
}
return it->second;
}
bool vfs::CVirtualFileSystem::RemoveDirectoryFromFS(vfs::Path const& sDir)
{
vfs::Path pattern = sDir + "*";
std::list<vfs::Path> files;
Iterator it = this->begin(pattern);
for(; !it.end(); it.next())
{
if(it.value()->IsWriteable())
{
files.push_back(it.value()->GetFullPath());
}
}
bool success = true;
std::list<vfs::Path>::iterator fit = files.begin();
for(; fit != files.end(); ++fit)
{
success &= this->RemoveFileFromFS(*fit);
}
return success;
}
bool vfs::CVirtualFileSystem::RemoveFileFromFS(vfs::Path const& sFilePath)
{
vfs::Path sPath,sFile;
sFilePath.SplitLast(sPath,sFile);
vfs::CVirtualProfile *pProf = m_oProfileStack.GetWriteProfile();
if(pProf)
{
vfs::IBaseLocation *pBL = pProf->GetLocation(sPath);
if(pBL && pBL->IsWriteable())
{
vfs::IDirectory<vfs::IWriteable> *pDir = pBL->Cast<vfs::IDirectory<vfs::IWriteable> >();
if(pDir)
{
bool bSuccess = false;
// remove file from virtual structures first
vfs::IBaseFile* file = pDir->GetFile(sFilePath);
if(file)
{
vfs::Path sDir,sFile;
sFilePath.SplitLast(sDir,sFile);
vfs::CVirtualLocation *pVLoc = this->GetVirtualLocation(sDir);
if(pVLoc)
{
bSuccess = pVLoc->RemoveFile(file);
}
}
// delete actual file
return bSuccess && pDir->DeleteFileFromDirectory(sFilePath);
}
}
}
return false;
}
bool vfs::CVirtualFileSystem::CreateNewFile(vfs::Path const& sFileName)
{
vfs::Path sPath,sFile;
sFileName.SplitLast(sPath,sFile);
vfs::CVirtualProfile *pProf = m_oProfileStack.GetWriteProfile();
if(pProf)
{
bool bIsExclusive = false;
bool bNewLocation = false;
vfs::IBaseLocation *pProfLoc = pProf->GetLocation(sPath);
if(!pProfLoc)
{
// try to find closest match
vfs::Path sTemp, sCreateDir, sRight, sLeft = sPath;
while(!pProfLoc && sLeft.SplitLast(sTemp,sRight))
{
sLeft = sTemp;
sCreateDir = sRight + sCreateDir;
pProfLoc = pProf->GetLocation(sLeft);
}
// see if the closest match is exclusive
// if yes, then the the new path is a subdirectory and has to be exclusive too
vfs::CVirtualLocation *pVLoc = this->GetVirtualLocation(sLeft);
if(pVLoc)
{
bIsExclusive = pVLoc->GetIsExclusive();
}
else
{
THROWEXCEPTION(L"location (closest match) should exist");
}
bNewLocation = true;
}
if(pProfLoc && pProfLoc->IsWriteable())
{
// create file and add to location
vfs::IDirectory<vfs::IWriteable> *pDir = pProfLoc->Cast<vfs::IDirectory<vfs::IWriteable> >();
vfs::IBaseFile* pFile = pDir->AddFile(sFileName);
if(bNewLocation)
{
pProf->AddLocation(pProfLoc);
}
if(pFile)
{
CVirtualLocation* pLoc = this->GetVirtualLocation(sPath,true);
if(bIsExclusive)
{
pLoc->SetIsExclusive(bIsExclusive);
}
pLoc->AddFile(pFile,pProf->Name);
return true;
}
}
}
// throw ?
return false;
}
/************************************************************************************************/
+135
View File
@@ -0,0 +1,135 @@
#ifndef _VFS_H_
#define _VFS_H_
#include "Interface/vfs_file_interface.h"
#include "Interface/vfs_location_interface.h"
#include "vfs_vloc.h"
#include "vfs_vfile.h"
#include "vfs_types.h"
#include <map>
#define USE_VFS
class CFileAllocator
{
public:
static void RegisterAllocator(BasicAllocator* allocator);
static void Clear();
private:
static std::vector<BasicAllocator*> _valloc;
};
namespace vfs
{
class CProfileStack;
class CVirtualFileSystem
{
typedef std::map<vfs::Path,CVirtualLocation*,vfs::Path::Less> tVFS;
public:
/*****************************************************/
class Iterator
{
public:
//////////////////////////////
class IImplemetation
{
public:
virtual ~IImplemetation() {};
virtual vfs::tReadableFile* value() = 0;
virtual void next() = 0;
};
//////////////////////////////
private:
friend class CVirtualFileSystem;
Iterator(IImplemetation* impl);
public:
Iterator();
~Iterator();
vfs::tReadableFile* value();
void next();
bool end();
private:
IImplemetation* _iter_impl;
vfs::tReadableFile* _file;
};
/*****************************************************/
class CRegularIterator : public vfs::CVirtualFileSystem::Iterator::IImplemetation
{
public:
CRegularIterator(vfs::CVirtualFileSystem& rVFS);
virtual ~CRegularIterator();
virtual vfs::tReadableFile* value();
virtual void next();
private:
vfs::CVirtualFileSystem& m_rVFS;
vfs::CVirtualFileSystem::tVFS::iterator _vloc_iter;
CVirtualLocation::Iterator _vfile_iter;
};
/*****************************************************/
class CMatchingIterator : public vfs::CVirtualFileSystem::Iterator::IImplemetation
{
public:
CMatchingIterator(vfs::Path const& sPattern, vfs::CVirtualFileSystem& rVFS);
virtual ~CMatchingIterator();
virtual vfs::tReadableFile* value();
virtual void next();
private:
bool nextLocationMatch();
bool nextFileMatch();
private:
vfs::Path m_sLocPattern, m_sFilePattern;
vfs::CVirtualFileSystem& m_rVFS;
vfs::CVirtualFileSystem::tVFS::iterator _vloc_iter;
CVirtualLocation::Iterator _vfile_iter;
};
/*****************************************************/
public:
~CVirtualFileSystem();
static CVirtualFileSystem* GetVFS();
static void ShutdownVFS();
CProfileStack* GetProfileStack();
vfs::CVirtualLocation* GetVirtualLocation(vfs::Path const& sPath, bool bCreate = false);
bool AddLocation(vfs::IBaseLocation* pLocation,
utf8string const& sProfileName,
bool bIsWriteable = false);
bool FileExists(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_TOP );
bool FileExists(vfs::Path const& rLocalFilePath, std::string const& sProfileName);
vfs::IBaseFile* GetFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_TOP );
vfs::IBaseFile* GetFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName);
vfs::tReadableFile* GetRFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_TOP );
vfs::tReadableFile* GetRFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName);
vfs::tWriteableFile* GetWFile(vfs::Path const& rLocalFilePath, vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_TOP );
vfs::tWriteableFile* GetWFile(vfs::Path const& rLocalFilePath, utf8string const& sProfileName);
bool RemoveFileFromFS(vfs::Path const& sFilePath);
bool RemoveDirectoryFromFS(vfs::Path const& sDir);
bool CreateNewFile(vfs::Path const& sFileName);
Iterator begin();
Iterator begin(vfs::Path const& sPattern);
private:
CProfileStack m_oProfileStack;
tVFS m_mapFS;
private:
CVirtualFileSystem();
static CVirtualFileSystem* m_pSingleton;
};
} // end namespace
vfs::CVirtualFileSystem* GetVFS();
#endif // _VFS_H_
+144
View File
@@ -0,0 +1,144 @@
#include "vfs_debug.h"
#include "utf8string.h"
#include "PropertyContainer.h"
#include "vfs_file_raii.h"
#include "FILE/vfs_file.h"
#include <sstream>
#include <ctime>
CBasicException::CBasicException(const wchar_t* text, const char* function, int line, const char* file, CBasicException* ex)
: std::exception(utf8string::as_utf8(text).c_str())
{
if(ex)
{
m_CallStack.insert(m_CallStack.end(), ex->m_CallStack.begin(), ex->m_CallStack.end());
}
_LINE = line;
_FILE = file;
_FUNCTION = function;
time_t rawtime;
time ( &rawtime );
std::string datetime(ctime(&rawtime));
IGNOREEXCEPTION(_time = utf8string(datetime.substr(0,datetime.length()-1)));
SEntry en;
en.message = text;
en.line = line;
en.file = file;
en.function = function;
en.time = _time;
m_CallStack.push_back(en);
};
CBasicException::CBasicException(utf8string const& text, utf8string const& function, int line, const char* file, CBasicException* ex)
: std::exception(text.utf8().c_str())
{
if(ex)
{
m_CallStack.insert(m_CallStack.end(), ex->m_CallStack.begin(), ex->m_CallStack.end());
}
_LINE = line;
_FILE = file;
_FUNCTION = function;
time_t rawtime;
time ( &rawtime );
std::string datetime(ctime(&rawtime));
IGNOREEXCEPTION(_time = utf8string(datetime.substr(0,datetime.length()-1)));
SEntry en;
en.message = text;
en.line = line;
en.file = file;
en.function = function;
en.time = _time;
m_CallStack.push_back(en);
};
utf8string CBasicException::GetLastEntryString() const
{
if(!m_CallStack.empty())
{
CALLSTACK::const_reverse_iterator rit = m_CallStack.rbegin();
std::wstringstream ss;
ss << rit->file.c_wcs() << L" (l. " << rit->line<< ") : [" << rit->function.c_wcs() << L"] - " << rit->message.c_wcs();
return ss.str();
}
return "";
}
utf8string CBasicException::GetExceptionString() const
{
if(!m_CallStack.empty())
{
std::wstringstream wss;
CALLSTACK::const_reverse_iterator rit = m_CallStack.rbegin();
for(; rit != m_CallStack.rend(); ++rit)
{
wss << L"========== " << rit->time << L" ==========\r\n";
wss << L"File : " << rit->file << L"\r\n";
wss << L"Line : " << rit->line << L"\r\n";
wss << L"Location : " << rit->function << L"\r\n\r\n";
wss << L" " << rit->message << L"\r\n\r\n";
}
return wss.str();
}
return L"";
}
void CBasicException::WriteFile(vfs::Path const& sPath)
{
try
{
vfs::COpenWriteFile oFile(sPath,true,true);
utf8string s = this->GetExceptionString();
vfs::UInt32 written;
oFile.file().Write(s.utf8().c_str(),s.length(),written);
oFile.file().Close();
}
catch(CBasicException &ex)
{
CBasicException ex2(L"Could not write exception file into VFS",
_FUNCTION_FORMAT_,__LINE__,__FILE__, &ex);
CBasicException out("Writing exception to disc failed : is there no writeable profile?",
_FUNCTION_FORMAT_,__LINE__,__FILE__, this);
out.m_CallStack.insert(out.m_CallStack.begin(),ex.m_CallStack.begin(),ex.m_CallStack.end());
vfs::Path sDir,sFile;
sPath.SplitLast(sDir,sFile);
vfs::CFile oFile(sFile);
try
{
// can also fail, but there is only so much we can do
vfs::COpenWriteFile file( vfs::tWriteableFile::Cast(&oFile) );
utf8string s = out.GetExceptionString();
vfs::UInt32 written;
file.file().Write(s.utf8().c_str(),s.length(),written);
}
catch(CBasicException &fex)
{
RETHROWEXCEPTION(L"Could write exception file at all",&fex);
}
}
}
void LogException(CBasicException const& ex)
{
static CLog& exlog = *CLog::Create(L"game_exceptions.log");
try
{
exlog << ">>>>>>>>>>>>>>>>>>>>>" << CLog::endl;
exlog << ex.GetExceptionString();
exlog << "<<<<<<<<<<<<<<<<<<<<<" << CLog::endl << CLog::endl;
}
catch(...)
{
// don't throw at all
}
}
+61
View File
@@ -0,0 +1,61 @@
#ifndef _VFS_DEBUG_H_
#define _VFS_DEBUG_H_
#include "vfs_types.h"
#include <list>
class CBasicException : public std::exception
{
public:
CBasicException(const wchar_t* text, const char* function, int line, const char* file, CBasicException* ex=NULL);
CBasicException(utf8string const& text, utf8string const& function, int line, const char* file, CBasicException* ex=NULL);
utf8string GetLastEntryString() const;
utf8string GetExceptionString() const;
void WriteFile(vfs::Path const& sPath);
struct SEntry
{
utf8string time;
utf8string message;
utf8string function;
int line;
utf8string file;
};
typedef std::list<SEntry> CALLSTACK;
CALLSTACK m_CallStack;
int _LINE;
utf8string _FILE;
utf8string _FUNCTION;
utf8string _time;
};
void LogException(CBasicException const& ex);
#ifdef WIN32
#define _FUNCTION_FORMAT_ __FUNCTION__
#else
//#define _FUNCTION_FORMAT_ __FUNCTION__
#define _FUNCTION_FORMAT_ __PRETTY_FUNCTION__
#endif
#define THROWEXCEPTION(message) throw CBasicException((message), _FUNCTION_FORMAT_, __LINE__, __FILE__, NULL)
#define RETHROWEXCEPTION(message,ex) throw CBasicException((message), _FUNCTION_FORMAT_, __LINE__, __FILE__, (ex))
#define THROWIFFALSE(boolexpr,message) if(!(boolexpr)){THROWEXCEPTION((message));}
#define TRYCATCH_RETHROW(expr,message) \
{ \
try { (expr); } \
catch(CBasicException &ex){ throw CBasicException((message),_FUNCTION_FORMAT_,__LINE__,__FILE__,&ex); } \
}
#define IGNOREEXCEPTION(expr) \
{ \
try{ (expr); } \
catch(CBasicException& ex){ LogException(ex); } \
}
#endif // _VFS_DEBUG_H_
+121
View File
@@ -0,0 +1,121 @@
#include "vfs_file_raii.h"
#include "vfs.h"
#include <sstream>
/********************************************************************************************/
/********************************************************************************************/
vfs::COpenReadFile::COpenReadFile(vfs::Path const& sPath, vfs::CVirtualFile::ESearchFile eSF)
{
vfs::IBaseFile *pFile = GetVFS()->GetFile(sPath,eSF);
THROWIFFALSE(pFile, (L"file \"" + sPath().c_wcs() + L"\" does not exist").c_str());
m_pFile = vfs::tReadableFile::Cast(pFile);
THROWIFFALSE(m_pFile, L"not readable");
THROWIFFALSE(m_pFile->OpenRead(), L"open read failed");
}
vfs::COpenReadFile::COpenReadFile(vfs::tReadableFile *pFile)
{
try
{
m_pFile = pFile;
THROWIFFALSE(m_pFile, L"no file");
THROWIFFALSE(m_pFile->OpenRead(), L"not open");
}
catch(CBasicException &ex)
{
RETHROWEXCEPTION(L"",&ex);
}
}
vfs::COpenReadFile::~COpenReadFile()
{
if(m_pFile)
{
m_pFile->Close();
m_pFile = NULL;
}
}
vfs::tReadableFile& vfs::COpenReadFile::file()
{
return *m_pFile;
}
void vfs::COpenReadFile::release()
{
m_pFile = NULL;
}
/**************************************************************************/
vfs::COpenWriteFile::COpenWriteFile(vfs::Path const& sPath,
bool bCreate,
bool bTruncate,
vfs::CVirtualFile::ESearchFile eSF)
{
vfs::IBaseFile *pFile = GetVFS()->GetFile(sPath,eSF);
if(!pFile && bCreate)
{
if(GetVFS()->CreateNewFile(sPath))
{
pFile = GetVFS()->GetFile(sPath,eSF);
}
else
{
std::wstringstream wss;
wss << L"Could not create VFS file \"" << sPath().c_wcs() << L"\"";
THROWEXCEPTION(wss.str().c_str());
}
}
if(!pFile)
{
std::wstringstream wss;
wss << L"File \"" << sPath().c_wcs() << L"\" not found";
THROWEXCEPTION(wss.str().c_str());
}
m_pFile = vfs::tWriteableFile::Cast(pFile);
if(!m_pFile)
{
std::wstringstream wss;
wss << L"File \"" << sPath().c_wcs() << L"\" exists, but is not writeable";
THROWEXCEPTION(wss.str().c_str());
}
if(!m_pFile->OpenWrite(bCreate,bTruncate))
{
std::wstringstream wss;
wss << L"File \"" << sPath().c_wcs() << L"\" could not be opened for writing";
THROWEXCEPTION(wss.str().c_str());
}
}
vfs::COpenWriteFile::COpenWriteFile(vfs::tWriteableFile *pFile)
{
try
{
m_pFile = pFile;
THROWIFFALSE(m_pFile, L"no file");
THROWIFFALSE(m_pFile->OpenWrite(true,false), L"not open");
}
catch(CBasicException& ex)
{
RETHROWEXCEPTION(L"",&ex);
};
}
vfs::COpenWriteFile::~COpenWriteFile()
{
if(m_pFile)
{
m_pFile->Close();
m_pFile = NULL;
}
}
vfs::tWriteableFile& vfs::COpenWriteFile::file()
{
return *m_pFile;
}
void vfs::COpenWriteFile::release()
{
m_pFile = NULL;
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef _VFS_FILE_RAII_H_
#define _VFS_FILE_RAII_H_
#include "Interface/vfs_file_interface.h"
#include "vfs_vfile.h"
namespace vfs
{
class COpenReadFile
{
public:
COpenReadFile(vfs::Path const& sPath, vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_TOP);
COpenReadFile(vfs::tReadableFile *pFile);
~COpenReadFile();
vfs::tReadableFile& file();
void release();
private:
vfs::tReadableFile* m_pFile;
};
class COpenWriteFile
{
public:
COpenWriteFile( vfs::Path const& sPath,
bool bCreate = false,
bool bTruncate = false,
vfs::CVirtualFile::ESearchFile eSF = vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
COpenWriteFile(vfs::tWriteableFile *pFile);
~COpenWriteFile();
vfs::tWriteableFile& file();
void release();
private:
vfs::tWriteableFile* m_pFile;
};
} // end namespace
#endif // _VFS_FILE_RAII_H_
+229
View File
@@ -0,0 +1,229 @@
#include "vfs_init.h"
#include "vfs.h"
#include "PropertyContainer.h"
#include "File/vfs_file.h"
#include "File/vfs_memory_file.h"
#include "Location/vfs_directory_tree.h"
#include "Location/vfs_slf_library.h"
#include "Location/vfs_7z_library.h"
#include "Location/vfs_create_7z_library.h"
/********************************************************************/
/********************************************************************/
bool InitVirtualFileSystem(vfs::Path const& vfs_ini)
{
std::list<vfs::Path> li;
li.push_back(vfs_ini);
return InitVirtualFileSystem(li);
}
bool InitVirtualFileSystem(std::list<vfs::Path> const& vfs_ini_list)
{
CPropertyContainer oVFSProps;
std::list<vfs::Path>::const_iterator clit = vfs_ini_list.begin();
for(; clit != vfs_ini_list.end(); ++clit)
{
oVFSProps.InitFromIniFile(*clit);
}
CLog _LOG(vfs::Path(L"vfs_init.log"));
vfs::CVirtualFileSystem *pVirtFileSys = GetVFS();
_LOG << "Initializing Virtual File System";
_LOG.Endl();
_LOG.Endl() << "reading profiles .. ";
std::list<utf8string> lProfiles, lLocSections;
oVFSProps.GetStringListProperty(L"vfs_config",L"PROFILES",lProfiles,L"");
if(lProfiles.empty())
{
_LOG << " ERROR";
return false;
}
else
{
_LOG << " OK";
}
_LOG.Endl() << " profiles to read : ";
std::list<utf8string>::const_iterator cit_profiles = lProfiles.begin();
for(; cit_profiles != lProfiles.end(); ++cit_profiles)
{
_LOG << (*cit_profiles) << ", ";
}
_LOG.Endl();
std::list<utf8string>::const_iterator prof_cit = lProfiles.begin();
for(; prof_cit != lProfiles.end(); ++prof_cit)
{
_LOG.Endl() << " reading profile [";
utf8string sProfSection = utf8string("PROFILE_") + utf8string(*prof_cit);
utf8string sProfName = oVFSProps.GetStringProperty(sProfSection,L"NAME",L"");
_LOG << sProfName << "] .. ";
vfs::Path profileRoot = oVFSProps.GetStringProperty(sProfSection,L"PROFILE_ROOT",L"");
lLocSections.clear();
oVFSProps.GetStringListProperty(sProfSection,L"LOCATIONS",lLocSections,L"");
_LOG << "OK";
_LOG.Endl() << " locations to read : ";
std::list<utf8string>::const_iterator cit_locations = lLocSections.begin();
for(; cit_locations != lLocSections.end(); ++cit_locations)
{
_LOG << (*cit_locations) << ", ";
}
_LOG.Endl().Endl();
std::list<utf8string>::iterator loc_it = lLocSections.begin();
bool bIsWriteable = oVFSProps.GetBoolProperty(sProfSection,L"WRITE",false);
for(; loc_it != lLocSections.end(); ++loc_it)
{
_LOG << " reading location [ ";
utf8string sLocSection = utf8string("LOC_") + utf8string(*loc_it);
vfs::Path sLocPath, sLocMountPoint;
utf8string sLocType;
sLocPath = oVFSProps.GetStringProperty(sLocSection,"PATH","");
sLocMountPoint = oVFSProps.GetStringProperty(sLocSection,L"MOUNT_POINT",L"");
sLocType = oVFSProps.GetStringProperty(sLocSection,L"TYPE",L"NOT_FOUND");
bool bOptional = oVFSProps.GetBoolProperty(sLocSection,L"OPTIONAL",false);
if(StrCmp::Equal(sLocType,L"LIBRARY"))
{
_LOG << sLocType << " | " << (*loc_it) << " ] .. ";
vfs::tReadableFile *pLibFile = NULL;
bool bOwnFile = false;
if(!sLocPath.empty())
{
pLibFile = vfs::tReadableFile::Cast( new vfs::CFile(profileRoot + sLocPath) );
bOwnFile = true;
}
if(!pLibFile)
{
sLocPath = oVFSProps.GetStringProperty(sLocSection,L"VFS_PATH",L"");
if(!sLocPath.empty())
{
pLibFile = pVirtFileSys->GetRFile(profileRoot + sLocPath);
}
}
if(pLibFile)
{
utf8string full_str = pLibFile->GetFileName()();
utf8string ext = full_str.c_wcs().substr(full_str.length()-3,3);
vfs::ILibrary *pLib = NULL;
if(StrCmp::Equal(ext,L"slf"))
{
pLib = new vfs::CSLFLibrary( pLibFile, sLocMountPoint );
}
else if(StrCmp::Equal(ext,L".7z"))
{
pLib = new vfs::CUncompressed7zLibrary( pLibFile, sLocMountPoint );
}
else
{
_LOG << "ERROR" << CLog::endl;
utf8string::str_t s = L"File [" + utf8string(sLocPath()).c_wcs() + L"] in not an SLF or 7z library";
THROWEXCEPTION(s.c_str());
return false;
}
if(!pLib->Init())
{
if(!bOptional)
{
_LOG << "ERROR" << CLog::endl;
//std::cout << "ERROR : library initialization failed [ " << full_str << " ]" << std::endl;
std::wstring s = L"Could not initialize library [ " + sLocPath().c_wcs()
+ L" ] in : profile [ " + utf8string(sProfName).c_wcs()
+ L" ], location [ " + (*loc_it).c_wcs()
+ L" ], path [ " + (profileRoot + sLocPath)().c_wcs() + L" ]";
THROWEXCEPTION(s.c_str());
return false;
}
_LOG << "optional library ignored" << CLog::endl;
}
else
{
_LOG << "OK" << CLog::endl;
}
pVirtFileSys->AddLocation(vfs::tReadLocation::Cast(pLib), sProfName, bIsWriteable);
}
else
{
_LOG << "ERROR" << CLog::endl;
THROWEXCEPTION(L"File not found");
}
}
else if(StrCmp::Equal(sLocType,L"DIRECTORY"))
{
_LOG << sLocType << " | " << (*loc_it) << " ] .. ";
vfs::CDirectoryTree *pDirTree = new vfs::CDirectoryTree(sLocMountPoint,profileRoot + sLocPath);
if(!pDirTree->Init())
{
_LOG << "ERROR" << CLog::endl;
std::wstring s = L"Could not initialize directory [\"" + sLocPath().c_wcs()
+ L"\"] in : profile [\"" + utf8string(sProfName).c_wcs()
+ L"\"], location [\"" + (*loc_it).c_wcs()
+ L"\"], path [\"" + (profileRoot + sLocPath)().c_wcs() + L"\"]";
THROWEXCEPTION(s.c_str());
return false;
}
pVirtFileSys->AddLocation(vfs::tReadLocation::Cast(pDirTree),sProfName,bIsWriteable);
_LOG << "OK" << CLog::endl;
}
else
{
_LOG << "]" << CLog::endl;
}
//else if( sLocType == "NOT_FOUND")
//{
// std::wstringstream wss;
// wss << L"No Type specified for location [" << sLocSection << L"]";
// THROWEXCEPTION(wss.str().c_str());
//}
}
if(bIsWriteable)
{
vfs::CProfileStack *pPS = pVirtFileSys->GetProfileStack();
vfs::CVirtualProfile *pProf = pPS->GetProfile(sProfName);
if(!pProf)
{
pProf = new vfs::CVirtualProfile(sProfName,true);
pPS->PushProfile(pProf);
}
else if(!pProf->Writeable)
{
std::wstringstream wss;
wss << L"Profile [" << sProfName << L"] is supposed to be writeable!";
THROWEXCEPTION(wss.str().c_str());
}
InitWriteProfile(*pProf, profileRoot);
}
}
_LOG.Endl() << "VFS successfully initialized" << CLog::endl;
return true;
}
bool InitWriteProfile(vfs::CVirtualProfile &rProf, vfs::Path const& profileRoot)
{
typedef vfs::IDirectory<vfs::IWriteable> tWDir;
tWDir *pDir = NULL;
vfs::CDirectoryTree *pDirTree = NULL;
vfs::IBaseLocation *pLoc = rProf.GetLocation(vfs::Path(vfs::Const::EMPTY()));
if(pLoc)
{
pDir = dynamic_cast<tWDir*>(pLoc);
}
else
{
vfs::CDirectoryTree *pDirTree = NULL;
pDirTree = new vfs::CDirectoryTree(vfs::Path(vfs::Const::EMPTY()),profileRoot);
if(!pDirTree->Init())
{
return false;
}
GetVFS()->AddLocation(pDirTree,rProf.Name,true);
pDir = pDirTree;
}
return pDir != NULL;
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef _VFS_INIT_H_
#define _VFS_INIT_H_
#include "vfs_types.h"
#include "vfs_profile.h"
bool InitWriteProfile(vfs::CVirtualProfile &rProf, vfs::Path const& profileRoot);
bool InitVirtualFileSystem(vfs::Path const& vfs_ini);
bool InitVirtualFileSystem(std::list<vfs::Path> const& vfs_ini_list);
#endif // _VFS_INIT_H_
+286
View File
@@ -0,0 +1,286 @@
#include "vfs_profile.h"
#include "vfs.h"
#include "Location/vfs_lib_dir.h"
#include "Location/vfs_directory_tree.h"
#include "PropertyContainer.h"
#include <sstream>
vfs::CVirtualProfile::Iterator::Iterator(vfs::CVirtualProfile& rProf)
: m_pProf(&rProf)
{
// only unique locations
_loc_iter = m_pProf->m_setLocations.begin();
}
vfs::CVirtualProfile::Iterator::Iterator()
: m_pProf(NULL)
{}
vfs::CVirtualProfile::Iterator::~Iterator()
{}
vfs::IBaseLocation* vfs::CVirtualProfile::Iterator::value() const
{
if(_loc_iter != m_pProf->m_setLocations.end())
{
return *_loc_iter;
}
THROWEXCEPTION(L"End of map");
}
void vfs::CVirtualProfile::Iterator::next()
{
if(_loc_iter != m_pProf->m_setLocations.end())
{
_loc_iter++;
}
// silently ignore error
}
bool vfs::CVirtualProfile::Iterator::end() const
{
return _loc_iter == m_pProf->m_setLocations.end();
}
/***************************************************************************/
/***************************************************************************/
vfs::CVirtualProfile::CVirtualProfile(utf8string const& sProfileName, bool bWriteable)
: Name(sProfileName), Writeable(bWriteable)
{};
vfs::CVirtualProfile::~CVirtualProfile()
{
tUniqueLoc::iterator it = m_setLocations.begin();
for(; it != m_setLocations.end(); ++it)
{
delete (*it);
(*it) = NULL;
}
m_setLocations.clear();
m_mapLocations.clear();
};
vfs::CVirtualProfile::Iterator vfs::CVirtualProfile::begin()
{
return Iterator(*this);
}
void vfs::CVirtualProfile::AddLocation(vfs::IBaseLocation* pLoc)
{
if(pLoc)
{
m_setLocations.insert(pLoc);
std::list<vfs::Path> lDirs;
pLoc->GetSubDirList(lDirs);
std::list<vfs::Path>::const_iterator cit = lDirs.begin();
for(;cit != lDirs.end(); ++cit)
{
vfs::IBaseLocation *pNewLoc = m_mapLocations[*cit];
if(!pNewLoc)
{
m_mapLocations[*cit] = pLoc;
}
else if(pNewLoc = pLoc)
{
// seems to be an update. do nothing
}
else
{
THROWEXCEPTION(L"Location already taken");
}
}
}
}
vfs::IBaseLocation* vfs::CVirtualProfile::GetLocation(vfs::Path const& sPath) const
{
tLocations::const_iterator it = m_mapLocations.find(sPath);
if(it != m_mapLocations.end())
{
return it->second;
}
return NULL;
}
vfs::IBaseFile* vfs::CVirtualProfile::GetFile(vfs::Path const& sPath) const
{
vfs::Path sDir,sFile;
sPath.SplitLast(sDir,sFile);
tLocations::const_iterator it = m_mapLocations.find(sDir);
if(it != m_mapLocations.end())
{
return it->second->GetFile(sPath);
}
return NULL;
}
/***************************************************************************/
/***************************************************************************/
vfs::CProfileStack::Iterator::Iterator(CProfileStack& rPStack)
: m_pPStack(&rPStack)
{
_prof_iter = m_pPStack->m_lProfiles.begin();
};
vfs::CProfileStack::Iterator::Iterator()
: m_pPStack(NULL)
{};
vfs::CProfileStack::Iterator::~Iterator()
{};
vfs::CVirtualProfile* vfs::CProfileStack::Iterator::value() const
{
if(_prof_iter != m_pPStack->m_lProfiles.end())
{
return *_prof_iter;
}
THROWEXCEPTION(L"end of container");
}
void vfs::CProfileStack::Iterator::next()
{
if(_prof_iter != m_pPStack->m_lProfiles.end())
{
_prof_iter++;
}
// silently ignore that we already are at the end of the list
}
bool vfs::CProfileStack::Iterator::end() const
{
return _prof_iter == m_pPStack->m_lProfiles.end();
}
/***************************************************************************/
/***************************************************************************/
vfs::CProfileStack::CProfileStack()
{
}
vfs::CProfileStack::~CProfileStack()
{
std::list<CVirtualProfile*>::iterator it = m_lProfiles.begin();
for(; it != m_lProfiles.end(); ++it)
{
delete (*it);
(*it) = NULL;
}
m_lProfiles.clear();
}
vfs::CVirtualProfile* vfs::CProfileStack::GetProfile(utf8string const& sName) const
{
std::list<CVirtualProfile*>::const_iterator it = m_lProfiles.begin();
for(;it != m_lProfiles.end(); ++it)
{
if( StrCmp::EqualCase((*it)->Name, sName) )
{
return *it;
}
}
return NULL;
}
vfs::CVirtualProfile* vfs::CProfileStack::GetWriteProfile()
{
std::list<CVirtualProfile*>::const_iterator it = m_lProfiles.begin();
for(;it != m_lProfiles.end(); ++it)
{
if((*it)->Writeable)
{
return *it;
}
}
return NULL;
}
vfs::CVirtualProfile* vfs::CProfileStack::TopProfile() const
{
if(!m_lProfiles.empty())
{
return m_lProfiles.front();
}
return NULL;
}
bool vfs::CProfileStack::PopProfile()
{
// there might be some files in this profile that are referenced in a CLog object
// we need to it to release the file
CLog::FlushAll();
// an observer pattern would probably be the better solution,
// but for now lets do it this way
bool bSuccess = true;
vfs::CVirtualProfile* prof = this->TopProfile();
if(prof)
{
vfs::CVirtualProfile::Iterator loc_it = prof->begin();
for(; !loc_it.end(); loc_it.next())
{
vfs::IBaseLocation* loc = loc_it.value();
vfs::IBaseLocation::Iterator f_it = loc->begin();
for(; !f_it.end(); f_it.next())
{
vfs::IBaseFile* file = f_it.value();
vfs::Path sDir, sFile;
if(file)
{
file->GetFullPath().SplitLast(sDir,sFile);
vfs::CVirtualLocation* vloc = GetVFS()->GetVirtualLocation(sDir);
if(vloc)
{
if( !(bSuccess &= vloc->RemoveFile(file)) )
{
std::wstringstream wss;
wss << L"Could not remove file ["
<< file->GetFullPath()()
<< L"] in Profile ["
<< prof->Name << L"]";
THROWEXCEPTION(wss.str().c_str());
}
}
else
{
std::wstringstream wss;
wss << L"Virtual location [" << sDir() << L"] doesn't exist. Maybe the VFS was not properly setup.";
THROWEXCEPTION(wss.str().c_str());
}
}
else
{
std::wstringstream wss;
wss << L"File is NULL during iteration over files in location [" << loc->GetFullPath()() << L"]";
THROWEXCEPTION(wss.str().c_str());
}
}
}
if(bSuccess)
{
// delete only when nothing went wrong
this->m_lProfiles.pop_front();
delete prof;
}
}
return bSuccess;
}
void vfs::CProfileStack::PushProfile(CVirtualProfile* pProfile)
{
if(!GetProfile(pProfile->Name))
{
m_lProfiles.push_front(pProfile);
return;
}
THROWEXCEPTION(L"A profile with this name already exists");
}
vfs::CProfileStack::Iterator vfs::CProfileStack::begin()
{
return Iterator(*this);
}
+95
View File
@@ -0,0 +1,95 @@
#ifndef _VFS_PROFILE_H_
#define _VFS_PROFILE_H_
#include "vfs_types.h"
#include "Interface/vfs_location_interface.h"
#include <map>
#include <set>
namespace vfs
{
class CVirtualProfile
{
typedef std::map<vfs::Path,vfs::IBaseLocation*, vfs::Path::Less> tLocations;
typedef std::set<vfs::IBaseLocation*> tUniqueLoc;
public:
//////////////////////////////////////////////
class Iterator
{
friend class CVirtualProfile;
private:
Iterator(CVirtualProfile& rProf);
public:
Iterator();
~Iterator();
//////
vfs::IBaseLocation* value() const;
void next();
bool end() const;
private:
CVirtualProfile* m_pProf;
tUniqueLoc::iterator _loc_iter;
};
//////////////////////////////////////////////
friend class Iterator;
public:
CVirtualProfile(utf8string const& sProfileName, bool bWriteable = false);
~CVirtualProfile();
const utf8string Name;
const bool Writeable;
Iterator begin();
void AddLocation(vfs::IBaseLocation* pLoc);
vfs::IBaseLocation* GetLocation(vfs::Path const& sPath) const;
vfs::IBaseFile* GetFile(vfs::Path const& sPath) const;
private:
tLocations m_mapLocations;
tUniqueLoc m_setLocations;
};
class CProfileStack
{
public:
//////////////////////////////////////////////
class Iterator
{
friend class CProfileStack;
private:
Iterator(CProfileStack& rPStack);
public:
Iterator();
~Iterator();
//////
CVirtualProfile* value() const;
void next();
bool end() const;
private:
CProfileStack* m_pPStack;
std::list<CVirtualProfile*>::iterator _prof_iter;
};
//////////////////////////////////////////////
friend class Iterator;
public:
CProfileStack();
~CProfileStack();
CVirtualProfile* GetWriteProfile();
CVirtualProfile* GetProfile(utf8string const& sName) const;
CVirtualProfile* TopProfile() const;
/**
* All files from the top profile will be removed from the VFS and the profile object will be deleted.
*/
bool PopProfile();
void PushProfile(CVirtualProfile* pProfile);
Iterator begin();
private:
std::list<CVirtualProfile*> m_lProfiles;
};
} // end namespace
#endif
+549
View File
@@ -0,0 +1,549 @@
#include "vfs_types.h"
#include "vfs_debug.h"
#include <vector>
//////////////////////////////////////////////////////////////////////
template<>
std::string vfs::TrimString<std::string>(std::string const& sStr, vfs::Int32 iMinPos, vfs::Int32 iMaxPos)
{
if(iMinPos >= iMaxPos || iMaxPos < 0)
{
return "";
}
vfs::Int32 iStart,iEnd;
iStart = sStr.find_first_not_of(" \t\r\n",iMinPos);
iEnd = sStr.find_last_not_of(" \t\r\n",iMaxPos);
if( (iStart >= 0) && (iEnd >= 0) )
{
return sStr.substr(iStart,iEnd-iStart+1);
}
return "";
}
template<>
std::wstring vfs::TrimString<std::wstring>(std::wstring const& sStr, vfs::Int32 iMinPos, vfs::Int32 iMaxPos)
{
if(iMinPos >= iMaxPos || iMaxPos < 0)
{
return L"";
}
vfs::Int32 iStart,iEnd;
iStart = sStr.find_first_not_of(L" \t\r\n",iMinPos);
iEnd = sStr.find_last_not_of(L" \t\r\n",iMaxPos);
if( (iStart >= 0) && (iEnd >= 0) )
{
return sStr.substr(iStart,iEnd-iStart+1);
}
return L"";
}
template<>
utf8string vfs::TrimString<utf8string>(utf8string const& sStr, vfs::Int32 iMinPos, vfs::Int32 iMaxPos)
{
return vfs::TrimString(sStr.c_wcs(), iMinPos, iMaxPos);
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
inline static void UnifySeparators(utf8string::str_t &sPath)
{
utf8string::char_t &raw = sPath[0];
utf8string::ptr_t raw_ptr = &raw;
while(*raw_ptr != 0)
{
if(*raw_ptr == '\\' || *raw_ptr == '/')
{
*raw_ptr = vfs::Const::SEPARATOR_CHAR();
}
raw_ptr++;
}
}
/**
* call after unifying separators
*/
inline unsigned int RemoveSeparators(utf8string::str_t &str)
{
vfs::UInt32 sepcount = 0;
vfs::Int32 numsep = 0;
size_t put_pos = 0;
size_t len = str.length();
utf8string::char_t& raw = str[0];
utf8string::ptr_t old_ptr = &raw;
utf8string::ptr_t new_ptr = &raw;
utf8string::ptr_t last_ptr = &raw;
while(*old_ptr != 0)
{
if(*old_ptr == vfs::Const::SEPARATOR_CHAR())
{
numsep++;
if(numsep == 1)
{
sepcount++;
}
}
else
{
// we have normal text (again)
numsep = 0;
}
if(numsep <= 1)
{
*new_ptr = *old_ptr;
last_ptr = new_ptr++;
put_pos++;
}
old_ptr++;
}
if(*last_ptr == vfs::Const::SEPARATOR_CHAR())
{
put_pos--;
if(sepcount>0)
{
sepcount--;
}
}
if(put_pos < len)
{
str.erase(put_pos);
}
return sepcount;
}
inline void RemoveLastSeparator(utf8string::str_t &str)
{
if( *str.rbegin() == vfs::Const::SEPARATOR_CHAR() )
{
str.erase( str.length()-1);
}
}
inline void RemoveDots(utf8string::str_t &str, vfs::UInt32 number_of_separators)
{
utf8string::char_t& raw = str[0];
utf8string::ptr_t old_ptr = &raw;
utf8string::ptr_t new_ptr = &raw;
utf8string::size_t new_pos = 0;
utf8string::size_t LENGTH = str.length();
bool dirty = false;
// see if we start with ./ (not . as this might be a hidden files on unix systems)
if( (LENGTH > 1) && (*old_ptr == vfs::Const::DOT_CHAR()) && (*(old_ptr+1) == vfs::Const::SEPARATOR_CHAR()) )
{
old_ptr += 2;
dirty = true;
}
std::vector<utf8string::ptr_t> sub_strings;
sub_strings.resize(number_of_separators);
int pos=0;
if(*old_ptr != 0 && *old_ptr == vfs::Const::SEPARATOR_CHAR())
{
if(!dirty)
{
// in-place : just move along
new_ptr++;
old_ptr++;
}
else
{
*new_ptr++ = *old_ptr++;
}
}
else
{
}
sub_strings[pos++] = new_ptr;
size_t current_position = 0;
while(*old_ptr != 0)
{
if(*old_ptr != vfs::Const::SEPARATOR_CHAR())
{
if(!dirty)
{
new_ptr++;
old_ptr++;
}
else
{
*new_ptr++ = *old_ptr++;
}
continue;
}
*new_ptr++ = *old_ptr++;
sub_strings[pos++] = new_ptr;
if((&raw+3) < old_ptr)
{
if( (*(old_ptr-4) == vfs::Const::SEPARATOR_CHAR()) &&
(*(old_ptr-3) == vfs::Const::DOT_CHAR()) &&
(*(old_ptr-2) == vfs::Const::DOT_CHAR()) &&
(*(old_ptr-1) == vfs::Const::SEPARATOR_CHAR()) )
{
if(pos > 1)
{
new_ptr = sub_strings[pos-3];
pos -= 2;
dirty = true;
}
}
else if((*(old_ptr-3) == vfs::Const::SEPARATOR_CHAR()) &&
(*(old_ptr-2) == vfs::Const::DOT_CHAR()) &&
(*(old_ptr-1) == vfs::Const::SEPARATOR_CHAR()) )
{
if(pos > 0)
{
new_ptr = sub_strings[pos-2];
pos -= 1;
dirty = true;
}
}
}
else if((&raw+2) < old_ptr)
{
if( (*(old_ptr-3) == vfs::Const::SEPARATOR_CHAR()) &&
(*(old_ptr-2) == vfs::Const::DOT_CHAR()) &&
(*(old_ptr-1) == vfs::Const::SEPARATOR_CHAR()) )
{
if(pos > 0)
{
new_ptr = sub_strings[pos-2];
pos -= 1;
dirty = true;
}
}
}
}
unsigned int ttt = (new_ptr - &raw);
if(ttt < LENGTH)
{
str.erase(ttt);
}
}
void GetFirstLastSeparator(utf8string::str_t &sPath, vfs::Int32 &iFirst, vfs::Int32 &iLast)
{
utf8string::char_t& raw = sPath[0];
utf8string::ptr_t ptr = &raw;
utf8string::size_t pos = 0;
while(*ptr != 0)
{
if(*ptr == vfs::Const::SEPARATOR_CHAR())
{
if(iFirst < 0)
{
iFirst = pos;
}
iLast = pos;
}
pos++;
ptr++;
}
}
//////////////////////////////////////////////////////////////////////
bool vfs::Path::Less::operator ()(vfs::Path const& s1, vfs::Path const& s2) const
{
return utf8string::less(s1._path,s2._path);
}
bool vfs::Path::Equal::operator ()(vfs::Path const& s1, vfs::Path const& s2) const
{
return utf8string::equal(s1._path,s2._path);
}
//////////////////////////////////////////////////////////////////////
vfs::Path::Path(utf8string const& sPath)
: _path(sPath), _first(-1), _last(-1)
{
DoCheck();
}
vfs::Path::Path(const char* sPath)
: _path(sPath), _first(-1), _last(-1)
{
DoCheck();
}
vfs::Path::Path(const wchar_t* sPath)
: _path(sPath), _first(-1), _last(-1)
{
DoCheck();
}
bool vfs::Path::empty() const
{
// is there a case where a non-empty string can become empty after a check?
// if it is so then i don't care
return _path.empty();
}
utf8string::size_t vfs::Path::length() const
{
return _path.length();
}
void vfs::Path::DoCheck()
{
if(!_path.empty())
{
UnifySeparators(_path.r_wcs());
vfs::UInt32 number_of_separators = RemoveSeparators(_path.r_wcs());
if(number_of_separators>0)
{
RemoveDots(_path.r_wcs(),number_of_separators+1);
GetFirstLastSeparator(_path.r_wcs(),_first,_last);
}
}
}
const utf8string& vfs::Path::operator()() const
{
return _path;
}
bool vfs::Path::SplitLast(vfs::Path &rsHead, vfs::Path &rsLast) const
{
bool success = SplitLast(rsHead._path, rsLast._path);
// no need to check, as the original path is already checked
//rPath.DoCheck();
//rFile.DoCheck();
return success;
}
bool vfs::Path::SplitLast(utf8string &rsHead, utf8string &rsLast) const
{
utf8string::str_t& rHead = rsHead.r_wcs();
utf8string::str_t& rLast = rsLast.r_wcs();
if(&rHead == &_path.c_wcs() || &rLast == &_path.c_wcs())
{
THROWEXCEPTION(L"cannot use output parameters that are equal to 'this'");
}
if(_path.empty())
{
return false;
}
utf8string::size_t LENGTH = _path.length();
#if 1
// use results from "GetFirstLastSeparator(..)"
if(_last >= 0)
{
rHead.assign(_path.c_wcs().substr(0,_last));
rLast.assign(_path.c_wcs().substr(_last+1,LENGTH-_last-1));
return true;
}
#endif
vfs::Int32 position = LENGTH;
while(--position >= 0)
{
utf8string::char_t const& c = _path.c_wcs()[position];
if(c == '\\' || c == '/')
{
break;
}
}
if(position >= 0)
{
rHead.assign(_path.c_wcs().substr(0,position));
rLast.assign(_path.c_wcs().substr(position+1,LENGTH-position-1));
}
else
{
rHead.assign(vfs::Const::EMPTY());
rLast.assign(_path.c_wcs());
}
return true;
}
bool vfs::Path::SplitFirst(vfs::Path &rsFirst, vfs::Path &rsTail) const
{
bool success = SplitFirst(rsFirst._path, rsTail._path);
// no need to check, as the original path is already checked
//rPath.DoCheck();
//rFile.DoCheck();
return success;
}
bool vfs::Path::SplitFirst(utf8string &rsFirst, utf8string &rsTail) const
{
utf8string::str_t& rFirst = rsFirst.r_wcs();
utf8string::str_t& rTail = rsTail.r_wcs();
if(_path.empty())
{
return false;
}
if(&rFirst == &_path.c_wcs() || &rTail == &_path.c_wcs())
{
THROWEXCEPTION(L"cannot use output parameters that are equal to this");
}
utf8string::size_t LENGTH = _path.length();
#if 1
// use results from "GetFirstLastSeparator(..)"
if(_first >= 0)
{
rFirst.assign(_path.c_wcs().substr(0,_first));
rTail.assign(_path.c_wcs().substr(_first+1,LENGTH-_first-1));
return true;
}
#endif
vfs::UInt32 position = 0;
while(position++ < LENGTH)
{
utf8string::char_t const& c = _path.c_wcs()[position];
if(c == '\\' || c == '/')
{
break;
}
}
if(position < LENGTH)
{
rFirst.assign(_path.c_wcs().substr(0,position));
rTail.assign(_path.c_wcs().substr(position+1,LENGTH-position-1));
}
else
{
rFirst.assign(_path.c_wcs());
rTail.assign(vfs::Const::EMPTY());
}
return true;
}
bool vfs::Path::Extension(utf8string &sExt) const
{
utf8string::size_t SIZE = _path.length();
if(_path.c_wcs().at(SIZE-1) == L'.')
{
// not an extension
return false;
}
for(vfs::UInt32 i=SIZE-2; i > 0; i--)
{
if(_path.c_wcs().at(i) == L'.')
{
sExt.r_wcs().assign(&_path.c_wcs().at(i+1),SIZE-i-1);
return true;
}
}
return false;
}
vfs::Path& vfs::Path::operator+=(vfs::Path const& p)
{
if(_path.empty())
{
_path = p._path;
}
else if(!p.empty())
{
utf8string::str_t& s =_path.r_wcs();
s += vfs::Const::SEPARATOR();
s += p._path.c_wcs();
GetFirstLastSeparator(s,_first,_last);
}
return *this;
}
vfs::Path operator+(vfs::Path const& p1, vfs::Path const& p2)
{
vfs::Path newpath = p1;
newpath += p2;
return newpath;
}
bool vfs::Path::operator==(vfs::Path const& p2)
{
return utf8string::equal(_path, p2._path);
}
class PathAccess
{
public:
PathAccess(vfs::Path const& p) : str(p._path) {};
utf8string const& str;
};
bool operator==(vfs::Path const& p1, vfs::Path const& p2)
{
return StrCmp::Equal(PathAccess(p1).str, PathAccess(p2).str);
}
bool operator==(vfs::Path const& p1, utf8string const& p2)
{
return StrCmp::Equal(PathAccess(p1).str, p2);
}
bool operator==(vfs::Path const& p1, utf8string::str_t const& p2)
{
return StrCmp::Equal(PathAccess(p1).str, p2);
}
bool operator==(vfs::Path const& p1, const utf8string::char_t* p2)
{
return StrCmp::Equal(PathAccess(p1).str, p2);
}
/*************************************************************************/
/*************************************************************************/
/**
* try to recursively match the pattern
*/
bool MatchPattern(utf8string const& sPattern, utf8string const& sStr)
{
return MatchPattern(sPattern,sStr.c_wcs());
}
bool MatchPattern(utf8string const& sPattern, utf8string::str_t const& sStr)
{
utf8string::str_t const& pat = sPattern.c_wcs();
utf8string::size_t star = pat.find_first_of(vfs::Const::STAR());
if(star == utf8string::str_t::npos)
{
return StrCmp::Equal( pat, sStr );
}
else if(star == 0)
{
if(pat.length() == 1)
{
// there is only the '*' -> matches all strings
return true;
}
utf8string::char_t atpos1 = pat.at(1);
utf8string::size_t match = -1;
do
{
match = sStr.find_first_of(atpos1,match+1);
if(match == utf8string::str_t::npos)
{
return false;
}
} while(!MatchPattern( pat.substr(1,pat.length()-1), sStr.substr(match,sStr.length()-match) ));
return true;
}
else // if(star > 0)
{
// check if characters before * match
if(!StrCmp::Equal(pat.substr(0,star), sStr.substr(0,star)) )
{
return false;
}
return MatchPattern( pat.substr(star,pat.length()-star), sStr.substr(star,sStr.length()-star) );
}
}
/*************************************************************************/
/*************************************************************************/
+177
View File
@@ -0,0 +1,177 @@
#ifndef _VFS_TYPES_H_
#define _VFS_TYPES_H_
#include <iostream>
#include "utf8string.h"
#include <string>
#include <vector>
namespace vfs
{
typedef unsigned long UInt64;
typedef unsigned int UInt32;
typedef unsigned short UInt16;
typedef unsigned char UInt8;
typedef unsigned char UByte;
typedef long Int64;
typedef int Int32;
typedef short Int16;
typedef char Int8;
typedef char Byte;
}
namespace vfs
{
namespace Const
{
inline const utf8string::str_t EMPTY() { return L""; };
inline const utf8string::char_t EMPTY_CHAR() { return L''; };
inline const utf8string::str_t DOT() { return L"."; };
inline const utf8string::char_t DOT_CHAR() { return L'.'; };
inline const utf8string::str_t DOTDOT() { return L".."; };
inline const utf8string::str_t DOTSVN() { return L".svn"; };
inline const utf8string::str_t STAR() { return L"*"; };
inline const utf8string::str_t DSTAR() { return L"**"; };
#ifdef WIN32
inline const utf8string::str_t SEPARATOR() { return L"\\"; };
inline const utf8string::char_t SEPARATOR_CHAR() { return L'\\'; };
#else
inline const utf8string::str_t SEPARATOR() { return L"/"; };
inline const utf8string::char_type SEPARATOR_CHAR() { return L'/'; };
#endif
}
}
namespace vfs
{
// remove leading and trailing white characters;
template<typename StringType>
StringType TrimString(StringType const& sStr, Int32 iMinPos, Int32 iMaxPos);
template<>
std::string TrimString<std::string>(std::string const& sStr, Int32 iMinPos, Int32 iMaxPos);
template<>
std::wstring TrimString<std::wstring>(std::wstring const& sStr, Int32 iMinPos, Int32 iMaxPos);
template<>
utf8string TrimString<utf8string>(utf8string const& sStr, Int32 iMinPos, Int32 iMaxPos);
}
class PathAccess;
namespace vfs
{
class Path
{
friend class PathAccess;
public:
class Less{
public:
bool operator()(vfs::Path const& s1, vfs::Path const& s2) const;
};
class Equal{
public:
bool operator()(vfs::Path const& s1, vfs::Path const& s2) const;
};
public:
Path() : _first(-1), _last(-1) {};
Path(const char* sPath);
Path(const wchar_t* sPath);
Path(utf8string const& sPath);
const utf8string& operator()() const;
Path& operator+=(Path const& p);
bool empty() const;
utf8string::size_t length() const;
void DoCheck();
bool SplitLast(utf8string& rsHead, utf8string& rsLast) const;
bool SplitLast(Path &rsHead, Path &rsLast) const;
bool SplitFirst(utf8string& rsFirst, utf8string& rsTail) const;
bool SplitFirst(Path &rsFirst, Path &rsTail) const;
bool Extension(utf8string &sExt) const;
bool operator==(vfs::Path const& p2);
private:
utf8string _path;
vfs::Int32 _first,_last;
};
}
// add only valid Path objects
vfs::Path operator+(vfs::Path const& p1, vfs::Path const& p2);
// compare path to string (that can be an invalid path)
bool operator==(vfs::Path const& p1, vfs::Path const& p2);
// use with care as these string can be different from the internal representation although they seem to be equal
bool operator==(vfs::Path const& p1, utf8string const& p2);
bool operator==(vfs::Path const& p1, utf8string::str_t const& p2);
bool operator==(vfs::Path const& p1, const utf8string::char_t* p2);
/*************************************************************************/
bool MatchPattern(utf8string const& sPattern, utf8string const& sStr);
bool MatchPattern(utf8string const& sPattern, utf8string::str_t const& sStr);
/*************************************************************************/
class BasicAllocator
{
public:
virtual ~BasicAllocator() {};
};
template<typename T>
class ObjBlockAllocator : public BasicAllocator
{
public:
ObjBlockAllocator(unsigned int blockSize=1024)
: BasicAllocator(), BLOCK_SIZE(blockSize), _ObjNew(0) {};
const unsigned int BLOCK_SIZE;
///
T* New(unsigned int *ID = NULL)
{
unsigned int block_id = _ObjNew/BLOCK_SIZE;
unsigned int file_id = _ObjNew % BLOCK_SIZE;
if(block_id >= _ObjPool.size())
{
tBlock* b = new tBlock();
b->resize(BLOCK_SIZE);
_ObjPool.push_back(b);
}
tBlock* block = _ObjPool[block_id];
T* obj = &(*block)[file_id];
if(ID)
{
*ID = _ObjNew;
}
_ObjNew++;
return obj;
}
///
virtual ~ObjBlockAllocator()
{
for(unsigned int i = 0; i < _ObjPool.size(); ++i)
{
delete _ObjPool[i];
}
}
private:
typedef std::vector<T> tBlock;
std::vector<tBlock*> _ObjPool;
unsigned int _ObjNew;
};
#endif // _VFS_TYPES_H_
+195
View File
@@ -0,0 +1,195 @@
#include "vfs_vfile.h"
#include "vfs_vloc.h"
#include "vfs.h"
// static member
ObjBlockAllocator<vfs::CVirtualFile>* vfs::CVirtualFile::_vfile_pool = NULL;
vfs::CVirtualFile* vfs::CVirtualFile::Create(vfs::Path const& sFilePath, vfs::CProfileStack& rPStack)
{
unsigned int ID=0;
#if 0
CVirtualFile* file = new CVirtualFile();
#else
if(!_vfile_pool)
{
_vfile_pool = new ObjBlockAllocator<vfs::CVirtualFile>();
CFileAllocator::RegisterAllocator(_vfile_pool);
}
CVirtualFile* file = _vfile_pool->New(&ID);
#endif
file->_path = sFilePath;
file->_pstack = &rPStack;
file->_myID = ID;
return file;
}
//vfs::CVirtualFile::CVirtualFile(vfs::Path const& sFilePath, CProfileStack& rPStack)
//: _path(sFilePath), _top_pname("_INVALID_"), _top_file(NULL), _rstack(rPStack)
//{
//};
vfs::CVirtualFile::CVirtualFile()
: _path(""), _top_pname("_INVALID_"), _top_file(NULL), _pstack(NULL)
, _myID(-1)
{
};
vfs::CVirtualFile::~CVirtualFile()
{
int i = 0;
}
vfs::Path const& vfs::CVirtualFile::Path()
{
return _path;
}
void vfs::CVirtualFile::Add(vfs::IBaseFile *pFile, utf8string sProfileName, bool bReplace)
{
if(pFile)
{
// if there is no file then just set it
// if bReplace is set to true then override all other settings and just set the file
if(!_top_file || bReplace)
{
_top_file = pFile;
_top_pname = sProfileName;
return;
}
// file already set, but new file is? exacly the same file
if(pFile == _top_file)
{
THROWIFFALSE( StrCmp::Equal(sProfileName,_top_pname), L"same file, different profile name");
}
// OK, not the same file, but these two different files are supposed to have the asme filename
THROWIFFALSE( _top_file->GetFileName() == pFile->GetFileName(), L"different filenames");
// set new file only when its profile is on top of the current file's profile
bool bFoundOld = false, bFoundNew = false;
vfs::CProfileStack::Iterator it = _pstack->begin();
for(; !it.end(); it.next())
{
if(_top_pname == it.value()->Name)
{
bFoundOld = true;
break;
}
else if(sProfileName == it.value()->Name)
{
bFoundNew = true;
break;
}
}
if(bFoundNew && !bFoundOld)
{
_top_file = pFile;
_top_pname = sProfileName;
}
}
}
/**
* @returns : returns true if pFile is not top file or top file could be replaced with another file
* returns false if there is no more files with given name. in this case object should be destroyed
*/
bool vfs::CVirtualFile::Remove(vfs::IBaseFile *pFile)
{
if(_top_file == pFile)
{
if(_path == pFile->GetFullPath())
{
// need to replace '_top_file'
vfs::CProfileStack::Iterator prof_it = _pstack->begin();
for(; !prof_it.end(); prof_it.next())
{
CVirtualProfile *pProf = prof_it.value();
if(pProf)
{
vfs::IBaseFile *file = pProf->GetFile(_path);
if(file && (file != pFile))
{
_top_file = file;
_top_pname = pProf->Name;
return true;
}
}
}
// no more files
_top_file = NULL;
_top_pname = "";
return false;
}
else
{
THROWEXCEPTION(L"Same file object but different file paths? WTH?");
}
}
return true;
}
vfs::IBaseFile* vfs::CVirtualFile::File(ESearchFile eSearch)
{
if(eSearch == SF_TOP)
{
return _top_file;
}
else if(eSearch == SF_FIRST_WRITEABLE)
{
CVirtualProfile *pVProf = _pstack->GetWriteProfile();
if(pVProf)
{
return pVProf->GetFile(_path);
}
}
else if(eSearch == SF_STOP_ON_WRITEABLE_PROFILE)
{
vfs::CProfileStack::Iterator prof_it = _pstack->begin();
for(; !prof_it.end(); prof_it.next())
{
CVirtualProfile *pProf = prof_it.value();
if(pProf)
{
if(pProf->Writeable)
{
return pProf->GetFile(_path);
}
else
{
vfs::IBaseFile *pFile = pProf->GetFile(_path);
if(pFile)
{
return pFile;
}
}
}
}
}
return NULL;
}
vfs::IBaseFile* vfs::CVirtualFile::File(utf8string const& sProfileName)
{
if(sProfileName == _top_pname)
{
return vfs::tReadableFile::Cast(_top_file);
}
else
{
CVirtualProfile* pProf = _pstack->GetProfile(sProfileName);
if(pProf)
{
CVirtualProfile::Iterator loc_it = pProf->begin();
for(; !loc_it.end(); loc_it.next())
{
if(loc_it.value() && loc_it.value()->FileExists(_path))
{
if(loc_it.value())
{
return loc_it.value()->GetFile(_path);
}
}
}
}
}
return NULL;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef _VFS_VFILE_H_
#define _VFS_VFILE_H_
#include "vfs_profile.h"
#include <vector>
namespace vfs
{
class CVirtualFile
{
public:
enum ESearchFile
{
SF_TOP,
SF_FIRST_WRITEABLE,
SF_STOP_ON_WRITEABLE_PROFILE,
};
public:
~CVirtualFile();
//CVirtualFile(vfs::Path const& sFilePath, CProfileStack& rPStack);
static CVirtualFile* Create(vfs::Path const& sFilePath, CProfileStack& rPStack);
vfs::Path const& Path();
void Add(vfs::IBaseFile *pFile, utf8string sProfileName, bool bReplace = false);
bool Remove(vfs::IBaseFile *pFile);
//////////////////////////////////////////////////
vfs::IBaseFile* File(ESearchFile eSearch);
vfs::IBaseFile* File(utf8string const& sProfileName);
//////////////////////////////////////////////////
private:
friend class std::vector<vfs::CVirtualFile>;
CVirtualFile();
private:
vfs::Path _path;
utf8string _top_pname;
vfs::IBaseFile* _top_file;
CProfileStack* _pstack;
private:
unsigned int _myID;
static ObjBlockAllocator<CVirtualFile>* _vfile_pool;
};
} // end namspace
#endif // _VFS_VFILE_H_
+148
View File
@@ -0,0 +1,148 @@
#include "vfs_vloc.h"
#include "vfs_vfile.h"
#include "vfs_profile.h"
#include "vfs.h"
/************************************************************************/
vfs::CVirtualLocation::Iterator::Iterator(CVirtualLocation* pLoc)
: m_pLoc(pLoc)
{
_vfile_iter = m_pLoc->m_mapVFiles.begin();
}
vfs::CVirtualLocation::Iterator::Iterator()
: m_pLoc(NULL)
{
}
vfs::CVirtualLocation::Iterator::~Iterator()
{
}
vfs::CVirtualFile* vfs::CVirtualLocation::Iterator::value()
{
if(m_pLoc && _vfile_iter != m_pLoc->m_mapVFiles.end())
{
return _vfile_iter->second;
}
return NULL;
}
void vfs::CVirtualLocation::Iterator::next()
{
if(m_pLoc && _vfile_iter != m_pLoc->m_mapVFiles.end())
{
_vfile_iter++;
}
}
bool vfs::CVirtualLocation::Iterator::end()
{
if(m_pLoc)
{
return _vfile_iter == m_pLoc->m_mapVFiles.end();
}
return true;
}
/************************************************************************/
vfs::CVirtualLocation::CVirtualLocation(vfs::Path const& sPath)
: Path(sPath), m_bExclusive(false)
{};
vfs::CVirtualLocation::~CVirtualLocation()
{
tVFiles::iterator it = m_mapVFiles.begin();
//for(; it != m_mapVFiles.end(); ++it)
//{
// delete it->second;
//}
m_mapVFiles.clear();
}
void vfs::CVirtualLocation::SetIsExclusive(bool bExclusive)
{
m_bExclusive = bExclusive;
}
bool vfs::CVirtualLocation::GetIsExclusive()
{
return m_bExclusive;
}
void vfs::CVirtualLocation::AddFile(vfs::IBaseFile* pFile, utf8string const& sProfileName)
{
tVFiles::iterator it = m_mapVFiles.find(pFile->GetFileName());
CVirtualFile *pVFile = NULL;
if(it == m_mapVFiles.end())
{
vfs::Path& fp = pFile->GetFullPath();
vfs::CProfileStack& stack = *(GetVFS()->GetProfileStack());
pVFile = vfs::CVirtualFile::Create(fp,stack);
it = m_mapVFiles.insert(m_mapVFiles.end(), std::pair<vfs::Path,vfs::CVirtualFile*>(pFile->GetFileName(),pVFile));
}
it->second->Add(pFile,sProfileName,true);
}
vfs::IBaseFile* vfs::CVirtualLocation::GetFile(vfs::Path const& sFilename, utf8string const& sProfileName) const
{
tVFiles::const_iterator cit = m_mapVFiles.find(sFilename);
if(cit != m_mapVFiles.end() && cit->second)
{
if(sProfileName.empty())
{
if(m_bExclusive)
{
return cit->second->File(vfs::CVirtualFile::SF_STOP_ON_WRITEABLE_PROFILE);
}
else
{
return cit->second->File(vfs::CVirtualFile::SF_TOP);
}
}
else
{
// you know what you are doing
return cit->second->File(sProfileName);
}
}
return NULL;
}
vfs::CVirtualFile* vfs::CVirtualLocation::GetVFile(vfs::Path const& sFilename)
{
tVFiles::const_iterator cit = m_mapVFiles.find(sFilename);
if(cit != m_mapVFiles.end())
{
return cit->second;
}
return NULL;
}
bool vfs::CVirtualLocation::RemoveFile(vfs::IBaseFile* pFile)
{
if(pFile)
{
vfs::Path sDir,sFile;
pFile->GetFullPath().SplitLast(sDir,sFile);
tVFiles::iterator it = m_mapVFiles.find(sFile);
if(it != m_mapVFiles.end())
{
if(!it->second->Remove(pFile))
{
CVirtualFile* vfile = it->second;
//delete vfile;
m_mapVFiles.erase(it);
}
return true;
}
}
return false;
}
vfs::CVirtualLocation::Iterator vfs::CVirtualLocation::iterate()
{
return Iterator(this);
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef _VFS_VLOC_H_
#define _VFS_VLOC_H_
#include "vfs_types.h"
#include "Interface/vfs_file_interface.h"
#include <map>
namespace vfs
{
class CVirtualFile;
class CVirtualLocation
{
typedef std::map<vfs::Path, CVirtualFile*, vfs::Path::Less> tVFiles;
public:
class Iterator
{
friend class CVirtualLocation;
Iterator(CVirtualLocation* pLoc);
public:
Iterator();
~Iterator();
CVirtualFile* value();
void next();
bool end();
private:
CVirtualLocation* m_pLoc;
tVFiles::iterator _vfile_iter;
};
public:
CVirtualLocation(vfs::Path const& sPath);
~CVirtualLocation();
const vfs::Path Path;
void SetIsExclusive(bool bExclusive);
bool GetIsExclusive();
void AddFile(vfs::IBaseFile* pFile, utf8string const& sProfileName);
vfs::IBaseFile* GetFile(vfs::Path const& sFilename, utf8string const& sProfileName = "") const;
vfs::CVirtualFile* GetVFile(vfs::Path const& sFilename);
bool RemoveFile(vfs::IBaseFile* pFile);
Iterator iterate();
private:
bool m_bExclusive;
tVFiles m_mapVFiles;
};
} // end namespace
#endif // _VFS_VLOC_H_