mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Reduces string allocations in paths.
This commit is contained in:
parent
d22d8776e6
commit
e63c80c613
8 changed files with 54 additions and 32 deletions
|
|
@ -311,7 +311,7 @@ cassert(sizeof(ECDR) == 22);
|
|||
// ArchiveFile_Zip
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ArchiveFile_Zip : public IArchiveFile
|
||||
class ArchiveFile_Zip final : public IArchiveFile
|
||||
{
|
||||
public:
|
||||
ArchiveFile_Zip(const PFile& file, off_t ofs, off_t csize, u32 checksum, ZipMethod method)
|
||||
|
|
@ -321,22 +321,22 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual size_t Precedence() const
|
||||
size_t Precedence() const override
|
||||
{
|
||||
return 2u;
|
||||
}
|
||||
|
||||
virtual wchar_t LocationCode() const
|
||||
wchar_t LocationCode() const override
|
||||
{
|
||||
return 'A';
|
||||
}
|
||||
|
||||
virtual OsPath Path() const
|
||||
const OsPath& Path() const override
|
||||
{
|
||||
return m_file->Pathname();
|
||||
}
|
||||
|
||||
virtual Status Load(const OsPath& /*name*/, const std::shared_ptr<u8>& buf, size_t size) const
|
||||
Status Load(const OsPath& /*name*/, const std::shared_ptr<u8>& buf, size_t size) const override
|
||||
{
|
||||
AdjustOffset();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ struct IFileLoader
|
|||
|
||||
virtual size_t Precedence() const = 0;
|
||||
virtual wchar_t LocationCode() const = 0;
|
||||
virtual OsPath Path() const = 0;
|
||||
virtual const OsPath& Path() const = 0;
|
||||
|
||||
virtual Status Load(const OsPath& name, const std::shared_ptr<u8>& buf, size_t size) const = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
class RealDirectory : public IFileLoader
|
||||
class RealDirectory final : public IFileLoader
|
||||
{
|
||||
NONCOPYABLE(RealDirectory);
|
||||
public:
|
||||
|
|
@ -50,13 +50,13 @@ public:
|
|||
}
|
||||
|
||||
// IFileLoader
|
||||
virtual size_t Precedence() const;
|
||||
virtual wchar_t LocationCode() const;
|
||||
virtual OsPath Path() const
|
||||
size_t Precedence() const override;
|
||||
wchar_t LocationCode() const override;
|
||||
const OsPath& Path() const override
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
virtual Status Load(const OsPath& name, const std::shared_ptr<u8>& buf, size_t size) const;
|
||||
Status Load(const OsPath& name, const std::shared_ptr<u8>& buf, size_t size) const override;
|
||||
|
||||
Status Store(const OsPath& name, const std::shared_ptr<u8>& fileContents, size_t size);
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,8 @@ Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames
|
|||
|
||||
for(size_t i = 0; osEnt->d_name[i] != '\0'; i++)
|
||||
RETURN_STATUS_IF_ERR(Path::Validate(osEnt->d_name[i]));
|
||||
const OsPath name(osEnt->d_name);
|
||||
|
||||
const std::wstring_view name{osEnt->d_name};
|
||||
|
||||
// get file information (mode, size, mtime)
|
||||
struct stat s;
|
||||
|
|
@ -124,7 +125,7 @@ Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames
|
|||
#else
|
||||
// .. call regular stat().
|
||||
errno = 0;
|
||||
const OsPath pathname = path / name;
|
||||
const OsPath pathname = path / OsPath(osEnt->d_name);
|
||||
if(wstat(pathname, &s) != 0)
|
||||
{
|
||||
if(errno == ENOENT)
|
||||
|
|
@ -140,9 +141,9 @@ Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames
|
|||
#endif
|
||||
|
||||
if(files && S_ISREG(s.st_mode))
|
||||
files->push_back(CFileInfo(name, s.st_size, s.st_mtime));
|
||||
files->emplace_back(osEnt->d_name, s.st_size, s.st_mtime);
|
||||
else if(subdirectoryNames && S_ISDIR(s.st_mode) && name != L"." && name != L"..")
|
||||
subdirectoryNames->push_back(name);
|
||||
subdirectoryNames->emplace_back(osEnt->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,21 +36,23 @@
|
|||
|
||||
class MockLoader : public IFileLoader
|
||||
{
|
||||
private:
|
||||
size_t m_Precedence;
|
||||
public:
|
||||
MockLoader(size_t precedence) :
|
||||
m_Precedence(precedence)
|
||||
{
|
||||
}
|
||||
|
||||
size_t Precedence() const { return m_Precedence; }
|
||||
wchar_t LocationCode() const { return L'\0'; }
|
||||
OsPath Path() const { return L"";}
|
||||
Status Load(const OsPath& /*name*/, const std::shared_ptr<u8>& /*buf*/, size_t /*size*/) const
|
||||
size_t Precedence() const override { return m_Precedence; }
|
||||
wchar_t LocationCode() const override { return L'\0'; }
|
||||
const OsPath& Path() const override { return m_Path; }
|
||||
Status Load(const OsPath& /*name*/, const std::shared_ptr<u8>& /*buf*/, size_t /*size*/) const override
|
||||
{
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_Precedence;
|
||||
OsPath m_Path;
|
||||
};
|
||||
|
||||
class TestVfsTree : public CxxTest::TestSuite
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include <istream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
namespace ERR
|
||||
{
|
||||
|
|
@ -95,6 +96,12 @@ public:
|
|||
DetectSeparator();
|
||||
}
|
||||
|
||||
Path(Path&& p)
|
||||
: path(std::move(p.path))
|
||||
{
|
||||
DetectSeparator();
|
||||
}
|
||||
|
||||
Path(const char* p)
|
||||
: path((const unsigned char*)p, (const unsigned char*)p+strlen(p))
|
||||
// interpret bytes as unsigned; makes no difference for ASCII,
|
||||
|
|
@ -115,7 +122,13 @@ public:
|
|||
DetectSeparator();
|
||||
}
|
||||
|
||||
Path(const std::wstring& s)
|
||||
Path(std::wstring s)
|
||||
: path(std::move(s))
|
||||
{
|
||||
DetectSeparator();
|
||||
}
|
||||
|
||||
Path(const std::wstring_view& s)
|
||||
: path(s)
|
||||
{
|
||||
DetectSeparator();
|
||||
|
|
@ -128,6 +141,13 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Path& operator=(Path&& rhs)
|
||||
{
|
||||
path = std::move(rhs.path);
|
||||
DetectSeparator();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return path.empty();
|
||||
|
|
@ -217,14 +237,13 @@ public:
|
|||
return filename.string().substr(0, idxDot);
|
||||
}
|
||||
|
||||
// (Path return type allows callers to use our operator==)
|
||||
Path Extension() const
|
||||
std::wstring_view Extension() const
|
||||
{
|
||||
const Path filename = Filename();
|
||||
const size_t idxDot = filename.string().find_last_of('.');
|
||||
const std::wstring_view filename{path};
|
||||
const size_t idxDot = filename.find_last_of('.');
|
||||
if(idxDot == String::npos)
|
||||
return Path();
|
||||
return filename.string().substr(idxDot);
|
||||
return {};
|
||||
return filename.substr(idxDot);
|
||||
}
|
||||
|
||||
Path ChangeExtension(Path extension) const
|
||||
|
|
@ -232,7 +251,7 @@ public:
|
|||
return Parent() / Path(Basename().string() + extension.string());
|
||||
}
|
||||
|
||||
Path operator/(Path rhs) const
|
||||
Path operator/(const Path& rhs) const
|
||||
{
|
||||
Path ret = *this;
|
||||
if(ret.path.empty()) // (empty paths assume '/')
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ bool CCacheLoader::CanUseArchiveCache(const VfsPath& sourcePath, const VfsPath&
|
|||
|
||||
VfsPath CCacheLoader::ArchiveCachePath(const VfsPath& sourcePath) const
|
||||
{
|
||||
return sourcePath.ChangeExtension(sourcePath.Extension().string() + L".cached" + m_FileExtension);
|
||||
return sourcePath.ChangeExtension(std::wstring{sourcePath.Extension()} + L".cached" + m_FileExtension);
|
||||
}
|
||||
|
||||
VfsPath CCacheLoader::LooseCachePath(const VfsPath& sourcePath, const MD5& initialHash, u32 version)
|
||||
|
|
@ -148,7 +148,7 @@ VfsPath CCacheLoader::LooseCachePath(const VfsPath& sourcePath, const MD5& initi
|
|||
|
||||
return VfsPath("cache") /
|
||||
path_name_only(path.BeforeCommon(sourcePath).Parent().string().c_str()) /
|
||||
sourcePath.ChangeExtension(sourcePath.Extension().string() +
|
||||
sourcePath.ChangeExtension(std::wstring{sourcePath.Extension()} +
|
||||
L"." +
|
||||
// Use a short prefix of the full hash (we don't need high collision-resistance)
|
||||
wstring_from_utf8(Hexify(digest, 8)) +
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ VfsPath GetBaseFilename(const VfsPath& filename)
|
|||
if (!VfsFileExists(filePath))
|
||||
throw std::runtime_error{fmt::format("The file \"{}\" does not exist.", filePath.string8())};
|
||||
|
||||
if (filePath.Extension().string8() != ".js")
|
||||
if (filePath.Extension() != L".js")
|
||||
{
|
||||
throw std::runtime_error{fmt::format("The file \"{}\" is not a JavaScript module.",
|
||||
filePath.string8())};
|
||||
|
|
|
|||
Loading…
Reference in a new issue