libnedit
Lightweight C++ library for Nintendo DS(i) formats
Loading...
Searching...
No Matches
fs_Stdio.hpp
1
2#pragma once
3#include <ntr/fs/fs_BinaryFile.hpp>
4#include <fstream>
5
6namespace ntr::fs {
7
8 // Note: these are just wrappers for stdio stuff (the rest of this library's fs code is basically nitrofs filesystems)
9
10 struct StdioFileHandle : public FileHandle {
11 FILE *file;
12
13 StdioFileHandle() : file(nullptr) {}
14
15 bool Exists(const std::string &path, size_t &out_size) override;
16 Result Open(const std::string &path, const OpenMode mode) override;
17 Result GetSize(size_t &out_size) override;
18 Result SetOffset(const size_t offset, const Position pos) override;
19 Result GetOffset(size_t &out_offset) override;
20 Result Read(void *read_buf, const size_t read_size, size_t &out_read_size) override;
21 Result Write(const void *write_buf, const size_t write_size) override;
22 Result Close() override;
23 };
24
25 Result CreateStdioDirectory(const std::string &dir);
26 bool IsStdioFile(const std::string &path);
27 Result GetStdioFileSize(const std::string &path, size_t &out_size);
28 Result DeleteStdioFile(const std::string &path);
29 Result DeleteStdioDirectory(const std::string &path);
30 Result CopyStdioFiles(const std::string &file, const std::string &new_file, const size_t offset);
31 Result ListAllStdioFiles(const std::string &path, std::vector<std::string> &out_files);
32
33 inline void EnsureBaseStdioDirectoryExists(const std::string &path) {
34 const auto base_dir = GetBaseDirectory(path);
35 CreateStdioDirectory(base_dir);
36 }
37
38 template<typename T>
40 static_assert(std::is_base_of_v<ExternalFsFileFormat, T>);
41
42 std::shared_ptr<T> ext_fs_file;
43 bool rw_from_ext_fs_file;
44 std::string ext_fs_path;
45 fs::BinaryFile ext_fs_bin_file;
46
47 ExternalFsFileHandle(std::shared_ptr<T> ext_fs_file) : ext_fs_file(ext_fs_file) {
48 // TODO: check err here?
49 fs::CreateStdioDirectory(ext_fs_file->ext_fs_root_path);
50 }
51
52 virtual bool ExistsImpl(const std::string &path, size_t &out_size) = 0;
53 virtual Result OpenImpl(const std::string &path) = 0;
54 virtual Result GetSizeImpl(size_t &out_offset) = 0;
55 virtual Result SetOffsetImpl(const size_t offset, const fs::Position pos) = 0;
56 virtual Result GetOffsetImpl(size_t &out_offset) = 0;
57 virtual Result ReadImpl(void *read_buf, const size_t read_size, size_t &out_read_size) = 0;
58 virtual Result CloseImpl() = 0;
59
60 bool Exists(const std::string &path, size_t &out_size) override {
61 return this->ExistsImpl(path, out_size);
62 }
63
64 Result Open(const std::string &path, const fs::OpenMode mode) override {
65 this->ext_fs_path = this->ext_fs_file->GetExternalFsPath(path);
66
67 this->rw_from_ext_fs_file = fs::IsStdioFile(this->ext_fs_path) || fs::CanWriteWithMode(mode);
68 if(this->rw_from_ext_fs_file) {
69 EnsureBaseStdioDirectoryExists(this->ext_fs_path);
70 return this->ext_fs_bin_file.Open(std::make_shared<fs::StdioFileHandle>(), this->ext_fs_path, mode);
71 }
72 else {
73 return this->OpenImpl(path);
74 }
75 }
76
77 Result GetSize(size_t &out_size) override {
78 if(this->rw_from_ext_fs_file) {
79 // ???
80 return this->ext_fs_bin_file.GetSize(out_size);
81 }
82 else {
83 return this->GetSizeImpl(out_size);
84 }
85 }
86
87 Result SetOffset(const size_t offset, const fs::Position pos) override {
88 if(this->rw_from_ext_fs_file) {
89 switch(pos) {
90 case fs::Position::Begin: {
91 return this->ext_fs_bin_file.SetAbsoluteOffset(offset);
92 }
93 case fs::Position::Current: {
94 return this->ext_fs_bin_file.MoveOffset(offset);
95 }
96 default: {
97 NTR_R_FAIL(ResultInvalidSeekPosition);
98 }
99 }
100 }
101 else {
102 return this->SetOffsetImpl(offset, pos);
103 }
104 }
105
106 Result GetOffset(size_t &out_offset) override {
107 if(this->rw_from_ext_fs_file) {
108 return this->ext_fs_bin_file.GetAbsoluteOffset(out_offset);
109 }
110 else {
111 return this->GetOffsetImpl(out_offset);
112 }
113 }
114
115 Result Read(void *read_buf, const size_t read_size, size_t &out_read_size) override {
116 if(this->rw_from_ext_fs_file) {
117 return this->ext_fs_bin_file.ReadData(read_buf, read_size, out_read_size);
118 }
119 else {
120 return this->ReadImpl(read_buf, read_size, out_read_size);
121 }
122 }
123
124 Result Write(const void *write_buf, const size_t write_size) override {
125 if(this->rw_from_ext_fs_file) {
126 return this->ext_fs_bin_file.WriteData(write_buf, write_size);
127 }
128 else {
129 NTR_R_FAIL(ResultWriteNotSupported);
130 }
131 }
132
133 Result Close() override {
134 this->ext_fs_path.clear();
135 if(this->rw_from_ext_fs_file) {
136 return this->ext_fs_bin_file.Close();
137 }
138 else {
139 return this->CloseImpl();
140 }
141 }
142 };
143
145 private:
146 std::vector<dirent> loaded_entries;
147
148 public:
149 StdioFileSystemIterator(const std::string &path) {
150
151 }
152 };
153
154 #define FS_FOR_EACH_STDIO_ENTRY(path, ...) { \
155 auto dir = opendir(path.c_str()); \
156 if(dir) { \
157 while(true) { \
158 auto ent = readdir(dir); \
159 if(ent == nullptr) { \
160 break; \
161 } \
162 const std::string entry_name = ent->d_name; \
163 const std::string entry_path = path + "/" + entry_name; \
164 const bool is_file = ent->d_type & DT_REG; \
165 const bool is_dir = ent->d_type & DT_DIR; \
166 __VA_ARGS__ \
167 } \
168 closedir(dir); \
169 } \
170 }
171
172}
Definition fs_BinaryFile.hpp:9
Definition fs_Stdio.hpp:144
Definition ntr_Include.hpp:75
Definition fs_Stdio.hpp:39
Definition fs_Base.hpp:34
Definition fs_Stdio.hpp:10