- Added missing projects "VFS" & "export" to SVN

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4447 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2011-05-26 11:25:04 +00:00
parent 6e2bdd557c
commit be95a2a7b1
203 changed files with 44525 additions and 0 deletions
+264
View File
@@ -0,0 +1,264 @@
/*
* bfVFS : vfs/Core/File/vfs_buffer_file.cpp
* - Buffer in RAM, implements File interface to unify usage of file and memory
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Core/File/vfs_buffer_file.h>
#include <vfs/Core/vfs_file_raii.h>
#include <vector>
#define ERROR_FILE(msg) (_BS(L"[") << this->getPath() << L"] - " << (msg) << _BS::wget)
#ifdef _DEBUG
#define IS_FILE_VALID() VFS_THROW_IFF( m_buffer.good(), ERROR_FILE(L"invalid file object") );
#else
#define IS_FILE_VALID() VFS_THROW_IFF( m_buffer.good(), ERROR_FILE(L"invalid file object") );
#endif
static inline std::ios::seekdir _seekDir(vfs::IBaseFile::ESeekDir seekDir)
{
if(seekDir == vfs::IBaseFile::SD_BEGIN)
{
return std::ios::beg;
}
else if(seekDir == vfs::IBaseFile::SD_CURRENT)
{
return std::ios::cur;
}
else if(seekDir == vfs::IBaseFile::SD_END)
{
return std::ios::end;
}
VFS_THROW(_BS(L"Unknown seek direction [") << seekDir << L"]" << _BS::wget);
}
///////////////////////////////////////////////////
vfs::CBufferFile::CBufferFile()
: tBaseClass(vfs::Path()), m_isOpen_read(false), m_isOpen_write(false)
{
m_buffer.str("");
}
vfs::CBufferFile::CBufferFile(vfs::Path const& fileName)
: tBaseClass(fileName), m_isOpen_read(false), m_isOpen_write(false)
{
m_buffer.str("");
}
vfs::CBufferFile::~CBufferFile()
{
m_buffer.str("");
m_buffer.clear();
}
vfs::FileAttributes vfs::CBufferFile::getAttributes()
{
return vfs::FileAttributes(vfs::FileAttributes::ATTRIB_NORMAL, vfs::FileAttributes::LT_NONE);
}
void vfs::CBufferFile::close()
{
m_buffer.clear();
m_isOpen_read = false;
m_isOpen_write = false;
IS_FILE_VALID();
}
vfs::size_t vfs::CBufferFile::getSize()
{
IS_FILE_VALID();
std::streampos size = 0;
if(!m_buffer.str().empty())
{
std::streampos current_position = m_buffer.tellg();
m_buffer.seekg(0,std::ios::end);
size = m_buffer.tellg();
m_buffer.seekg(current_position,std::ios::beg);
}
IS_FILE_VALID();
return (vfs::size_t)size;
}
bool vfs::CBufferFile::isOpenRead()
{
return m_isOpen_read;
}
bool vfs::CBufferFile::openRead()
{
if(!m_buffer.good())
{
return false;
}
return m_isOpen_read = true;
}
vfs::size_t vfs::CBufferFile::read(vfs::Byte* data, vfs::size_t bytesToRead)
{
if(!m_buffer.eof())
{
IS_FILE_VALID();
VFS_THROW_IFF(m_isOpen_read || this->openRead(), ERROR_FILE(L"open error"));
m_buffer.read(static_cast<Byte*>(data), bytesToRead);
std::streamsize bytesRead = m_buffer.gcount();
VFS_THROW_IFF( m_buffer.good() || m_buffer.eof(), ERROR_FILE(L"read error") );
return (vfs::size_t)bytesRead;
}
return 0;
}
vfs::size_t vfs::CBufferFile::getReadPosition()
{
IS_FILE_VALID();
VFS_THROW_IFF(m_isOpen_read || this->openRead(), ERROR_FILE(L"open error"));
return (vfs::size_t)m_buffer.tellg();
}
void vfs::CBufferFile::setReadPosition(vfs::size_t positionInBytes)
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_read || this->openRead(), ERROR_FILE(L"open error") );
m_buffer.seekg((std::streamoff)positionInBytes);
IS_FILE_VALID();
}
void vfs::CBufferFile::setReadPosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_read || this->openRead(), ERROR_FILE(L"open error") );
std::ios::seekdir ioSeekDir;
VFS_TRYCATCH_RETHROW(ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
m_buffer.seekg(offsetInBytes, ioSeekDir);
IS_FILE_VALID();
}
bool vfs::CBufferFile::isOpenWrite()
{
return m_isOpen_write;
}
bool vfs::CBufferFile::openWrite(bool bCreateWhenNotExist, bool bTruncate)
{
if( !m_buffer.good() )
return false;
if( m_isOpen_write )
return true;
if(bTruncate)
{
m_buffer.str("");
m_buffer.clear();
}
m_isOpen_write = m_buffer.good();
return m_isOpen_write;
}
vfs::size_t vfs::CBufferFile::write(const vfs::Byte* data, vfs::size_t bytesToWrite)
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
std::streampos start = 0;
if(!m_buffer.str().empty())
{
start = m_buffer.tellp();
}
VFS_THROW_IFF( m_buffer.write(data, bytesToWrite), ERROR_FILE(L"write error") );
std::streampos bytesWritten = m_buffer.tellp() - start;
IS_FILE_VALID();
return (vfs::size_t)bytesWritten;
}
vfs::size_t vfs::CBufferFile::getWritePosition()
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
return (vfs::size_t)m_buffer.tellp();
}
void vfs::CBufferFile::setWritePosition(vfs::size_t positionInBytes)
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
m_buffer.seekp((std::streamoff)positionInBytes);
IS_FILE_VALID();
}
void vfs::CBufferFile::setWritePosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
IS_FILE_VALID();
VFS_THROW_IFF( m_isOpen_write || this->openWrite(), ERROR_FILE(L"open error") );
std::ios::seekdir ioSeekDir;
VFS_TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error") );
m_buffer.seekp(offsetInBytes, ioSeekDir);
IS_FILE_VALID();
}
void vfs::CBufferFile::copyToBuffer(vfs::tReadableFile& rFile)
{
try
{
bool needToClose = !rFile.isOpenRead();
vfs::COpenReadFile readfile(&rFile);
if(!needToClose)
{
readfile.release();
}
typedef std::vector<vfs::Byte> tByteVector;
vfs::size_t size = rFile.getSize();
if(size > 0)
{
tByteVector vBuffer(size);
rFile.read(&vBuffer[0], size);
this->write(&vBuffer[0], size);
}
}
catch(std::exception& ex)
{
VFS_RETHROW(ERROR_FILE(L""), ex);
}
}
bool vfs::CBufferFile::deleteFile()
{
m_buffer.clear();
m_buffer.str("");
return m_buffer.good();
}
+156
View File
@@ -0,0 +1,156 @@
/*
* bfVFS : vfs/Core/File/vfs_dir_file.cpp
* - read/read-write files for usage in vfs locations (directories)
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Core/File/vfs_dir_file.h>
#include <vfs/Core/Interface/vfs_directory_interface.h>
#include <vfs/Core/vfs_os_functions.h>
#include <vfs/Aspects/vfs_settings.h>
vfs::CReadOnlyDirFile::CReadOnlyDirFile(vfs::Path const& filename, tLocation *directory)
: vfs::CReadOnlyFile(filename), _location(directory)
{
}
vfs::CReadOnlyDirFile::~CReadOnlyDirFile()
{
}
vfs::Path vfs::CReadOnlyDirFile::getPath()
{
if(_location)
{
return _location->getPath() + m_filename;
}
else
{
return m_filename;
}
}
bool vfs::CReadOnlyDirFile::_getRealPath(vfs::Path& path)
{
if(_location)
{
path = _location->getRealPath() + m_filename;
return true;
}
return false;
}
vfs::FileAttributes vfs::CReadOnlyDirFile::getAttributes()
{
vfs::FileAttributes _attribs = vfs::CReadOnlyFile::getAttributes();
vfs::UInt32 attr = _attribs.getAttrib();
attr |= vfs::FileAttributes::ATTRIB_READONLY;
return vfs::FileAttributes(attr, vfs::FileAttributes::LT_READONLY_DIRECTORY);
}
bool vfs::CReadOnlyDirFile::openRead()
{
vfs::Path filename;
if(!_getRealPath(filename))
{
return false;
}
return _internalOpenRead(filename);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
vfs::CDirFile::CDirFile(vfs::Path const& filename, tLocation *directory)
: CFile(filename), _location(directory)
{
}
vfs::CDirFile::~CDirFile()
{
}
vfs::Path vfs::CDirFile::getPath()
{
if(_location)
{
return _location->getPath() + m_filename;
}
else
{
return m_filename;
}
}
bool vfs::CDirFile::deleteFile()
{
this->close();
vfs::Path fname;
if(_getRealPath(fname))
{
return vfs::OS::deleteRealFile(fname);
}
return false;
}
bool vfs::CDirFile::_getRealPath(vfs::Path& path)
{
if(_location)
{
path = _location->getRealPath() + m_filename;
return true;
}
return false;
}
vfs::FileAttributes vfs::CDirFile::getAttributes()
{
vfs::FileAttributes _attribs = vfs::CFile::getAttributes();
return vfs::FileAttributes(_attribs.getAttrib(), vfs::FileAttributes::LT_DIRECTORY);
}
bool vfs::CDirFile::openRead()
{
vfs::Path filename;
if(!_getRealPath(filename))
{
return false;
}
return _internalOpenRead(filename);
}
bool vfs::CDirFile::openWrite(bool createWhenNotExist, bool truncate)
{
vfs::Path filename;
if(!_getRealPath(filename))
{
return false;
}
return _internalOpenWrite(filename, createWhenNotExist, truncate);
}
+619
View File
@@ -0,0 +1,619 @@
/*
* bfVFS : vfs/Core/File/vfs_file.cpp
* - File with read/read-write access
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Core/File/vfs_file.h>
#include <vfs/Core/vfs_debug.h>
#include <vfs/Core/vfs_os_functions.h>
#include <vfs/Aspects/vfs_settings.h>
#include <sys/stat.h>
#define ERROR_FILE(msg) (_BS(L"[") << this->getPath() << L"] - " << (msg) << _BS::wget)
static inline bool hasAttrib(vfs::UInt32 const& attrib, vfs::UInt32 Attribs)
{
return attrib == (attrib & Attribs);
}
static inline void copyAttributes(vfs::UInt32 osFileAttributes, vfs::UInt32& vfsFileAttributes)
{
if(vfs::OS::FileAttributes::ATTRIB_ARCHIVE == (vfs::OS::FileAttributes::ATTRIB_ARCHIVE & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_ARCHIVE;
}
if(vfs::OS::FileAttributes::ATTRIB_COMPRESSED == (vfs::OS::FileAttributes::ATTRIB_COMPRESSED & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_COMPRESSED;
}
if(vfs::OS::FileAttributes::ATTRIB_DIRECTORY == (vfs::OS::FileAttributes::ATTRIB_DIRECTORY & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_DIRECTORY;
}
if(vfs::OS::FileAttributes::ATTRIB_HIDDEN == (vfs::OS::FileAttributes::ATTRIB_HIDDEN & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_HIDDEN;
}
if(vfs::OS::FileAttributes::ATTRIB_NORMAL == (vfs::OS::FileAttributes::ATTRIB_NORMAL & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_NORMAL;
}
if(vfs::OS::FileAttributes::ATTRIB_OFFLINE == (vfs::OS::FileAttributes::ATTRIB_OFFLINE & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_OFFLINE;
}
if(vfs::OS::FileAttributes::ATTRIB_READONLY == (vfs::OS::FileAttributes::ATTRIB_READONLY & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_READONLY;
}
if(vfs::OS::FileAttributes::ATTRIB_SYSTEM == (vfs::OS::FileAttributes::ATTRIB_SYSTEM & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_SYSTEM;
}
if(vfs::OS::FileAttributes::ATTRIB_TEMPORARY == (vfs::OS::FileAttributes::ATTRIB_TEMPORARY & osFileAttributes))
{
vfsFileAttributes |= vfs::FileAttributes::ATTRIB_TEMPORARY;
}
}
#ifdef WIN32
static inline DWORD _seekDir(vfs::IBaseFile::ESeekDir seekDir)
{
if(seekDir == vfs::IBaseFile::SD_BEGIN)
{
return FILE_BEGIN;
}
else if(seekDir == vfs::IBaseFile::SD_CURRENT)
{
return FILE_CURRENT;
}
else if(seekDir == vfs::IBaseFile::SD_END)
{
return FILE_END;
}
VFS_THROW(_BS(L"Unknown seek direction [") << seekDir << L"]" << _BS::wget);
}
#else
static inline int _seekDir(vfs::IBaseFile::ESeekDir seekDir)
{
if(seekDir == vfs::IBaseFile::SD_BEGIN)
{
return SEEK_SET;
}
else if(seekDir == vfs::IBaseFile::SD_CURRENT)
{
return SEEK_CUR;
}
else if(seekDir == vfs::IBaseFile::SD_END)
{
return SEEK_END;
}
VFS_THROW(_BS(L"Unknown seek direction [") << seekDir << L"]" << _BS::wget);
}
#endif
template<typename WriteType>
vfs::TFile<WriteType>::TFile(vfs::Path const& filename)
: tBaseClass(filename), m_isOpen_read(false), m_file(0)
{
}
template<typename WriteType>
vfs::TFile<WriteType>::~TFile()
{
//VFS_LOCK(m_mutex);
#ifndef WIN32
if(m_file)clearerr(m_file);
#endif
if(m_isOpen_read)
{
this->close();
}
}
template<typename WriteType>
void vfs::TFile<WriteType>::close()
{
//VFS_LOCK(m_mutex);
if(m_file)
{
#ifdef WIN32
if(!CloseHandle(m_file))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"Could not close file : ") << err << _BS::wget) );
}
}
#else
//clearerr(m_file);
fflush(m_file);
int error = fclose(m_file);
if(error)
{
//const char* error_str = perror(error);
VFS_THROW( ERROR_FILE(_BS(L"Could not close file : ") << error << _BS::wget) );
}
#endif
m_file = NULL;
}
m_isOpen_read = false;
}
template<typename WriteType>
vfs::FileAttributes vfs::TFile<WriteType>::getAttributes()
{
//VFS_LOCK(m_mutex);
vfs::Path fullpath;
VFS_THROW_IFF(this->_getRealPath(fullpath), ERROR_FILE(L""));
vfs::UInt32 osFileAttributes = 0;
vfs::OS::FileAttributes fa;
VFS_THROW_IFF( fa.getFileAttributes(fullpath, osFileAttributes), ERROR_FILE(L"Could not read file attributes") );
vfs::UInt32 _attribs = vfs::FileAttributes::ATTRIB_INVALID;
copyAttributes(osFileAttributes, _attribs);
if(!this->implementsWritable())
{
_attribs &= ~vfs::FileAttributes::ATTRIB_NORMAL;
_attribs |= vfs::FileAttributes::ATTRIB_READONLY;
}
return vfs::FileAttributes(_attribs, vfs::FileAttributes::LT_NONE);
}
template<typename WriteType>
bool vfs::TFile<WriteType>::isOpenRead()
{
//VFS_LOCK(m_mutex);
return m_isOpen_read;
}
template<typename WriteType>
bool vfs::TFile<WriteType>::_internalOpenRead(vfs::Path const& path)
{
//VFS_LOCK(m_mutex);
if( m_isOpen_read )
return true;
#ifdef WIN32
m_file = vfs::Settings::getUseUnicode() ?
CreateFileW(path.c_str(),GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL) :
CreateFileA(vfs::String::narrow(path.c_str(),path.length()).c_str(),GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD err = GetLastError();
if(err != NO_ERROR && err != ERROR_ALREADY_EXISTS)
{
VFS_LOG_ERROR( ERROR_FILE(_BS(L"Error when opening file : ") << err << _BS::wget) );
return m_isOpen_read = false;
}
return m_isOpen_read = true;
#else
m_file = fopen(path.to_string().c_str(), "r");
return m_isOpen_read = (m_file != NULL);
#endif
}
template<typename WriteType>
bool vfs::TFile<WriteType>::openRead()
{
//VFS_LOCK(m_mutex);
return _internalOpenRead(this->m_filename);
}
template<typename WriteType>
vfs::size_t vfs::TFile<WriteType>::read(vfs::Byte* pData, vfs::size_t bytesToRead)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
#ifdef WIN32
DWORD has_read = 0;
if(!ReadFile(m_file, pData, bytesToRead, &has_read, NULL))
{
DWORD err = GetLastError();
if(err != NO_ERROR && err != ERROR_HANDLE_EOF)
{
VFS_THROW( ERROR_FILE(_BS(L"read error : ") << err << _BS::wget) );
}
}
#else
size_t has_read = fread(pData,1,bytesToRead,m_file);
if(has_read != bytesToRead)
{
int error = ferror(m_file);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"read error : ") << error << _BS::wget) );
}
clearerr(m_file);
}
#endif
return has_read;
}
template<typename WriteType>
vfs::size_t vfs::TFile<WriteType>::getReadPosition()
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
#ifdef WIN32
LARGE_INTEGER current_position,zero;
zero.QuadPart = 0;
if(!SetFilePointerEx(m_file, zero, &current_position, FILE_CURRENT))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
return (vfs::size_t)current_position.QuadPart;
#else
long int pos = ftell(m_file);
if(pos == -1L)
{
int error = ferror(m_file);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
}
return (vfs::size_t)pos;
#endif
}
template<typename WriteType>
void vfs::TFile<WriteType>::setReadPosition(vfs::size_t positionInBytes)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
#ifdef WIN32
LARGE_INTEGER pos;
pos.QuadPart = positionInBytes;
if(!SetFilePointerEx(m_file, pos, NULL, FILE_BEGIN))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
#else
int error = fseek(m_file,positionInBytes,SEEK_SET);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
#endif
}
template<typename WriteType>
void vfs::TFile<WriteType>::setReadPosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
#ifdef WIN32
DWORD ioSeekDir;
VFS_TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
LARGE_INTEGER offset;
offset.QuadPart = offsetInBytes;
if(!SetFilePointerEx(m_file, offset, NULL, ioSeekDir))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
#else
int ioSeekDir;
VFS_TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
int error = fseek(m_file, offsetInBytes, ioSeekDir);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
#endif
}
/********************************************************************************/
/********************************************************************************/
vfs::CFile::CFile(vfs::Path const& filename)
: tBaseClass(filename), m_isOpen_write(false)
{
}
vfs::CFile::~CFile()
{
//VFS_LOCK(m_mutex);
if(m_isOpen_read || m_isOpen_write)
{
this->close();
}
}
void vfs::CFile::close()
{
//VFS_LOCK(m_mutex);
tBaseClass::close();
m_isOpen_write = false;
}
bool vfs::CFile::deleteFile()
{
//VFS_LOCK(m_mutex);
this->close();
return vfs::OS::deleteRealFile(m_filename);
}
bool vfs::CFile::isOpenWrite()
{
//VFS_LOCK(m_mutex);
return m_isOpen_write;
}
bool vfs::CFile::_internalOpenWrite(vfs::Path const& path, bool createWhenNotExist, bool truncate)
{
//VFS_LOCK(m_mutex);
if( m_isOpen_write )
return true;
#ifdef WIN32
DWORD Mode = 0;
if(createWhenNotExist)
{
Mode |= OPEN_ALWAYS;
}
else
{
Mode |= OPEN_EXISTING;
}
if(truncate)
{
Mode |= TRUNCATE_EXISTING;
}
m_file = vfs::Settings::getUseUnicode() ?
CreateFileW(path.c_str(),GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,Mode,FILE_ATTRIBUTE_NORMAL,NULL) :
CreateFileA(vfs::String::narrow(path.c_str(),path.length()).c_str(),GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,Mode,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD err = GetLastError();
if(truncate && err == ERROR_FILE_NOT_FOUND)
{
Mode = CREATE_ALWAYS;
m_file = vfs::Settings::getUseUnicode() ?
CreateFileW(path.c_str(),GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,Mode,FILE_ATTRIBUTE_NORMAL,NULL) :
CreateFileA(vfs::String::narrow(path.c_str(),path.length()).c_str(),GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,Mode,FILE_ATTRIBUTE_NORMAL,NULL);
err = GetLastError();
}
if(err != NO_ERROR && err != ERROR_ALREADY_EXISTS)
{
VFS_LOG_ERROR(_BS(L"Error when opening file - ") << path << L" - [" << err << L"]" << _BS::wget);
return m_isOpen_write = false;
}
return m_isOpen_write = true;
#else
m_file = fopen(path.to_string().c_str(), "r+");
if( (!m_file && createWhenNotExist) || (m_file && truncate))
{
m_file = fopen(path.to_string().c_str(), "w");
}
return m_isOpen_write = (m_file != NULL);
#endif
}
bool vfs::CFile::openWrite(bool createWhenNotExist, bool truncate)
{
//VFS_LOCK(m_mutex);
return _internalOpenWrite(m_filename, createWhenNotExist, truncate);
}
vfs::size_t vfs::CFile::write(const vfs::Byte* data, vfs::size_t bytesToWrite)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_write, ERROR_FILE(L"file not opened") );
#ifdef WIN32
DWORD has_written = 0;
if(!WriteFile(m_file, data, bytesToWrite, &has_written, NULL))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW(_BS(L"write error : ") << err << _BS::wget);
}
}
#else
size_t has_written = fwrite(data, 1, bytesToWrite, m_file);
if(has_written != bytesToWrite)
{
int error = ferror(m_file);
if(error)
{
VFS_THROW(_BS(L"write error : ") << error << _BS::wget);
}
}
#endif
return (vfs::size_t)has_written;
}
vfs::size_t vfs::CFile::getWritePosition()
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_write, ERROR_FILE(L"file not opened") );
#ifdef WIN32
LARGE_INTEGER current_position, zero;
zero.QuadPart = 0;
if(!SetFilePointerEx(m_file, zero, &current_position, FILE_CURRENT))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
return (vfs::size_t)current_position.QuadPart;
#else
long int pos = ftell(m_file);
if(pos == -1L)
{
int error = ferror(m_file);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
}
return (vfs::size_t)pos;
#endif
}
void vfs::CFile::setWritePosition(vfs::size_t positionInBytes)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_write, ERROR_FILE(L"file not opened") );
#ifdef WIN32
LARGE_INTEGER pos;
pos.QuadPart = positionInBytes;
if(!SetFilePointerEx(m_file, pos, NULL, FILE_CURRENT))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
#else
int error = fseek(m_file,positionInBytes,SEEK_SET);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
#endif
}
void vfs::CFile::setWritePosition(vfs::offset_t offsetInBytes, vfs::IBaseFile::ESeekDir seekDir)
{
//VFS_LOCK(m_mutex);
VFS_THROW_IFF( m_isOpen_write, ERROR_FILE(L"file not opened") );
#ifdef WIN32
DWORD ioSeekDir;
VFS_TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
LARGE_INTEGER offset;
offset.QuadPart = offsetInBytes;
if(!SetFilePointerEx(m_file, offset, NULL, ioSeekDir))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << err << _BS::wget) );
}
}
#else
int ioSeekDir;
VFS_TRYCATCH_RETHROW( ioSeekDir = _seekDir(seekDir), ERROR_FILE(L"seek error"));
int error = fseek(m_file, offsetInBytes, ioSeekDir);
if(error)
{
VFS_THROW( ERROR_FILE(_BS(L"set position error : ") << error << _BS::wget) );
}
#endif
}
template<typename T>
vfs::size_t vfs::TFile<T>::getSize()
{
//VFS_LOCK(m_mutex);
#ifdef WIN32
bool was_open = false;
if(m_file)
{
was_open = true;
}
else
{
VFS_THROW_IFF(this->openRead(),ERROR_FILE(L"could not open file"));
}
vfs::size_t size;
# ifdef _MSC_VER
LARGE_INTEGER li_size;
if(!GetFileSizeEx(m_file, &li_size))
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"get size error : ") << err << _BS::wget) );
}
}
size = (vfs::size_t)li_size.QuadPart;
# else
DWORD low_part, high_part;
low_part = GetFileSize(m_file, &high_part);
if(low_part == INVALID_FILE_SIZE)
{
DWORD err = GetLastError();
if(err != NO_ERROR)
{
VFS_THROW( ERROR_FILE(_BS(L"get size error : ") << err << _BS::wget) );
}
}
size = low_part;
# endif
if(!was_open)
{
this->close();
}
return size;
#else
// if file was alredy opened, keep it open, otherwise close it
bool closeAtExit = !m_isOpen_read;
VFS_THROW_IFF( m_isOpen_read || this->openRead(), ERROR_FILE(L"could not open file") )
// save current position
long int current_position = ftell(m_file);
// move to end of the file
fseek(m_file, 0, SEEK_END);
long int file_size = ftell(m_file);
// move to old position
fseek(m_file, current_position, SEEK_SET);
VFS_THROW_IFF(current_position == ftell(m_file), ERROR_FILE(L"could not restore seek position"));
if(closeAtExit)
{
this->close();
}
return (vfs::size_t)file_size;
#endif
}
/******************************************************************/
/******************************************************************/
template class vfs::TFile<vfs::IWriteType>;
template class vfs::TFile<vfs::IWritable>;
+163
View File
@@ -0,0 +1,163 @@
/*
* bfVFS : vfs/Core/File/vfs_lib_file.cpp
* - read/read-write files for usage in vfs locations (libraries)
*
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
*
* This file is part of the bfVFS library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <vfs/Core/File/vfs_lib_file.h>
#include <vfs/Core/vfs.h>
#define ERROR_FILE(msg) (_BS(L"[") << this->getPath()() << L"] - " << msg << _BS::wget)
vfs::ObjBlockAllocator<vfs::CLibFile>* vfs::CLibFile::_lfile_pool = NULL;
vfs::CLibFile* vfs::CLibFile::create(vfs::Path const& filename,
tLocation *location,
ILibrary *library,
vfs::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 vfs::ObjBlockAllocator<vfs::CLibFile>();
vfs::ObjectAllocator::registerAllocator(_lfile_pool);
}
pFile = _lfile_pool->New();
}
#endif
pFile->m_filename = filename;
pFile->m_location = location;
pFile->m_library = library;
return pFile;
}
vfs::CLibFile::CLibFile()
: tBaseClass(L""),
m_isOpen_read(false),
m_library(NULL),
m_location(NULL)
{
};
vfs::CLibFile::~CLibFile()
{
}
void vfs::CLibFile::close()
{
if(m_isOpen_read)
{
m_library->close(this);
m_isOpen_read = false;
}
}
vfs::FileAttributes vfs::CLibFile::getAttributes()
{
return vfs::FileAttributes(vfs::FileAttributes::ATTRIB_NORMAL | vfs::FileAttributes::ATTRIB_READONLY,
vfs::FileAttributes::LT_LIBRARY);
}
vfs::Path vfs::CLibFile::getPath()
{
if(m_location)
{
return m_location->getPath() + m_filename;
}
else
{
return m_filename;
}
}
bool vfs::CLibFile::isOpenRead()
{
return m_isOpen_read;
}
bool vfs::CLibFile::openRead()
{
if(!m_isOpen_read)
{
VFS_TRYCATCH_RETHROW(m_isOpen_read = m_library->openRead(this), ERROR_FILE(L"read open error"));
}
return m_isOpen_read;
}
vfs::size_t vfs::CLibFile::read(vfs::Byte* data, vfs::size_t bytesToRead)
{
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
try
{
return m_library->read(this, data, bytesToRead);
}
catch(std::exception& ex)
{
VFS_RETHROW(ERROR_FILE(L"read error"), ex);
}
}
vfs::size_t vfs::CLibFile::getReadPosition()
{
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
try
{
return m_library->getReadPosition(this);
}
catch(std::exception& ex)
{
VFS_RETHROW(ERROR_FILE(L"library error"), ex);
}
}
void vfs::CLibFile::setReadPosition(vfs::size_t uiPositionInBytes)
{
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
VFS_TRYCATCH_RETHROW(m_library->setReadPosition(this,uiPositionInBytes), ERROR_FILE(L"library error") );
}
void vfs::CLibFile::setReadPosition(vfs::offset_t offsetInBytes, IBaseFile::ESeekDir seekDir)
{
VFS_THROW_IFF( m_isOpen_read, ERROR_FILE(L"file not opened") );
VFS_TRYCATCH_RETHROW(m_library->setReadPosition(this, offsetInBytes, seekDir), ERROR_FILE(L"library error"));
}
vfs::size_t vfs::CLibFile::getSize()
{
VFS_THROW_IFF( m_isOpen_read || this->openRead(), ERROR_FILE(L"could not open file") );
try
{
return m_library->getSize(this);
}
catch(std::exception& ex)
{
VFS_RETHROW(ERROR_FILE(L"library error"), ex);
}
}