mirror of
https://github.com/1dot13/source.git
synced 2026-08-12 14:10:23 +02:00
- 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:
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* bfVFS : vfs/Core/vfs_init.cpp
|
||||
* - initialization functions/classes
|
||||
*
|
||||
* 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/vfs.h>
|
||||
#include <vfs/Core/vfs_init.h>
|
||||
#include <vfs/Core/File/vfs_file.h>
|
||||
#include <vfs/Core/File/vfs_buffer_file.h>
|
||||
#include <vfs/Core/Location/vfs_directory_tree.h>
|
||||
#include <vfs/Core/Interface/vfs_library_interface.h>
|
||||
|
||||
#ifdef VFS_WITH_SLF
|
||||
# include <vfs/Ext/slf/vfs_slf_library.h>
|
||||
#endif
|
||||
#ifdef VFS_WITH_7ZIP
|
||||
# include <vfs/Ext/7z/vfs_7z_library.h>
|
||||
# include <vfs/Ext/7z/vfs_create_7z_library.h>
|
||||
#endif
|
||||
|
||||
#include <vfs/Tools/vfs_property_container.h>
|
||||
#include <vfs/Tools/vfs_log.h>
|
||||
|
||||
#include <vfs/Aspects/vfs_logging.h>
|
||||
#include <vfs/Aspects/vfs_settings.h>
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
vfs_init::Location::Location()
|
||||
: m_optional(false)
|
||||
{
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
vfs_init::Profile::Profile()
|
||||
: m_writable(false)
|
||||
{
|
||||
};
|
||||
|
||||
vfs_init::Profile::~Profile()
|
||||
{
|
||||
t_locations::iterator it = locations.begin();
|
||||
for(;it != locations.end(); ++it)
|
||||
{
|
||||
if(it->first) delete it->second;
|
||||
}
|
||||
locations.clear();
|
||||
}
|
||||
|
||||
void vfs_init::Profile::addLocation(Location* loc, bool own)
|
||||
{
|
||||
locations.push_back(std::make_pair(own,loc));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
vfs_init::VfsConfig::~VfsConfig()
|
||||
{
|
||||
t_profiles::iterator it = profiles.begin();
|
||||
for(;it != profiles.end(); ++it)
|
||||
{
|
||||
if(it->first) delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_init::VfsConfig::addProfile(Profile* prof, bool own)
|
||||
{
|
||||
profiles.push_back(std::make_pair(own,prof));
|
||||
}
|
||||
|
||||
void vfs_init::VfsConfig::appendConfig(VfsConfig& conf)
|
||||
{
|
||||
VfsConfig::t_profiles::iterator it = conf.profiles.begin();
|
||||
for(; it != conf.profiles.end(); ++it)
|
||||
{
|
||||
// even if the other object owns its profiles, this one does not
|
||||
profiles.push_back(std::make_pair(false,it->second));
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
|
||||
bool vfs_init::initVirtualFileSystem(vfs::Path const& vfs_ini)
|
||||
{
|
||||
std::list<vfs::Path> li;
|
||||
li.push_back(vfs_ini);
|
||||
return initVirtualFileSystem(li);
|
||||
}
|
||||
bool vfs_init::initVirtualFileSystem(std::list<vfs::Path> const& vfs_ini_list)
|
||||
{
|
||||
vfs::PropertyContainer oVFSProps;
|
||||
std::list<vfs::Path>::const_iterator clit = vfs_ini_list.begin();
|
||||
for(; clit != vfs_ini_list.end(); ++clit)
|
||||
{
|
||||
oVFSProps.initFromIniFile(*clit);
|
||||
}
|
||||
return initVirtualFileSystem(oVFSProps);
|
||||
}
|
||||
bool vfs_init::initVirtualFileSystem(vfs::PropertyContainer& oVFSProps)
|
||||
{
|
||||
VFS_LOG_INFO(L"Processing VFS configuration");
|
||||
vfs_init::VfsConfig conf;
|
||||
|
||||
std::list<vfs::String> lProfiles, lLocSections;
|
||||
|
||||
oVFSProps.getStringListProperty(L"vfs_config",L"PROFILES",lProfiles,L"");
|
||||
if(lProfiles.empty())
|
||||
{
|
||||
VFS_LOG_ERROR(L"no profiles specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<vfs::String>::const_iterator prof_cit = lProfiles.begin();
|
||||
for(; prof_cit != lProfiles.end(); ++prof_cit)
|
||||
{
|
||||
vfs::String sProfSection = vfs::String("PROFILE_") + vfs::String(*prof_cit);
|
||||
|
||||
vfs_init::Profile *prof = new vfs_init::Profile();
|
||||
prof->m_name = oVFSProps.getStringProperty(sProfSection,L"NAME",L"");
|
||||
prof->m_root = oVFSProps.getStringProperty(sProfSection,L"PROFILE_ROOT",L"");
|
||||
prof->m_writable = oVFSProps.getBoolProperty(sProfSection,L"WRITE",false);
|
||||
|
||||
lLocSections.clear();
|
||||
oVFSProps.getStringListProperty(sProfSection,L"LOCATIONS",lLocSections,L"");
|
||||
|
||||
std::list<vfs::String>::iterator loc_it = lLocSections.begin();
|
||||
for(; loc_it != lLocSections.end(); ++loc_it)
|
||||
{
|
||||
vfs::String sLocSection = vfs::String("LOC_") + vfs::String(*loc_it);
|
||||
|
||||
vfs_init::Location *loc = new vfs_init::Location();
|
||||
loc->m_path = oVFSProps.getStringProperty(sLocSection,L"PATH",L"");
|
||||
loc->m_vfs_path = oVFSProps.getStringProperty(sLocSection,L"VFS_PATH",L"");
|
||||
loc->m_mount_point = oVFSProps.getStringProperty(sLocSection,L"MOUNT_POINT",L"");
|
||||
loc->m_type = oVFSProps.getStringProperty(sLocSection,L"TYPE",L"NOT_FOUND");
|
||||
loc->m_optional = oVFSProps.getBoolProperty(sLocSection,L"OPTIONAL",false);
|
||||
|
||||
prof->addLocation(loc,true);
|
||||
}
|
||||
conf.addProfile(prof,true);
|
||||
}
|
||||
return initVirtualFileSystem(conf);
|
||||
}
|
||||
|
||||
bool vfs_init::initWriteProfile(vfs::CVirtualProfile &rProf)
|
||||
{
|
||||
typedef vfs::TDirectory<vfs::IWritable> tWDir;
|
||||
tWDir *pDir = NULL;
|
||||
vfs::IBaseLocation *pLoc = rProf.getLocation(vfs::Path(vfs::Const::EMPTY()));
|
||||
if(pLoc)
|
||||
{
|
||||
pDir = dynamic_cast<tWDir*>(pLoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
VFS_LOG_WARNING(_BS(L"Could not find location (\"\") for profile '") << rProf.cName << L"'" << _BS::wget );
|
||||
VFS_LOG_WARNING(_BS(L"Trying to initialize profile root : ") << rProf.cRoot << _BS::wget );
|
||||
vfs::CDirectoryTree *pDirTree = NULL;
|
||||
pDirTree = new vfs::CDirectoryTree(vfs::Path(vfs::Const::EMPTY()),rProf.cRoot);
|
||||
if(!pDirTree->init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
VFS_TRYCATCH_RETHROW( rProf.addLocation(pDirTree), L"" );
|
||||
getVFS()->addLocation(pDirTree, &rProf);
|
||||
pDir = pDirTree;
|
||||
}
|
||||
return pDir != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool vfs_init::initVirtualFileSystem(vfs_init::VfsConfig const& conf)
|
||||
{
|
||||
VFS_LOG_INFO(L"Initializing Virtual File System");
|
||||
|
||||
vfs::CVirtualFileSystem *pVFS = getVFS();
|
||||
|
||||
if(conf.profiles.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
vfs_init::VfsConfig::t_profiles::const_iterator prof_it = conf.profiles.begin();
|
||||
for(; prof_it != conf.profiles.end(); ++prof_it)
|
||||
{
|
||||
vfs_init::Profile* prof = prof_it->second;
|
||||
VFS_LOG_INFO(_BS(L" Reading profile : ") << prof->m_name << _BS::wget);
|
||||
|
||||
vfs::Path profileRoot = prof->m_root;
|
||||
|
||||
bool bIsWritable = prof->m_writable;
|
||||
|
||||
vfs::CProfileStack *pPS = pVFS->getProfileStack();
|
||||
vfs::CVirtualProfile *pProf = pPS->getProfile(prof->m_name);
|
||||
if(!pProf)
|
||||
{
|
||||
pProf = new vfs::CVirtualProfile(prof->m_name, profileRoot, bIsWritable);
|
||||
pPS->pushProfile(pProf);
|
||||
}
|
||||
else
|
||||
{
|
||||
VFS_THROW_IFF(pProf->cWritable == bIsWritable, L"profile already exists, but their write properties differ");
|
||||
VFS_THROW_IFF(pProf->cRoot == profileRoot, L"profile already exists, but their root directories differ");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
vfs_init::Profile::t_locations::iterator loc_it = prof->locations.begin();
|
||||
loc_it = prof->locations.begin();
|
||||
for(; loc_it != prof->locations.end(); ++loc_it)
|
||||
{
|
||||
vfs_init::Location *loc = loc_it->second;
|
||||
|
||||
bool bOptional = loc->m_optional;
|
||||
if(vfs::StrCmp::Equal(loc->m_type,L"LIBRARY"))
|
||||
{
|
||||
vfs::tReadableFile *pLibFile = NULL;
|
||||
bool bOwnFile = false;
|
||||
|
||||
vfs::Path fullpath = profileRoot + loc->m_path;
|
||||
VFS_LOG_INFO( _BS(L" library : \"") << fullpath << L"\"" << _BS::wget );
|
||||
|
||||
if(!loc->m_path.empty())
|
||||
{
|
||||
// try regular file
|
||||
pLibFile = vfs::tReadableFile::cast( new vfs::CFile(fullpath) );
|
||||
bOwnFile = true;
|
||||
}
|
||||
if(!pLibFile && !loc->m_vfs_path.empty())
|
||||
{
|
||||
// if regular file doesn't exist, try to find it in the (partially initialized) VFS
|
||||
pLibFile = pVFS->getReadFile(profileRoot + loc->m_vfs_path);
|
||||
}
|
||||
if(pLibFile)
|
||||
{
|
||||
vfs::String full_str = pLibFile->getName()();
|
||||
vfs::String ext = full_str.c_wcs().substr(full_str.length()-3,3);
|
||||
vfs::ILibrary *pLib = NULL;
|
||||
if(vfs::StrCmp::Equal(ext,L"slf"))
|
||||
{
|
||||
#ifdef VFS_WITH_SLF
|
||||
pLib = new vfs::CSLFLibrary( pLibFile, loc->m_mount_point );
|
||||
#else
|
||||
VFS_LOG_ERROR(L"Trying to init slf library : SLF support disabled");
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
else if(vfs::StrCmp::Equal(ext,L".7z"))
|
||||
{
|
||||
#ifdef VFS_WITH_7ZIP
|
||||
pLib = new vfs::CUncompressed7zLibrary( pLibFile, loc->m_mount_point );
|
||||
#else
|
||||
VFS_LOG_ERROR(L"Trying to init 7z library : 7zip support disabled");
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
VFS_THROW(_BS(L"File [") << loc->m_path << L"] in not an SLF or 7z library" << _BS::wget);
|
||||
}
|
||||
if(!pLib->init())
|
||||
{
|
||||
if(!bOptional)
|
||||
{
|
||||
VFS_THROW(_BS(L"Could not initialize library [ ") << loc->m_path << L" ]" <<
|
||||
L" in : profile [ " << prof->m_name << L" ]," <<
|
||||
L" path [ " << fullpath << L" ]" << _BS::wget);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pProf->addLocation(pLib);
|
||||
pVFS->addLocation(vfs::tReadLocation::cast(pLib), pProf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VFS_THROW(_BS(L"File not found : ") << loc->m_path << _BS::wget);
|
||||
}
|
||||
}
|
||||
else if(vfs::StrCmp::Equal(loc->m_type,L"DIRECTORY"))
|
||||
{
|
||||
vfs::Path fullpath = profileRoot + loc->m_path;
|
||||
VFS_LOG_INFO( _BS(L" directory : \"") << fullpath << L"\"" << _BS::wget );
|
||||
|
||||
vfs::IBaseLocation *pDirLocation = NULL;
|
||||
bool init_success = false;
|
||||
if(bIsWritable)
|
||||
{
|
||||
vfs::CDirectoryTree *pDirTree = new vfs::CDirectoryTree(loc->m_mount_point, fullpath);
|
||||
init_success = pDirTree->init();
|
||||
pDirLocation = pDirTree;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfs::CReadOnlyDirectoryTree *pDirTree = new vfs::CReadOnlyDirectoryTree(loc->m_mount_point, fullpath);
|
||||
init_success = pDirTree->init();
|
||||
pDirLocation = pDirTree;
|
||||
}
|
||||
if(!init_success)
|
||||
{
|
||||
VFS_THROW(_BS(L"Could not initialize directory [\"") << loc->m_path << L"\"]" <<
|
||||
L" in : profile [\"" << prof->m_name << L"\"]," <<
|
||||
L" path [\"" << fullpath << L"\"]" << _BS::wget);
|
||||
}
|
||||
else
|
||||
{
|
||||
pProf->addLocation(pDirLocation);
|
||||
pVFS->addLocation(pDirLocation, pProf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bIsWritable)
|
||||
{
|
||||
vfs::CProfileStack *pPS = pVFS->getProfileStack();
|
||||
vfs::CVirtualProfile *pProf = pPS->getProfile(prof->m_name);
|
||||
if(!pProf)
|
||||
{
|
||||
pProf = new vfs::CVirtualProfile(prof->m_name,profileRoot,true);
|
||||
pPS->pushProfile(pProf);
|
||||
}
|
||||
else if(!pProf->cWritable)
|
||||
{
|
||||
VFS_THROW(_BS(L"Profile [") << prof->m_name << L"] is supposed to be writable!" << _BS::wget);
|
||||
}
|
||||
initWriteProfile(*pProf);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user