file_sys: Comply to style guidelines
This commit is contained in:
parent
bfb945c243
commit
167bfddafa
8 changed files with 60 additions and 47 deletions
|
@ -5,6 +5,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "content_archive.h"
|
#include "content_archive.h"
|
||||||
|
@ -67,9 +68,10 @@ const std::vector<MetaRecord>& CNMT::GetMetaRecords() const {
|
||||||
bool CNMT::UnionRecords(const CNMT& other) {
|
bool CNMT::UnionRecords(const CNMT& other) {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
for (const auto& rec : other.content_records) {
|
for (const auto& rec : other.content_records) {
|
||||||
const auto iter = std::find_if(
|
const auto iter = std::find_if(content_records.begin(), content_records.end(),
|
||||||
content_records.begin(), content_records.end(),
|
[&rec](const ContentRecord& r) {
|
||||||
[rec](const ContentRecord& r) { return r.nca_id == rec.nca_id && r.type == rec.type; });
|
return r.nca_id == rec.nca_id && r.type == rec.type;
|
||||||
|
});
|
||||||
if (iter == content_records.end()) {
|
if (iter == content_records.end()) {
|
||||||
content_records.emplace_back(rec);
|
content_records.emplace_back(rec);
|
||||||
++header->number_content_entries;
|
++header->number_content_entries;
|
||||||
|
@ -78,7 +80,7 @@ bool CNMT::UnionRecords(const CNMT& other) {
|
||||||
}
|
}
|
||||||
for (const auto& rec : other.meta_records) {
|
for (const auto& rec : other.meta_records) {
|
||||||
const auto iter =
|
const auto iter =
|
||||||
std::find_if(meta_records.begin(), meta_records.end(), [rec](const MetaRecord& r) {
|
std::find_if(meta_records.begin(), meta_records.end(), [&rec](const MetaRecord& r) {
|
||||||
return r.title_id == rec.title_id && r.title_version == rec.title_version &&
|
return r.title_id == rec.title_id && r.title_version == rec.title_version &&
|
||||||
r.type == rec.type;
|
r.type == rec.type;
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
|
@ -23,13 +23,13 @@ bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FollowsTwoDigitDirFormat(std::string_view name) {
|
static bool FollowsTwoDigitDirFormat(std::string_view name) {
|
||||||
const static std::regex two_digit_regex(
|
static const std::regex two_digit_regex(
|
||||||
"000000[0123456789abcdefABCDEF][0123456789abcdefABCDEF]");
|
"000000[0123456789abcdefABCDEF][0123456789abcdefABCDEF]");
|
||||||
return std::regex_match(name.begin(), name.end(), two_digit_regex);
|
return std::regex_match(name.begin(), name.end(), two_digit_regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FollowsNcaIdFormat(std::string_view name) {
|
static bool FollowsNcaIdFormat(std::string_view name) {
|
||||||
const static std::regex nca_id_regex("[0123456789abcdefABCDEF]+.nca");
|
static const std::regex nca_id_regex("[0123456789abcdefABCDEF]+.nca");
|
||||||
return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex);
|
return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ static std::string GetCNMTName(TitleType type, u64 title_id) {
|
||||||
"" ///< Currently unknown 'DeltaTitle'
|
"" ///< Currently unknown 'DeltaTitle'
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t index = static_cast<size_t>(type);
|
auto index = static_cast<size_t>(type);
|
||||||
if (index >= 0x80)
|
if (index >= 0x80)
|
||||||
index -= 0x80;
|
index -= 0x80;
|
||||||
return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id);
|
return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id);
|
||||||
|
@ -90,15 +90,15 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir,
|
||||||
VirtualFile file = nullptr;
|
VirtualFile file = nullptr;
|
||||||
|
|
||||||
const auto files = nca_dir->GetFiles();
|
const auto files = nca_dir->GetFiles();
|
||||||
if (files.size() == 1 && files[0]->GetName() == "00")
|
if (files.size() == 1 && files[0]->GetName() == "00") {
|
||||||
file = files[0];
|
file = files[0];
|
||||||
else {
|
} else {
|
||||||
std::vector<VirtualFile> concat;
|
std::vector<VirtualFile> concat;
|
||||||
for (u8 i = 0; i < 0x10; ++i) {
|
for (u8 i = 0; i < 0x10; ++i) {
|
||||||
auto next = nca_dir->GetFile(fmt::format("{:02X}", i));
|
auto next = nca_dir->GetFile(fmt::format("{:02X}", i));
|
||||||
if (next != nullptr)
|
if (next != nullptr) {
|
||||||
concat.push_back(std::move(next));
|
concat.push_back(std::move(next));
|
||||||
else {
|
} else {
|
||||||
next = nca_dir->GetFile(fmt::format("{:02x}", i));
|
next = nca_dir->GetFile(fmt::format("{:02x}", i));
|
||||||
if (next != nullptr)
|
if (next != nullptr)
|
||||||
concat.push_back(std::move(next));
|
concat.push_back(std::move(next));
|
||||||
|
@ -146,7 +146,8 @@ boost::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id,
|
||||||
return boost::make_optional(iter->nca_id);
|
return boost::make_optional(iter->nca_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisteredCache::AccumulateFiles(std::vector<NcaID>& ids) const {
|
std::vector<NcaID> RegisteredCache::AccumulateFiles() const {
|
||||||
|
std::vector<NcaID> ids;
|
||||||
for (const auto& d2_dir : dir->GetSubdirectories()) {
|
for (const auto& d2_dir : dir->GetSubdirectories()) {
|
||||||
if (FollowsNcaIdFormat(d2_dir->GetName())) {
|
if (FollowsNcaIdFormat(d2_dir->GetName())) {
|
||||||
ids.push_back(HexStringToArray<0x10, true>(d2_dir->GetName().substr(0, 0x20)));
|
ids.push_back(HexStringToArray<0x10, true>(d2_dir->GetName().substr(0, 0x20)));
|
||||||
|
@ -175,6 +176,7 @@ void RegisteredCache::AccumulateFiles(std::vector<NcaID>& ids) const {
|
||||||
if (FollowsNcaIdFormat(d2_file->GetName()))
|
if (FollowsNcaIdFormat(d2_file->GetName()))
|
||||||
ids.push_back(HexStringToArray<0x10, true>(d2_file->GetName().substr(0, 0x20)));
|
ids.push_back(HexStringToArray<0x10, true>(d2_file->GetName().substr(0, 0x20)));
|
||||||
}
|
}
|
||||||
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisteredCache::ProcessFiles(const std::vector<NcaID>& ids) {
|
void RegisteredCache::ProcessFiles(const std::vector<NcaID>& ids) {
|
||||||
|
@ -185,8 +187,9 @@ void RegisteredCache::ProcessFiles(const std::vector<NcaID>& ids) {
|
||||||
continue;
|
continue;
|
||||||
const auto nca = std::make_shared<NCA>(parser(file, id));
|
const auto nca = std::make_shared<NCA>(parser(file, id));
|
||||||
if (nca->GetStatus() != Loader::ResultStatus::Success ||
|
if (nca->GetStatus() != Loader::ResultStatus::Success ||
|
||||||
nca->GetType() != NCAContentType::Meta)
|
nca->GetType() != NCAContentType::Meta) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const auto section0 = nca->GetSubdirectories()[0];
|
const auto section0 = nca->GetSubdirectories()[0];
|
||||||
|
|
||||||
|
@ -218,8 +221,7 @@ void RegisteredCache::AccumulateYuzuMeta() {
|
||||||
void RegisteredCache::Refresh() {
|
void RegisteredCache::Refresh() {
|
||||||
if (dir == nullptr)
|
if (dir == nullptr)
|
||||||
return;
|
return;
|
||||||
std::vector<NcaID> ids;
|
const auto ids = AccumulateFiles();
|
||||||
AccumulateFiles(ids);
|
|
||||||
ProcessFiles(ids);
|
ProcessFiles(ids);
|
||||||
AccumulateYuzuMeta();
|
AccumulateYuzuMeta();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
#include "content_archive.h"
|
#include "content_archive.h"
|
||||||
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
#include "nca_metadata.h"
|
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
class XCI;
|
class XCI;
|
||||||
|
@ -49,7 +52,7 @@ public:
|
||||||
// Parsing function defines the conversion from raw file to NCA. If there are other steps
|
// Parsing function defines the conversion from raw file to NCA. If there are other steps
|
||||||
// besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom
|
// besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom
|
||||||
// parsing function.
|
// parsing function.
|
||||||
RegisteredCache(VirtualDir dir,
|
explicit RegisteredCache(VirtualDir dir,
|
||||||
RegisteredCacheParsingFunction parsing_function =
|
RegisteredCacheParsingFunction parsing_function =
|
||||||
[](const VirtualFile& file, const NcaID& id) { return file; });
|
[](const VirtualFile& file, const NcaID& id) { return file; });
|
||||||
|
|
||||||
|
@ -86,7 +89,7 @@ private:
|
||||||
void IterateAllMetadata(std::vector<T>& out,
|
void IterateAllMetadata(std::vector<T>& out,
|
||||||
std::function<T(const CNMT&, const ContentRecord&)> proc,
|
std::function<T(const CNMT&, const ContentRecord&)> proc,
|
||||||
std::function<bool(const CNMT&, const ContentRecord&)> filter) const;
|
std::function<bool(const CNMT&, const ContentRecord&)> filter) const;
|
||||||
void AccumulateFiles(std::vector<NcaID>& ids) const;
|
std::vector<NcaID> AccumulateFiles() const;
|
||||||
void ProcessFiles(const std::vector<NcaID>& ids);
|
void ProcessFiles(const std::vector<NcaID>& ids);
|
||||||
void AccumulateYuzuMeta();
|
void AccumulateYuzuMeta();
|
||||||
boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
|
boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
|
||||||
|
|
|
@ -9,17 +9,17 @@
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name) {
|
VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name) {
|
||||||
if (files.empty())
|
if (files.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (files.size() == 1)
|
if (files.size() == 1)
|
||||||
return files[0];
|
return files[0];
|
||||||
|
|
||||||
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), name));
|
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string_view name)
|
ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string name)
|
||||||
: name(name) {
|
: name(std::move(name)) {
|
||||||
size_t next_offset = 0;
|
size_t next_offset = 0;
|
||||||
for (const auto& file : files_) {
|
for (const auto& file : files_) {
|
||||||
files[next_offset] = file;
|
files[next_offset] = file;
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases.
|
// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases.
|
||||||
VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name = "");
|
VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name = "");
|
||||||
|
|
||||||
// Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently
|
// Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently
|
||||||
// read-only.
|
// read-only.
|
||||||
class ConcatenatedVfsFile : public VfsFile {
|
class ConcatenatedVfsFile : public VfsFile {
|
||||||
friend VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name);
|
friend VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name);
|
||||||
|
|
||||||
ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string_view name);
|
ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
|
|
|
@ -619,7 +619,7 @@ void GMainWindow::OnMenuLoadFolder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMenuInstallToNAND() {
|
void GMainWindow::OnMenuInstallToNAND() {
|
||||||
const static QString file_filter =
|
const QString file_filter =
|
||||||
tr("Installable Switch File (*.nca *.xci);;Nintendo Content Archive (*.nca);;NX Cartridge "
|
tr("Installable Switch File (*.nca *.xci);;Nintendo Content Archive (*.nca);;NX Cartridge "
|
||||||
"Image (*.xci)");
|
"Image (*.xci)");
|
||||||
QString filename = QFileDialog::getOpenFileName(this, tr("Install File"),
|
QString filename = QFileDialog::getOpenFileName(this, tr("Install File"),
|
||||||
|
@ -629,36 +629,36 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
const auto xci = std::make_shared<FileSys::XCI>(
|
const auto xci = std::make_shared<FileSys::XCI>(
|
||||||
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
|
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
|
||||||
if (xci->GetStatus() != Loader::ResultStatus::Success) {
|
if (xci->GetStatus() != Loader::ResultStatus::Success) {
|
||||||
QMessageBox::critical(
|
QMessageBox::warning(
|
||||||
this, tr("Failed to Install XCI"),
|
this, tr("Failed to Install XCI"),
|
||||||
tr("The XCI file you provided is invalid. Please double-check your encryption "
|
tr("The XCI file you provided is invalid. Please double-check your encryption "
|
||||||
"keys and the file and try again."));
|
"keys and the file and try again."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Service::FileSystem::GetUserNANDContents()->InstallEntry(xci)) {
|
if (Service::FileSystem::GetUserNANDContents()->InstallEntry(xci)) {
|
||||||
QMessageBox::critical(
|
|
||||||
this, tr("Failed to Install XCI"),
|
|
||||||
tr("There was an error while attempting to install the provided XCI file. It "
|
|
||||||
"could have an incorrect format or be missing a metadata entry. Please "
|
|
||||||
"double-check your file and try again."));
|
|
||||||
} else {
|
|
||||||
QMessageBox::information(this, tr("Successfully Installed XCI"),
|
QMessageBox::information(this, tr("Successfully Installed XCI"),
|
||||||
tr("The file was successfully installed."));
|
tr("The file was successfully installed."));
|
||||||
game_list->PopulateAsync(UISettings::values.gamedir,
|
game_list->PopulateAsync(UISettings::values.gamedir,
|
||||||
UISettings::values.gamedir_deepscan);
|
UISettings::values.gamedir_deepscan);
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Failed to Install XCI"),
|
||||||
|
tr("There was an error while attempting to install the provided XCI file. It "
|
||||||
|
"could have an incorrect format or be missing a metadata entry. Please "
|
||||||
|
"double-check your file and try again."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto nca = std::make_shared<FileSys::NCA>(
|
const auto nca = std::make_shared<FileSys::NCA>(
|
||||||
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
|
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
|
||||||
if (nca->GetStatus() != Loader::ResultStatus::Success) {
|
if (nca->GetStatus() != Loader::ResultStatus::Success) {
|
||||||
QMessageBox::critical(
|
QMessageBox::warning(
|
||||||
this, tr("Failed to Install NCA"),
|
this, tr("Failed to Install NCA"),
|
||||||
tr("The NCA file you provided is invalid. Please double-check your encryption "
|
tr("The NCA file you provided is invalid. Please double-check your encryption "
|
||||||
"keys and the file and try again."));
|
"keys and the file and try again."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static QStringList tt_options{"System Application",
|
static const QStringList tt_options{"System Application",
|
||||||
"System Archive",
|
"System Archive",
|
||||||
"System Application Update",
|
"System Application Update",
|
||||||
"Firmware Package (Type A)",
|
"Firmware Package (Type A)",
|
||||||
|
@ -676,7 +676,7 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
|
|
||||||
auto index = tt_options.indexOf(item);
|
auto index = tt_options.indexOf(item);
|
||||||
if (!ok || index == -1) {
|
if (!ok || index == -1) {
|
||||||
QMessageBox::critical(this, tr("Failed to Install NCA"),
|
QMessageBox::warning(this, tr("Failed to Install NCA"),
|
||||||
tr("The title type you selected for the NCA is invalid."));
|
tr("The title type you selected for the NCA is invalid."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -684,18 +684,18 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
if (index >= 5)
|
if (index >= 5)
|
||||||
index += 0x80;
|
index += 0x80;
|
||||||
|
|
||||||
if (!Service::FileSystem::GetUserNANDContents()->InstallEntry(
|
if (Service::FileSystem::GetUserNANDContents()->InstallEntry(
|
||||||
nca, static_cast<FileSys::TitleType>(index))) {
|
nca, static_cast<FileSys::TitleType>(index))) {
|
||||||
QMessageBox::critical(this, tr("Failed to Install NCA"),
|
|
||||||
tr("There was an error while attempting to install the "
|
|
||||||
"provided NCA file. An error might have occured creating "
|
|
||||||
"the metadata file or parsing the NCA. Please "
|
|
||||||
"double-check your file and try again."));
|
|
||||||
} else {
|
|
||||||
QMessageBox::information(this, tr("Successfully Installed NCA"),
|
QMessageBox::information(this, tr("Successfully Installed NCA"),
|
||||||
tr("The file was successfully installed."));
|
tr("The file was successfully installed."));
|
||||||
game_list->PopulateAsync(UISettings::values.gamedir,
|
game_list->PopulateAsync(UISettings::values.gamedir,
|
||||||
UISettings::values.gamedir_deepscan);
|
UISettings::values.gamedir_deepscan);
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(this, tr("Failed to Install NCA"),
|
||||||
|
tr("There was an error while attempting to install the "
|
||||||
|
"provided NCA file. An error might have occured creating "
|
||||||
|
"the metadata file or parsing the NCA. Please "
|
||||||
|
"double-check your file and try again."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue