summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/nca_metadata.cpp
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-08-11 21:39:09 +0200
committerZach Hilman <zachhilman@gmail.com>2018-08-12 04:50:48 +0200
commit893447b6b0f5068f3cc2111b5f21c3cff68002e2 (patch)
treef2451fcb2478243621b6952ca5b006f22f957022 /src/core/file_sys/nca_metadata.cpp
parentnca_metadata: Remove unnecessary reference to base file (diff)
downloadyuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar.gz
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar.bz2
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar.lz
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar.xz
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.tar.zst
yuzu-893447b6b0f5068f3cc2111b5f21c3cff68002e2.zip
Diffstat (limited to 'src/core/file_sys/nca_metadata.cpp')
-rw-r--r--src/core/file_sys/nca_metadata.cpp63
1 files changed, 35 insertions, 28 deletions
diff --git a/src/core/file_sys/nca_metadata.cpp b/src/core/file_sys/nca_metadata.cpp
index 38b5eae80..234d70199 100644
--- a/src/core/file_sys/nca_metadata.cpp
+++ b/src/core/file_sys/nca_metadata.cpp
@@ -4,36 +4,44 @@
#include <cstring>
#include "common/common_funcs.h"
+#include "common/logging/log.h"
#include "common/swap.h"
#include "content_archive.h"
#include "core/file_sys/nca_metadata.h"
namespace FileSys {
-CNMT::CNMT(VirtualFile file) : header(std::make_unique<CNMTHeader>()) {
- if (file->ReadObject(header.get()) != sizeof(CNMTHeader))
+bool operator>=(TitleType lhs, TitleType rhs) {
+ return static_cast<size_t>(lhs) >= static_cast<size_t>(rhs);
+}
+
+bool operator<=(TitleType lhs, TitleType rhs) {
+ return static_cast<size_t>(lhs) <= static_cast<size_t>(rhs);
+}
+
+CNMT::CNMT(VirtualFile file) {
+ if (file->ReadObject(&header) != sizeof(CNMTHeader))
return;
// If type is {Application, Update, AOC} has opt-header.
- if (static_cast<u8>(header->type) >= 0x80 && static_cast<u8>(header->type) <= 0x82) {
- opt_header = std::make_unique<OptionalHeader>();
- if (file->ReadObject(opt_header.get(), sizeof(CNMTHeader)) != sizeof(OptionalHeader)) {
- opt_header = nullptr;
+ if (header.type >= TitleType::Application && header.type <= TitleType::AOC) {
+ if (file->ReadObject(&opt_header, sizeof(CNMTHeader)) != sizeof(OptionalHeader)) {
+ LOG_WARNING(Loader, "Failed to read optional header.");
}
}
- for (u16 i = 0; i < header->number_content_entries; ++i) {
+ for (u16 i = 0; i < header.number_content_entries; ++i) {
auto& next = content_records.emplace_back(ContentRecord{});
if (file->ReadObject(&next, sizeof(CNMTHeader) + i * sizeof(ContentRecord) +
- header->table_offset) != sizeof(ContentRecord)) {
+ header.table_offset) != sizeof(ContentRecord)) {
content_records.erase(content_records.end() - 1);
}
}
- for (u16 i = 0; i < header->number_meta_entries; ++i) {
+ for (u16 i = 0; i < header.number_meta_entries; ++i) {
auto& next = meta_records.emplace_back(MetaRecord{});
if (file->ReadObject(&next, sizeof(CNMTHeader) + i * sizeof(MetaRecord) +
- header->table_offset) != sizeof(MetaRecord)) {
+ header.table_offset) != sizeof(MetaRecord)) {
meta_records.erase(meta_records.end() - 1);
}
}
@@ -41,20 +49,19 @@ CNMT::CNMT(VirtualFile file) : header(std::make_unique<CNMTHeader>()) {
CNMT::CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records,
std::vector<MetaRecord> meta_records)
- : header(std::make_unique<CNMTHeader>(std::move(header))),
- opt_header(std::make_unique<OptionalHeader>(std::move(opt_header))),
+ : header(std::move(header)), opt_header(std::move(opt_header)),
content_records(std::move(content_records)), meta_records(std::move(meta_records)) {}
u64 CNMT::GetTitleID() const {
- return header->title_id;
+ return header.title_id;
}
u32 CNMT::GetTitleVersion() const {
- return header->title_version;
+ return header.title_version;
}
TitleType CNMT::GetType() const {
- return header->type;
+ return header.type;
}
const std::vector<ContentRecord>& CNMT::GetContentRecords() const {
@@ -74,7 +81,7 @@ bool CNMT::UnionRecords(const CNMT& other) {
});
if (iter == content_records.end()) {
content_records.emplace_back(rec);
- ++header->number_content_entries;
+ ++header.number_content_entries;
change = true;
}
}
@@ -86,7 +93,7 @@ bool CNMT::UnionRecords(const CNMT& other) {
});
if (iter == meta_records.end()) {
meta_records.emplace_back(rec);
- ++header->number_meta_entries;
+ ++header.number_meta_entries;
change = true;
}
}
@@ -94,30 +101,30 @@ bool CNMT::UnionRecords(const CNMT& other) {
}
std::vector<u8> CNMT::Serialize() const {
- if (header == nullptr)
- return {};
- std::vector<u8> out(sizeof(CNMTHeader));
- out.reserve(0x100); // Avoid resizing -- average size.
- memcpy(out.data(), header.get(), sizeof(CNMTHeader));
- if (opt_header != nullptr) {
- out.resize(out.size() + sizeof(OptionalHeader));
- memcpy(out.data() + sizeof(CNMTHeader), opt_header.get(), sizeof(OptionalHeader));
+ const bool has_opt_header =
+ header.type >= TitleType::Application && header.type <= TitleType::AOC;
+ std::vector<u8> out(sizeof(CNMTHeader) + (has_opt_header ? sizeof(OptionalHeader) : 0));
+ memcpy(out.data(), &header, sizeof(CNMTHeader));
+
+ // Optional Header
+ if (has_opt_header) {
+ memcpy(out.data() + sizeof(CNMTHeader), &opt_header, sizeof(OptionalHeader));
}
- auto offset = header->table_offset;
+ auto offset = header.table_offset;
const auto dead_zone = offset + sizeof(CNMTHeader) - out.size();
if (dead_zone > 0)
out.resize(offset + sizeof(CNMTHeader));
+ out.resize(out.size() + content_records.size() * sizeof(ContentRecord));
for (const auto& rec : content_records) {
- out.resize(out.size() + sizeof(ContentRecord));
memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(ContentRecord));
offset += sizeof(ContentRecord);
}
+ out.resize(out.size() + content_records.size() * sizeof(MetaRecord));
for (const auto& rec : meta_records) {
- out.resize(out.size() + sizeof(MetaRecord));
memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(MetaRecord));
offset += sizeof(MetaRecord);
}