mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
Merge pull request #8134 from JosJuice/filesystem-string-view
DiscIO: Use std::string_view in FileSystem::FindFileInfo
This commit is contained in:
@ -13,6 +13,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -618,9 +619,9 @@ private:
|
|||||||
static_assert(sizeof(Entry) == 512, "Wrong size");
|
static_assert(sizeof(Entry) == 512, "Wrong size");
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
UpdateResult UpdateFromManifest(const std::string& manifest_name);
|
UpdateResult UpdateFromManifest(std::string_view manifest_name);
|
||||||
UpdateResult ProcessEntry(u32 type, std::bitset<32> attrs, const TitleInfo& title,
|
UpdateResult ProcessEntry(u32 type, std::bitset<32> attrs, const TitleInfo& title,
|
||||||
const std::string& path);
|
std::string_view path);
|
||||||
|
|
||||||
UpdateCallback m_update_callback;
|
UpdateCallback m_update_callback;
|
||||||
std::unique_ptr<DiscIO::Volume> m_volume;
|
std::unique_ptr<DiscIO::Volume> m_volume;
|
||||||
@ -655,7 +656,7 @@ UpdateResult DiscSystemUpdater::DoDiscUpdate()
|
|||||||
return UpdateFromManifest("__update.inf");
|
return UpdateFromManifest("__update.inf");
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateResult DiscSystemUpdater::UpdateFromManifest(const std::string& manifest_name)
|
UpdateResult DiscSystemUpdater::UpdateFromManifest(std::string_view manifest_name)
|
||||||
{
|
{
|
||||||
const DiscIO::FileSystem* disc_fs = m_volume->GetFileSystem(m_partition);
|
const DiscIO::FileSystem* disc_fs = m_volume->GetFileSystem(m_partition);
|
||||||
if (!disc_fs)
|
if (!disc_fs)
|
||||||
@ -693,7 +694,7 @@ UpdateResult DiscSystemUpdater::UpdateFromManifest(const std::string& manifest_n
|
|||||||
const u64 title_id = Common::swap64(entry.data() + offsetof(Entry, title_id));
|
const u64 title_id = Common::swap64(entry.data() + offsetof(Entry, title_id));
|
||||||
const u16 title_version = Common::swap16(entry.data() + offsetof(Entry, title_version));
|
const u16 title_version = Common::swap16(entry.data() + offsetof(Entry, title_version));
|
||||||
const char* path_pointer = reinterpret_cast<const char*>(entry.data() + offsetof(Entry, path));
|
const char* path_pointer = reinterpret_cast<const char*>(entry.data() + offsetof(Entry, path));
|
||||||
const std::string path{path_pointer, strnlen(path_pointer, sizeof(Entry::path))};
|
const std::string_view path{path_pointer, strnlen(path_pointer, sizeof(Entry::path))};
|
||||||
|
|
||||||
if (!m_update_callback(i, num_entries, title_id))
|
if (!m_update_callback(i, num_entries, title_id))
|
||||||
return UpdateResult::Cancelled;
|
return UpdateResult::Cancelled;
|
||||||
@ -712,7 +713,7 @@ UpdateResult DiscSystemUpdater::UpdateFromManifest(const std::string& manifest_n
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
||||||
const TitleInfo& title, const std::string& path)
|
const TitleInfo& title, std::string_view path)
|
||||||
{
|
{
|
||||||
// Skip any unknown type and boot2 updates (for now).
|
// Skip any unknown type and boot2 updates (for now).
|
||||||
if (type != 2 && type != 3 && type != 6 && type != 7)
|
if (type != 2 && type != 3 && type != 6 && type != 7)
|
||||||
@ -734,7 +735,7 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
|||||||
auto blob = DiscIO::VolumeFileBlobReader::Create(*m_volume, m_partition, path);
|
auto blob = DiscIO::VolumeFileBlobReader::Create(*m_volume, m_partition, path);
|
||||||
if (!blob)
|
if (!blob)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CORE, "Could not find %s", path.c_str());
|
ERROR_LOG(CORE, "Could not find %s", std::string(path).c_str());
|
||||||
return UpdateResult::DiscReadFailed;
|
return UpdateResult::DiscReadFailed;
|
||||||
}
|
}
|
||||||
const DiscIO::WiiWAD wad{std::move(blob)};
|
const DiscIO::WiiWAD wad{std::move(blob)};
|
||||||
|
@ -69,7 +69,7 @@ u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* f
|
|||||||
return read_length;
|
return read_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 ReadFile(const Volume& volume, const Partition& partition, const std::string& path, u8* buffer,
|
u64 ReadFile(const Volume& volume, const Partition& partition, std::string_view path, u8* buffer,
|
||||||
u64 max_buffer_size, u64 offset_in_file)
|
u64 max_buffer_size, u64 offset_in_file)
|
||||||
{
|
{
|
||||||
const FileSystem* file_system = volume.GetFileSystem(partition);
|
const FileSystem* file_system = volume.GetFileSystem(partition);
|
||||||
@ -117,7 +117,7 @@ bool ExportFile(const Volume& volume, const Partition& partition, const FileInfo
|
|||||||
export_filename);
|
export_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExportFile(const Volume& volume, const Partition& partition, const std::string& path,
|
bool ExportFile(const Volume& volume, const Partition& partition, std::string_view path,
|
||||||
const std::string& export_filename)
|
const std::string& export_filename)
|
||||||
{
|
{
|
||||||
const FileSystem* file_system = volume.GetFileSystem(partition);
|
const FileSystem* file_system = volume.GetFileSystem(partition);
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
@ -24,13 +26,13 @@ std::string NameForPartitionType(u32 partition_type, bool include_prefix);
|
|||||||
|
|
||||||
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
||||||
u8* buffer, u64 max_buffer_size, u64 offset_in_file = 0);
|
u8* buffer, u64 max_buffer_size, u64 offset_in_file = 0);
|
||||||
u64 ReadFile(const Volume& volume, const Partition& partition, const std::string& path, u8* buffer,
|
u64 ReadFile(const Volume& volume, const Partition& partition, std::string_view path, u8* buffer,
|
||||||
u64 max_buffer_size, u64 offset_in_file = 0);
|
u64 max_buffer_size, u64 offset_in_file = 0);
|
||||||
bool ExportData(const Volume& volume, const Partition& partition, u64 offset, u64 size,
|
bool ExportData(const Volume& volume, const Partition& partition, u64 offset, u64 size,
|
||||||
const std::string& export_filename);
|
const std::string& export_filename);
|
||||||
bool ExportFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
bool ExportFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
||||||
const std::string& export_filename);
|
const std::string& export_filename);
|
||||||
bool ExportFile(const Volume& volume, const Partition& partition, const std::string& path,
|
bool ExportFile(const Volume& volume, const Partition& partition, std::string_view path,
|
||||||
const std::string& export_filename);
|
const std::string& export_filename);
|
||||||
|
|
||||||
// update_progress is called once for each child (file or directory).
|
// update_progress is called once for each child (file or directory).
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <locale>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
@ -118,6 +120,43 @@ std::string FileInfoGCWii::GetName() const
|
|||||||
return SHIFTJISToUTF8(reinterpret_cast<const char*>(m_fst + GetNameOffset()));
|
return SHIFTJISToUTF8(reinterpret_cast<const char*>(m_fst + GetNameOffset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileInfoGCWii::NameCaseInsensitiveEquals(std::string_view other) const
|
||||||
|
{
|
||||||
|
// For speed, this function avoids allocating new strings, except when we are comparing
|
||||||
|
// non-ASCII characters with non-ASCII characters, which is a rare case.
|
||||||
|
|
||||||
|
const char* this_ptr = reinterpret_cast<const char*>(m_fst + GetNameOffset());
|
||||||
|
const char* other_ptr = other.data();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < other.size(); ++i, ++this_ptr, ++other_ptr)
|
||||||
|
{
|
||||||
|
if (*this_ptr == '\0')
|
||||||
|
{
|
||||||
|
// A null byte in this is always a terminator and a null byte in other is never a terminator,
|
||||||
|
// so if we reach this case, this is shorter than other
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (static_cast<unsigned char>(*this_ptr) >= 0x80 &&
|
||||||
|
static_cast<unsigned char>(*other_ptr) >= 0x80)
|
||||||
|
{
|
||||||
|
// other is in UTF-8 and this is in Shift-JIS, so we convert so that we can compare correctly
|
||||||
|
const std::string this_utf8 = SHIFTJISToUTF8(this_ptr);
|
||||||
|
return std::equal(this_utf8.cbegin(), this_utf8.cend(), other.cbegin() + i, other.cend(),
|
||||||
|
[](char a, char b) {
|
||||||
|
return std::tolower(a, std::locale::classic()) ==
|
||||||
|
std::tolower(b, std::locale::classic());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (std::tolower(*this_ptr, std::locale::classic()) !=
|
||||||
|
std::tolower(*other_ptr, std::locale::classic()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this_ptr == '\0'; // If we're not at a null byte, this is longer than other
|
||||||
|
}
|
||||||
|
|
||||||
std::string FileInfoGCWii::GetPath() const
|
std::string FileInfoGCWii::GetPath() const
|
||||||
{
|
{
|
||||||
// The root entry doesn't have a name
|
// The root entry doesn't have a name
|
||||||
@ -257,7 +296,7 @@ const FileInfo& FileSystemGCWii::GetRoot() const
|
|||||||
return m_root;
|
return m_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(const std::string& path) const
|
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(std::string_view path) const
|
||||||
{
|
{
|
||||||
if (!IsValid())
|
if (!IsValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -265,7 +304,7 @@ std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(const std::string& path)
|
|||||||
return FindFileInfo(path, m_root);
|
return FindFileInfo(path, m_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(const std::string& path,
|
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(std::string_view path,
|
||||||
const FileInfo& file_info) const
|
const FileInfo& file_info) const
|
||||||
{
|
{
|
||||||
// Given a path like "directory1/directory2/fileA.bin", this function will
|
// Given a path like "directory1/directory2/fileA.bin", this function will
|
||||||
@ -276,12 +315,14 @@ std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(const std::string& path,
|
|||||||
return file_info.clone(); // We're done
|
return file_info.clone(); // We're done
|
||||||
|
|
||||||
const size_t name_end = path.find('/', name_start);
|
const size_t name_end = path.find('/', name_start);
|
||||||
const std::string name = path.substr(name_start, name_end - name_start);
|
const std::string_view name = path.substr(name_start, name_end - name_start);
|
||||||
const std::string rest_of_path = (name_end != std::string::npos) ? path.substr(name_end + 1) : "";
|
const std::string_view rest_of_path =
|
||||||
|
(name_end != std::string::npos) ? path.substr(name_end + 1) : "";
|
||||||
|
|
||||||
for (const FileInfo& child : file_info)
|
for (const FileInfo& child : file_info)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(child.GetName().c_str(), name.c_str()))
|
// We need case insensitive comparison since some games have OPENING.BNR instead of opening.bnr
|
||||||
|
if (child.NameCaseInsensitiveEquals(name))
|
||||||
{
|
{
|
||||||
// A match is found. The rest of the path is passed on to finish the search.
|
// A match is found. The rest of the path is passed on to finish the search.
|
||||||
std::unique_ptr<FileInfo> result = FindFileInfo(rest_of_path, child);
|
std::unique_ptr<FileInfo> result = FindFileInfo(rest_of_path, child);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -44,6 +45,7 @@ public:
|
|||||||
bool IsDirectory() const override;
|
bool IsDirectory() const override;
|
||||||
u32 GetTotalChildren() const override;
|
u32 GetTotalChildren() const override;
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
|
bool NameCaseInsensitiveEquals(std::string_view other) const override;
|
||||||
std::string GetPath() const override;
|
std::string GetPath() const override;
|
||||||
|
|
||||||
bool IsValid(u64 fst_size, const FileInfoGCWii& parent_directory) const;
|
bool IsValid(u64 fst_size, const FileInfoGCWii& parent_directory) const;
|
||||||
@ -90,7 +92,7 @@ public:
|
|||||||
|
|
||||||
bool IsValid() const override { return m_valid; }
|
bool IsValid() const override { return m_valid; }
|
||||||
const FileInfo& GetRoot() const override;
|
const FileInfo& GetRoot() const override;
|
||||||
std::unique_ptr<FileInfo> FindFileInfo(const std::string& path) const override;
|
std::unique_ptr<FileInfo> FindFileInfo(std::string_view path) const override;
|
||||||
std::unique_ptr<FileInfo> FindFileInfo(u64 disc_offset) const override;
|
std::unique_ptr<FileInfo> FindFileInfo(u64 disc_offset) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -100,7 +102,7 @@ private:
|
|||||||
// Maps the end offset of files to FST indexes
|
// Maps the end offset of files to FST indexes
|
||||||
mutable std::map<u64, u32> m_offset_file_info_cache;
|
mutable std::map<u64, u32> m_offset_file_info_cache;
|
||||||
|
|
||||||
std::unique_ptr<FileInfo> FindFileInfo(const std::string& path, const FileInfo& file_info) const;
|
std::unique_ptr<FileInfo> FindFileInfo(std::string_view path, const FileInfo& file_info) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DiscIO
|
} // namespace DiscIO
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
@ -93,6 +94,7 @@ public:
|
|||||||
// Not guaranteed to return a meaningful value for files.
|
// Not guaranteed to return a meaningful value for files.
|
||||||
virtual u32 GetTotalChildren() const = 0;
|
virtual u32 GetTotalChildren() const = 0;
|
||||||
virtual std::string GetName() const = 0;
|
virtual std::string GetName() const = 0;
|
||||||
|
virtual bool NameCaseInsensitiveEquals(std::string_view other) const = 0;
|
||||||
// GetPath will find the parents of the current object and call GetName on them,
|
// GetPath will find the parents of the current object and call GetName on them,
|
||||||
// so it's slower than other functions. If you're traversing through folders
|
// so it's slower than other functions. If you're traversing through folders
|
||||||
// to get a file and its path, building the path while traversing is faster.
|
// to get a file and its path, building the path while traversing is faster.
|
||||||
@ -117,7 +119,7 @@ public:
|
|||||||
// are only valid for as long as the file system object is valid.
|
// are only valid for as long as the file system object is valid.
|
||||||
virtual const FileInfo& GetRoot() const = 0;
|
virtual const FileInfo& GetRoot() const = 0;
|
||||||
// Returns nullptr if not found
|
// Returns nullptr if not found
|
||||||
virtual std::unique_ptr<FileInfo> FindFileInfo(const std::string& path) const = 0;
|
virtual std::unique_ptr<FileInfo> FindFileInfo(std::string_view path) const = 0;
|
||||||
// Returns nullptr if not found
|
// Returns nullptr if not found
|
||||||
virtual std::unique_ptr<FileInfo> FindFileInfo(u64 disc_offset) const = 0;
|
virtual std::unique_ptr<FileInfo> FindFileInfo(u64 disc_offset) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "DiscIO/VolumeFileBlobReader.h"
|
#include "DiscIO/VolumeFileBlobReader.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "DiscIO/Filesystem.h"
|
#include "DiscIO/Filesystem.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
@ -11,7 +14,7 @@ namespace DiscIO
|
|||||||
{
|
{
|
||||||
std::unique_ptr<VolumeFileBlobReader> VolumeFileBlobReader::Create(const Volume& volume,
|
std::unique_ptr<VolumeFileBlobReader> VolumeFileBlobReader::Create(const Volume& volume,
|
||||||
const Partition& partition,
|
const Partition& partition,
|
||||||
const std::string& file_path)
|
std::string_view file_path)
|
||||||
{
|
{
|
||||||
const FileSystem* file_system = volume.GetFileSystem(partition);
|
const FileSystem* file_system = volume.GetFileSystem(partition);
|
||||||
if (!file_system)
|
if (!file_system)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "DiscIO/Blob.h"
|
#include "DiscIO/Blob.h"
|
||||||
@ -20,7 +20,7 @@ class VolumeFileBlobReader final : public BlobReader
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<VolumeFileBlobReader>
|
static std::unique_ptr<VolumeFileBlobReader>
|
||||||
Create(const Volume& volume, const Partition& partition, const std::string& file_path);
|
Create(const Volume& volume, const Partition& partition, std::string_view file_path);
|
||||||
|
|
||||||
BlobType GetBlobType() const override { return BlobType::PLAIN; }
|
BlobType GetBlobType() const override { return BlobType::PLAIN; }
|
||||||
u64 GetRawSize() const override;
|
u64 GetRawSize() const override;
|
||||||
|
Reference in New Issue
Block a user