libnedit
Lightweight C++ library for Nintendo DS(i) formats
Loading...
Searching...
No Matches
nfs_NitroFs.hpp
1
2#pragma once
3#include <ntr/fs/fs_Stdio.hpp>
4
5namespace ntr::fmt::nfs {
6
7 constexpr u16 InitialDirectoryId = 61440;
8 constexpr size_t MaxEntryNameLength = 128;
9 constexpr const char RootDirectoryPseudoName[] = "<root>";
10
12 u32 start;
13 u16 id;
14 u16 parent_id;
15 };
16
18 u32 file_start;
19 u32 file_end;
20 };
21
23 u32 entry_offset;
24
25 Result GetName(fs::BinaryFile &base_bf, std::string &out_name) const;
26 };
27
28 struct NitroFile : public NitroEntryBase {
29 size_t offset;
30 size_t size;
31
32 Result Read(fs::BinaryFile &base_bf, const size_t offset, void *read_buf, const size_t read_size, size_t &out_read_size) const;
33 };
34
36 bool is_root;
37 std::vector<NitroDirectory> dirs;
38 std::vector<NitroFile> files;
39 };
40
41 Result ReadNitroFsFrom(const size_t fat_data_offset, const size_t fnt_data_offset, fs::BinaryFile &bf, NitroDirectory &out_fs_root_dir);
42
44 nfs::NitroDirectory nitro_fs;
45
47
48 virtual size_t GetBaseOffset() {
49 return 0;
50 }
51
52 virtual bool GetAlignmentBetweenFileData(size_t &out_align) {
53 return false;
54 }
55
56 virtual size_t GetFatEntriesOffset() = 0;
57 virtual size_t GetFatEntryCount() = 0;
58
59 virtual Result OnFileSystemWrite(fs::BinaryFile &w_bf, const ssize_t size_diff) = 0;
60
61 Result LookupFile(const std::string &path, NitroFile &out_file) const;
62 Result GetName(const NitroEntryBase &entry, std::string &out_name) const;
63
64 inline Result DoWithReadFile(std::function<Result(fs::BinaryFile&)> fn) const {
66 NTR_R_TRY(bf.Open(this->read_file_handle, this->read_path, fs::OpenMode::Read, this->comp));
67
68 NTR_R_TRY(fn(bf));
69 NTR_R_SUCCEED();
70 }
71
72 Result SaveFileSystem() override;
73 };
74
75 template<typename T>
77 static_assert(std::is_base_of_v<NitroFsFileFormat, T>);
78
79 NitroFile file;
80 fs::BinaryFile base_bf;
81
83
84 bool ExistsImpl(const std::string &path, size_t &out_size) override {
85 NitroFile file = {};
86 if(this->ext_fs_file->LookupFile(path, file).IsSuccess()) {
87 out_size = file.size;
88 return true;
89 }
90 else {
91 return false;
92 }
93 }
94
95 Result OpenImpl(const std::string &path) override {
96 NTR_R_TRY(this->ext_fs_file->LookupFile(path, this->file));
97
98 NTR_R_TRY(this->base_bf.Open(this->ext_fs_file->read_file_handle, this->ext_fs_file->read_path, fs::OpenMode::Read, this->ext_fs_file->comp));
99 const auto f_base_offset = this->ext_fs_file->GetBaseOffset() + this->file.offset;
100 NTR_R_TRY(this->base_bf.SetAbsoluteOffset(f_base_offset));
101
102 NTR_R_SUCCEED();
103 }
104
105 Result GetSizeImpl(size_t &out_size) override {
106 out_size = this->file.size;
107 NTR_R_SUCCEED();
108 }
109
110 Result SetOffsetImpl(const size_t offset, const fs::Position pos) override {
111 const auto f_base_offset = this->ext_fs_file->GetBaseOffset() + this->file.offset;
112
113 size_t base_bf_abs_offset;
114 NTR_R_TRY(this->base_bf.GetAbsoluteOffset(base_bf_abs_offset));
116
117 switch(pos) {
118 case fs::Position::Begin: {
119 if(offset > this->file.size) {
120 NTR_R_FAIL(ResultEndOfData);
121 }
122 else {
123 return this->base_bf.SetAbsoluteOffset(f_base_offset + offset);
124 }
125 }
126 case fs::Position::Current: {
127 if((f_cur_offset + offset) > this->file.size) {
128 NTR_R_FAIL(ResultEndOfData);
129 }
130 else {
131 return this->base_bf.SetAbsoluteOffset(f_base_offset + f_cur_offset + offset);
132 }
133 }
134 default: {
135 NTR_R_FAIL(ResultInvalidSeekPosition);
136 }
137 }
138 }
139
140 Result GetOffsetImpl(size_t &out_offset) override {
141 const auto f_base_offset = this->ext_fs_file->GetBaseOffset() + this->file.offset;
142
143 size_t base_bf_abs_offset;
144 NTR_R_TRY(this->base_bf.GetAbsoluteOffset(base_bf_abs_offset));
146 NTR_R_SUCCEED();
147 }
148
149 Result ReadImpl(void *read_buf, const size_t read_size, size_t &out_read_size) override {
151 size_t offset;
152 NTR_R_TRY(this->GetOffsetImpl(offset));
153 if((offset + actual_read_size) > this->file.size) {
154 actual_read_size = this->file.size - offset;
155 }
156
157 if(actual_read_size > 0) {
158 return this->base_bf.ReadData(read_buf, actual_read_size, out_read_size);
159 }
160 else {
161 NTR_R_FAIL(ResultEndOfData);
162 }
163 }
164
165 Result CloseImpl() override {
166 return this->base_bf.Close();
167 }
168 };
169
170}
Definition fs_BinaryFile.hpp:9
Definition ntr_Include.hpp:75
Definition nfs_NitroFs.hpp:11
Definition nfs_NitroFs.hpp:17
Definition nfs_NitroFs.hpp:35
Definition nfs_NitroFs.hpp:22
Definition nfs_NitroFs.hpp:28
Definition nfs_NitroFs.hpp:43
Definition nfs_NitroFs.hpp:76
Definition fs_Base.hpp:92
Definition fs_Stdio.hpp:39