refactor path interface:
- use wrapper class instead of std::wstring (reduces mixing of strings/paths; allows safe+easy join via operator/ and convenient case-insensitive comparison via operator==, avoids NativePathFromString, similar to boost::filesystem) - NativePath -> OsPath - add hash and To/FromJSVal for Path - add TS_ASSERT_PATH_EQUALS - replace _wfopen_s with sys_OpenFile - remove obsolete SortFiles/Directories This was SVN commit r9107.
This commit is contained in:
parent
e39fb7d0de
commit
dcd192cb60
@ -203,11 +203,11 @@ VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension,
|
||||
// (TODO: the comments and variable names say "pmd" but actually they can
|
||||
// be "psa" too.)
|
||||
|
||||
VfsPath dae(Path::ChangeExtension(pathnameNoExtension, L".dae"));
|
||||
VfsPath dae(pathnameNoExtension.ChangeExtension(L".dae"));
|
||||
if (! VfsFileExists(dae))
|
||||
{
|
||||
// No .dae - got to use the .pmd, assuming there is one
|
||||
return Path::ChangeExtension(pathnameNoExtension, extn);
|
||||
return pathnameNoExtension.ChangeExtension(extn);
|
||||
}
|
||||
|
||||
// There is a .dae - see if there's an up-to-date cached copy
|
||||
@ -216,7 +216,7 @@ VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension,
|
||||
if (g_VFS->GetFileInfo(dae, &fileInfo) < 0)
|
||||
{
|
||||
// This shouldn't occur for any sensible reasons
|
||||
LOGERROR(L"Failed to stat DAE file '%ls'", dae.c_str());
|
||||
LOGERROR(L"Failed to stat DAE file '%ls'", dae.string().c_str());
|
||||
return VfsPath();
|
||||
}
|
||||
|
||||
@ -240,16 +240,16 @@ VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension,
|
||||
extension += extn;
|
||||
|
||||
// realDaePath_ is "[..]/mods/whatever/art/meshes/whatever.dae"
|
||||
std::wstring realDaePath_;
|
||||
OsPath realDaePath_;
|
||||
LibError ret = g_VFS->GetRealPath(dae, realDaePath_);
|
||||
debug_assert(ret == INFO::OK);
|
||||
wchar_t realDaeBuf[PATH_MAX];
|
||||
wcscpy_s(realDaeBuf, ARRAY_SIZE(realDaeBuf), realDaePath_.c_str());
|
||||
wcscpy_s(realDaeBuf, ARRAY_SIZE(realDaeBuf), realDaePath_.string().c_str());
|
||||
const wchar_t* realDaePath = wcsstr(realDaeBuf, L"mods/");
|
||||
|
||||
// cachedPmdVfsPath is "cache/mods/whatever/art/meshes/whatever_{hash}.pmd"
|
||||
VfsPath cachedPmdVfsPath = Path::Join("cache", VfsPath(realDaePath));
|
||||
cachedPmdVfsPath = Path::ChangeExtension(cachedPmdVfsPath, extension);
|
||||
VfsPath cachedPmdVfsPath = VfsPath("cache") / realDaePath;
|
||||
cachedPmdVfsPath = cachedPmdVfsPath.ChangeExtension(extension);
|
||||
|
||||
// If it's not in the cache, we'll have to create it first
|
||||
if (! VfsFileExists(cachedPmdVfsPath))
|
||||
|
@ -58,10 +58,10 @@ bool CMapGenerator::GenerateMap(const VfsPath& scriptFile, const CScriptValRoote
|
||||
return false;
|
||||
|
||||
// Load RMS
|
||||
LOGMESSAGE(L"Loading RMS '%ls'", scriptFile.c_str());
|
||||
LOGMESSAGE(L"Loading RMS '%ls'", scriptFile.string().c_str());
|
||||
if (!m_ScriptInterface.LoadGlobalScriptFile(scriptFile))
|
||||
{
|
||||
LOGERROR(L"Failed to load RMS '%ls'", scriptFile.c_str());
|
||||
LOGERROR(L"Failed to load RMS '%ls'", scriptFile.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -108,17 +108,17 @@ bool CMapGenerator::LoadScripts(const std::wstring& libraryName)
|
||||
// Load all scripts in mapgen directory
|
||||
if (fs_util::GetPathnames(g_VFS, path, L"*.js", pathnames) < 0)
|
||||
{
|
||||
LOGERROR(L"Error reading scripts in directory '%ls'", path.c_str());
|
||||
LOGERROR(L"Error reading scripts in directory '%ls'", path.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it)
|
||||
{
|
||||
LOGMESSAGE(L"Loading map generator script '%ls'", it->c_str());
|
||||
LOGMESSAGE(L"Loading map generator script '%ls'", it->string().c_str());
|
||||
|
||||
if (!m_ScriptInterface.LoadGlobalScriptFile(*it))
|
||||
{
|
||||
LOGERROR(L"Failed to load script '%ls'", it->c_str());
|
||||
LOGERROR(L"Failed to load script '%ls'", it->string().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_,
|
||||
|
||||
m_CameraStartupTarget = INVALID_ENTITY;
|
||||
|
||||
filename_xml = Path::ChangeExtension(pathname, L".xml");
|
||||
filename_xml = pathname.ChangeExtension(L".xml");
|
||||
|
||||
// In some cases (particularly tests) we don't want to bother storing a large
|
||||
// mostly-empty .pmp file, so we let the XML file specify basic terrain instead.
|
||||
@ -310,7 +310,7 @@ int CMapReader::ApplyData()
|
||||
|
||||
PSRETURN CMapSummaryReader::LoadMap(const VfsPath& pathname)
|
||||
{
|
||||
VfsPath filename_xml = Path::ChangeExtension(pathname, L".xml");
|
||||
VfsPath filename_xml = pathname.ChangeExtension(L".xml");
|
||||
|
||||
CXeromyces xmb_file;
|
||||
if (xmb_file.Load(g_VFS, filename_xml) != PSRETURN_OK)
|
||||
|
@ -62,7 +62,7 @@ void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain,
|
||||
// write it out
|
||||
packer.Write(pathname);
|
||||
|
||||
VfsPath pathnameXML = Path::ChangeExtension(pathname, L".xml");
|
||||
VfsPath pathnameXML = pathname.ChangeExtension(L".xml");
|
||||
WriteXML(pathnameXML, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pSimulation2);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ CMeshManager::~CMeshManager()
|
||||
|
||||
CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname)
|
||||
{
|
||||
const VfsPath name = Path::ChangeExtension(pathname, L"");
|
||||
const VfsPath name = pathname.ChangeExtension(L"");
|
||||
|
||||
// Find the mesh if it's already been loaded and cached
|
||||
mesh_map::iterator iter = m_MeshMap.find(name);
|
||||
@ -53,7 +53,7 @@ CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname)
|
||||
|
||||
if (pmdFilename.empty())
|
||||
{
|
||||
LOGERROR(L"Could not load mesh '%ls'", pathname.c_str());
|
||||
LOGERROR(L"Could not load mesh '%ls'", pathname.string().c_str());
|
||||
return CModelDefPtr();
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname)
|
||||
}
|
||||
catch (PSERROR_File&)
|
||||
{
|
||||
LOGERROR(L"Could not load mesh '%ls'", pathname.c_str());
|
||||
LOGERROR(L"Could not load mesh '%ls'", pathname.string().c_str());
|
||||
return CModelDefPtr();
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,10 @@
|
||||
#ifndef INCLUDED_MESHMANAGER
|
||||
#define INCLUDED_MESHMANAGER
|
||||
|
||||
#include "ps/CStr.h"
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "lib/sysdep/stl.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
class CModelDef;
|
||||
@ -40,7 +39,7 @@ public:
|
||||
CModelDefPtr GetMesh(const VfsPath& pathname);
|
||||
|
||||
private:
|
||||
typedef STL_HASH_MAP<CStrW, boost::weak_ptr<CModelDef>, CStrW_hash_compare> mesh_map;
|
||||
typedef boost::unordered_map<VfsPath, boost::weak_ptr<CModelDef> > mesh_map;
|
||||
mesh_map m_MeshMap;
|
||||
CColladaManager& m_ColladaManager;
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ bool CObjectBase::Load(const VfsPath& pathname)
|
||||
m_VariantGroups.clear();
|
||||
|
||||
m_Pathname = pathname;
|
||||
m_ShortName = Path::Basename(pathname);
|
||||
m_ShortName = pathname.Basename().string();
|
||||
|
||||
|
||||
// Set up the vector<vector<T>> m_Variants to contain the right number
|
||||
@ -142,11 +142,11 @@ bool CObjectBase::Load(const VfsPath& pathname)
|
||||
|
||||
if (option_name == el_mesh)
|
||||
{
|
||||
currentVariant->m_ModelFilename = Path::Join("art/meshes", option.GetText().FromUTF8());
|
||||
currentVariant->m_ModelFilename = VfsPath("art/meshes") / option.GetText().FromUTF8();
|
||||
}
|
||||
else if (option_name == el_texture)
|
||||
{
|
||||
currentVariant->m_TextureFilename = Path::Join("art/textures/skins", option.GetText().FromUTF8());
|
||||
currentVariant->m_TextureFilename = VfsPath("art/textures/skins") / option.GetText().FromUTF8();
|
||||
}
|
||||
else if (option_name == el_decal)
|
||||
{
|
||||
@ -178,7 +178,7 @@ bool CObjectBase::Load(const VfsPath& pathname)
|
||||
}
|
||||
else if (ae.Name == at_file)
|
||||
{
|
||||
anim.m_FileName = Path::Join("art/animation", ae.Value.FromUTF8());
|
||||
anim.m_FileName = VfsPath("art/animation") / ae.Value.FromUTF8();
|
||||
}
|
||||
else if (ae.Name == at_speed)
|
||||
{
|
||||
@ -224,7 +224,7 @@ bool CObjectBase::Load(const VfsPath& pathname)
|
||||
|
||||
if (currentGroup->size() == 0)
|
||||
{
|
||||
LOGERROR(L"Actor group has zero variants ('%ls')", pathname.c_str());
|
||||
LOGERROR(L"Actor group has zero variants ('%ls')", pathname.string().c_str());
|
||||
}
|
||||
|
||||
++currentGroup;
|
||||
@ -239,7 +239,7 @@ bool CObjectBase::Load(const VfsPath& pathname)
|
||||
}
|
||||
else if (child_name == el_material)
|
||||
{
|
||||
m_Material = Path::Join("art/materials", child.GetText().FromUTF8());
|
||||
m_Material = VfsPath("art/materials") / child.GetText().FromUTF8();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
// name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
|
||||
CStr m_PropPointName;
|
||||
// name of the model file - art/actors/props/sword.xml or whatever
|
||||
VfsPath m_ModelName;
|
||||
CStrW m_ModelName;
|
||||
};
|
||||
|
||||
struct Decal
|
||||
|
@ -103,7 +103,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
|
||||
CModelDefPtr modeldef (objectManager.GetMeshManager().GetMesh(m_ModelName));
|
||||
if (!modeldef)
|
||||
{
|
||||
LOGERROR(L"CObjectEntry::BuildVariation(): Model %ls failed to load", m_ModelName.c_str());
|
||||
LOGERROR(L"CObjectEntry::BuildVariation(): Model %ls failed to load", m_ModelName.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
|
||||
{
|
||||
// start up idling
|
||||
if (!model->SetAnimation(GetRandomAnimation("idle")))
|
||||
LOGERROR(L"Failed to set idle animation in model \"%ls\"", m_ModelName.c_str());
|
||||
LOGERROR(L"Failed to set idle animation in model \"%ls\"", m_ModelName.string().c_str());
|
||||
}
|
||||
|
||||
// build props - TODO, RC - need to fix up bounds here
|
||||
@ -211,7 +211,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
|
||||
propmodel->ToCModel()->SetAnimation(oe->GetRandomAnimation("idle"));
|
||||
}
|
||||
else
|
||||
LOGERROR(L"Failed to find matching prop point called \"%hs\" in model \"%ls\" for actor \"%ls\"", ppn.c_str(), m_ModelName.c_str(), m_Base->m_ShortName.c_str());
|
||||
LOGERROR(L"Failed to find matching prop point called \"%hs\" in model \"%ls\" for actor \"%ls\"", ppn.c_str(), m_ModelName.string().c_str(), m_Base->m_ShortName.c_str());
|
||||
}
|
||||
|
||||
// setup flags
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
// so we can have lots of colour variations without wasting memory on
|
||||
// lots of objectEntries)
|
||||
|
||||
CStrW m_ProjectileModelName;
|
||||
std::wstring m_ProjectileModelName;
|
||||
|
||||
// Returns a randomly-chosen animation matching the given name.
|
||||
// If none is found, returns NULL.
|
||||
|
@ -85,7 +85,7 @@ CObjectBase* CObjectManager::FindObjectBase(const CStrW& objectname)
|
||||
|
||||
CObjectBase* obj = new CObjectBase(*this);
|
||||
|
||||
VfsPath pathname = Path::Join("art/actors/", objectname);
|
||||
VfsPath pathname = VfsPath("art/actors/") / objectname;
|
||||
|
||||
if (obj->Load(pathname))
|
||||
{
|
||||
@ -123,7 +123,7 @@ CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, const std::
|
||||
// Look to see whether this particular variation has already been loaded
|
||||
|
||||
std::vector<u8> choices = base->CalculateVariationKey(selections);
|
||||
ObjectKey key (base->m_Pathname, choices);
|
||||
ObjectKey key (base->m_Pathname.string(), choices);
|
||||
|
||||
std::map<ObjectKey, CObjectEntry*>::iterator it = m_Objects.find(key);
|
||||
if (it != m_Objects.end())
|
||||
|
@ -108,11 +108,11 @@ bool CEmitter::LoadXml(const VfsPath& pathname)
|
||||
|
||||
if( root.GetNodeName() != el_Emitter )
|
||||
{
|
||||
LOGERROR(L"CEmitter::LoadXml: XML root was not \"Emitter\" in file %ls. Load failed.", pathname.c_str() );
|
||||
LOGERROR(L"CEmitter::LoadXml: XML root was not \"Emitter\" in file %ls. Load failed.", pathname.string().c_str() );
|
||||
return( false );
|
||||
}
|
||||
|
||||
m_tag = Path::Basename(pathname);
|
||||
m_tag = pathname.Basename().string();
|
||||
|
||||
//TODO figure out if we need to use Type attribute to construct different emitter types,
|
||||
// probably have to move some of this code into a static factory method or out into ParticleEngine class
|
||||
|
@ -51,7 +51,7 @@ CSkeletonAnimManager::~CSkeletonAnimManager()
|
||||
// doesn't refer to valid animation file
|
||||
CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname)
|
||||
{
|
||||
VfsPath name = Path::ChangeExtension(pathname, L"");
|
||||
VfsPath name = pathname.ChangeExtension(L"");
|
||||
|
||||
// Find if it's already been loaded
|
||||
boost::unordered_map<VfsPath, CSkeletonAnimDef*>::iterator iter = m_Animations.find(name);
|
||||
@ -65,7 +65,7 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname)
|
||||
|
||||
if (psaFilename.empty())
|
||||
{
|
||||
LOGERROR(L"Could not load animation '%ls'", pathname.c_str());
|
||||
LOGERROR(L"Could not load animation '%ls'", pathname.string().c_str());
|
||||
def = NULL;
|
||||
}
|
||||
else
|
||||
@ -81,9 +81,9 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname)
|
||||
}
|
||||
|
||||
if (def)
|
||||
LOGMESSAGE(L"CSkeletonAnimManager::GetAnimation(%ls): Loaded successfully", pathname.c_str());
|
||||
LOGMESSAGE(L"CSkeletonAnimManager::GetAnimation(%ls): Loaded successfully", pathname.string().c_str());
|
||||
else
|
||||
LOGERROR(L"CSkeletonAnimManager::GetAnimation(%ls): Failed loading, marked file as bad", pathname.c_str());
|
||||
LOGERROR(L"CSkeletonAnimManager::GetAnimation(%ls): Failed loading, marked file as bad", pathname.string().c_str());
|
||||
|
||||
// Add to map
|
||||
m_Animations[name] = def; // NULL if failed to load - we won't try loading it again
|
||||
|
@ -56,7 +56,7 @@ CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p
|
||||
{
|
||||
LOGERROR(
|
||||
L"TerrainProperties: Loading %ls: Root node is not terrains (found \"%hs\")",
|
||||
pathname.c_str(),
|
||||
pathname.string().c_str(),
|
||||
rootName.c_str());
|
||||
return CTerrainPropertiesPtr();
|
||||
}
|
||||
@ -81,7 +81,7 @@ CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p
|
||||
{
|
||||
LOGWARNING(
|
||||
L"TerrainProperties: Loading %ls: Unexpected node %hs\n",
|
||||
pathname.c_str(),
|
||||
pathname.string().c_str(),
|
||||
XeroFile.GetElementString(child.GetNodeName()).c_str());
|
||||
// Keep reading - typos shouldn't be showstoppers
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "lib/utf8.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
@ -54,7 +55,7 @@ CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr props, const Vf
|
||||
for (;it!=m_Groups.end();++it)
|
||||
(*it)->AddTerrain(this);
|
||||
|
||||
m_Tag = CStrW(Path::Basename(path)).ToUTF8();
|
||||
m_Tag = utf8_from_wstring(path.Basename().string());
|
||||
}
|
||||
|
||||
CTerrainTextureEntry::~CTerrainTextureEntry()
|
||||
|
@ -124,8 +124,9 @@ void CTerrainTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, co
|
||||
// 'real' texture name
|
||||
for(size_t i = 0; i < pathnames.size(); i++)
|
||||
{
|
||||
if(boost::algorithm::ends_with(Path::Filename(pathnames[i]), L".cached.dds"))
|
||||
pathnames[i] = Path::Join(Path::Path(pathnames[i]), boost::algorithm::erase_last_copy(Path::Filename(pathnames[i]), L".cached.dds"));
|
||||
const std::wstring filename = pathnames[i].Filename().string();
|
||||
if(boost::algorithm::ends_with(filename, L".cached.dds"))
|
||||
pathnames[i] = pathnames[i].Parent() / boost::algorithm::erase_last_copy(filename, L".cached.dds");
|
||||
}
|
||||
|
||||
// Remove any duplicates created by the stripping
|
||||
@ -143,14 +144,14 @@ void CTerrainTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, co
|
||||
if(!tex_is_known_extension(pathnames[i]))
|
||||
continue;
|
||||
|
||||
VfsPath pathnameXML = Path::ChangeExtension(pathnames[i], L".xml");
|
||||
VfsPath pathnameXML = pathnames[i].ChangeExtension(L".xml");
|
||||
CTerrainPropertiesPtr myprops;
|
||||
// Has XML file -> attempt to load properties
|
||||
if (VfsFileExists(pathnameXML))
|
||||
{
|
||||
myprops = GetPropertiesFromFile(props, pathnameXML);
|
||||
if (myprops)
|
||||
LOGMESSAGE(L"CTerrainTextureManager: Successfully loaded override xml %ls for texture %ls", pathnameXML.c_str(), pathnames[i].c_str());
|
||||
LOGMESSAGE(L"CTerrainTextureManager: Successfully loaded override xml %ls for texture %ls", pathnameXML.string().c_str(), pathnames[i].string().c_str());
|
||||
}
|
||||
|
||||
// Error or non-existant xml file -> use parent props
|
||||
@ -163,19 +164,19 @@ void CTerrainTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, co
|
||||
|
||||
void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path)
|
||||
{
|
||||
//LOGMESSAGE(L"CTextureManager::RecurseDirectory(%ls)", path.c_str());
|
||||
//LOGMESSAGE(L"CTextureManager::RecurseDirectory(%ls)", path.string().c_str());
|
||||
|
||||
CTerrainPropertiesPtr props;
|
||||
|
||||
// Load terrains.xml first, if it exists
|
||||
VfsPath pathname = Path::Join(path, "terrains.xml");
|
||||
VfsPath pathname = path / "terrains.xml";
|
||||
if (VfsFileExists(pathname))
|
||||
props = GetPropertiesFromFile(parentProps, pathname);
|
||||
|
||||
// No terrains.xml, or read failures -> use parent props (i.e.
|
||||
if (!props)
|
||||
{
|
||||
LOGMESSAGE(L"CTerrainTextureManager::RecurseDirectory(%ls): no terrains.xml (or errors while loading) - using parent properties", path.c_str());
|
||||
LOGMESSAGE(L"CTerrainTextureManager::RecurseDirectory(%ls): no terrains.xml (or errors while loading) - using parent properties", path.string().c_str());
|
||||
props = parentProps;
|
||||
}
|
||||
|
||||
@ -184,7 +185,7 @@ void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& paren
|
||||
(void)g_VFS->GetDirectoryEntries(path, 0, &subdirectoryNames);
|
||||
for (size_t i=0;i<subdirectoryNames.size();i++)
|
||||
{
|
||||
VfsPath subdirectoryPath = Path::AddSlash(Path::Join(path, subdirectoryNames[i]));
|
||||
VfsPath subdirectoryPath = path / subdirectoryNames[i] / "";
|
||||
RecurseDirectory(props, subdirectoryPath);
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath&
|
||||
|
||||
if (root.GetNodeName() != el_textures)
|
||||
{
|
||||
LOGERROR(L"Invalid texture settings file \"%ls\" (unrecognised root element)", path.c_str());
|
||||
LOGERROR(L"Invalid texture settings file \"%ls\" (unrecognised root element)", path.string().c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -317,14 +317,14 @@ bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath
|
||||
size_t fileSize;
|
||||
if (m_VFS->LoadFile(src, file, fileSize) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to load texture \"%ls\"", src.c_str());
|
||||
LOGERROR(L"Failed to load texture \"%ls\"", src.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Tex tex;
|
||||
if (tex_decode(file, fileSize, &tex) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to decode texture \"%ls\"", src.c_str());
|
||||
LOGERROR(L"Failed to decode texture \"%ls\"", src.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -334,7 +334,7 @@ bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath
|
||||
// Convert to uncompressed BGRA with no mipmaps
|
||||
if (tex_transform_to(&tex, (tex.flags | TEX_BGR | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS)) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to transform texture \"%ls\"", src.c_str());
|
||||
LOGERROR(L"Failed to transform texture \"%ls\"", src.string().c_str());
|
||||
tex_free(&tex);
|
||||
return false;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ public:
|
||||
Handle h = ogl_tex_load(m_VFS, path, RES_UNIQUE);
|
||||
if (h <= 0)
|
||||
{
|
||||
LOGERROR(L"Texture failed to load; \"%ls\"", texture->m_Properties.m_Path.c_str());
|
||||
LOGERROR(L"Texture failed to load; \"%ls\"", texture->m_Properties.m_Path.string().c_str());
|
||||
|
||||
// Replace with error texture to make it obvious
|
||||
texture->SetHandle(m_ErrorHandle);
|
||||
@ -211,7 +211,7 @@ public:
|
||||
// Upload to GL
|
||||
if (!m_DisableGL && ogl_tex_upload(h) < 0)
|
||||
{
|
||||
LOGERROR(L"Texture failed to upload: \"%ls\"", texture->m_Properties.m_Path.c_str());
|
||||
LOGERROR(L"Texture failed to upload: \"%ls\"", texture->m_Properties.m_Path.string().c_str());
|
||||
|
||||
ogl_tex_free(h);
|
||||
|
||||
@ -303,7 +303,7 @@ public:
|
||||
CTexturePtr texture = CreateTexture(textureProps);
|
||||
CTextureConverter::Settings settings = GetConverterSettings(texture);
|
||||
|
||||
if (!m_TextureConverter.ConvertTexture(texture, sourcePath, Path::Join("cache", archiveCachePath), settings))
|
||||
if (!m_TextureConverter.ConvertTexture(texture, sourcePath, VfsPath("cache") / archiveCachePath, settings))
|
||||
return false;
|
||||
|
||||
while (true)
|
||||
@ -334,7 +334,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(L"Texture failed to convert: \"%ls\"", texture->m_Properties.m_Path.c_str());
|
||||
LOGERROR(L"Texture failed to convert: \"%ls\"", texture->m_Properties.m_Path.string().c_str());
|
||||
texture->SetHandle(m_ErrorHandle);
|
||||
}
|
||||
texture->m_State = CTexture::LOADED;
|
||||
@ -404,18 +404,18 @@ public:
|
||||
*/
|
||||
CTextureConverter::Settings GetConverterSettings(const CTexturePtr& texture)
|
||||
{
|
||||
fs::wpath srcPath = texture->m_Properties.m_Path;
|
||||
fs::wpath srcPath = texture->m_Properties.m_Path.string();
|
||||
|
||||
std::vector<CTextureConverter::SettingsFile*> files;
|
||||
VfsPath p;
|
||||
for (fs::wpath::iterator it = srcPath.begin(); it != srcPath.end(); ++it)
|
||||
{
|
||||
VfsPath settingsPath = Path::Join(p, "textures.xml");
|
||||
VfsPath settingsPath = p / "textures.xml";
|
||||
m_HotloadFiles[settingsPath].insert(texture);
|
||||
CTextureConverter::SettingsFile* f = GetSettingsFile(settingsPath);
|
||||
if (f)
|
||||
files.push_back(f);
|
||||
p = Path::Join(p, *it);
|
||||
p = p / *it;
|
||||
}
|
||||
return m_TextureConverter.ComputeSettings(srcPath.leaf(), files);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "lib/self_test.h"
|
||||
|
||||
#include "lib/file/file_system_util.h"
|
||||
#include "lib/file/vfs/vfs.h"
|
||||
#include "lib/file/io/io.h"
|
||||
|
||||
@ -27,17 +28,17 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/XML/RelaxNG.h"
|
||||
|
||||
static NativePath MOD_PATH(Path::Join(DataDir(), "mods/_test.mesh"));
|
||||
static NativePath CACHE_PATH(Path::Join(DataDir(), "_testcache"));
|
||||
static OsPath MOD_PATH(DataDir()/"mods/_test.mesh");
|
||||
static OsPath CACHE_PATH(DataDir()/"_testcache");
|
||||
|
||||
const wchar_t* srcDAE = L"collada/sphere.dae";
|
||||
const wchar_t* srcPMD = L"collada/sphere.pmd";
|
||||
const wchar_t* testDAE = L"art/skeletons/test.dae";
|
||||
const wchar_t* testPMD = L"art/skeletons/test.pmd";
|
||||
const wchar_t* testBase = L"art/skeletons/test";
|
||||
const OsPath srcDAE(L"collada/sphere.dae");
|
||||
const OsPath srcPMD(L"collada/sphere.pmd");
|
||||
const OsPath testDAE(L"art/skeletons/test.dae");
|
||||
const OsPath testPMD(L"art/skeletons/test.pmd");
|
||||
const OsPath testBase(L"art/skeletons/test");
|
||||
|
||||
const wchar_t* srcSkeletonDefs = L"collada/skeletons.xml";
|
||||
const wchar_t* testSkeletonDefs = L"art/skeletons/skeletons.xml";
|
||||
const OsPath srcSkeletonDefs(L"collada/skeletons.xml");
|
||||
const OsPath testSkeletonDefs(L"art/skeletons/skeletons.xml");
|
||||
|
||||
extern PIVFS g_VFS;
|
||||
|
||||
@ -51,15 +52,15 @@ class TestMeshManager : public CxxTest::TestSuite
|
||||
|
||||
// Make sure the required directories doesn't exist when we start,
|
||||
// in case the previous test aborted and left them full of junk
|
||||
if(DirectoryExists(MOD_PATH))
|
||||
if(fs_util::DirectoryExists(MOD_PATH))
|
||||
DeleteDirectory(MOD_PATH);
|
||||
if(DirectoryExists(CACHE_PATH))
|
||||
if(fs_util::DirectoryExists(CACHE_PATH))
|
||||
DeleteDirectory(CACHE_PATH);
|
||||
|
||||
g_VFS = CreateVfs(20*MiB);
|
||||
|
||||
TS_ASSERT_OK(g_VFS->Mount(L"", MOD_PATH));
|
||||
TS_ASSERT_OK(g_VFS->Mount(L"collada/", Path::Join(DataDir(), "tests/collada"), VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(g_VFS->Mount(L"collada/", DataDir()/"tests/collada", VFS_MOUNT_MUST_EXIST));
|
||||
|
||||
// Mount _testcache onto virtual /cache - don't use the normal cache
|
||||
// directory because that's full of loads of cached files from the
|
||||
@ -126,7 +127,7 @@ public:
|
||||
|
||||
CModelDefPtr modeldef = meshManager->GetMesh(testPMD);
|
||||
TS_ASSERT(modeldef);
|
||||
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName(), testBase);
|
||||
if (modeldef) TS_ASSERT_PATH_EQUALS(modeldef->GetName(), testBase);
|
||||
}
|
||||
|
||||
void test_load_pmd_without_extension()
|
||||
@ -135,7 +136,7 @@ public:
|
||||
|
||||
CModelDefPtr modeldef = meshManager->GetMesh(testBase);
|
||||
TS_ASSERT(modeldef);
|
||||
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName(), testBase);
|
||||
if (modeldef) TS_ASSERT_PATH_EQUALS(modeldef->GetName(), testBase);
|
||||
}
|
||||
|
||||
void test_caching()
|
||||
@ -155,7 +156,7 @@ public:
|
||||
|
||||
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
||||
TS_ASSERT(modeldef);
|
||||
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName(), testBase);
|
||||
if (modeldef) TS_ASSERT_PATH_EQUALS(modeldef->GetName(), testBase);
|
||||
}
|
||||
|
||||
void test_load_dae_caching()
|
||||
@ -166,7 +167,7 @@ public:
|
||||
VfsPath daeName1 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD);
|
||||
VfsPath daeName2 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD);
|
||||
TS_ASSERT(!daeName1.empty());
|
||||
TS_ASSERT_WSTR_EQUALS(daeName1, daeName2);
|
||||
TS_ASSERT_PATH_EQUALS(daeName1, daeName2);
|
||||
// TODO: it'd be nice to test that it really isn't doing the DAE->PMD
|
||||
// conversion a second time, but there doesn't seem to be an easy way
|
||||
// to check that
|
||||
@ -229,7 +230,7 @@ public:
|
||||
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
||||
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
||||
TS_ASSERT(modeldef);
|
||||
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName(), testBase);
|
||||
if (modeldef) TS_ASSERT_PATH_EQUALS(modeldef->GetName(), testBase);
|
||||
|
||||
TS_ASSERT(v.Validate(L"doc", L"<test>2.0</test>"));
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ public:
|
||||
|
||||
void setUp()
|
||||
{
|
||||
DeleteDirectory(Path::Join(DataDir(), "_testcache")); // clean up in case the last test run failed
|
||||
DeleteDirectory(DataDir()/"_testcache"); // clean up in case the last test run failed
|
||||
|
||||
m_VFS = CreateVfs(20*MiB);
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"", Path::Join(DataDir(), "mods/_test.tex"), VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"cache/", Path::Join(DataDir(), "_testcache")));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"", DataDir()/"mods/_test.tex", VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"cache/", DataDir()/"_testcache"));
|
||||
|
||||
tex_codec_register_all();
|
||||
}
|
||||
@ -46,7 +46,7 @@ public:
|
||||
tex_codec_unregister_all();
|
||||
|
||||
m_VFS.reset();
|
||||
DeleteDirectory(Path::Join(DataDir(), "_testcache"));
|
||||
DeleteDirectory(DataDir()/"_testcache");
|
||||
}
|
||||
|
||||
void test_convert_quality()
|
||||
|
@ -34,11 +34,11 @@ public:
|
||||
|
||||
void setUp()
|
||||
{
|
||||
DeleteDirectory(Path::Join(DataDir(), "_testcache")); // clean up in case the last test run failed
|
||||
DeleteDirectory(DataDir()/"_testcache"); // clean up in case the last test run failed
|
||||
|
||||
m_VFS = CreateVfs(20*MiB);
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"", Path::Join(DataDir(), "mods/_test.tex"), VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"cache/", Path::Join(DataDir(), "_testcache")));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"", DataDir()/"mods/_test.tex", VFS_MOUNT_MUST_EXIST));
|
||||
TS_ASSERT_OK(m_VFS->Mount(L"cache/", DataDir()/"_testcache"));
|
||||
|
||||
h_mgr_init();
|
||||
tex_codec_register_all();
|
||||
@ -54,7 +54,7 @@ public:
|
||||
h_mgr_shutdown();
|
||||
|
||||
m_VFS.reset();
|
||||
DeleteDirectory(Path::Join(DataDir(), "_testcache"));
|
||||
DeleteDirectory(DataDir()/"_testcache");
|
||||
}
|
||||
|
||||
void test_load_basic()
|
||||
|
@ -1083,7 +1083,7 @@ void CGUI::LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& P
|
||||
}
|
||||
catch (PSERROR_GUI& e)
|
||||
{
|
||||
LOGERROR(L"Errors loading GUI file %ls (%d)", Filename.c_str(), e.getCode());
|
||||
LOGERROR(L"Errors loading GUI file %ls (%d)", Filename.string().c_str(), e.getCode());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1578,7 +1578,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
|
||||
|
||||
if (attr_name == "texture")
|
||||
{
|
||||
image.m_TextureName = Path::Join("art/textures/ui", attr_value);
|
||||
image.m_TextureName = VfsPath("art/textures/ui") / attr_value;
|
||||
}
|
||||
else
|
||||
if (attr_name == "size")
|
||||
|
@ -115,7 +115,7 @@ void CGUIManager::LoadPage(SGUIPage& page)
|
||||
page.gui.reset(new CGUI());
|
||||
page.gui->Initialize();
|
||||
|
||||
VfsPath path = Path::Join("gui", VfsPath(page.name.c_str()));
|
||||
VfsPath path = VfsPath("gui") / page.name;
|
||||
page.inputs.insert(path);
|
||||
|
||||
CXeromyces xero;
|
||||
@ -144,7 +144,7 @@ void CGUIManager::LoadPage(SGUIPage& page)
|
||||
|
||||
CStrW name (node.GetText().FromUTF8());
|
||||
TIMER(name.c_str());
|
||||
VfsPath path = Path::Join("gui", VfsPath(name.c_str()));
|
||||
VfsPath path = VfsPath("gui") / name;
|
||||
page.gui->LoadXmlFile(path, page.inputs);
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ LibError CGUIManager::ReloadChangedFiles(const VfsPath& path)
|
||||
{
|
||||
if (it->inputs.count(path))
|
||||
{
|
||||
LOGMESSAGE(L"GUI file '%ls' changed - reloading page '%ls'", path.c_str(), it->name.c_str());
|
||||
LOGMESSAGE(L"GUI file '%ls' changed - reloading page '%ls'", path.string().c_str(), it->name.c_str());
|
||||
LoadPage(*it);
|
||||
// TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName,
|
||||
// TODO: Should check (nicely) that this is a valid file?
|
||||
SGUIImage Image;
|
||||
|
||||
Image.m_TextureName = Path::Join("art/textures/ui", wstring_from_utf8(SpriteName.substr(10)));
|
||||
Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(10));
|
||||
|
||||
CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
|
||||
Image.m_Size = ca;
|
||||
|
@ -312,7 +312,7 @@ CScriptVal LoadMapSettings(void* cbdata, VfsPath pathname)
|
||||
|
||||
CMapSummaryReader reader;
|
||||
|
||||
if (reader.LoadMap(VfsPath(pathname + L".xml")) != PSRETURN_OK)
|
||||
if (reader.LoadMap(pathname.ChangeExtension(L".xml")) != PSRETURN_OK)
|
||||
return CScriptVal();
|
||||
|
||||
return reader.GetMapSettings(guiManager->GetScriptInterface()).get();
|
||||
@ -433,8 +433,8 @@ void ForceGC(void* cbdata)
|
||||
|
||||
void DumpSimState(void* UNUSED(cbdata))
|
||||
{
|
||||
NativePath path = Path::Join(psLogDir(), "sim_dump.txt");
|
||||
std::ofstream file (StringFromNativePath(path).c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
OsPath path = psLogDir()/"sim_dump.txt";
|
||||
std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
g_Game->GetSimulation2()->DumpDebugState(file);
|
||||
}
|
||||
|
||||
|
@ -41,14 +41,14 @@ static void def_override_gl_upload_caps()
|
||||
}
|
||||
|
||||
|
||||
static const NativePath& def_get_log_dir()
|
||||
static const OsPath& def_get_log_dir()
|
||||
{
|
||||
static NativePath logDir;
|
||||
static OsPath logDir;
|
||||
if(logDir.empty())
|
||||
{
|
||||
NativePath exePathname;
|
||||
OsPath exePathname;
|
||||
(void)sys_get_executable_name(exePathname);
|
||||
logDir = Path::Path(exePathname);
|
||||
logDir = exePathname.Parent();
|
||||
}
|
||||
return logDir;
|
||||
}
|
||||
@ -153,7 +153,7 @@ void ah_override_gl_upload_caps()
|
||||
ah.override_gl_upload_caps();
|
||||
}
|
||||
|
||||
const NativePath& ah_get_log_dir()
|
||||
const OsPath& ah_get_log_dir()
|
||||
{
|
||||
return ah.get_log_dir();
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ extern void ah_override_gl_upload_caps();
|
||||
*
|
||||
* @return path ending with directory separator (e.g. '/').
|
||||
**/
|
||||
extern const NativePath& ah_get_log_dir();
|
||||
extern const OsPath& ah_get_log_dir();
|
||||
|
||||
/**
|
||||
* gather all app-related logs/information and write it to file.
|
||||
@ -179,7 +179,7 @@ extern ErrorReactionInternal ah_display_error(const wchar_t* text, size_t flags)
|
||||
struct AppHooks
|
||||
{
|
||||
void (*override_gl_upload_caps)();
|
||||
const NativePath& (*get_log_dir)();
|
||||
const OsPath& (*get_log_dir)();
|
||||
void (*bundle_logs)(FILE* f);
|
||||
const wchar_t* (*translate)(const wchar_t* text);
|
||||
void (*translate_free)(const wchar_t* text);
|
||||
|
@ -173,10 +173,9 @@ LibError debug_WriteCrashlog(const wchar_t* text)
|
||||
if(!cpu_CAS(&state, IDLE, BUSY))
|
||||
return ERR::REENTERED; // NOWARN
|
||||
|
||||
FILE* f;
|
||||
NativePath pathname = Path::Join(ah_get_log_dir(), "crashlog.txt");
|
||||
errno_t err = _wfopen_s(&f, pathname.c_str(), L"w");
|
||||
if(err != 0)
|
||||
OsPath pathname = ah_get_log_dir()/"crashlog.txt";
|
||||
FILE* f = sys_OpenFile(pathname, "w");
|
||||
if(!f)
|
||||
{
|
||||
state = FAILED; // must come before DEBUG_DISPLAY_ERROR
|
||||
DEBUG_DISPLAY_ERROR(L"Unable to open crashlog.txt for writing (please ensure the log directory is writable)");
|
||||
|
@ -43,8 +43,8 @@ void dbghelp_ImportFunctions()
|
||||
// application loaded.") and then the system directory, whose
|
||||
// dbghelp.dll is too old. we therefore specify the full path
|
||||
// to our executable directory, which contains a newer dbghelp.dll.
|
||||
const NativePath pathname = Path::Join(wutil_DetectExecutablePath(), "dbghelp.dll");
|
||||
HMODULE hDbghelp = LoadLibraryW(pathname.c_str());
|
||||
const OsPath pathname = wutil_DetectExecutablePath()/"dbghelp.dll";
|
||||
HMODULE hDbghelp = LoadLibraryW(OsString(pathname).c_str());
|
||||
debug_assert(hDbghelp);
|
||||
#define FUNC(ret, name, params) p##name = (ret (__stdcall*) params)GetProcAddress(hDbghelp, #name);
|
||||
#include "lib/external_libraries/dbghelp_funcs.h"
|
||||
|
@ -91,7 +91,7 @@ struct IArchiveWriter
|
||||
* @param pathname the actual file to add
|
||||
* @param pathnameInArchive the name to store in the archive
|
||||
**/
|
||||
virtual LibError AddFile(const NativePath& pathname, const NativePath& pathameInArchive) = 0;
|
||||
virtual LibError AddFile(const OsPath& pathname, const Path& pathameInArchive) = 0;
|
||||
};
|
||||
|
||||
typedef shared_ptr<IArchiveWriter> PIArchiveWriter;
|
||||
|
@ -34,8 +34,8 @@
|
||||
#include "lib/bits.h"
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/fat_time.h"
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/allocators/pool.h"
|
||||
#include "lib/sysdep/filesystem.h"
|
||||
#include "lib/file/archive/archive.h"
|
||||
#include "lib/file/archive/codec_zlib.h"
|
||||
#include "lib/file/archive/stream.h"
|
||||
@ -64,9 +64,9 @@ enum ZipMethod
|
||||
class LFH
|
||||
{
|
||||
public:
|
||||
void Init(const FileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const NativePath& pathname)
|
||||
void Init(const FileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const Path& pathname)
|
||||
{
|
||||
const std::string pathnameUTF8 = utf8_from_wstring(pathname);
|
||||
const std::string pathnameUTF8 = utf8_from_wstring(pathname.string());
|
||||
const size_t pathnameSize = pathnameUTF8.length();
|
||||
|
||||
m_magic = lfh_magic;
|
||||
@ -112,9 +112,9 @@ cassert(sizeof(LFH) == 30);
|
||||
class CDFH
|
||||
{
|
||||
public:
|
||||
void Init(const FileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const NativePath& pathname, size_t slack)
|
||||
void Init(const FileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const Path& pathname, size_t slack)
|
||||
{
|
||||
const std::string pathnameUTF8 = utf8_from_wstring(pathname);
|
||||
const std::string pathnameUTF8 = utf8_from_wstring(pathname.string());
|
||||
const size_t pathnameLength = pathnameUTF8.length();
|
||||
|
||||
m_magic = cdfh_magic;
|
||||
@ -135,11 +135,11 @@ public:
|
||||
memcpy((char*)this + sizeof(CDFH), pathnameUTF8.c_str(), pathnameLength);
|
||||
}
|
||||
|
||||
NativePath Pathname() const
|
||||
Path Pathname() const
|
||||
{
|
||||
const size_t length = (size_t)read_le16(&m_fn_len);
|
||||
const char* pathname = (const char*)this + sizeof(CDFH); // not 0-terminated!
|
||||
return NativePathFromString(std::string(pathname, length));
|
||||
return Path(std::string(pathname, length));
|
||||
}
|
||||
|
||||
off_t HeaderOffset() const
|
||||
@ -264,12 +264,12 @@ public:
|
||||
return 'A';
|
||||
}
|
||||
|
||||
virtual NativePath Path() const
|
||||
virtual OsPath Path() const
|
||||
{
|
||||
return m_file->Pathname();
|
||||
}
|
||||
|
||||
virtual LibError Load(const NativePath& UNUSED(name), const shared_ptr<u8>& buf, size_t size) const
|
||||
virtual LibError Load(const OsPath& UNUSED(name), const shared_ptr<u8>& buf, size_t size) const
|
||||
{
|
||||
AdjustOffset();
|
||||
|
||||
@ -381,7 +381,7 @@ private:
|
||||
class ArchiveReader_Zip : public IArchiveReader
|
||||
{
|
||||
public:
|
||||
ArchiveReader_Zip(const NativePath& pathname)
|
||||
ArchiveReader_Zip(const OsPath& pathname)
|
||||
: m_file(new File(pathname, 'r'))
|
||||
{
|
||||
FileInfo fileInfo;
|
||||
@ -411,10 +411,10 @@ public:
|
||||
if(!cdfh)
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
|
||||
const VfsPath relativePathname(cdfh->Pathname());
|
||||
if(!Path::IsDirectory(relativePathname))
|
||||
const Path relativePathname(cdfh->Pathname());
|
||||
if(!relativePathname.IsDirectory())
|
||||
{
|
||||
const NativePath name = Path::Filename(relativePathname);
|
||||
const OsPath name = relativePathname.Filename();
|
||||
FileInfo fileInfo(name, cdfh->USize(), cdfh->MTime());
|
||||
shared_ptr<ArchiveFile_Zip> archiveFile(new ArchiveFile_Zip(m_file, cdfh->HeaderOffset(), cdfh->CSize(), cdfh->Checksum(), cdfh->Method()));
|
||||
cb(relativePathname, fileInfo, archiveFile, cbData);
|
||||
@ -514,7 +514,7 @@ private:
|
||||
off_t m_fileSize;
|
||||
};
|
||||
|
||||
PIArchiveReader CreateArchiveReader_Zip(const NativePath& archivePathname)
|
||||
PIArchiveReader CreateArchiveReader_Zip(const OsPath& archivePathname)
|
||||
{
|
||||
return PIArchiveReader(new ArchiveReader_Zip(archivePathname));
|
||||
}
|
||||
@ -527,7 +527,7 @@ PIArchiveReader CreateArchiveReader_Zip(const NativePath& archivePathname)
|
||||
class ArchiveWriter_Zip : public IArchiveWriter
|
||||
{
|
||||
public:
|
||||
ArchiveWriter_Zip(const NativePath& archivePathname, bool noDeflate)
|
||||
ArchiveWriter_Zip(const OsPath& archivePathname, bool noDeflate)
|
||||
: m_file(new File(archivePathname, 'w')), m_fileSize(0)
|
||||
, m_unalignedWriter(new UnalignedWriter(m_file, 0))
|
||||
, m_numEntries(0), m_noDeflate(noDeflate)
|
||||
@ -552,16 +552,16 @@ public:
|
||||
|
||||
(void)pool_destroy(&m_cdfhPool);
|
||||
|
||||
const NativePath pathname = m_file->Pathname(); // (must be retrieved before resetting m_file)
|
||||
const OsPath pathname = m_file->Pathname(); // (must be retrieved before resetting m_file)
|
||||
m_file.reset();
|
||||
|
||||
m_fileSize += off_t(cd_size+sizeof(ECDR));
|
||||
|
||||
// remove padding added by UnalignedWriter
|
||||
wtruncate(pathname.c_str(), m_fileSize);
|
||||
wtruncate(pathname, m_fileSize);
|
||||
}
|
||||
|
||||
LibError AddFile(const NativePath& pathname, const NativePath& pathnameInArchive)
|
||||
LibError AddFile(const OsPath& pathname, const OsPath& pathnameInArchive)
|
||||
{
|
||||
FileInfo fileInfo;
|
||||
RETURN_ERR(GetFileInfo(pathname, &fileInfo));
|
||||
@ -580,7 +580,7 @@ public:
|
||||
PFile file(new File);
|
||||
RETURN_ERR(file->Open(pathname, 'r'));
|
||||
|
||||
const size_t pathnameLength = pathnameInArchive.length();
|
||||
const size_t pathnameLength = pathnameInArchive.string().length();
|
||||
|
||||
// choose method and the corresponding codec
|
||||
ZipMethod method;
|
||||
@ -638,9 +638,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static bool IsFileTypeIncompressible(const NativePath& pathname)
|
||||
static bool IsFileTypeIncompressible(const OsPath& pathname)
|
||||
{
|
||||
const NativePath extension = Path::Extension(pathname);
|
||||
const OsPath extension = pathname.Extension();
|
||||
|
||||
// file extensions that we don't want to compress
|
||||
static const wchar_t* incompressibleExtensions[] =
|
||||
@ -652,7 +652,7 @@ private:
|
||||
|
||||
for(size_t i = 0; i < ARRAY_SIZE(incompressibleExtensions); i++)
|
||||
{
|
||||
if(!wcscasecmp(extension.c_str(), incompressibleExtensions[i]))
|
||||
if(extension == incompressibleExtensions[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -669,7 +669,7 @@ private:
|
||||
bool m_noDeflate;
|
||||
};
|
||||
|
||||
PIArchiveWriter CreateArchiveWriter_Zip(const NativePath& archivePathname, bool noDeflate)
|
||||
PIArchiveWriter CreateArchiveWriter_Zip(const OsPath& archivePathname, bool noDeflate)
|
||||
{
|
||||
return PIArchiveWriter(new ArchiveWriter_Zip(archivePathname, noDeflate));
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "lib/file/archive/archive.h"
|
||||
|
||||
LIB_API PIArchiveReader CreateArchiveReader_Zip(const NativePath& archivePathname);
|
||||
LIB_API PIArchiveWriter CreateArchiveWriter_Zip(const NativePath& archivePathname, bool noDeflate);
|
||||
LIB_API PIArchiveReader CreateArchiveReader_Zip(const OsPath& archivePathname);
|
||||
LIB_API PIArchiveWriter CreateArchiveWriter_Zip(const OsPath& archivePathname, bool noDeflate);
|
||||
|
||||
#endif // #ifndef INCLUDED_ARCHIVE_ZIP
|
||||
|
@ -31,9 +31,9 @@ struct IFileLoader
|
||||
|
||||
virtual size_t Precedence() const = 0;
|
||||
virtual wchar_t LocationCode() const = 0;
|
||||
virtual NativePath Path() const = 0;
|
||||
virtual OsPath Path() const = 0;
|
||||
|
||||
virtual LibError Load(const NativePath& name, const shared_ptr<u8>& buf, size_t size) const = 0;
|
||||
virtual LibError Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const = 0;
|
||||
};
|
||||
|
||||
typedef shared_ptr<IFileLoader> PIFileLoader;
|
||||
|
@ -23,12 +23,12 @@
|
||||
#include "precompiled.h"
|
||||
#include "lib/file/common/real_directory.h"
|
||||
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/sysdep/filesystem.h"
|
||||
#include "lib/file/file.h"
|
||||
#include "lib/file/io/io.h"
|
||||
|
||||
|
||||
RealDirectory::RealDirectory(const NativePath& path, size_t priority, size_t flags)
|
||||
RealDirectory::RealDirectory(const OsPath& path, size_t priority, size_t flags)
|
||||
: m_path(path), m_priority(priority), m_flags(flags)
|
||||
{
|
||||
}
|
||||
@ -46,9 +46,9 @@ RealDirectory::RealDirectory(const NativePath& path, size_t priority, size_t fla
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ LibError RealDirectory::Load(const NativePath& name, const shared_ptr<u8>& buf, size_t size) const
|
||||
/*virtual*/ LibError RealDirectory::Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const
|
||||
{
|
||||
const NativePath pathname = Path::Join(m_path, name);
|
||||
const OsPath pathname = m_path / name;
|
||||
|
||||
PFile file(new File);
|
||||
RETURN_ERR(file->Open(pathname, 'r'));
|
||||
@ -58,9 +58,9 @@ RealDirectory::RealDirectory(const NativePath& path, size_t priority, size_t fla
|
||||
}
|
||||
|
||||
|
||||
LibError RealDirectory::Store(const NativePath& name, const shared_ptr<u8>& fileContents, size_t size)
|
||||
LibError RealDirectory::Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size)
|
||||
{
|
||||
const NativePath pathname = Path::Join(m_path, name);
|
||||
const OsPath pathname = m_path / name;
|
||||
|
||||
{
|
||||
PFile file(new File);
|
||||
@ -72,7 +72,7 @@ LibError RealDirectory::Store(const NativePath& name, const shared_ptr<u8>& file
|
||||
// length. ftruncate can't be used because Windows' FILE_FLAG_NO_BUFFERING
|
||||
// only allows resizing to sector boundaries, so the file must first
|
||||
// be closed.
|
||||
wtruncate(pathname.c_str(), size);
|
||||
wtruncate(pathname, size);
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
@ -85,8 +85,8 @@ void RealDirectory::Watch()
|
||||
}
|
||||
|
||||
|
||||
PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const NativePath& subdirectoryName)
|
||||
PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const OsPath& subdirectoryName)
|
||||
{
|
||||
const NativePath path = Path::AddSlash(Path::Join(realDirectory->Path(), subdirectoryName));
|
||||
const OsPath path = realDirectory->Path() / subdirectoryName/"";
|
||||
return PRealDirectory(new RealDirectory(path, realDirectory->Priority(), realDirectory->Flags()));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class RealDirectory : public IFileLoader
|
||||
{
|
||||
NONCOPYABLE(RealDirectory);
|
||||
public:
|
||||
RealDirectory(const NativePath& path, size_t priority, size_t flags);
|
||||
RealDirectory(const OsPath& path, size_t priority, size_t flags);
|
||||
|
||||
size_t Priority() const
|
||||
{
|
||||
@ -45,13 +45,13 @@ public:
|
||||
// IFileLoader
|
||||
virtual size_t Precedence() const;
|
||||
virtual wchar_t LocationCode() const;
|
||||
virtual NativePath Path() const
|
||||
virtual OsPath Path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
virtual LibError Load(const NativePath& name, const shared_ptr<u8>& buf, size_t size) const;
|
||||
virtual LibError Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const;
|
||||
|
||||
LibError Store(const NativePath& name, const shared_ptr<u8>& fileContents, size_t size);
|
||||
LibError Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size);
|
||||
|
||||
void Watch();
|
||||
|
||||
@ -59,7 +59,7 @@ private:
|
||||
// note: paths are relative to the root directory, so storing the
|
||||
// entire path instead of just the portion relative to the mount point
|
||||
// is not all too wasteful.
|
||||
const NativePath m_path;
|
||||
const OsPath m_path;
|
||||
|
||||
const size_t m_priority;
|
||||
|
||||
@ -72,6 +72,6 @@ private:
|
||||
|
||||
typedef shared_ptr<RealDirectory> PRealDirectory;
|
||||
|
||||
extern PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const NativePath& subdirectoryName);
|
||||
extern PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const OsPath& subdirectoryName);
|
||||
|
||||
#endif // #ifndef INCLUDED_REAL_DIRECTORY
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
TraceEntry t1(TraceEntry::Load, L"example.txt", 1234);
|
||||
TS_ASSERT_EQUALS(t1.Action(), TraceEntry::Load);
|
||||
TS_ASSERT_WSTR_EQUALS(t1.Pathname(), L"example.txt");
|
||||
TS_ASSERT_PATH_EQUALS(t1.Pathname(), OsPath(L"example.txt"));
|
||||
TS_ASSERT_EQUALS(t1.Size(), (size_t)1234);
|
||||
|
||||
buf1 = t1.EncodeAsText();
|
||||
@ -44,7 +44,7 @@ public:
|
||||
|
||||
TraceEntry t2(TraceEntry::Store, L"example two.txt", 16777216);
|
||||
TS_ASSERT_EQUALS(t2.Action(), TraceEntry::Store);
|
||||
TS_ASSERT_WSTR_EQUALS(t2.Pathname(), L"example two.txt");
|
||||
TS_ASSERT_PATH_EQUALS(t2.Pathname(), OsPath(L"example two.txt"));
|
||||
TS_ASSERT_EQUALS(t2.Size(), (size_t)16777216);
|
||||
|
||||
buf2 = t2.EncodeAsText();
|
||||
@ -52,20 +52,20 @@ public:
|
||||
|
||||
TraceEntry t3(buf1);
|
||||
TS_ASSERT_EQUALS(t3.Action(), TraceEntry::Load);
|
||||
TS_ASSERT_WSTR_EQUALS(t3.Pathname(), L"example.txt");
|
||||
TS_ASSERT_PATH_EQUALS(t3.Pathname(), OsPath(L"example.txt"));
|
||||
TS_ASSERT_EQUALS(t3.Size(), (size_t)1234);
|
||||
|
||||
TraceEntry t4(buf2);
|
||||
TS_ASSERT_EQUALS(t4.Action(), TraceEntry::Store);
|
||||
TS_ASSERT_WSTR_EQUALS(t4.Pathname(), L"example two.txt");
|
||||
TS_ASSERT_PATH_EQUALS(t4.Pathname(), OsPath(L"example two.txt"));
|
||||
TS_ASSERT_EQUALS(t4.Size(), (size_t)16777216);
|
||||
}
|
||||
|
||||
void test_maxpath()
|
||||
{
|
||||
NativePath path1(PATH_MAX, L'x');
|
||||
std::wstring buf1 = L"0: L \"" + path1 + L"\" 0\n";
|
||||
OsPath path1(std::wstring(PATH_MAX, L'x'));
|
||||
std::wstring buf1 = L"0: L \"" + path1.string() + L"\" 0\n";
|
||||
TraceEntry t1(buf1);
|
||||
TS_ASSERT_WSTR_EQUALS(t1.Pathname(), path1);
|
||||
TS_ASSERT_PATH_EQUALS(t1.Pathname(), path1);
|
||||
}
|
||||
};
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "lib/allocators/pool.h"
|
||||
#include "lib/bits.h" // round_up
|
||||
#include "lib/timer.h" // timer_Time
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/sysdep/sysdep.h" // sys_OpenFile
|
||||
|
||||
|
||||
/*virtual*/ ITrace::~ITrace()
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TraceEntry::TraceEntry(EAction action, const NativePath& pathname, size_t size)
|
||||
TraceEntry::TraceEntry(EAction action, const Path& pathname, size_t size)
|
||||
: m_timestamp((float)timer_Time())
|
||||
, m_action(action)
|
||||
, m_pathname(pathname)
|
||||
@ -74,9 +74,9 @@ TraceEntry::TraceEntry(const std::wstring& text)
|
||||
stream >> dummy;
|
||||
debug_assert(dummy == '"');
|
||||
|
||||
NativePath pathname;
|
||||
Path::String pathname;
|
||||
std::getline(stream, pathname, L'"');
|
||||
m_pathname = pathname;
|
||||
m_pathname = Path(pathname);
|
||||
|
||||
stream >> m_size;
|
||||
|
||||
@ -90,7 +90,7 @@ std::wstring TraceEntry::EncodeAsText() const
|
||||
{
|
||||
const wchar_t action = (wchar_t)m_action;
|
||||
wchar_t buf[1000];
|
||||
swprintf_s(buf, ARRAY_SIZE(buf), L"%#010f: %c \"%ls\" %lu\n", m_timestamp, action, m_pathname.c_str(), (unsigned long)m_size);
|
||||
swprintf_s(buf, ARRAY_SIZE(buf), L"%#010f: %c \"%ls\" %lu\n", m_timestamp, action, m_pathname.string().c_str(), (unsigned long)m_size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -105,20 +105,20 @@ public:
|
||||
|
||||
}
|
||||
|
||||
virtual void NotifyLoad(const NativePath& UNUSED(pathname), size_t UNUSED(size))
|
||||
virtual void NotifyLoad(const Path& UNUSED(pathname), size_t UNUSED(size))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void NotifyStore(const NativePath& UNUSED(pathname), size_t UNUSED(size))
|
||||
virtual void NotifyStore(const Path& UNUSED(pathname), size_t UNUSED(size))
|
||||
{
|
||||
}
|
||||
|
||||
virtual LibError Load(const NativePath& UNUSED(pathname))
|
||||
virtual LibError Load(const OsPath& UNUSED(pathname))
|
||||
{
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
virtual LibError Store(const NativePath& UNUSED(pathname)) const
|
||||
virtual LibError Store(const OsPath& UNUSED(pathname)) const
|
||||
{
|
||||
return INFO::OK;
|
||||
}
|
||||
@ -156,24 +156,23 @@ public:
|
||||
(void)pool_destroy(&m_pool);
|
||||
}
|
||||
|
||||
virtual void NotifyLoad(const NativePath& pathname, size_t size)
|
||||
virtual void NotifyLoad(const Path& pathname, size_t size)
|
||||
{
|
||||
new(Allocate()) TraceEntry(TraceEntry::Load, pathname, size);
|
||||
}
|
||||
|
||||
virtual void NotifyStore(const NativePath& pathname, size_t size)
|
||||
virtual void NotifyStore(const Path& pathname, size_t size)
|
||||
{
|
||||
new(Allocate()) TraceEntry(TraceEntry::Store, pathname, size);
|
||||
}
|
||||
|
||||
virtual LibError Load(const NativePath& pathname)
|
||||
virtual LibError Load(const OsPath& pathname)
|
||||
{
|
||||
pool_free_all(&m_pool);
|
||||
|
||||
errno = 0;
|
||||
FILE* file;
|
||||
errno_t err = _wfopen_s(&file, pathname.c_str(), L"rt");
|
||||
if(err != 0)
|
||||
FILE* file = sys_OpenFile(pathname, "rt");
|
||||
if(!file)
|
||||
return LibError_from_errno();
|
||||
|
||||
for(;;)
|
||||
@ -188,12 +187,11 @@ public:
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
virtual LibError Store(const NativePath& pathname) const
|
||||
virtual LibError Store(const OsPath& pathname) const
|
||||
{
|
||||
errno = 0;
|
||||
FILE* file;
|
||||
errno_t err = _wfopen_s(&file, pathname.c_str(), L"at");
|
||||
if(err != 0)
|
||||
FILE* file = sys_OpenFile(pathname, "at");
|
||||
if(!file)
|
||||
return LibError_from_errno();
|
||||
for(size_t i = 0; i < NumEntries(); i++)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
Store = 'S'
|
||||
};
|
||||
|
||||
TraceEntry(EAction action, const NativePath& pathname, size_t size);
|
||||
TraceEntry(EAction action, const Path& pathname, size_t size);
|
||||
TraceEntry(const std::wstring& text);
|
||||
|
||||
EAction Action() const
|
||||
@ -55,7 +55,7 @@ public:
|
||||
return m_action;
|
||||
}
|
||||
|
||||
const NativePath& Pathname() const
|
||||
const Path& Pathname() const
|
||||
{
|
||||
return m_pathname;
|
||||
}
|
||||
@ -78,7 +78,7 @@ private:
|
||||
|
||||
EAction m_action;
|
||||
|
||||
NativePath m_pathname;
|
||||
Path m_pathname;
|
||||
|
||||
// size of file.
|
||||
// rationale: other applications using this trace format might not
|
||||
@ -93,8 +93,8 @@ struct ITrace
|
||||
{
|
||||
virtual ~ITrace();
|
||||
|
||||
virtual void NotifyLoad(const NativePath& pathname, size_t size) = 0;
|
||||
virtual void NotifyStore(const NativePath& pathname, size_t size) = 0;
|
||||
virtual void NotifyLoad(const Path& pathname, size_t size) = 0;
|
||||
virtual void NotifyStore(const Path& pathname, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* store all entries into a file.
|
||||
@ -105,7 +105,7 @@ struct ITrace
|
||||
* because storing filename strings in a binary format would be a
|
||||
* bit awkward.
|
||||
**/
|
||||
virtual LibError Store(const NativePath& pathname) const = 0;
|
||||
virtual LibError Store(const OsPath& pathname) const = 0;
|
||||
|
||||
/**
|
||||
* load entries from file.
|
||||
@ -114,7 +114,7 @@ struct ITrace
|
||||
*
|
||||
* replaces any existing entries.
|
||||
**/
|
||||
virtual LibError Load(const NativePath& osPathname) = 0;
|
||||
virtual LibError Load(const OsPath& pathname) = 0;
|
||||
|
||||
virtual const TraceEntry* Entries() const = 0;
|
||||
virtual size_t NumEntries() const = 0;
|
||||
|
@ -38,7 +38,7 @@ ERROR_ASSOCIATE(ERR::IO, L"Error during IO", EIO);
|
||||
|
||||
namespace FileImpl {
|
||||
|
||||
LibError Open(const NativePath& pathname, wchar_t accessType, int& fd)
|
||||
LibError Open(const OsPath& pathname, wchar_t accessType, int& fd)
|
||||
{
|
||||
int oflag = 0;
|
||||
switch(accessType)
|
||||
@ -61,7 +61,7 @@ LibError Open(const NativePath& pathname, wchar_t accessType, int& fd)
|
||||
// prevent exploits by disallowing writes to our files by other users.
|
||||
// note that the system-wide installed cache is read-only.
|
||||
const mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; // 0644
|
||||
fd = wopen(pathname.c_str(), oflag, mode);
|
||||
fd = wopen(pathname, oflag, mode);
|
||||
if(fd < 0)
|
||||
return LibError_from_errno(false);
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace ERR
|
||||
|
||||
namespace FileImpl
|
||||
{
|
||||
LIB_API LibError Open(const NativePath& pathname, wchar_t mode, int& fd);
|
||||
LIB_API LibError Open(const OsPath& pathname, wchar_t mode, int& fd);
|
||||
LIB_API void Close(int& fd);
|
||||
LIB_API LibError IO(int fd, wchar_t mode, off_t ofs, u8* buf, size_t size);
|
||||
LIB_API LibError Issue(aiocb& req, int fd, wchar_t mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize);
|
||||
@ -55,7 +55,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
LibError Open(const NativePath& pathname, wchar_t mode)
|
||||
LibError Open(const OsPath& pathname, wchar_t mode)
|
||||
{
|
||||
RETURN_ERR(FileImpl::Open(pathname, mode, m_fd));
|
||||
m_pathname = pathname;
|
||||
@ -68,7 +68,7 @@ public:
|
||||
FileImpl::Close(m_fd);
|
||||
}
|
||||
|
||||
File(const NativePath& pathname, wchar_t mode)
|
||||
File(const OsPath& pathname, wchar_t mode)
|
||||
{
|
||||
(void)Open(pathname, mode);
|
||||
}
|
||||
@ -78,7 +78,7 @@ public:
|
||||
Close();
|
||||
}
|
||||
|
||||
const NativePath& Pathname() const
|
||||
const OsPath& Pathname() const
|
||||
{
|
||||
return m_pathname;
|
||||
}
|
||||
@ -104,7 +104,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
NativePath m_pathname;
|
||||
OsPath m_pathname;
|
||||
int m_fd;
|
||||
wchar_t m_mode;
|
||||
};
|
||||
|
@ -40,19 +40,11 @@ struct DirDeleter
|
||||
}
|
||||
};
|
||||
|
||||
// is name "." or ".."?
|
||||
static bool IsDummyDirectory(const NativePath& name)
|
||||
{
|
||||
if(name[0] != '.')
|
||||
return false;
|
||||
return (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
|
||||
}
|
||||
|
||||
LibError GetDirectoryEntries(const NativePath& path, FileInfos* files, DirectoryNames* subdirectoryNames)
|
||||
LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames)
|
||||
{
|
||||
// open directory
|
||||
errno = 0;
|
||||
WDIR* pDir = wopendir(path.c_str());
|
||||
WDIR* pDir = wopendir(path);
|
||||
if(!pDir)
|
||||
return LibError_from_errno(false);
|
||||
shared_ptr<WDIR> osDir(pDir, DirDeleter());
|
||||
@ -69,8 +61,8 @@ LibError GetDirectoryEntries(const NativePath& path, FileInfos* files, Directory
|
||||
return LibError_from_errno();
|
||||
}
|
||||
|
||||
const NativePath name(osEnt->d_name);
|
||||
RETURN_ERR(path_component_validate(name.c_str()));
|
||||
const OsPath name(osEnt->d_name);
|
||||
RETURN_ERR(name.Validate());
|
||||
|
||||
// get file information (mode, size, mtime)
|
||||
struct stat s;
|
||||
@ -80,39 +72,39 @@ LibError GetDirectoryEntries(const NativePath& path, FileInfos* files, Directory
|
||||
#else
|
||||
// .. call regular stat().
|
||||
errno = 0;
|
||||
const NativePath pathname = Path::Join(path, name);
|
||||
if(wstat(pathname.c_str(), &s) != 0)
|
||||
const OsPath pathname = path / name;
|
||||
if(wstat(pathname, &s) != 0)
|
||||
return LibError_from_errno();
|
||||
#endif
|
||||
|
||||
if(files && S_ISREG(s.st_mode))
|
||||
files->push_back(FileInfo(name, s.st_size, s.st_mtime));
|
||||
else if(subdirectoryNames && S_ISDIR(s.st_mode) && !IsDummyDirectory(name))
|
||||
else if(subdirectoryNames && S_ISDIR(s.st_mode) && name != L"." && name != L"..")
|
||||
subdirectoryNames->push_back(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LibError GetFileInfo(const NativePath& pathname, FileInfo* pfileInfo)
|
||||
LibError GetFileInfo(const OsPath& pathname, FileInfo* pfileInfo)
|
||||
{
|
||||
errno = 0;
|
||||
struct stat s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
if(wstat(pathname.c_str(), &s) != 0)
|
||||
if(wstat(pathname, &s) != 0)
|
||||
return LibError_from_errno();
|
||||
|
||||
*pfileInfo = FileInfo(Path::Filename(pathname), s.st_size, s.st_mtime);
|
||||
*pfileInfo = FileInfo(pathname.Filename(), s.st_size, s.st_mtime);
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
LibError CreateDirectories(const NativePath& path, mode_t mode)
|
||||
LibError CreateDirectories(const OsPath& path, mode_t mode)
|
||||
{
|
||||
if(path.empty())
|
||||
return INFO::OK;
|
||||
|
||||
struct stat s;
|
||||
if(wstat(path.c_str(), &s) == 0)
|
||||
if(wstat(path, &s) == 0)
|
||||
{
|
||||
if(!S_ISDIR(s.st_mode)) // encountered a file
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
@ -120,21 +112,21 @@ LibError CreateDirectories(const NativePath& path, mode_t mode)
|
||||
}
|
||||
|
||||
// If we were passed a path ending with '/', strip the '/' now so that
|
||||
// we can consistently use Path to find parent directory names
|
||||
if(Path::IsDirectory(path))
|
||||
return CreateDirectories(Path::Path(path), mode);
|
||||
// we can consistently use Parent to find parent directory names
|
||||
if(path.IsDirectory())
|
||||
return CreateDirectories(path.Parent(), mode);
|
||||
|
||||
RETURN_ERR(CreateDirectories(Path::Path(path), mode));
|
||||
RETURN_ERR(CreateDirectories(path.Parent(), mode));
|
||||
|
||||
errno = 0;
|
||||
if(wmkdir(path.c_str(), mode) != 0)
|
||||
if(wmkdir(path, mode) != 0)
|
||||
return LibError_from_errno();
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
LibError DeleteDirectory(const NativePath& path)
|
||||
LibError DeleteDirectory(const OsPath& path)
|
||||
{
|
||||
// note: we have to recursively empty the directory before it can
|
||||
// be deleted (required by Windows and POSIX rmdir()).
|
||||
@ -145,18 +137,18 @@ LibError DeleteDirectory(const NativePath& path)
|
||||
// delete files
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
const NativePath pathname = Path::Join(path, files[i].Name());
|
||||
const OsPath pathname = path / files[i].Name();
|
||||
errno = 0;
|
||||
if(wunlink(pathname.c_str()) != 0)
|
||||
if(wunlink(pathname) != 0)
|
||||
return LibError_from_errno();
|
||||
}
|
||||
|
||||
// recurse over subdirectoryNames
|
||||
for(size_t i = 0; i < subdirectoryNames.size(); i++)
|
||||
RETURN_ERR(DeleteDirectory(Path::Join(path, subdirectoryNames[i])));
|
||||
RETURN_ERR(DeleteDirectory(path / subdirectoryNames[i]));
|
||||
|
||||
errno = 0;
|
||||
if(wrmdir(path.c_str()) != 0)
|
||||
if(wrmdir(path) != 0)
|
||||
return LibError_from_errno();
|
||||
|
||||
return INFO::OK;
|
||||
|
@ -34,12 +34,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
FileInfo(const NativePath& name, off_t size, time_t mtime)
|
||||
FileInfo(const OsPath& name, off_t size, time_t mtime)
|
||||
: name(name), size(size), mtime(mtime)
|
||||
{
|
||||
}
|
||||
|
||||
const NativePath& Name() const
|
||||
const OsPath& Name() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
@ -55,22 +55,22 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
NativePath name;
|
||||
OsPath name;
|
||||
off_t size;
|
||||
time_t mtime;
|
||||
};
|
||||
|
||||
extern LibError GetFileInfo(const NativePath& pathname, FileInfo* fileInfo);
|
||||
extern LibError GetFileInfo(const OsPath& pathname, FileInfo* fileInfo);
|
||||
|
||||
typedef std::vector<FileInfo> FileInfos;
|
||||
typedef std::vector<NativePath> DirectoryNames;
|
||||
typedef std::vector<OsPath> DirectoryNames;
|
||||
|
||||
extern LibError GetDirectoryEntries(const NativePath& path, FileInfos* files, DirectoryNames* subdirectoryNames);
|
||||
extern LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames);
|
||||
|
||||
// same as boost::filesystem::create_directories, except that mkdir is invoked with
|
||||
// <mode> instead of 0755.
|
||||
extern LibError CreateDirectories(const NativePath& path, mode_t mode);
|
||||
extern LibError CreateDirectories(const OsPath& path, mode_t mode);
|
||||
|
||||
extern LibError DeleteDirectory(const NativePath& dirPath);
|
||||
extern LibError DeleteDirectory(const OsPath& dirPath);
|
||||
|
||||
#endif // #ifndef INCLUDED_FILE_SYSTEM
|
||||
|
@ -31,12 +31,40 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/sysdep/filesystem.h"
|
||||
#include "lib/regex.h"
|
||||
|
||||
|
||||
namespace fs_util {
|
||||
|
||||
bool DirectoryExists(const OsPath& path)
|
||||
{
|
||||
WDIR* dir = wopendir(path);
|
||||
if(dir)
|
||||
{
|
||||
wclosedir(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FileExists(const OsPath& pathname)
|
||||
{
|
||||
struct stat s;
|
||||
const bool exists = wstat(pathname, &s) == 0;
|
||||
return exists;
|
||||
}
|
||||
|
||||
|
||||
u64 FileSize(const OsPath& pathname)
|
||||
{
|
||||
struct stat s;
|
||||
debug_assert(wstat(pathname, &s) == 0);
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
|
||||
LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames)
|
||||
{
|
||||
std::vector<FileInfo> files;
|
||||
@ -47,42 +75,14 @@ LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filte
|
||||
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
if(match_wildcard(files[i].Name().c_str(), filter))
|
||||
pathnames.push_back(Path::Join(path, files[i].Name()));
|
||||
if(match_wildcard(files[i].Name().string().c_str(), filter))
|
||||
pathnames.push_back(path / files[i].Name());
|
||||
}
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
struct FileInfoNameLess : public std::binary_function<const FileInfo, const FileInfo, bool>
|
||||
{
|
||||
bool operator()(const FileInfo& fileInfo1, const FileInfo& fileInfo2) const
|
||||
{
|
||||
return wcscasecmp(fileInfo1.Name().c_str(), fileInfo2.Name().c_str()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
void SortFiles(FileInfos& files)
|
||||
{
|
||||
std::sort(files.begin(), files.end(), FileInfoNameLess());
|
||||
}
|
||||
|
||||
|
||||
struct NameLess : public std::binary_function<const NativePath, const NativePath, bool>
|
||||
{
|
||||
bool operator()(const NativePath& name1, const NativePath& name2) const
|
||||
{
|
||||
return wcscasecmp(name1.c_str(), name2.c_str()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
void SortDirectories(DirectoryNames& directories)
|
||||
{
|
||||
std::sort(directories.begin(), directories.end(), NameLess());
|
||||
}
|
||||
|
||||
|
||||
LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags)
|
||||
{
|
||||
// (declare here to avoid reallocations)
|
||||
@ -91,7 +91,7 @@ LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb,
|
||||
// (a FIFO queue is more efficient than recursion because it uses less
|
||||
// stack space and avoids seeks due to breadth-first traversal.)
|
||||
std::queue<VfsPath> pendingDirectories;
|
||||
pendingDirectories.push(Path::AddSlash(startPath));
|
||||
pendingDirectories.push(startPath/"");
|
||||
while(!pendingDirectories.empty())
|
||||
{
|
||||
const VfsPath& path = pendingDirectories.front();
|
||||
@ -101,10 +101,10 @@ LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb,
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
const FileInfo fileInfo = files[i];
|
||||
if(!match_wildcard(fileInfo.Name().c_str(), pattern))
|
||||
if(!match_wildcard(fileInfo.Name().string().c_str(), pattern))
|
||||
continue;
|
||||
|
||||
const VfsPath pathname(Path::Join(path, fileInfo.Name())); // (FileInfo only stores the name)
|
||||
const VfsPath pathname(path / fileInfo.Name()); // (FileInfo only stores the name)
|
||||
cb(pathname, fileInfo, cbData);
|
||||
}
|
||||
|
||||
@ -112,15 +112,7 @@ LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb,
|
||||
break;
|
||||
|
||||
for(size_t i = 0; i < subdirectoryNames.size(); i++)
|
||||
{
|
||||
VfsPath pathname;
|
||||
if(path == L"/") // special case for startPath == L""
|
||||
pathname = Path::AddSlash(VfsPath(subdirectoryNames[i]));
|
||||
else
|
||||
pathname = Path::AddSlash(Path::Join(path, subdirectoryNames[i]));
|
||||
|
||||
pendingDirectories.push(pathname);
|
||||
}
|
||||
pendingDirectories.push(path / subdirectoryNames[i]/"");
|
||||
pendingDirectories.pop();
|
||||
}
|
||||
|
||||
@ -137,8 +129,8 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t
|
||||
// add 3rd -> without this measure it would get number 1, not 3.
|
||||
if(nextNumber == 0)
|
||||
{
|
||||
const NativePath nameFormat = Path::Filename(pathnameFormat);
|
||||
const VfsPath path = Path::AddSlash(Path::Path(pathnameFormat));
|
||||
const VfsPath nameFormat = pathnameFormat.Filename();
|
||||
const VfsPath path = pathnameFormat.Parent()/"";
|
||||
|
||||
size_t maxNumber = 0;
|
||||
FileInfos files;
|
||||
@ -146,7 +138,7 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
int number;
|
||||
if(swscanf_s(files[i].Name().c_str(), nameFormat.c_str(), &number) == 1)
|
||||
if(swscanf_s(files[i].Name().string().c_str(), nameFormat.string().c_str(), &number) == 1)
|
||||
maxNumber = std::max(size_t(number), maxNumber);
|
||||
}
|
||||
|
||||
@ -161,7 +153,7 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t
|
||||
do
|
||||
{
|
||||
wchar_t pathnameBuf[PATH_MAX];
|
||||
swprintf_s(pathnameBuf, ARRAY_SIZE(pathnameBuf), pathnameFormat.c_str(), nextNumber++);
|
||||
swprintf_s(pathnameBuf, ARRAY_SIZE(pathnameBuf), pathnameFormat.string().c_str(), nextNumber++);
|
||||
nextPathname = pathnameBuf;
|
||||
}
|
||||
while(fs->GetFileInfo(nextPathname, 0) == INFO::OK);
|
||||
|
@ -27,16 +27,18 @@
|
||||
#ifndef INCLUDED_FILE_SYSTEM_UTIL
|
||||
#define INCLUDED_FILE_SYSTEM_UTIL
|
||||
|
||||
#include "lib/native_path.h"
|
||||
#include "lib/file/vfs/vfs.h"
|
||||
|
||||
namespace fs_util {
|
||||
|
||||
extern void SortFiles(FileInfos& files);
|
||||
extern void SortDirectories(DirectoryNames& directories);
|
||||
extern bool DirectoryExists(const OsPath& path);
|
||||
extern bool FileExists(const OsPath& pathname);
|
||||
|
||||
extern u64 FileSize(const OsPath& pathname);
|
||||
|
||||
extern LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames);
|
||||
|
||||
|
||||
/**
|
||||
* called for files in a directory.
|
||||
*
|
||||
|
@ -43,9 +43,10 @@ BlockId::BlockId()
|
||||
{
|
||||
}
|
||||
|
||||
BlockId::BlockId(const NativePath& pathname, off_t ofs)
|
||||
BlockId::BlockId(const OsPath& pathname, off_t ofs)
|
||||
{
|
||||
m_id = fnv_hash64(pathname.c_str(), pathname.length()*sizeof(pathname[0]));
|
||||
const Path::String& string = pathname.string();
|
||||
m_id = fnv_hash64(string.c_str(), string.length()*sizeof(string[0]));
|
||||
const size_t indexBits = 16;
|
||||
m_id <<= indexBits;
|
||||
const off_t blockIndex = off_t(ofs / BLOCK_SIZE);
|
||||
|
@ -36,7 +36,7 @@ class BlockId
|
||||
{
|
||||
public:
|
||||
BlockId();
|
||||
BlockId(const NativePath& pathname, off_t ofs);
|
||||
BlockId(const OsPath& pathname, off_t ofs);
|
||||
bool operator==(const BlockId& rhs) const;
|
||||
bool operator!=(const BlockId& rhs) const;
|
||||
|
||||
|
@ -216,7 +216,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Cache< VfsPath, shared_ptr<u8> > CacheType;
|
||||
typedef Cache<VfsPath, shared_ptr<u8> > CacheType;
|
||||
CacheType m_cache;
|
||||
|
||||
PAllocator m_allocator;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "lib/file/vfs/vfs.h"
|
||||
|
||||
#include "lib/allocators/shared_ptr.h"
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/file/file_system_util.h"
|
||||
#include "lib/file/common/file_stats.h"
|
||||
#include "lib/file/common/trace.h"
|
||||
#include "lib/file/archive/archive.h"
|
||||
@ -47,9 +47,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const NativePath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
|
||||
{
|
||||
if(!DirectoryExists(path))
|
||||
if(!fs_util::DirectoryExists(path))
|
||||
{
|
||||
if(flags & VFS_MOUNT_MUST_EXIST)
|
||||
return ERR::VFS_DIR_NOT_FOUND; // NOWARN
|
||||
@ -119,7 +119,7 @@ public:
|
||||
CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE));
|
||||
|
||||
const PRealDirectory& realDirectory = directory->AssociatedDirectory();
|
||||
const NativePath name = Path::Filename(pathname);
|
||||
const OsPath name = pathname.Filename();
|
||||
RETURN_ERR(realDirectory->Store(name, fileContents, size));
|
||||
|
||||
// wipe out any cached blocks. this is necessary to cover the (rare) case
|
||||
@ -129,7 +129,7 @@ public:
|
||||
const VfsFile file(name, size, time(0), realDirectory->Priority(), realDirectory);
|
||||
directory->AddFile(file);
|
||||
|
||||
m_trace->NotifyStore(pathname.c_str(), size);
|
||||
m_trace->NotifyStore(pathname, size);
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ public:
|
||||
|
||||
stats_io_user_request(size);
|
||||
stats_cache(isCacheHit? CR_HIT : CR_MISS, size);
|
||||
m_trace->NotifyLoad(pathname.c_str(), size);
|
||||
m_trace->NotifyLoad(pathname, size);
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
@ -176,20 +176,20 @@ public:
|
||||
return textRepresentation;
|
||||
}
|
||||
|
||||
virtual LibError GetRealPath(const VfsPath& pathname, NativePath& realPathname)
|
||||
virtual LibError GetRealPath(const VfsPath& pathname, OsPath& realPathname)
|
||||
{
|
||||
VfsDirectory* directory; VfsFile* file;
|
||||
CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
|
||||
realPathname = Path::Join(file->Loader()->Path(), Path::Filename(pathname));
|
||||
realPathname = file->Loader()->Path() / pathname.Filename();
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
virtual LibError GetVirtualPath(const NativePath& realPathname, VfsPath& pathname)
|
||||
virtual LibError GetVirtualPath(const OsPath& realPathname, VfsPath& pathname)
|
||||
{
|
||||
const NativePath realPath = Path::AddSlash(Path::Path(realPathname));
|
||||
const OsPath realPath = realPathname.Parent()/"";
|
||||
VfsPath path;
|
||||
RETURN_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path));
|
||||
pathname = Path::Join(path, Path::Filename(realPathname));
|
||||
pathname = path / realPathname.Filename();
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ public:
|
||||
|
||||
VfsDirectory* directory;
|
||||
RETURN_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0));
|
||||
const NativePath name = Path::Filename(pathname);
|
||||
const OsPath name = pathname.Filename();
|
||||
directory->Invalidate(name);
|
||||
|
||||
return INFO::OK;
|
||||
@ -211,7 +211,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
LibError FindRealPathR(const NativePath& realPath, const VfsDirectory& directory, const VfsPath& curPath, VfsPath& path)
|
||||
LibError FindRealPathR(const OsPath& realPath, const VfsDirectory& directory, const VfsPath& curPath, VfsPath& path)
|
||||
{
|
||||
PRealDirectory realDirectory = directory.AssociatedDirectory();
|
||||
if(realDirectory && realDirectory->Path() == realPath)
|
||||
@ -223,9 +223,9 @@ private:
|
||||
const VfsDirectory::VfsSubdirectories& subdirectories = directory.Subdirectories();
|
||||
for(VfsDirectory::VfsSubdirectories::const_iterator it = subdirectories.begin(); it != subdirectories.end(); ++it)
|
||||
{
|
||||
const NativePath& subdirectoryName = it->first;
|
||||
const OsPath& subdirectoryName = it->first;
|
||||
const VfsDirectory& subdirectory = it->second;
|
||||
LibError ret = FindRealPathR(realPath, subdirectory, Path::AddSlash(Path::Join(curPath, subdirectoryName)), path);
|
||||
LibError ret = FindRealPathR(realPath, subdirectory, curPath / subdirectoryName/"", path);
|
||||
if(ret == INFO::OK)
|
||||
return INFO::OK;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ struct IVFS
|
||||
* if files with archive extensions are seen, their contents are added
|
||||
* as well.
|
||||
**/
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const NativePath& path, size_t flags = 0, size_t priority = 0) = 0;
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags = 0, size_t priority = 0) = 0;
|
||||
|
||||
/**
|
||||
* Retrieve information about a file (similar to POSIX stat).
|
||||
@ -151,7 +151,7 @@ struct IVFS
|
||||
*
|
||||
* this is useful for passing paths to external libraries.
|
||||
**/
|
||||
virtual LibError GetRealPath(const VfsPath& pathname, NativePath& realPathname) = 0;
|
||||
virtual LibError GetRealPath(const VfsPath& pathname, OsPath& realPathname) = 0;
|
||||
|
||||
/**
|
||||
* retrieve the VFS pathname that corresponds to a real file.
|
||||
@ -162,7 +162,7 @@ struct IVFS
|
||||
* number of directories; this could be accelerated by only checking
|
||||
* directories below a mount point with a matching real path.
|
||||
**/
|
||||
virtual LibError GetVirtualPath(const NativePath& realPathname, VfsPath& pathname) = 0;
|
||||
virtual LibError GetVirtualPath(const OsPath& realPathname, VfsPath& pathname) = 0;
|
||||
|
||||
/**
|
||||
* indicate that a file has changed; remove its data from the cache and
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "lib/external_libraries/suppress_boost_warnings.h"
|
||||
|
||||
#include "lib/path_util.h" // path_foreach_component
|
||||
#include "lib/sysdep/filesystem.h"
|
||||
#include "lib/file/vfs/vfs.h" // error codes
|
||||
#include "lib/file/vfs/vfs_tree.h"
|
||||
#include "lib/file/vfs/vfs_populate.h"
|
||||
@ -37,11 +37,11 @@
|
||||
#include "lib/timer.h"
|
||||
|
||||
|
||||
static LibError CreateDirectory(const NativePath& path)
|
||||
static LibError CreateDirectory(const OsPath& path)
|
||||
{
|
||||
{
|
||||
const mode_t mode = S_IRWXU; // 0700 as prescribed by XDG basedir
|
||||
const int ret = wmkdir(path.c_str(), mode);
|
||||
const int ret = wmkdir(path, mode);
|
||||
if(ret == 0) // success
|
||||
return INFO::OK;
|
||||
}
|
||||
@ -55,7 +55,7 @@ static LibError CreateDirectory(const NativePath& path)
|
||||
// but first ensure it's really a directory (otherwise, a
|
||||
// file is "in the way" and needs to be deleted)
|
||||
struct stat s;
|
||||
const int ret = wstat(path.c_str(), &s);
|
||||
const int ret = wstat(path, &s);
|
||||
debug_assert(ret == 0); // (wmkdir said it existed)
|
||||
debug_assert(S_ISDIR(s.st_mode));
|
||||
return INFO::OK;
|
||||
@ -96,10 +96,10 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi
|
||||
size_t pos = 0; // (needed outside of loop)
|
||||
for(;;)
|
||||
{
|
||||
const size_t nextSlash = pathname.find_first_of('/', pos);
|
||||
if(nextSlash == VfsPath::npos)
|
||||
const size_t nextSlash = pathname.string().find_first_of('/', pos);
|
||||
if(nextSlash == VfsPath::String::npos)
|
||||
break;
|
||||
const NativePath subdirectoryName = pathname.substr(pos, nextSlash-pos);
|
||||
const VfsPath subdirectoryName = pathname.string().substr(pos, nextSlash-pos);
|
||||
pos = nextSlash+1;
|
||||
|
||||
VfsDirectory* subdirectory = directory->GetSubdirectory(subdirectoryName);
|
||||
@ -113,10 +113,10 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi
|
||||
|
||||
if(createMissingDirectories && !subdirectory->AssociatedDirectory())
|
||||
{
|
||||
NativePath currentPath;
|
||||
OsPath currentPath;
|
||||
if(directory->AssociatedDirectory()) // (is NULL when mounting into root)
|
||||
currentPath = directory->AssociatedDirectory()->Path();
|
||||
currentPath = Path::Join(currentPath, subdirectoryName);
|
||||
currentPath = currentPath / subdirectoryName;
|
||||
|
||||
RETURN_ERR(CreateDirectory(currentPath));
|
||||
|
||||
@ -132,8 +132,8 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi
|
||||
|
||||
if(pfile)
|
||||
{
|
||||
const NativePath& filename = pathname.substr(pos);
|
||||
debug_assert(!filename.empty()); // asked for file but specified directory path
|
||||
debug_assert(!pathname.IsDirectory());
|
||||
const VfsPath filename = pathname.string().substr(pos);
|
||||
*pfile = directory->GetFile(filename);
|
||||
if(!*pfile)
|
||||
return ERR::VFS_FILE_NOT_FOUND; // NOWARN
|
||||
|
@ -36,7 +36,8 @@
|
||||
* there is no restriction on path length; when dimensioning character
|
||||
* arrays, prefer PATH_MAX.
|
||||
**/
|
||||
typedef std::wstring VfsPath;
|
||||
|
||||
typedef Path VfsPath;
|
||||
|
||||
typedef std::vector<VfsPath> VfsPaths;
|
||||
|
||||
|
@ -104,13 +104,12 @@ private:
|
||||
|
||||
LibError AddFiles(const FileInfos& files) const
|
||||
{
|
||||
const NativePath path(m_realDirectory->Path());
|
||||
const OsPath path(m_realDirectory->Path());
|
||||
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
const NativePath pathname = Path::Join(path, files[i].Name());
|
||||
const NativePath extension = Path::Extension(pathname);
|
||||
if(wcscasecmp(extension.c_str(), L".zip") == 0)
|
||||
const OsPath pathname = path / files[i].Name();
|
||||
if(pathname.Extension() == L".zip")
|
||||
{
|
||||
PIArchiveReader archiveReader = CreateArchiveReader_Zip(pathname);
|
||||
RETURN_ERR(archiveReader->ReadEntries(AddArchiveFile, (uintptr_t)this));
|
||||
@ -128,7 +127,7 @@ private:
|
||||
{
|
||||
// skip version control directories - this avoids cluttering the
|
||||
// VFS with hundreds of irrelevant files.
|
||||
if(wcscasecmp(subdirectoryNames[i].c_str(), L".svn") == 0)
|
||||
if(subdirectoryNames[i] == L".svn")
|
||||
continue;
|
||||
|
||||
VfsDirectory* subdirectory = m_directory->AddSubdirectory(subdirectoryNames[i]);
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
VfsFile::VfsFile(const NativePath& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& loader)
|
||||
VfsFile::VfsFile(const VfsPath& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& loader)
|
||||
: m_name(name), m_size(size), m_mtime(mtime), m_priority(priority), m_loader(loader)
|
||||
{
|
||||
}
|
||||
@ -78,7 +78,7 @@ static bool ShouldReplaceWith(const VfsFile& previousFile, const VfsFile& newFil
|
||||
|
||||
VfsFile* VfsDirectory::AddFile(const VfsFile& file)
|
||||
{
|
||||
std::pair<NativePath, VfsFile> value = std::make_pair(file.Name(), file);
|
||||
std::pair<VfsPath, VfsFile> value = std::make_pair(file.Name(), file);
|
||||
std::pair<VfsFiles::iterator, bool> ret = m_files.insert(value);
|
||||
if(!ret.second) // already existed
|
||||
{
|
||||
@ -98,26 +98,26 @@ VfsFile* VfsDirectory::AddFile(const VfsFile& file)
|
||||
|
||||
// rationale: passing in a pre-constructed VfsDirectory and copying that into
|
||||
// our map would be slower and less convenient for the caller.
|
||||
VfsDirectory* VfsDirectory::AddSubdirectory(const NativePath& name)
|
||||
VfsDirectory* VfsDirectory::AddSubdirectory(const VfsPath& name)
|
||||
{
|
||||
std::pair<NativePath, VfsDirectory> value = std::make_pair(name, VfsDirectory());
|
||||
std::pair<VfsPath, VfsDirectory> value = std::make_pair(name.string(), VfsDirectory());
|
||||
std::pair<VfsSubdirectories::iterator, bool> ret = m_subdirectories.insert(value);
|
||||
return &(*ret.first).second;
|
||||
}
|
||||
|
||||
|
||||
VfsFile* VfsDirectory::GetFile(const NativePath& name)
|
||||
VfsFile* VfsDirectory::GetFile(const VfsPath& name)
|
||||
{
|
||||
VfsFiles::iterator it = m_files.find(name);
|
||||
VfsFiles::iterator it = m_files.find(name.string());
|
||||
if(it == m_files.end())
|
||||
return 0;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
|
||||
VfsDirectory* VfsDirectory::GetSubdirectory(const NativePath& name)
|
||||
VfsDirectory* VfsDirectory::GetSubdirectory(const VfsPath& name)
|
||||
{
|
||||
VfsSubdirectories::iterator it = m_subdirectories.find(name);
|
||||
VfsSubdirectories::iterator it = m_subdirectories.find(name.string());
|
||||
if(it == m_subdirectories.end())
|
||||
return 0;
|
||||
return &it->second;
|
||||
@ -138,9 +138,9 @@ bool VfsDirectory::ShouldPopulate()
|
||||
}
|
||||
|
||||
|
||||
void VfsDirectory::Invalidate(const NativePath& name)
|
||||
void VfsDirectory::Invalidate(const VfsPath& name)
|
||||
{
|
||||
m_files.erase(name);
|
||||
m_files.erase(name.string());
|
||||
m_shouldPopulate = 1;
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ std::wstring FileDescription(const VfsFile& file)
|
||||
wcsftime(timestamp, ARRAY_SIZE(timestamp), L"%a %b %d %H:%M:%S %Y", localtime(&mtime));
|
||||
|
||||
wchar_t buf[200];
|
||||
swprintf_s(buf, ARRAY_SIZE(buf), L"(%c; %6lu; %ls) %ls", file.Loader()->LocationCode(), (unsigned long)file.Size(), timestamp, file.Name().c_str());
|
||||
swprintf_s(buf, ARRAY_SIZE(buf), L"(%c; %6lu; %ls) %ls", file.Loader()->LocationCode(), (unsigned long)file.Size(), timestamp, file.Name().string().c_str());
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -195,10 +195,10 @@ void DirectoryDescriptionR(std::wstring& descriptions, const VfsDirectory& direc
|
||||
const VfsDirectory::VfsSubdirectories& subdirectories = directory.Subdirectories();
|
||||
for(VfsDirectory::VfsSubdirectories::const_iterator it = subdirectories.begin(); it != subdirectories.end(); ++it)
|
||||
{
|
||||
const NativePath& name = it->first;
|
||||
const VfsPath& name = it->first;
|
||||
const VfsDirectory& subdirectory = it->second;
|
||||
descriptions += indentation;
|
||||
descriptions += std::wstring(L"[") + name + L"]\n";
|
||||
descriptions += std::wstring(L"[") + name.string() + L"]\n";
|
||||
descriptions += FileDescriptions(subdirectory, indentLevel+1);
|
||||
|
||||
DirectoryDescriptionR(descriptions, subdirectory, indentLevel+1);
|
||||
|
@ -32,13 +32,14 @@
|
||||
#include "lib/file/file_system.h" // FileInfo
|
||||
#include "lib/file/common/file_loader.h" // PIFileLoader
|
||||
#include "lib/file/common/real_directory.h" // PRealDirectory
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
|
||||
class VfsFile
|
||||
{
|
||||
public:
|
||||
VfsFile(const NativePath& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& provider);
|
||||
VfsFile(const VfsPath& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& provider);
|
||||
|
||||
const NativePath& Name() const
|
||||
const VfsPath& Name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
@ -64,7 +65,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
NativePath m_name;
|
||||
VfsPath m_name;
|
||||
size_t m_size;
|
||||
time_t m_mtime;
|
||||
|
||||
@ -77,8 +78,8 @@ private:
|
||||
class VfsDirectory
|
||||
{
|
||||
public:
|
||||
typedef std::map<NativePath, VfsFile> VfsFiles;
|
||||
typedef std::map<NativePath, VfsDirectory> VfsSubdirectories;
|
||||
typedef std::map<VfsPath, VfsFile> VfsFiles;
|
||||
typedef std::map<VfsPath, VfsDirectory> VfsSubdirectories;
|
||||
|
||||
VfsDirectory();
|
||||
|
||||
@ -90,19 +91,19 @@ public:
|
||||
/**
|
||||
* @return address of existing or newly inserted subdirectory.
|
||||
**/
|
||||
VfsDirectory* AddSubdirectory(const NativePath& name);
|
||||
VfsDirectory* AddSubdirectory(const VfsPath& name);
|
||||
|
||||
/**
|
||||
* @return file with the given name.
|
||||
* (note: non-const to allow changes to the file)
|
||||
**/
|
||||
VfsFile* GetFile(const NativePath& name);
|
||||
VfsFile* GetFile(const VfsPath& name);
|
||||
|
||||
/**
|
||||
* @return subdirectory with the given name.
|
||||
* (note: non-const to allow changes to the subdirectory)
|
||||
**/
|
||||
VfsDirectory* GetSubdirectory(const NativePath& name);
|
||||
VfsDirectory* GetSubdirectory(const VfsPath& name);
|
||||
|
||||
// note: exposing only iterators wouldn't enable callers to reserve space.
|
||||
|
||||
@ -137,7 +138,7 @@ public:
|
||||
* indicate that a file has changed; ensure its new version supersedes
|
||||
* the old by removing it and marking the directory for re-population.
|
||||
**/
|
||||
void Invalidate(const NativePath& name);
|
||||
void Invalidate(const VfsPath& name);
|
||||
|
||||
/**
|
||||
* empty file and subdirectory lists (e.g. when rebuilding VFS).
|
||||
|
@ -23,43 +23,34 @@
|
||||
#ifndef INCLUDED_NATIVE_PATH
|
||||
#define INCLUDED_NATIVE_PATH
|
||||
|
||||
#include <string>
|
||||
#include "lib/path_util.h"
|
||||
|
||||
// rationale:
|
||||
// this is conceptually a different kind of path, not a superset of VfsPath,
|
||||
// hence NativePath instead of Path (PathUtil is a bit clunky as a
|
||||
// namespace anyway).
|
||||
// a typedef instead of wrapper class avoids the need for accessor functions
|
||||
// (e.g. boost::filesystem::string()) at the cost of somewhat diminished safety.
|
||||
// users are responsible for ensuring the path doesn't contain any forbidden
|
||||
// characters (including any code points >= 0x100 on anything but Windows)
|
||||
typedef std::wstring NativePath;
|
||||
|
||||
static inline NativePath NativePathFromString(const std::string& string)
|
||||
{
|
||||
return NativePath(string.begin(), string.end());
|
||||
}
|
||||
typedef Path OsPath;
|
||||
|
||||
#if OS_WIN
|
||||
|
||||
static inline std::wstring StringFromNativePath(const NativePath& npath)
|
||||
static inline const Path::String& OsString(const OsPath& path)
|
||||
{
|
||||
return npath;
|
||||
return path.string();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline std::string StringFromNativePath(const NativePath& npath)
|
||||
static inline std::string OsString(const OsPath& path)
|
||||
{
|
||||
std::string string(npath.length(), '\0');
|
||||
for(size_t i = 0; i < npath.length(); i++)
|
||||
const Path::String& wstring = path.string();
|
||||
std::string string(wstring.length(), '\0');
|
||||
for(size_t i = 0; i < wstring.length(); i++)
|
||||
{
|
||||
debug_assert(npath[i] <= UCHAR_MAX);
|
||||
string[i] = npath[i];
|
||||
debug_assert(wstring[i] <= UCHAR_MAX);
|
||||
string[i] = wstring[i];
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // #ifndef INCLUDED_NATIVE_PATH
|
||||
|
@ -77,32 +77,6 @@ bool path_is_subpath(const wchar_t* s1, const wchar_t* s2)
|
||||
}
|
||||
|
||||
|
||||
// if name is invalid, return a descriptive error code, otherwise INFO::OK.
|
||||
// (name is a path component, i.e. that between directory separators)
|
||||
LibError path_component_validate(const wchar_t* name)
|
||||
{
|
||||
// disallow empty strings
|
||||
if(*name == '\0')
|
||||
WARN_RETURN(ERR::PATH_EMPTY);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
const int c = *name++;
|
||||
|
||||
// disallow *any* dir separators (regardless of which
|
||||
// platform we're on).
|
||||
if(c == '\\' || c == ':' || c == '/')
|
||||
WARN_RETURN(ERR::PATH_COMPONENT_SEPARATOR);
|
||||
|
||||
// end of string, no errors encountered
|
||||
if(c == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// return pointer to the name component within path (i.e. skips over all
|
||||
@ -117,7 +91,5 @@ const wchar_t* path_name_only(const wchar_t* path)
|
||||
|
||||
// return name, i.e. component after the last slash
|
||||
const wchar_t* name = std::max(slash1, slash2)+1;
|
||||
if(name[0] != '\0') // else path_component_validate would complain
|
||||
path_component_validate(name);
|
||||
return name;
|
||||
}
|
||||
|
@ -37,8 +37,9 @@
|
||||
#ifndef INCLUDED_PATH_UTIL
|
||||
#define INCLUDED_PATH_UTIL
|
||||
|
||||
#include "lib/native_path.h"
|
||||
#include "lib/posix/posix_filesystem.h"
|
||||
#if CONFIG_ENABLE_BOOST
|
||||
# include "boost/functional/hash.hpp"
|
||||
#endif
|
||||
|
||||
namespace ERR
|
||||
{
|
||||
@ -47,13 +48,6 @@ namespace ERR
|
||||
const LibError PATH_NOT_FOUND = -100302;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if name is valid. (see source for criteria)
|
||||
*
|
||||
* @return LibError (ERR::PATH_* or INFO::OK)
|
||||
**/
|
||||
LIB_API LibError path_component_validate(const wchar_t* name);
|
||||
|
||||
/**
|
||||
* is s2 a subpath of s1, or vice versa? (equal counts as subpath)
|
||||
*
|
||||
@ -63,141 +57,168 @@ LIB_API LibError path_component_validate(const wchar_t* name);
|
||||
LIB_API bool path_is_subpath(const wchar_t* s1, const wchar_t* s2);
|
||||
|
||||
/**
|
||||
* Get the name component of a path.
|
||||
* Get the path component of a path.
|
||||
* Skips over all characters up to the last dir separator, if any.
|
||||
*
|
||||
* @param path Input path.
|
||||
* @return pointer to name component within \<path\>.
|
||||
* @return pointer to path component within \<path\>.
|
||||
**/
|
||||
LIB_API const wchar_t* path_name_only(const wchar_t* path);
|
||||
|
||||
namespace Path {
|
||||
|
||||
template<class Path_t>
|
||||
static inline bool IsDirectory(const Path_t& pathname)
|
||||
// NB: there is a need for 'generic' paths (e.g. for Trace entry / archive pathnames).
|
||||
// converting via c_str would be inefficient, and the Os/VfsPath typedefs are hopefully
|
||||
// sufficient to avoid errors.
|
||||
class Path
|
||||
{
|
||||
if(pathname.empty()) // (ensure length()-1 is safe)
|
||||
return true; // (the VFS root directory is represented as an empty string)
|
||||
public:
|
||||
typedef std::wstring String;
|
||||
|
||||
// note: ideally, path strings would only contain '/' or even SYS_DIR_SEP.
|
||||
// however, windows-specific code (e.g. the sound driver detection)
|
||||
// uses these routines with '\\' strings. converting them all to
|
||||
// '/' and then back before passing to OS functions would be annoying.
|
||||
// also, the self-tests verify correct operation of such strings.
|
||||
// it would be error-prone to only test the platform's separator
|
||||
// strings there. hence, we allow all separators here.
|
||||
return pathname[pathname.length()-1] == '/' || pathname[pathname.length()-1] == '\\';
|
||||
}
|
||||
Path() {}
|
||||
Path(const char* p) : path(p, p+strlen(p)) {}
|
||||
Path(const wchar_t* p) : path(p, p+wcslen(p)) {}
|
||||
Path(const std::string& s) : path(s.begin(), s.end()) {}
|
||||
Path(const std::wstring& s) : path(s) {}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Path(const Path_t& pathname)
|
||||
{
|
||||
size_t n = pathname.find_last_of('/');
|
||||
if(n == Path_t::npos)
|
||||
bool empty() const
|
||||
{
|
||||
n = pathname.find_last_of('\\');
|
||||
if(n == Path_t::npos)
|
||||
return L"";
|
||||
return path.empty();
|
||||
}
|
||||
return pathname.substr(0, n);
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Filename(const Path_t& pathname)
|
||||
{
|
||||
size_t n = pathname.find_last_of('/');
|
||||
if(n == Path_t::npos)
|
||||
const String& string() const
|
||||
{
|
||||
n = pathname.find_last_of('\\');
|
||||
if(n == Path_t::npos)
|
||||
return pathname;
|
||||
return path;
|
||||
}
|
||||
return pathname.substr(n+1);
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Basename(const Path_t& pathname)
|
||||
{
|
||||
const Path_t filename = Filename(pathname);
|
||||
const size_t idxDot = filename.find_last_of('.');
|
||||
if(idxDot == Path_t::npos)
|
||||
return filename;
|
||||
return filename.substr(0, idxDot);
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline std::wstring Extension(const Path_t& pathname)
|
||||
{
|
||||
const size_t idxDot = pathname.find_last_of('.');
|
||||
if(idxDot == Path_t::npos)
|
||||
return Path_t();
|
||||
return pathname.substr(idxDot);
|
||||
}
|
||||
|
||||
static inline std::wstring JoinPathStrings(const std::wstring& path1, const std::wstring& path2)
|
||||
{
|
||||
std::wstring ret = path1;
|
||||
if(!IsDirectory(path1))
|
||||
ret += '/';
|
||||
ret += path2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Join(const Path_t& path1, const Path_t& path2)
|
||||
{
|
||||
return JoinPathStrings(path1, path2);
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Join(const Path_t& path1, const char* literal)
|
||||
{
|
||||
return JoinPathStrings(path1, NativePathFromString(literal));
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t Join(const char* literal, const Path_t& path2)
|
||||
{
|
||||
return JoinPathStrings(NativePathFromString(literal), path2);
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t AddSlash(const Path_t& path)
|
||||
{
|
||||
return IsDirectory(path)? path : path+L'/';
|
||||
}
|
||||
|
||||
template<class Path_t>
|
||||
static inline Path_t ChangeExtension(const Path_t& pathname, const std::wstring& extension)
|
||||
{
|
||||
return Join(Path(pathname), Basename(pathname)+extension);
|
||||
}
|
||||
|
||||
} // namespace Path
|
||||
|
||||
static inline bool FileExists(const NativePath& pathname)
|
||||
{
|
||||
struct stat s;
|
||||
const bool exists = wstat(pathname.c_str(), &s) == 0;
|
||||
return exists;
|
||||
}
|
||||
|
||||
static inline u64 FileSize(const NativePath& pathname)
|
||||
{
|
||||
struct stat s;
|
||||
debug_assert(wstat(pathname.c_str(), &s) == 0);
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
static inline bool DirectoryExists(const NativePath& path)
|
||||
{
|
||||
WDIR* dir = wopendir(path.c_str());
|
||||
if(dir)
|
||||
bool operator<(const Path& rhs) const
|
||||
{
|
||||
wclosedir(dir);
|
||||
return true;
|
||||
return wcscasecmp(path.c_str(), rhs.path.c_str()) < 0;
|
||||
}
|
||||
return false;
|
||||
|
||||
bool operator==(const Path& rhs) const
|
||||
{
|
||||
return wcscasecmp(path.c_str(), rhs.path.c_str()) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const Path& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
bool IsDirectory() const
|
||||
{
|
||||
if(empty()) // (ensure length()-1 is safe)
|
||||
return true; // (the VFS root directory is represented as an empty string)
|
||||
|
||||
// note: ideally, path strings would only contain '/' or even SYS_DIR_SEP.
|
||||
// however, windows-specific code (e.g. the sound driver detection)
|
||||
// uses these routines with '\\' strings. converting them all to
|
||||
// '/' and then back before passing to OS functions would be annoying.
|
||||
// also, the self-tests verify correct operation of such strings.
|
||||
// it would be error-prone to only test the platform's separators.
|
||||
// we therefore allow all separators here.
|
||||
return path[path.length()-1] == '/' || path[path.length()-1] == '\\';
|
||||
}
|
||||
|
||||
Path Parent() const
|
||||
{
|
||||
size_t idxSlash = path.find_last_of('/');
|
||||
if(idxSlash == String::npos)
|
||||
{
|
||||
idxSlash = path.find_last_of('\\');
|
||||
if(idxSlash == String::npos)
|
||||
return L"";
|
||||
}
|
||||
return path.substr(0, idxSlash);
|
||||
}
|
||||
|
||||
Path Filename() const
|
||||
{
|
||||
size_t idxSlash = path.find_last_of('/');
|
||||
if(idxSlash == String::npos)
|
||||
{
|
||||
idxSlash = path.find_last_of('\\');
|
||||
if(idxSlash == String::npos)
|
||||
return path;
|
||||
}
|
||||
return path.substr(idxSlash+1);
|
||||
}
|
||||
|
||||
Path Basename() const
|
||||
{
|
||||
const Path filename = Filename();
|
||||
const size_t idxDot = filename.string().find_last_of('.');
|
||||
if(idxDot == String::npos)
|
||||
return filename;
|
||||
return filename.string().substr(0, idxDot);
|
||||
}
|
||||
|
||||
// (Path return type allows callers to use our operator==)
|
||||
Path Extension() const
|
||||
{
|
||||
const Path filename = Filename();
|
||||
const size_t idxDot = filename.string().find_last_of('.');
|
||||
if(idxDot == String::npos)
|
||||
return Path();
|
||||
return filename.string().substr(idxDot);
|
||||
}
|
||||
|
||||
Path ChangeExtension(Path extension) const
|
||||
{
|
||||
return Parent() / Path(Basename().string() + extension.string());
|
||||
}
|
||||
|
||||
Path operator/(Path rhs) const
|
||||
{
|
||||
Path ret = *this;
|
||||
if(!ret.IsDirectory())
|
||||
ret.path += '/';
|
||||
ret.path += rhs.path;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LibError Validate() const
|
||||
{
|
||||
for(size_t i = 0; i < path.length(); i++)
|
||||
{
|
||||
}
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
private:
|
||||
String path;
|
||||
};
|
||||
|
||||
static inline std::wostream& operator<<(std::wostream& s, const Path& path)
|
||||
{
|
||||
s << path.string();
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline std::wistream& operator>>(std::wistream& s, Path& path)
|
||||
{
|
||||
Path::String string;
|
||||
s >> string;
|
||||
path = Path(string);
|
||||
return s;
|
||||
}
|
||||
|
||||
#if CONFIG_ENABLE_BOOST
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<>
|
||||
struct hash<Path> : std::unary_function<Path, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const Path& path) const
|
||||
{
|
||||
return hash_value(path.string());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // #if CONFIG_ENABLE_BOOST
|
||||
|
||||
#endif // #ifndef INCLUDED_PATH_UTIL
|
||||
|
@ -188,21 +188,20 @@ static void Cursor_dtor(Cursor* c)
|
||||
|
||||
static LibError Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name, Handle)
|
||||
{
|
||||
const VfsPath path(L"art/textures/cursors");
|
||||
const VfsPath pathname(Path::Join(path, name));
|
||||
const VfsPath pathname(VfsPath(L"art/textures/cursors") / name);
|
||||
|
||||
// read pixel offset of the cursor's hotspot [the bit of it that's
|
||||
// drawn at (g_mouse_x,g_mouse_y)] from file.
|
||||
int hotspotx = 0, hotspoty = 0;
|
||||
{
|
||||
const VfsPath pathnameHotspot = Path::ChangeExtension(pathname, L".txt");
|
||||
const VfsPath pathnameHotspot = pathname.ChangeExtension(L".txt");
|
||||
shared_ptr<u8> buf; size_t size;
|
||||
RETURN_ERR(vfs->LoadFile(pathnameHotspot, buf, size));
|
||||
std::wstringstream s(std::wstring((const wchar_t*)buf.get(), size));
|
||||
s >> hotspotx >> hotspoty;
|
||||
}
|
||||
|
||||
const VfsPath pathnameImage = Path::ChangeExtension(pathname, L".png");
|
||||
const VfsPath pathnameImage = pathname.ChangeExtension(L".png");
|
||||
|
||||
// try loading as system cursor (2d, hardware accelerated)
|
||||
if(load_sys_cursor(vfs, pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK)
|
||||
|
@ -165,7 +165,7 @@ static LibError Ogl_Shader_reload(Ogl_Shader* shdr, const PIVFS& vfs, const VfsP
|
||||
{
|
||||
char* infolog = new char[log_length];
|
||||
pglGetShaderInfoLog(shdr->id, log_length, 0, infolog);
|
||||
debug_printf(L"Compile log for shader %ls (type %ls):\n%hs", pathname.c_str(), type.c_str(), infolog);
|
||||
debug_printf(L"Compile log for shader %ls (type %ls):\n%hs", pathname.string().c_str(), type.c_str(), infolog);
|
||||
delete[] infolog;
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ static LibError Ogl_Shader_reload(Ogl_Shader* shdr, const PIVFS& vfs, const VfsP
|
||||
// useful some time.
|
||||
ogl_WarnIfError();
|
||||
|
||||
debug_printf(L"Failed to compile shader %ls (type %ls)\n", pathname.c_str(), type.c_str());
|
||||
debug_printf(L"Failed to compile shader %ls (type %ls)\n", pathname.string().c_str(), type.c_str());
|
||||
|
||||
err = ERR::SHDR_COMPILE;
|
||||
goto fail_shadercreated;
|
||||
@ -284,7 +284,7 @@ static LibError do_load_shader(
|
||||
|
||||
if (Type.empty())
|
||||
{
|
||||
LOGERROR(L"%ls: Missing attribute \"type\" in element \"Shader\".", pathname.c_str());
|
||||
LOGERROR(L"%ls: Missing attribute \"type\" in element \"Shader\".", pathname.string().c_str());
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ static LibError do_load_shader(
|
||||
|
||||
if (!shadertype)
|
||||
{
|
||||
LOGERROR(L"%ls: Unknown shader type \"%hs\" (valid are: VERTEX_SHADER, FRAGMENT_SHADER).", pathname.c_str(), Type.c_str());
|
||||
LOGERROR(L"%ls: Unknown shader type \"%hs\" (valid are: VERTEX_SHADER, FRAGMENT_SHADER).", pathname.string().c_str(), Type.c_str());
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ static LibError do_load_shader(
|
||||
|
||||
if (pathnameShader.empty())
|
||||
{
|
||||
LOGERROR(L"%ls: Missing shader name.", pathname.c_str());
|
||||
LOGERROR(L"%ls: Missing shader name.", pathname.string().c_str());
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPa
|
||||
|
||||
if (Root.GetNodeName() != el_program)
|
||||
{
|
||||
LOGERROR(L"%ls: XML root was not \"Program\".", pathname.c_str());
|
||||
LOGERROR(L"%ls: XML root was not \"Program\".", pathname.string().c_str());
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPa
|
||||
|
||||
if (Shader.GetNodeName() != el_shader)
|
||||
{
|
||||
LOGERROR(L"%ls: Only \"Shader\" may be child of \"Shaders\".", pathname.c_str());
|
||||
LOGERROR(L"%ls: Only \"Shader\" may be child of \"Shaders\".", pathname.string().c_str());
|
||||
WARN_RETURN(ERR::CORRUPTED);
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPa
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGWARNING(L"%ls: Unknown child of \"Program\".", pathname.c_str());
|
||||
LOGWARNING(L"%ls: Unknown child of \"Program\".", pathname.string().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,13 +403,13 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPa
|
||||
{
|
||||
char* infolog = new char[log_length];
|
||||
pglGetProgramInfoLog(p->id, log_length, 0, infolog);
|
||||
debug_printf(L"Linker log for %ls:\n%hs\n", pathname.c_str(), infolog);
|
||||
debug_printf(L"Linker log for %ls:\n%hs\n", pathname.string().c_str(), infolog);
|
||||
delete[] infolog;
|
||||
}
|
||||
|
||||
if (!linked)
|
||||
{
|
||||
debug_printf(L"Link failed for %ls\n", pathname.c_str());
|
||||
debug_printf(L"Link failed for %ls\n", pathname.string().c_str());
|
||||
WARN_RETURN(ERR::SHDR_LINK);
|
||||
}
|
||||
|
||||
|
@ -517,7 +517,7 @@ Handle ogl_tex_load(const PIVFS& vfs, const VfsPath& pathname, size_t flags)
|
||||
// is still in memory; otherwise, a negative error code.
|
||||
Handle ogl_tex_find(const VfsPath& pathname)
|
||||
{
|
||||
const uintptr_t key = fnv_hash(pathname.c_str(), pathname.length()*sizeof(pathname[0]));
|
||||
const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
|
||||
return h_find(H_OglTex, key);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
class TestTex : public CxxTest::TestSuite
|
||||
{
|
||||
void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const NativePath& extension)
|
||||
void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const OsPath& extension)
|
||||
{
|
||||
// generate test data
|
||||
const size_t size = w*h*bpp/8;
|
||||
|
@ -85,8 +85,8 @@ static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& base
|
||||
|
||||
// Read font definition file into a stringstream
|
||||
shared_ptr<u8> buf; size_t size;
|
||||
const VfsPath fntName(basename + L".fnt");
|
||||
RETURN_ERR(vfs->LoadFile(Path::Join(path, fntName), buf, size)); // [cumulative for 12: 36ms]
|
||||
const VfsPath fntName(basename.ChangeExtension(L".fnt"));
|
||||
RETURN_ERR(vfs->LoadFile(path / fntName, buf, size)); // [cumulative for 12: 36ms]
|
||||
std::istringstream FNTStream(std::string((const char*)buf.get(), size));
|
||||
|
||||
int Version;
|
||||
@ -150,8 +150,8 @@ static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& base
|
||||
|
||||
// Load glyph texture
|
||||
// [cumulative for 12: 20ms]
|
||||
const VfsPath imgName(basename + L".png");
|
||||
Handle ht = ogl_tex_load(vfs, Path::Join(path, imgName));
|
||||
const VfsPath imgName(basename.ChangeExtension(L".png"));
|
||||
Handle ht = ogl_tex_load(vfs, path / imgName);
|
||||
RETURN_ERR(ht);
|
||||
(void)ogl_tex_set_filter(ht, GL_NEAREST);
|
||||
// override is necessary because the GL format is chosen as LUMINANCE,
|
||||
@ -188,7 +188,7 @@ static LibError UniFont_to_string(const UniFont* f, wchar_t* buf)
|
||||
if (f->ht) // not true if this is called after dtor (which it is)
|
||||
{
|
||||
const VfsPath& path = h_filename(f->ht);
|
||||
swprintf_s(buf, H_STRING_LEN, L"Font %ls", path.c_str());
|
||||
swprintf_s(buf, H_STRING_LEN, L"Font %ls", path.string().c_str());
|
||||
}
|
||||
else
|
||||
swprintf_s(buf, H_STRING_LEN, L"Font");
|
||||
|
@ -572,7 +572,7 @@ Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t fl
|
||||
{
|
||||
RETURN_ERR(type_validate(type));
|
||||
|
||||
const uintptr_t key = fnv_hash(pathname.c_str(), pathname.length()*sizeof(pathname[0]));
|
||||
const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
|
||||
|
||||
// see if we can reuse an existing handle
|
||||
Handle h = reuse_existing_handle(key, type, flags);
|
||||
@ -622,7 +622,7 @@ static LibError h_free_idx(ssize_t idx, HDATA* hd)
|
||||
wchar_t buf[H_STRING_LEN];
|
||||
if(vtbl->to_string(hd->user, buf) < 0)
|
||||
wcscpy_s(buf, ARRAY_SIZE(buf), L"(error)");
|
||||
debug_printf(L"H_MGR| free %ls %ls accesses=%lu %ls\n", hd->type->name, hd->pathname.c_str(), (unsigned long)hd->num_derefs, buf);
|
||||
debug_printf(L"H_MGR| free %ls %ls accesses=%lu %ls\n", hd->type->name, hd->pathname.string().c_str(), (unsigned long)hd->num_derefs, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -690,7 +690,7 @@ VfsPath h_filename(const Handle h)
|
||||
if(!hd)
|
||||
{
|
||||
debug_assert(0);
|
||||
return 0;
|
||||
return VfsPath();
|
||||
}
|
||||
return hd->pathname;
|
||||
}
|
||||
@ -699,7 +699,7 @@ VfsPath h_filename(const Handle h)
|
||||
// TODO: what if iterating through all handles is too slow?
|
||||
LibError h_reload(const PIVFS& vfs, const VfsPath& pathname)
|
||||
{
|
||||
const u32 key = fnv_hash(pathname.c_str(), pathname.length()*sizeof(pathname[0]));
|
||||
const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
|
||||
|
||||
// destroy (note: not free!) all handles backed by this file.
|
||||
// do this before reloading any of them, because we don't specify reload
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "lib/external_libraries/vorbis.h"
|
||||
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/file/file.h"
|
||||
#include "lib/file/file_system_util.h"
|
||||
|
||||
|
||||
static LibError LibErrorFromVorbis(int err)
|
||||
@ -52,7 +52,7 @@ class VorbisFileAdapter
|
||||
public:
|
||||
VorbisFileAdapter(const PFile& openedFile)
|
||||
: file(openedFile)
|
||||
, size(FileSize(openedFile->Pathname()))
|
||||
, size(fs_util::FileSize(openedFile->Pathname()))
|
||||
, offset(0)
|
||||
{
|
||||
}
|
||||
@ -258,7 +258,7 @@ private:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LibError OpenOggStream(const NativePath& pathname, OggStreamPtr& stream)
|
||||
LibError OpenOggStream(const OsPath& pathname, OggStreamPtr& stream)
|
||||
{
|
||||
PFile file(new File);
|
||||
RETURN_ERR(file->Open(pathname, L'r'));
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
typedef shared_ptr<OggStream> OggStreamPtr;
|
||||
|
||||
extern LibError OpenOggStream(const NativePath& pathname, OggStreamPtr& stream);
|
||||
extern LibError OpenOggStream(const OsPath& pathname, OggStreamPtr& stream);
|
||||
|
||||
/**
|
||||
* A non-streaming OggStream (reading the whole file in advance)
|
||||
|
@ -1296,7 +1296,7 @@ static LibError VSrc_reload(VSrc* vs, const PIVFS& vfs, const VfsPath& pathname,
|
||||
|
||||
// pathname is a definition file containing the data file name and
|
||||
// its gain.
|
||||
if(fs::extension(pathname) == L".txt")
|
||||
if(pathname.Extension() == L".txt")
|
||||
{
|
||||
shared_ptr<u8> buf; size_t size;
|
||||
RETURN_ERR(vfs->LoadFile(pathname, buf, size));
|
||||
|
@ -257,33 +257,6 @@ int tsprintf_s(tchar* buf, size_t max_chars, const tchar* fmt, ...)
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
// note: there is no portable wfopen, so we need separate implementations
|
||||
// of tfopen_s. (the Unicode version just converts to UTF8)
|
||||
#if defined(WSECURE_CRT)
|
||||
|
||||
errno_t _wfopen_s(FILE** pfile, const wchar_t* filename, const wchar_t* mode)
|
||||
{
|
||||
*pfile = NULL;
|
||||
const std::string filename_c = utf8_from_wstring(filename);
|
||||
const std::string mode_c = utf8_from_wstring(mode);
|
||||
return fopen_s(pfile, filename_c.c_str(), mode_c.c_str());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
errno_t fopen_s(FILE** pfile, const char* filename, const char* mode)
|
||||
{
|
||||
*pfile = NULL;
|
||||
FILE* file = fopen(filename, mode);
|
||||
if(!file)
|
||||
return ENOENT;
|
||||
*pfile = file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #if EMULATE_SECURE_CRT
|
||||
|
||||
#undef tchar
|
||||
|
@ -98,10 +98,6 @@ extern int vswprintf_s(wchar_t* dst, size_t max_dst_chars, const wchar_t* fmt, v
|
||||
extern int sprintf_s(char* buf, size_t max_chars, const char* fmt, ...) PRINTF_ARGS(3);
|
||||
extern int swprintf_s(wchar_t* buf, size_t max_chars, const wchar_t* fmt, ...) WPRINTF_ARGS(3);
|
||||
|
||||
typedef int errno_t;
|
||||
extern errno_t fopen_s(FILE** pfile, const char* filename, const char* mode);
|
||||
extern errno_t _wfopen_s(FILE** pfile, const wchar_t* filename, const wchar_t* mode);
|
||||
|
||||
// we'd like to avoid deprecation warnings caused by scanf. selective
|
||||
// 'undeprecation' isn't possible, replacing all stdio declarations with
|
||||
// our own deprecation scheme is a lot of work, suppressing all deprecation
|
||||
|
@ -266,6 +266,8 @@ namespace CxxTest
|
||||
#define TSM_ASSERT_STR_EQUALS(m, str1, str2) TSM_ASSERT_EQUALS(m, std::string(str1), std::string(str2))
|
||||
#define TS_ASSERT_WSTR_EQUALS(str1, str2) TS_ASSERT_EQUALS(std::wstring(str1), std::wstring(str2))
|
||||
#define TSM_ASSERT_WSTR_EQUALS(m, str1, str2) TSM_ASSERT_EQUALS(m, std::wstring(str1), std::wstring(str2))
|
||||
#define TS_ASSERT_PATH_EQUALS(path1, path2) TS_ASSERT_EQUALS(path1.string(), path2.string())
|
||||
#define TSM_ASSERT_PATH_EQUALS(m, path1, path2) TSM_ASSERT_EQUALS(m, path1.string(), path2.string())
|
||||
|
||||
bool ts_str_contains(const std::wstring& str1, const std::wstring& str2); // defined in test_setup.cpp
|
||||
#define TS_ASSERT_WSTR_CONTAINS(str1, str2) TSM_ASSERT(str1, ts_str_contains(str1, str2))
|
||||
@ -285,6 +287,6 @@ void ScriptTestSetup(ScriptInterface&);
|
||||
// Default game data directory
|
||||
// (TODO: game-specific functions like this probably shouldn't be inside lib/, but it's useful
|
||||
// here since lots of tests use it)
|
||||
NativePath DataDir(); // defined in test_setup.cpp
|
||||
OsPath DataDir(); // defined in test_setup.cpp
|
||||
|
||||
#endif // #ifndef INCLUDED_SELF_TEST
|
||||
|
@ -27,7 +27,7 @@
|
||||
#ifndef INCLUDED_DIR_WATCH
|
||||
#define INCLUDED_DIR_WATCH
|
||||
|
||||
#include "lib/path_util.h"
|
||||
#include "lib/native_path.h"
|
||||
|
||||
struct DirWatch;
|
||||
typedef shared_ptr<DirWatch> PDirWatch;
|
||||
@ -49,7 +49,7 @@ typedef shared_ptr<DirWatch> PDirWatch;
|
||||
* convenient to store PDirWatch there instead of creating a second
|
||||
* tree structure here.
|
||||
**/
|
||||
LIB_API LibError dir_watch_Add(const NativePath& path, PDirWatch& dirWatch);
|
||||
LIB_API LibError dir_watch_Add(const OsPath& path, PDirWatch& dirWatch);
|
||||
|
||||
class DirWatchNotification
|
||||
{
|
||||
@ -61,12 +61,12 @@ public:
|
||||
Changed
|
||||
};
|
||||
|
||||
DirWatchNotification(const NativePath& pathname, EType type)
|
||||
DirWatchNotification(const OsPath& pathname, EType type)
|
||||
: pathname(pathname), type(type)
|
||||
{
|
||||
}
|
||||
|
||||
const NativePath& Pathname() const
|
||||
const OsPath& Pathname() const
|
||||
{
|
||||
return pathname;
|
||||
}
|
||||
@ -77,7 +77,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
NativePath pathname;
|
||||
OsPath pathname;
|
||||
EType type;
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,9 @@
|
||||
#ifndef INCLUDED_FILESYSTEM
|
||||
#define INCLUDED_FILESYSTEM
|
||||
|
||||
#include "lib/native_path.h"
|
||||
#include "lib/posix/posix_filesystem.h" // mode_t
|
||||
|
||||
|
||||
//
|
||||
// dirent.h
|
||||
@ -42,7 +45,7 @@ struct wdirent
|
||||
wchar_t* d_name;
|
||||
};
|
||||
|
||||
extern WDIR* wopendir(const wchar_t* path);
|
||||
extern WDIR* wopendir(const OsPath& path);
|
||||
|
||||
extern struct wdirent* wreaddir(WDIR*);
|
||||
|
||||
@ -74,8 +77,8 @@ extern int wclosedir(WDIR*);
|
||||
#define O_NONBLOCK 0x1000000
|
||||
#endif
|
||||
|
||||
extern int wopen(const wchar_t* pathname, int oflag);
|
||||
extern int wopen(const wchar_t* pathname, int oflag, mode_t mode);
|
||||
extern int wopen(const OsPath& pathname, int oflag);
|
||||
extern int wopen(const OsPath& pathname, int oflag, mode_t mode);
|
||||
extern int wclose(int fd);
|
||||
|
||||
|
||||
@ -83,33 +86,33 @@ extern int wclose(int fd);
|
||||
// unistd.h
|
||||
//
|
||||
|
||||
LIB_API int wtruncate(const wchar_t* pathname, off_t length);
|
||||
LIB_API int wtruncate(const OsPath& pathname, off_t length);
|
||||
|
||||
LIB_API int wunlink(const wchar_t* pathname);
|
||||
LIB_API int wunlink(const OsPath& pathname);
|
||||
|
||||
LIB_API int wrmdir(const wchar_t* path);
|
||||
LIB_API int wrmdir(const OsPath& path);
|
||||
|
||||
|
||||
//
|
||||
// stdio.h
|
||||
//
|
||||
|
||||
LIB_API int wrename(const wchar_t* pathnameOld, const wchar_t* pathnameNew);
|
||||
LIB_API int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew);
|
||||
|
||||
|
||||
//
|
||||
// stdlib.h
|
||||
//
|
||||
|
||||
LIB_API wchar_t* wrealpath(const wchar_t* pathname, wchar_t* resolved);
|
||||
LIB_API OsPath wrealpath(const OsPath& pathname);
|
||||
|
||||
|
||||
//
|
||||
// sys/stat.h
|
||||
//
|
||||
|
||||
LIB_API int wstat(const wchar_t* pathname, struct stat* buf);
|
||||
LIB_API int wstat(const OsPath& pathname, struct stat* buf);
|
||||
|
||||
LIB_API int wmkdir(const wchar_t* path, mode_t mode);
|
||||
LIB_API int wmkdir(const OsPath& path, mode_t mode);
|
||||
|
||||
#endif // #ifndef INCLUDED_FILESYSTEM
|
||||
|
@ -74,7 +74,7 @@ struct DirWatch
|
||||
FAMCancelMonitor(&fc, &req);
|
||||
}
|
||||
|
||||
NativePath path;
|
||||
OsPath path;
|
||||
int reqnum;
|
||||
};
|
||||
|
||||
@ -155,7 +155,7 @@ static void* fam_event_loop(void*)
|
||||
}
|
||||
}
|
||||
|
||||
LibError dir_watch_Add(const NativePath& npath, PDirWatch& dirWatch)
|
||||
LibError dir_watch_Add(const OsPath& path, PDirWatch& dirWatch)
|
||||
{
|
||||
// init already failed; don't try again or complain
|
||||
if(initialized == -1)
|
||||
@ -188,16 +188,15 @@ LibError dir_watch_Add(const NativePath& npath, PDirWatch& dirWatch)
|
||||
// but it would only save tens of milliseconds of CPU time, so it's probably
|
||||
// not worthwhile
|
||||
|
||||
const std::string path = StringFromNativePath(npath);
|
||||
FAMRequest req;
|
||||
if(FAMMonitorDirectory(&fc, path.c_str(), &req, tmpDirWatch.get()) < 0)
|
||||
if(FAMMonitorDirectory(&fc, OsString(path).c_str(), &req, tmpDirWatch.get()) < 0)
|
||||
{
|
||||
debug_warn(L"res_watch_dir failed!");
|
||||
WARN_RETURN(ERR::FAIL); // no way of getting error code?
|
||||
}
|
||||
|
||||
dirWatch.swap(tmpDirWatch);
|
||||
dirWatch->path = npath;
|
||||
dirWatch->path = path;
|
||||
dirWatch->reqnum = req.reqnum;
|
||||
|
||||
return INFO::OK;
|
||||
@ -209,7 +208,7 @@ LibError dir_watch_Poll(DirWatchNotifications& notifications)
|
||||
{
|
||||
if(initialized == -1)
|
||||
return ERR::FAIL; // NOWARN
|
||||
if(!initialized) // XXX Fix Atlas instead of supressing the warning
|
||||
if(!initialized) // XXX Fix Atlas instead of suppressing the warning
|
||||
return ERR::FAIL; //WARN_RETURN(ERR::LOGIC);
|
||||
|
||||
std::vector<NotificationEvent> polled_notifications;
|
||||
@ -236,7 +235,7 @@ LibError dir_watch_Poll(DirWatchNotifications& notifications)
|
||||
continue;
|
||||
}
|
||||
DirWatch* dirWatch = (DirWatch*)polled_notifications[i].userdata;
|
||||
NativePath pathname = Path::Join(dirWatch->path, NativePathFromString(polled_notifications[i].filename));
|
||||
OsPath pathname = dirWatch->path / polled_notifications[i].filename;
|
||||
notifications.push_back(DirWatchNotification(pathname, type));
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
LibError sys_get_executable_name(NativePath& pathname)
|
||||
LibError sys_get_executable_name(OsPath& pathname)
|
||||
{
|
||||
const char* path;
|
||||
Dl_info dl_info;
|
||||
@ -52,7 +52,7 @@ LibError sys_get_executable_name(NativePath& pathname)
|
||||
char* resolved = realpath(path, resolvedBuf);
|
||||
if (!resolved)
|
||||
return ERR::FAIL;
|
||||
pathname = NativePathFromString(resolved);
|
||||
pathname = resolved;
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ LibError sys_get_executable_name(NativePath& pathname)
|
||||
char* resolved = realpath(absolute, resolvedBuf);
|
||||
if (!resolved)
|
||||
return ERR::NO_SYS;
|
||||
pathname = NativePathFromString(resolved);
|
||||
pathname = resolved;
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
// stub implementations
|
||||
|
||||
LibError dir_watch_Add(const NativePath& UNUSED(path), PDirWatch& UNUSED(dirWatch))
|
||||
LibError dir_watch_Add(const OsPath& UNUSED(path), PDirWatch& UNUSED(dirWatch))
|
||||
{
|
||||
return INFO::OK;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ LibError gfx_get_video_mode(int* xres, int* yres, int* bpp, int* freq)
|
||||
}
|
||||
|
||||
|
||||
LibError sys_get_executable_name(NativePath& pathname)
|
||||
LibError sys_get_executable_name(OsPath& pathname)
|
||||
{
|
||||
static char name[PATH_MAX];
|
||||
static bool init = false;
|
||||
@ -102,7 +102,7 @@ LibError sys_get_executable_name(NativePath& pathname)
|
||||
debug_printf(L"app bundle name: %hs\n", name);
|
||||
}
|
||||
|
||||
pathname = NativePathFromString(name);
|
||||
pathname = name;
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
@ -34,14 +34,13 @@
|
||||
struct WDIR
|
||||
{
|
||||
DIR* d;
|
||||
wchar_t name[300];
|
||||
wchar_t name[PATH_MAX];
|
||||
wdirent ent;
|
||||
};
|
||||
|
||||
WDIR* wopendir(const wchar_t* wpath)
|
||||
WDIR* wopendir(const OsPath& path)
|
||||
{
|
||||
const std::string path = StringFromNativePath(wpath);
|
||||
DIR* d = opendir(path.c_str());
|
||||
DIR* d = opendir(OsString(path).c_str());
|
||||
if(!d)
|
||||
return 0;
|
||||
WDIR* wd = new WDIR;
|
||||
@ -56,8 +55,7 @@ struct wdirent* wreaddir(WDIR* wd)
|
||||
dirent* ent = readdir(wd->d);
|
||||
if(!ent)
|
||||
return 0;
|
||||
NativePath name = NativePathFromString(ent->d_name);
|
||||
wcscpy_s(wd->name, ARRAY_SIZE(wd->name), name.c_str());
|
||||
wcscpy_s(wd->name, ARRAY_SIZE(wd->name), ent->d_name);
|
||||
return &wd->ent;
|
||||
}
|
||||
|
||||
@ -69,17 +67,15 @@ int wclosedir(WDIR* wd)
|
||||
}
|
||||
|
||||
|
||||
int wopen(const wchar_t* wpathname, int oflag)
|
||||
int wopen(const OsPath& pathname, int oflag)
|
||||
{
|
||||
debug_assert(!(oflag & O_CREAT));
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
return open(pathname.c_str(), oflag);
|
||||
return open(OsString(pathname).c_str(), oflag);
|
||||
}
|
||||
|
||||
int wopen(const wchar_t* wpathname, int oflag, mode_t mode)
|
||||
int wopen(const OsPath& pathname, int oflag, mode_t mode)
|
||||
{
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
return open(pathname.c_str(), oflag, mode);
|
||||
return open(OsString(pathname).c_str(), oflag, mode);
|
||||
}
|
||||
|
||||
int wclose(int fd)
|
||||
@ -88,51 +84,41 @@ int wclose(int fd)
|
||||
}
|
||||
|
||||
|
||||
int wtruncate(const wchar_t* wpathname, off_t length)
|
||||
int wtruncate(const OsPath& pathname, off_t length)
|
||||
{
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
return truncate(pathname.c_str(), length);
|
||||
return truncate(OsString(pathname).c_str(), length);
|
||||
}
|
||||
|
||||
int wunlink(const wchar_t* wpathname)
|
||||
int wunlink(const OsPath& pathname)
|
||||
{
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
return unlink(pathname.c_str());
|
||||
return unlink(OsString(pathname).c_str());
|
||||
}
|
||||
|
||||
int wrmdir(const wchar_t* wpath)
|
||||
int wrmdir(const OsPath& path)
|
||||
{
|
||||
const std::string path = StringFromNativePath(wpath);
|
||||
return rmdir(path.c_str());
|
||||
return rmdir(OsString(path).c_str());
|
||||
}
|
||||
|
||||
int wrename(const wchar_t* wpathnameOld, const wchar_t* wpathnameNew)
|
||||
int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew)
|
||||
{
|
||||
const std::string pathnameOld = StringFromNativePath(wpathnameOld);
|
||||
const std::string pathnameNew = StringFromNativePath(wpathnameNew);
|
||||
return rename(pathnameOld.c_str(), pathnameNew.c_str());
|
||||
return rename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str());
|
||||
}
|
||||
|
||||
wchar_t* wrealpath(const wchar_t* wpathname, wchar_t* wresolved)
|
||||
OsPath realpath(const OsPath& pathname)
|
||||
{
|
||||
char resolvedBuf[PATH_MAX];
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
const char* resolved = realpath(pathname.c_str(), resolvedBuf);
|
||||
const char* resolved = realpath(OsString(pathname).c_str(), resolvedBuf);
|
||||
if(!resolved)
|
||||
return 0;
|
||||
NativePath nresolved = NativePathFromString(resolved);
|
||||
wcscpy_s(wresolved, PATH_MAX, nresolved.c_str());
|
||||
return wresolved;
|
||||
return OsPath();
|
||||
return resolved;
|
||||
}
|
||||
|
||||
int wstat(const wchar_t* wpathname, struct stat* buf)
|
||||
int wstat(const OsPath& pathname, struct stat* buf)
|
||||
{
|
||||
const std::string pathname = StringFromNativePath(wpathname);
|
||||
return stat(pathname.c_str(), buf);
|
||||
return stat(OsString(pathname).c_str(), buf);
|
||||
}
|
||||
|
||||
int wmkdir(const wchar_t* wpath, mode_t mode)
|
||||
int wmkdir(const OsPath& path, mode_t mode)
|
||||
{
|
||||
const std::string path = StringFromNativePath(wpath);
|
||||
return mkdir(path.c_str(), mode);
|
||||
return mkdir(OsString(path).c_str(), mode);
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ static void UninstallDriver()
|
||||
}
|
||||
|
||||
|
||||
static void StartDriver(const NativePath& driverPathname)
|
||||
static void StartDriver(const OsPath& driverPathname)
|
||||
{
|
||||
const SC_HANDLE hSCM = OpenServiceControlManager();
|
||||
if(!hSCM)
|
||||
@ -290,7 +290,7 @@ static void StartDriver(const NativePath& driverPathname)
|
||||
// NB: Windows 7 seems to insist upon backslashes (i.e. external_file_string)
|
||||
hService = CreateServiceW(hSCM, AKEN_NAME, AKEN_NAME,
|
||||
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
|
||||
driverPathname.c_str(), 0, 0, 0, startName, 0);
|
||||
OsString(driverPathname).c_str(), 0, 0, 0, startName, 0);
|
||||
debug_assert(hService != 0);
|
||||
}
|
||||
|
||||
@ -323,7 +323,7 @@ static bool Is64BitOs()
|
||||
#endif
|
||||
}
|
||||
|
||||
static NativePath DriverPathname()
|
||||
static OsPath DriverPathname()
|
||||
{
|
||||
const char* const bits = Is64BitOs()? "64" : "";
|
||||
#ifdef NDEBUG
|
||||
@ -333,7 +333,7 @@ static NativePath DriverPathname()
|
||||
#endif
|
||||
char filename[PATH_MAX];
|
||||
sprintf_s(filename, ARRAY_SIZE(filename), "aken%s%s.sys", bits, debug);
|
||||
return Path::Join(wutil_ExecutablePath(), filename);
|
||||
return wutil_ExecutablePath() / filename;
|
||||
}
|
||||
|
||||
|
||||
@ -345,7 +345,7 @@ static LibError Init()
|
||||
return ERR::NOT_SUPPORTED; // NOWARN
|
||||
|
||||
{
|
||||
const NativePath driverPathname = DriverPathname();
|
||||
const OsPath driverPathname = DriverPathname();
|
||||
StartDriver(driverPathname);
|
||||
}
|
||||
|
||||
|
@ -1871,8 +1871,8 @@ void wdbg_sym_WriteMinidump(EXCEPTION_POINTERS* exception_pointers)
|
||||
|
||||
WinScopedLock lock(WDBG_SYM_CS);
|
||||
|
||||
NativePath path = Path::Join(ah_get_log_dir(), "crashlog.dmp");
|
||||
HANDLE hFile = CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
|
||||
OsPath path = ah_get_log_dir()/"crashlog.dmp";
|
||||
HANDLE hFile = CreateFileW(OsString(path).c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DEBUG_DISPLAY_ERROR(L"wdbg_sym_WriteMinidump: unable to create crashlog.dmp.");
|
||||
|
@ -44,12 +44,12 @@ WINIT_REGISTER_MAIN_SHUTDOWN(wdir_watch_Shutdown);
|
||||
class DirHandle
|
||||
{
|
||||
public:
|
||||
DirHandle(const NativePath& path)
|
||||
DirHandle(const OsPath& path)
|
||||
{
|
||||
WinScopedPreserveLastError s; // CreateFile
|
||||
const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
const DWORD flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
|
||||
m_hDir = CreateFileW(path.c_str(), FILE_LIST_DIRECTORY, share, 0, OPEN_EXISTING, flags, 0);
|
||||
m_hDir = CreateFileW(OsString(path).c_str(), FILE_LIST_DIRECTORY, share, 0, OPEN_EXISTING, flags, 0);
|
||||
}
|
||||
|
||||
~DirHandle()
|
||||
@ -81,7 +81,7 @@ class DirWatchRequest
|
||||
{
|
||||
NONCOPYABLE(DirWatchRequest);
|
||||
public:
|
||||
DirWatchRequest(const NativePath& path)
|
||||
DirWatchRequest(const OsPath& path)
|
||||
: m_path(path), m_dirHandle(path), m_data(new u8[dataSize])
|
||||
{
|
||||
m_ovl = (OVERLAPPED*)calloc(1, sizeof(OVERLAPPED)); // rationale for dynamic alloc: see decl
|
||||
@ -124,7 +124,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
const NativePath& Path() const
|
||||
const OsPath& Path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
@ -162,12 +162,12 @@ public:
|
||||
const FILE_NOTIFY_INFORMATION* fni = (const FILE_NOTIFY_INFORMATION*)m_data;
|
||||
for(;;)
|
||||
{
|
||||
// convert name from BSTR (non-zero-terminated) to NativePath
|
||||
// convert name from BSTR (non-zero-terminated) to OsPath
|
||||
cassert(sizeof(wchar_t) == sizeof(WCHAR));
|
||||
const size_t nameChars = fni->FileNameLength / sizeof(WCHAR);
|
||||
const NativePath name(fni->FileName, nameChars);
|
||||
const OsPath name(Path::String(fni->FileName, nameChars));
|
||||
|
||||
const NativePath pathname = Path::Join(Path(), name);
|
||||
const OsPath pathname = m_path / name;
|
||||
const DirWatchNotification::EType type = TypeFromAction(fni->Action);
|
||||
notifications.push_back(DirWatchNotification(pathname, type));
|
||||
|
||||
@ -199,7 +199,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
NativePath m_path;
|
||||
OsPath m_path;
|
||||
DirHandle m_dirHandle;
|
||||
|
||||
// rationale:
|
||||
@ -368,9 +368,9 @@ private:
|
||||
class DirWatchManager
|
||||
{
|
||||
public:
|
||||
LibError Add(const NativePath& path, PDirWatch& dirWatch)
|
||||
LibError Add(const OsPath& path, PDirWatch& dirWatch)
|
||||
{
|
||||
debug_assert(Path::IsDirectory(path));
|
||||
debug_assert(path.IsDirectory());
|
||||
|
||||
// check if this is a subdirectory of a tree that's already being
|
||||
// watched (this is much faster than issuing a new watch; it also
|
||||
@ -378,7 +378,7 @@ public:
|
||||
for(IntrusiveLink* link = m_sentinel.Next(); link != &m_sentinel; link = link->Next())
|
||||
{
|
||||
DirWatch* const existingDirWatch = (DirWatch*)(uintptr_t(link) - offsetof(DirWatch, link));
|
||||
if(path_is_subpath(path.c_str(), existingDirWatch->request->Path().c_str()))
|
||||
if(path_is_subpath(OsString(path).c_str(), OsString(existingDirWatch->request->Path()).c_str()))
|
||||
{
|
||||
dirWatch.reset(new DirWatch(&m_sentinel, existingDirWatch->request));
|
||||
return INFO::OK;
|
||||
@ -412,7 +412,7 @@ static DirWatchManager* s_dirWatchManager;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LibError dir_watch_Add(const NativePath& path, PDirWatch& dirWatch)
|
||||
LibError dir_watch_Add(const OsPath& path, PDirWatch& dirWatch)
|
||||
{
|
||||
WinScopedLock lock(WDIR_WATCH_CS);
|
||||
return s_dirWatchManager->Add(path, dirWatch);
|
||||
|
@ -43,18 +43,18 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static LibError ReadVersionString(const NativePath& modulePathname, wchar_t* out_ver, size_t out_ver_len)
|
||||
static LibError ReadVersionString(const OsPath& modulePathname, wchar_t* out_ver, size_t out_ver_len)
|
||||
{
|
||||
WinScopedPreserveLastError s; // GetFileVersion*, Ver*
|
||||
|
||||
// determine size of and allocate memory for version information.
|
||||
DWORD unused;
|
||||
const DWORD ver_size = GetFileVersionInfoSizeW(modulePathname.c_str(), &unused); // [bytes]
|
||||
const DWORD ver_size = GetFileVersionInfoSizeW(OsString(modulePathname).c_str(), &unused); // [bytes]
|
||||
if(!ver_size)
|
||||
{
|
||||
// check if the failure is due to not finding modulePathname
|
||||
// (necessary since GetFileVersionInfoSize doesn't SetLastError)
|
||||
HMODULE hModule = LoadLibraryExW(modulePathname.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
HMODULE hModule = LoadLibraryExW(OsString(modulePathname).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if(!hModule)
|
||||
return ERR::FAIL; // NOWARN (file not found - due to FS redirection?)
|
||||
FreeLibrary(hModule);
|
||||
@ -62,7 +62,7 @@ static LibError ReadVersionString(const NativePath& modulePathname, wchar_t* out
|
||||
}
|
||||
|
||||
shared_ptr<u8> mem = Allocate(ver_size);
|
||||
if(!GetFileVersionInfoW(modulePathname.c_str(), 0, ver_size, mem.get()))
|
||||
if(!GetFileVersionInfoW(OsString(modulePathname).c_str(), 0, ver_size, mem.get()))
|
||||
WARN_RETURN(ERR::_3);
|
||||
|
||||
u16* lang; // -> 16 bit language ID, 16 bit codepage
|
||||
@ -83,7 +83,7 @@ static LibError ReadVersionString(const NativePath& modulePathname, wchar_t* out
|
||||
}
|
||||
|
||||
|
||||
void wdll_ver_Append(const NativePath& pathname, VersionList& list)
|
||||
void wdll_ver_Append(const OsPath& pathname, VersionList& list)
|
||||
{
|
||||
if(pathname.empty())
|
||||
return; // avoid error in ReadVersionString
|
||||
@ -91,10 +91,10 @@ void wdll_ver_Append(const NativePath& pathname, VersionList& list)
|
||||
// pathname may not have an extension (e.g. driver names from the
|
||||
// registry). note that always appending ".dll" would be incorrect
|
||||
// since some have ".sys" extension.
|
||||
NativePath modulePathname(pathname);
|
||||
if(Path::Extension(modulePathname).empty())
|
||||
modulePathname = Path::ChangeExtension(modulePathname, L".dll");
|
||||
const NativePath moduleName(Path::Filename(modulePathname));
|
||||
OsPath modulePathname(pathname);
|
||||
if(modulePathname.Extension() == "")
|
||||
modulePathname = modulePathname.ChangeExtension(L".dll");
|
||||
const OsPath moduleName(modulePathname.Filename());
|
||||
|
||||
// read file version. try this with and without FS redirection since
|
||||
// pathname might assume both.
|
||||
@ -112,7 +112,7 @@ void wdll_ver_Append(const NativePath& pathname, VersionList& list)
|
||||
if(!list.empty())
|
||||
list += L", ";
|
||||
|
||||
list += moduleName;
|
||||
list += moduleName.Filename().string();
|
||||
list += L" (";
|
||||
list += versionString;
|
||||
list += L")";
|
||||
|
@ -41,6 +41,6 @@ typedef std::wstring VersionList;
|
||||
* The text output includes the module name.
|
||||
* On failure, the version is given as "unknown".
|
||||
**/
|
||||
extern void wdll_ver_Append(const NativePath& pathname, VersionList& list);
|
||||
extern void wdll_ver_Append(const OsPath& pathname, VersionList& list);
|
||||
|
||||
#endif // #ifndef INCLUDED_WDLL_VER
|
||||
|
@ -139,7 +139,7 @@ static DWORD CreationDisposition(int oflag)
|
||||
|
||||
// (re)open file in asynchronous mode and associate handle with fd.
|
||||
// (this works because the files default to DENY_NONE sharing)
|
||||
LibError waio_reopen(int fd, const wchar_t* pathname, int oflag, ...)
|
||||
LibError waio_reopen(int fd, const OsPath& pathname, int oflag, ...)
|
||||
{
|
||||
WinScopedPreserveLastError s; // CreateFile
|
||||
|
||||
@ -176,7 +176,7 @@ LibError waio_reopen(int fd, const wchar_t* pathname, int oflag, ...)
|
||||
|
||||
// open file
|
||||
const DWORD create = CreationDisposition(oflag);
|
||||
const HANDLE hFile = CreateFileW(pathname, access, share, 0, create, FILE_ATTRIBUTE_NORMAL|flags, 0);
|
||||
const HANDLE hFile = CreateFileW(OsString(pathname).c_str(), access, share, 0, create, FILE_ATTRIBUTE_NORMAL|flags, 0);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return LibError_from_GLE();
|
||||
|
||||
|
@ -27,12 +27,12 @@
|
||||
#ifndef INCLUDED_WAIO
|
||||
#define INCLUDED_WAIO
|
||||
|
||||
#include "lib/lib_errors.h"
|
||||
#include "lib/native_path.h"
|
||||
#include "lib/sysdep/os/win/wposix/wposix_types.h"
|
||||
|
||||
#include "lib/sysdep/os/win/wposix/no_crt_posix.h"
|
||||
|
||||
#include "lib/lib_errors.h"
|
||||
|
||||
// Note: transfer buffers, offsets, and lengths must be sector-aligned
|
||||
// (we don't bother copying to an align buffer because the file cache
|
||||
// already requires splitting IOs into aligned blocks)
|
||||
@ -115,7 +115,7 @@ extern int lio_listio(int, struct aiocb* const[], int, struct sigevent*);
|
||||
|
||||
// (re)open file in asynchronous mode and associate handle with fd.
|
||||
// (this works because the files default to DENY_NONE sharing)
|
||||
extern LibError waio_reopen(int fd, const wchar_t* pathname, int oflag, ...);
|
||||
extern LibError waio_reopen(int fd, const OsPath& pathname, int oflag, ...);
|
||||
extern LibError waio_close(int fd);
|
||||
|
||||
#endif // #ifndef INCLUDED_WAIO
|
||||
|
@ -57,8 +57,8 @@ void* dlopen(const char* so_name, int flags)
|
||||
{
|
||||
debug_assert(!(flags & RTLD_GLOBAL));
|
||||
|
||||
NativePath pathname = Path::ChangeExtension(NativePathFromString(so_name), L".dll");
|
||||
HMODULE hModule = LoadLibraryW(pathname.c_str());
|
||||
OsPath pathname = Path(so_name).ChangeExtension(L".dll");
|
||||
HMODULE hModule = LoadLibraryW(OsString(pathname).c_str());
|
||||
return void_from_HMODULE(hModule);
|
||||
}
|
||||
|
||||
|
@ -190,9 +190,9 @@ static inline void wdir_free(WDIR* d)
|
||||
static const DWORD hs = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
|
||||
|
||||
// make sure path exists and is a normal (according to attributes) directory.
|
||||
static bool is_normal_dir(const wchar_t* path)
|
||||
static bool is_normal_dir(const OsPath& path)
|
||||
{
|
||||
const DWORD fa = GetFileAttributesW(path);
|
||||
const DWORD fa = GetFileAttributesW(OsString(path).c_str());
|
||||
|
||||
// path not found
|
||||
if(fa == INVALID_FILE_ATTRIBUTES)
|
||||
@ -213,7 +213,7 @@ static bool is_normal_dir(const wchar_t* path)
|
||||
}
|
||||
|
||||
|
||||
WDIR* wopendir(const wchar_t* path)
|
||||
WDIR* wopendir(const OsPath& path)
|
||||
{
|
||||
if(!is_normal_dir(path))
|
||||
{
|
||||
@ -228,16 +228,14 @@ WDIR* wopendir(const wchar_t* path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// build search path for FindFirstFileW. note: "path\\dir" only returns
|
||||
// information about that directory; trailing slashes aren't allowed.
|
||||
// for dir entries to be returned, we have to append "\\*".
|
||||
wchar_t search_path[PATH_MAX];
|
||||
swprintf_s(search_path, ARRAY_SIZE(search_path), L"%ls\\*", path);
|
||||
// NB: c:\path only returns information about that directory; trailing
|
||||
// slashes aren't allowed. append * to retrieve directory entries.
|
||||
OsPath searchPath = path/"*";
|
||||
|
||||
// note: we could store search_path and defer FindFirstFileW until
|
||||
// wreaddir. this way is a bit more complex but required for
|
||||
// correctness (we must return a valid DIR iff <path> is valid).
|
||||
d->hFind = FindFirstFileW(search_path, &d->fd);
|
||||
d->hFind = FindFirstFileW(OsString(searchPath).c_str(), &d->fd);
|
||||
if(d->hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
// not an error - the directory is just empty.
|
||||
@ -327,13 +325,13 @@ int wclosedir(WDIR* d)
|
||||
// fcntl.h
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int wopen(const wchar_t* pathname, int oflag)
|
||||
int wopen(const OsPath& pathname, int oflag)
|
||||
{
|
||||
debug_assert(!(oflag & O_CREAT));
|
||||
return wopen(pathname, oflag, _S_IREAD|_S_IWRITE);
|
||||
return wopen(OsString(pathname).c_str(), oflag, _S_IREAD|_S_IWRITE);
|
||||
}
|
||||
|
||||
int wopen(const wchar_t* pathname, int oflag, mode_t mode_arg)
|
||||
int wopen(const OsPath& pathname, int oflag, mode_t mode_arg)
|
||||
{
|
||||
mode_t mode = _S_IREAD|_S_IWRITE;
|
||||
if(oflag & O_CREAT)
|
||||
@ -341,7 +339,7 @@ int wopen(const wchar_t* pathname, int oflag, mode_t mode_arg)
|
||||
|
||||
WinScopedPreserveLastError s; // _wsopen_s's CreateFileW
|
||||
int fd;
|
||||
errno_t ret = _wsopen_s(&fd, pathname, oflag, _SH_DENYNO, mode);
|
||||
errno_t ret = _wsopen_s(&fd, OsString(pathname).c_str(), oflag, _SH_DENYNO, mode);
|
||||
if(ret != 0)
|
||||
{
|
||||
errno = ret;
|
||||
@ -376,9 +374,9 @@ int wclose(int fd)
|
||||
// unistd.h
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int wtruncate(const wchar_t* pathname, off_t length)
|
||||
int wtruncate(const OsPath& pathname, off_t length)
|
||||
{
|
||||
HANDLE hFile = CreateFileW(pathname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
HANDLE hFile = CreateFileW(OsString(pathname).c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||
debug_assert(hFile != INVALID_HANDLE_VALUE);
|
||||
LARGE_INTEGER ofs; ofs.QuadPart = length;
|
||||
WARN_IF_FALSE(SetFilePointerEx(hFile, ofs, 0, FILE_BEGIN));
|
||||
@ -388,28 +386,29 @@ int wtruncate(const wchar_t* pathname, off_t length)
|
||||
}
|
||||
|
||||
|
||||
int wunlink(const wchar_t* pathname)
|
||||
int wunlink(const OsPath& pathname)
|
||||
{
|
||||
return _wunlink(pathname);
|
||||
return _wunlink(OsString(pathname).c_str());
|
||||
}
|
||||
|
||||
|
||||
int wrmdir(const wchar_t* path)
|
||||
int wrmdir(const OsPath& path)
|
||||
{
|
||||
return _wrmdir(path);
|
||||
return _wrmdir(OsString(path).c_str());
|
||||
}
|
||||
|
||||
|
||||
int wrename(const wchar_t* pathnameOld, const wchar_t* pathnameNew)
|
||||
int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew)
|
||||
{
|
||||
return _wrename(pathnameOld, pathnameNew);
|
||||
return _wrename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str());
|
||||
}
|
||||
|
||||
|
||||
wchar_t* wrealpath(const wchar_t* pathname, wchar_t* resolved)
|
||||
OsPath wrealpath(const OsPath& pathname)
|
||||
{
|
||||
if(!GetFullPathNameW(pathname, PATH_MAX, resolved, 0))
|
||||
return 0;
|
||||
wchar_t resolved[PATH_MAX];
|
||||
if(!GetFullPathNameW(OsString(pathname).c_str(), PATH_MAX, resolved, 0))
|
||||
return OsPath();
|
||||
return resolved;
|
||||
}
|
||||
|
||||
@ -433,9 +432,9 @@ static int ErrnoFromCreateDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
int wmkdir(const wchar_t* path, mode_t UNUSED(mode))
|
||||
int wmkdir(const OsPath& path, mode_t UNUSED(mode))
|
||||
{
|
||||
if(!CreateDirectoryW(path, (LPSECURITY_ATTRIBUTES)NULL))
|
||||
if(!CreateDirectoryW(OsString(path).c_str(), (LPSECURITY_ATTRIBUTES)NULL))
|
||||
{
|
||||
errno = ErrnoFromCreateDirectory();
|
||||
return -1;
|
||||
@ -445,7 +444,7 @@ int wmkdir(const wchar_t* path, mode_t UNUSED(mode))
|
||||
}
|
||||
|
||||
|
||||
int wstat(const wchar_t* pathname, struct stat* buf)
|
||||
int wstat(const OsPath& pathname, struct stat* buf)
|
||||
{
|
||||
return _wstat64(pathname, buf);
|
||||
return _wstat64(OsString(pathname).c_str(), buf);
|
||||
}
|
||||
|
@ -1478,7 +1478,7 @@ void SDL_Quit()
|
||||
}
|
||||
|
||||
|
||||
static NativePath GetStdoutPathname()
|
||||
static OsPath GetStdoutPathname()
|
||||
{
|
||||
// the current directory is unreliable, so use the full path to
|
||||
// the current executable.
|
||||
@ -1489,7 +1489,7 @@ static NativePath GetStdoutPathname()
|
||||
// add the EXE name to the filename to allow multiple executables
|
||||
// with their own redirections. (we can't use wutil_ExecutablePath
|
||||
// because it doesn't return the basename)
|
||||
NativePath pathname = Path::ChangeExtension(NativePath(pathnameEXE), L"_stdout.txt");
|
||||
OsPath pathname = OsPath(pathnameEXE).ChangeExtension(L"_stdout.txt");
|
||||
return pathname;
|
||||
}
|
||||
|
||||
@ -1500,7 +1500,7 @@ static void RedirectStdout()
|
||||
if(wutil_IsValidHandle(GetStdHandle(STD_OUTPUT_HANDLE)))
|
||||
return;
|
||||
|
||||
const NativePath pathname = GetStdoutPathname();
|
||||
const OsPath pathname = GetStdoutPathname();
|
||||
|
||||
// ignore BoundsChecker warnings here. subsystem is set to "Windows"
|
||||
// to prevent the OS from opening a console on startup (ugly).
|
||||
@ -1509,7 +1509,7 @@ static void RedirectStdout()
|
||||
FILE* f = 0;
|
||||
// (return value ignored - it indicates 'file already exists' even
|
||||
// if f is valid)
|
||||
(void)_wfreopen_s(&f, pathname.c_str(), L"wt", stdout);
|
||||
(void)_wfreopen_s(&f, OsString(pathname).c_str(), L"wt", stdout);
|
||||
// executable directory (probably Program Files) is read-only for
|
||||
// non-Administrators. we can't pick another directory because
|
||||
// ah_log_dir might not be valid until the app's init has run,
|
||||
|
@ -40,27 +40,27 @@
|
||||
#include "lib/sysdep/os/win/wmi.h"
|
||||
|
||||
|
||||
static bool IsOpenAlDllName(const NativePath& name)
|
||||
static bool IsOpenAlDllName(const Path::String& name)
|
||||
{
|
||||
// (matches "*oal.dll" and "*OpenAL*", as with OpenAL router's search)
|
||||
return name.find(L"oal.dll") != NativePath::npos || name.find(L"OpenAL") != NativePath::npos;
|
||||
return name.find(L"oal.dll") != Path::String::npos || name.find(L"OpenAL") != Path::String::npos;
|
||||
}
|
||||
|
||||
// ensures each OpenAL DLL is only listed once (even if present in several
|
||||
// directories on our search path).
|
||||
typedef std::set<NativePath> StringSet;
|
||||
typedef std::set<Path::String> StringSet;
|
||||
|
||||
// find all OpenAL DLLs in a dir.
|
||||
// call in library search order (exe dir, then win sys dir); otherwise,
|
||||
// DLLs in the executable's starting directory hide those of the
|
||||
// same name in the system directory.
|
||||
static void add_oal_dlls_in_dir(const NativePath& path, StringSet& dlls, VersionList& versionList)
|
||||
static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, VersionList& versionList)
|
||||
{
|
||||
FileInfos files;
|
||||
(void)GetDirectoryEntries(path, &files, 0);
|
||||
for(size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
const NativePath name = files[i].Name();
|
||||
const Path::String name = files[i].Name().string();
|
||||
if(!IsOpenAlDllName(name))
|
||||
continue;
|
||||
|
||||
@ -69,7 +69,7 @@ static void add_oal_dlls_in_dir(const NativePath& path, StringSet& dlls, Version
|
||||
if(!ret.second) // insert failed - element already there
|
||||
continue;
|
||||
|
||||
wdll_ver_Append(Path::Join(path, name), versionList);
|
||||
wdll_ver_Append(path / name, versionList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ static void add_oal_dlls_in_dir(const NativePath& path, StringSet& dlls, Version
|
||||
// the version info for that bogus driver path, we'll skip this code there.
|
||||
// (delay-loading dsound.dll eliminates any overhead)
|
||||
|
||||
static NativePath directSoundDriverPath;
|
||||
static OsPath directSoundDriverPath;
|
||||
|
||||
// store sound card name and path to DirectSound driver.
|
||||
// called for each DirectSound driver, but aborts after first valid driver.
|
||||
@ -99,14 +99,14 @@ static BOOL CALLBACK DirectSoundCallback(void* guid, const wchar_t* UNUSED(descr
|
||||
|
||||
// note: $system\\drivers is not in LoadLibrary's search list,
|
||||
// so we have to give the full pathname.
|
||||
directSoundDriverPath = Path::Join(Path::Join(wutil_SystemPath(), "drivers"), NativePath(module));
|
||||
directSoundDriverPath = wutil_SystemPath()/"drivers" / module;
|
||||
|
||||
// we assume the first "driver name" (sound card) is the one we want;
|
||||
// stick with that and stop calling.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const NativePath& GetDirectSoundDriverPath()
|
||||
static const OsPath& GetDirectSoundDriverPath()
|
||||
{
|
||||
#define DS_OK 0
|
||||
typedef BOOL (CALLBACK* LPDSENUMCALLBACKW)(void*, const wchar_t*, const wchar_t*, void*);
|
||||
|
@ -363,7 +363,7 @@ LibError sys_error_description_r(int user_err, wchar_t* buf, size_t max_chars)
|
||||
}
|
||||
|
||||
|
||||
LibError sys_get_module_filename(void* addr, NativePath& pathname)
|
||||
LibError sys_get_module_filename(void* addr, OsPath& pathname)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
const SIZE_T bytesWritten = VirtualQuery(addr, &mbi, sizeof(mbi));
|
||||
@ -382,7 +382,7 @@ LibError sys_get_module_filename(void* addr, NativePath& pathname)
|
||||
}
|
||||
|
||||
|
||||
LibError sys_get_executable_name(NativePath& pathname)
|
||||
LibError sys_get_executable_name(OsPath& pathname)
|
||||
{
|
||||
wchar_t pathnameBuf[MAX_PATH+1];
|
||||
const DWORD charsWritten = GetModuleFileNameW(0, pathnameBuf, (DWORD)ARRAY_SIZE(pathnameBuf));
|
||||
@ -418,21 +418,19 @@ static int CALLBACK BrowseCallback(HWND hWnd, unsigned int msg, LPARAM UNUSED(lP
|
||||
return 0;
|
||||
}
|
||||
|
||||
LibError sys_pick_directory(NativePath& path)
|
||||
LibError sys_pick_directory(OsPath& path)
|
||||
{
|
||||
// (must not use multi-threaded apartment due to BIF_NEWDIALOGSTYLE)
|
||||
const HRESULT hr = CoInitialize(0);
|
||||
debug_assert(hr == S_OK || hr == S_FALSE); // S_FALSE == already initialized
|
||||
|
||||
// NB: BFFM_SETSELECTIONW can't deal with '/' separators
|
||||
const NativePath initialPath = path;
|
||||
|
||||
// note: bi.pszDisplayName isn't the full path, so it isn't of any use.
|
||||
BROWSEINFOW bi;
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE|BIF_NONEWFOLDERBUTTON;
|
||||
// for setting starting directory:
|
||||
bi.lpfn = (BFFCALLBACK)BrowseCallback;
|
||||
const Path::String initialPath = OsString(path); // NB: BFFM_SETSELECTIONW can't deal with '/' separators
|
||||
bi.lParam = (LPARAM)initialPath.c_str();
|
||||
const LPITEMIDLIST pidl = SHBrowseForFolderW(&bi);
|
||||
if(!pidl) // user canceled
|
||||
@ -597,3 +595,11 @@ done:
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FILE* sys_OpenFile(const OsPath& pathname, const char* mode)
|
||||
{
|
||||
FILE* f = 0;
|
||||
const std::wstring wmode(mode, mode+strlen(mode));
|
||||
(void)_wfopen_s(&f, OsString(pathname).c_str(), wmode.c_str());
|
||||
return f;
|
||||
}
|
||||
|
@ -267,30 +267,30 @@ bool wutil_HasCommandLineArgument(const wchar_t* arg)
|
||||
//-----------------------------------------------------------------------------
|
||||
// directories
|
||||
|
||||
NativePath wutil_DetectExecutablePath()
|
||||
OsPath wutil_DetectExecutablePath()
|
||||
{
|
||||
wchar_t modulePathname[MAX_PATH+1] = {0};
|
||||
const DWORD len = GetModuleFileNameW(GetModuleHandle(0), modulePathname, MAX_PATH);
|
||||
debug_assert(len != 0);
|
||||
return Path::Path(NativePath(modulePathname));
|
||||
return OsPath(modulePathname).Parent();
|
||||
}
|
||||
|
||||
// (NB: wutil_Init is called before static ctors => use placement new)
|
||||
static NativePath* systemPath;
|
||||
static NativePath* executablePath;
|
||||
static NativePath* appdataPath;
|
||||
static OsPath* systemPath;
|
||||
static OsPath* executablePath;
|
||||
static OsPath* appdataPath;
|
||||
|
||||
const NativePath& wutil_SystemPath()
|
||||
const OsPath& wutil_SystemPath()
|
||||
{
|
||||
return *systemPath;
|
||||
}
|
||||
|
||||
const NativePath& wutil_ExecutablePath()
|
||||
const OsPath& wutil_ExecutablePath()
|
||||
{
|
||||
return *executablePath;
|
||||
}
|
||||
|
||||
const NativePath& wutil_AppdataPath()
|
||||
const OsPath& wutil_AppdataPath()
|
||||
{
|
||||
return *appdataPath;
|
||||
}
|
||||
@ -305,11 +305,11 @@ static void GetDirectories()
|
||||
{
|
||||
const UINT charsWritten = GetSystemDirectoryW(path, MAX_PATH);
|
||||
debug_assert(charsWritten != 0);
|
||||
systemPath = new(wutil_Allocate(sizeof(NativePath))) NativePath(path);
|
||||
systemPath = new(wutil_Allocate(sizeof(OsPath))) OsPath(path);
|
||||
}
|
||||
|
||||
// executable's directory
|
||||
executablePath = new(wutil_Allocate(sizeof(NativePath))) NativePath(wutil_DetectExecutablePath());
|
||||
executablePath = new(wutil_Allocate(sizeof(OsPath))) OsPath(wutil_DetectExecutablePath());
|
||||
|
||||
// application data
|
||||
{
|
||||
@ -317,18 +317,18 @@ static void GetDirectories()
|
||||
HANDLE token = 0;
|
||||
const HRESULT ret = SHGetFolderPathW(hwnd, CSIDL_APPDATA, token, 0, path);
|
||||
debug_assert(SUCCEEDED(ret));
|
||||
appdataPath = new(wutil_Allocate(sizeof(NativePath))) NativePath(path);
|
||||
appdataPath = new(wutil_Allocate(sizeof(OsPath))) OsPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void FreeDirectories()
|
||||
{
|
||||
systemPath->~NativePath();
|
||||
systemPath->~OsPath();
|
||||
wutil_Free(systemPath);
|
||||
executablePath->~NativePath();
|
||||
executablePath->~OsPath();
|
||||
wutil_Free(executablePath);
|
||||
appdataPath->~NativePath();
|
||||
appdataPath->~OsPath();
|
||||
wutil_Free(appdataPath);
|
||||
}
|
||||
|
||||
|
@ -170,11 +170,11 @@ extern bool wutil_HasCommandLineArgument(const wchar_t* arg);
|
||||
|
||||
// used by wutil_ExecutablePath, but provided in case other code
|
||||
// needs to know this before our wutil_Init runs.
|
||||
extern NativePath wutil_DetectExecutablePath();
|
||||
extern OsPath wutil_DetectExecutablePath();
|
||||
|
||||
extern const NativePath& wutil_SystemPath();
|
||||
extern const NativePath& wutil_ExecutablePath();
|
||||
extern const NativePath& wutil_AppdataPath();
|
||||
extern const OsPath& wutil_SystemPath();
|
||||
extern const OsPath& wutil_ExecutablePath();
|
||||
extern const OsPath& wutil_AppdataPath();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -111,7 +111,7 @@ extern LibError sys_error_description_r(int err, wchar_t* buf, size_t max_chars)
|
||||
*
|
||||
* note: this is useful for handling exceptions in other modules.
|
||||
**/
|
||||
LibError sys_get_module_filename(void* addr, NativePath& pathname);
|
||||
LibError sys_get_module_filename(void* addr, OsPath& pathname);
|
||||
|
||||
/**
|
||||
* Get path to the current executable.
|
||||
@ -121,7 +121,7 @@ LibError sys_get_module_filename(void* addr, NativePath& pathname);
|
||||
*
|
||||
* this is useful for determining installation directory, e.g. for VFS.
|
||||
**/
|
||||
LIB_API LibError sys_get_executable_name(NativePath& pathname);
|
||||
LIB_API LibError sys_get_executable_name(OsPath& pathname);
|
||||
|
||||
/**
|
||||
* Get the current user's login name.
|
||||
@ -137,7 +137,7 @@ extern std::wstring sys_get_user_name();
|
||||
* faster browsing. if INFO::OK is returned, it receives
|
||||
* chosen directory path.
|
||||
**/
|
||||
extern LibError sys_pick_directory(NativePath& path);
|
||||
extern LibError sys_pick_directory(OsPath& path);
|
||||
|
||||
/**
|
||||
* Open the user's default web browser to the given URL.
|
||||
@ -185,6 +185,8 @@ LIB_API LibError sys_generate_random_bytes(u8* buf, size_t count);
|
||||
**/
|
||||
LIB_API LibError sys_get_proxy_config(const std::wstring& url, std::wstring& proxy);
|
||||
|
||||
LIB_API FILE* sys_OpenFile(const OsPath& pathname, const char* mode);
|
||||
|
||||
/**
|
||||
* directory separation character
|
||||
**/
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "lib/secure_crt.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/sysdep/filesystem.h"
|
||||
#include "lib/sysdep/sysdep.h"
|
||||
|
||||
#if OS_LINUX
|
||||
@ -49,16 +50,16 @@ public:
|
||||
|
||||
void test_sys_get_executable_name()
|
||||
{
|
||||
NativePath path;
|
||||
OsPath path;
|
||||
|
||||
// Try it first with the real executable (i.e. the
|
||||
// one that's running this test code)
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
// Check it's absolute
|
||||
TSM_ASSERT(L"Path: "+path, path_is_absolute(path.c_str()));
|
||||
TSM_ASSERT(L"Path: "+path.string(), path_is_absolute(path.string().c_str()));
|
||||
// Check the file exists
|
||||
struct stat s;
|
||||
TSM_ASSERT_EQUALS(L"Path: "+path, wstat(path.c_str(), &s), 0);
|
||||
TSM_ASSERT_EQUALS(L"Path: "+path.string(), wstat(path, &s), 0);
|
||||
|
||||
// Do some platform-specific tests, based on the
|
||||
// implementations of sys_get_executable_name:
|
||||
@ -78,7 +79,7 @@ public:
|
||||
TS_ASSERT(realpath(root, rootres));
|
||||
|
||||
std::string rootstr(rootres);
|
||||
std::wstring rootstrw(wstring_from_utf8(rootstr));
|
||||
OsPath rootstrw(rootstr);
|
||||
|
||||
const char* dirs[] = {
|
||||
"/example",
|
||||
@ -111,12 +112,12 @@ public:
|
||||
{
|
||||
Mock_dladdr d(rootstr+"/example/executable");
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
TS_ASSERT_WSTR_EQUALS(path, rootstrw+L"/example/executable");
|
||||
TS_ASSERT_PATH_EQUALS(path, rootstrw/L"example/executable");
|
||||
}
|
||||
{
|
||||
Mock_dladdr d(rootstr+"/example/./a/b/../e/../../executable");
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
TS_ASSERT_WSTR_EQUALS(path, rootstrw+L"/example/executable");
|
||||
TS_ASSERT_PATH_EQUALS(path, rootstrw/L"example/executable");
|
||||
}
|
||||
|
||||
// Try with relative paths
|
||||
@ -124,19 +125,19 @@ public:
|
||||
Mock_dladdr d("./executable");
|
||||
Mock_getcwd m(rootstr+"/example");
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
TS_ASSERT_WSTR_EQUALS(path, rootstrw+L"/example/executable");
|
||||
TS_ASSERT_PATH_EQUALS(path, rootstrw/L"example/executable");
|
||||
}
|
||||
{
|
||||
Mock_dladdr d("./executable");
|
||||
Mock_getcwd m(rootstr+"/example/");
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
TS_ASSERT_WSTR_EQUALS(path, rootstrw+L"/example/executable");
|
||||
TS_ASSERT_PATH_EQUALS(path, rootstrw/L"example/executable");
|
||||
}
|
||||
{
|
||||
Mock_dladdr d("../d/../../f/executable");
|
||||
Mock_getcwd m(rootstr+"/example/a/b/c");
|
||||
TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK);
|
||||
TS_ASSERT_WSTR_EQUALS(path, rootstrw+L"/example/a/f/executable");
|
||||
TS_ASSERT_PATH_EQUALS(path, rootstrw/L"example/a/f/executable");
|
||||
}
|
||||
|
||||
// Try with pathless names
|
||||
|
@ -566,7 +566,7 @@ bool tex_is_known_extension(const VfsPath& pathname)
|
||||
{
|
||||
const TexCodecVTbl* dummy;
|
||||
// found codec for it => known extension
|
||||
const NativePath extension = Path::Extension(pathname);
|
||||
const OsPath extension = pathname.Extension();
|
||||
if(tex_codec_for_filename(extension, &dummy) == INFO::OK)
|
||||
return true;
|
||||
|
||||
@ -699,7 +699,7 @@ size_t tex_hdr_size(const VfsPath& filename)
|
||||
{
|
||||
const TexCodecVTbl* c;
|
||||
|
||||
const NativePath extension = Path::Extension(filename);
|
||||
const OsPath extension = filename.Extension();
|
||||
CHECK_ERR(tex_codec_for_filename(extension, &c));
|
||||
return c->hdr_size(0);
|
||||
}
|
||||
@ -751,7 +751,7 @@ LibError tex_decode(const shared_ptr<u8>& data, size_t data_size, Tex* t)
|
||||
}
|
||||
|
||||
|
||||
LibError tex_encode(Tex* t, const NativePath& extension, DynArray* da)
|
||||
LibError tex_encode(Tex* t, const OsPath& extension, DynArray* da)
|
||||
{
|
||||
CHECK_TEX(t);
|
||||
CHECK_ERR(tex_validate_plain_format(t->bpp, t->flags));
|
||||
|
@ -105,6 +105,7 @@ library and IO layer. Read and write are zero-copy.
|
||||
#define INCLUDED_TEX
|
||||
|
||||
#include "lib/res/handle.h"
|
||||
#include "lib/native_path.h"
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "lib/allocators/dynarray.h"
|
||||
|
||||
@ -290,7 +291,7 @@ extern LibError tex_decode(const shared_ptr<u8>& data, size_t data_size, Tex* t)
|
||||
* when no longer needed. Invalid unless function succeeds.
|
||||
* @return LibError
|
||||
**/
|
||||
extern LibError tex_encode(Tex* t, const NativePath& extension, DynArray* da);
|
||||
extern LibError tex_encode(Tex* t, const OsPath& extension, DynArray* da);
|
||||
|
||||
/**
|
||||
* store the given image data into a Tex object; this will be as if
|
||||
|
@ -74,9 +74,9 @@ static bool bmp_is_hdr(const u8* file)
|
||||
}
|
||||
|
||||
|
||||
static bool bmp_is_ext(const NativePath& extension)
|
||||
static bool bmp_is_ext(const OsPath& extension)
|
||||
{
|
||||
return !wcscasecmp(extension.c_str(), L".bmp");
|
||||
return extension == L".bmp";
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ void tex_codec_unregister_all()
|
||||
// or return ERR::TEX_UNKNOWN_FORMAT if unknown.
|
||||
// note: does not raise a warning because it is used by
|
||||
// tex_is_known_extension.
|
||||
LibError tex_codec_for_filename(const NativePath& extension, const TexCodecVTbl** c)
|
||||
LibError tex_codec_for_filename(const OsPath& extension, const TexCodecVTbl** c)
|
||||
{
|
||||
for(*c = codecs; *c; *c = (*c)->next)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ struct TexCodecVTbl
|
||||
* @param extension (including '.')
|
||||
* @return bool
|
||||
**/
|
||||
bool (*is_ext)(const NativePath& extension);
|
||||
bool (*is_ext)(const OsPath& extension);
|
||||
|
||||
/**
|
||||
* return size of the file header supported by this codec.
|
||||
@ -170,7 +170,7 @@ extern int tex_codec_register(TexCodecVTbl* c);
|
||||
* called by tex_is_known_extension) if no codec indicates they can
|
||||
* handle the given extension.
|
||||
**/
|
||||
extern LibError tex_codec_for_filename(const NativePath& extension, const TexCodecVTbl** c);
|
||||
extern LibError tex_codec_for_filename(const OsPath& extension, const TexCodecVTbl** c);
|
||||
|
||||
/**
|
||||
* find codec that recognizes the header's magic field.
|
||||
|
@ -579,9 +579,9 @@ static bool dds_is_hdr(const u8* file)
|
||||
}
|
||||
|
||||
|
||||
static bool dds_is_ext(const NativePath& extension)
|
||||
static bool dds_is_ext(const OsPath& extension)
|
||||
{
|
||||
return !wcscasecmp(extension.c_str(), L".dds");
|
||||
return extension == L".dds";
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,9 +573,9 @@ static bool jpg_is_hdr(const u8* file)
|
||||
}
|
||||
|
||||
|
||||
static bool jpg_is_ext(const NativePath& extension)
|
||||
static bool jpg_is_ext(const OsPath& extension)
|
||||
{
|
||||
return !wcscasecmp(extension.c_str(), L".jpg") || !wcscasecmp(extension.c_str(), L".jpeg");
|
||||
return extension == L".jpg" || extension == L".jpeg";
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,9 +183,9 @@ static bool png_is_hdr(const u8* file)
|
||||
}
|
||||
|
||||
|
||||
static bool png_is_ext(const NativePath& extension)
|
||||
static bool png_is_ext(const OsPath& extension)
|
||||
{
|
||||
return !wcscasecmp(extension.c_str(), L".png");
|
||||
return extension == L".png";
|
||||
}
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user