summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
authorGravatar Subv2018-03-19 22:58:55 -0500
committerGravatar Subv2018-03-19 22:58:55 -0500
commita9ba2c2000d9f2e4c6018aa6fc1e754eca82f72c (patch)
treed31aeca8eacb374ab130dcd2449744cde2d5befd /src/core/file_sys
parentFS: Support the file Append open mode. (diff)
downloadyuzu-a9ba2c2000d9f2e4c6018aa6fc1e754eca82f72c.tar.gz
yuzu-a9ba2c2000d9f2e4c6018aa6fc1e754eca82f72c.tar.xz
yuzu-a9ba2c2000d9f2e4c6018aa6fc1e754eca82f72c.zip
FS: Updated the Directory Entry structure to match the Switch.
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/directory.h37
-rw-r--r--src/core/file_sys/disk_filesystem.cpp48
-rw-r--r--src/core/file_sys/disk_filesystem.h22
-rw-r--r--src/core/file_sys/filesystem.h2
-rw-r--r--src/core/file_sys/romfs_filesystem.h5
5 files changed, 84 insertions, 30 deletions
diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h
index 5a40bf472..c7639795e 100644
--- a/src/core/file_sys/directory.h
+++ b/src/core/file_sys/directory.h
@@ -6,34 +6,28 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include "common/common_funcs.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/file_sys/filesystem.h"
10 12
11//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
12// FileSys namespace 14// FileSys namespace
13 15
14namespace FileSys { 16namespace FileSys {
15 17
16// Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format 18// Structure of a directory entry, from
17const size_t FILENAME_LENGTH = 0x20C / 2; 19// http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry
20const size_t FILENAME_LENGTH = 0x300;
18struct Entry { 21struct Entry {
19 char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated) 22 char filename[FILENAME_LENGTH];
20 std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated) 23 INSERT_PADDING_BYTES(4);
21 char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD) 24 EntryType type;
22 std::array<char, 4> 25 INSERT_PADDING_BYTES(3);
23 extension; // 8.3 file extension (set to spaces for directories, null-terminated) 26 u64 file_size;
24 char unknown2; // unknown (always 0x01)
25 char unknown3; // unknown (0x00 or 0x08)
26 char is_directory; // directory flag
27 char is_hidden; // hidden flag
28 char is_archive; // archive flag
29 char is_read_only; // read-only flag
30 u64 file_size; // file size (for files only)
31}; 27};
32static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!"); 28static_assert(sizeof(Entry) == 0x310, "Directory Entry struct isn't exactly 0x310 bytes long!");
33static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry."); 29static_assert(offsetof(Entry, type) == 0x304, "Wrong offset for type in Entry.");
34static_assert(offsetof(Entry, extension) == 0x216, "Wrong offset for extension in Entry."); 30static_assert(offsetof(Entry, file_size) == 0x308, "Wrong offset for file_size in Entry.");
35static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry.");
36static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry.");
37 31
38class DirectoryBackend : NonCopyable { 32class DirectoryBackend : NonCopyable {
39public: 33public:
@@ -46,7 +40,10 @@ public:
46 * @param entries Buffer to read data into 40 * @param entries Buffer to read data into
47 * @return Number of entries listed 41 * @return Number of entries listed
48 */ 42 */
49 virtual u32 Read(const u32 count, Entry* entries) = 0; 43 virtual u64 Read(const u64 count, Entry* entries) = 0;
44
45 /// Returns the number of entries still left to read.
46 virtual u64 GetEntryCount() const = 0;
50 47
51 /** 48 /**
52 * Close the directory 49 * Close the directory
diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp
index 9d456e0bf..e2092b9df 100644
--- a/src/core/file_sys/disk_filesystem.cpp
+++ b/src/core/file_sys/disk_filesystem.cpp
@@ -153,14 +153,50 @@ bool Disk_Storage::SetSize(const u64 size) const {
153 return false; 153 return false;
154} 154}
155 155
156u32 Disk_Directory::Read(const u32 count, Entry* entries) { 156Disk_Directory::Disk_Directory(const std::string& path) : directory() {
157 LOG_WARNING(Service_FS, "(STUBBED) called"); 157 unsigned size = FileUtil::ScanDirectoryTree(path, directory);
158 return 0; 158 directory.size = size;
159 directory.isDirectory = true;
160 children_iterator = directory.children.begin();
161}
162
163u64 Disk_Directory::Read(const u64 count, Entry* entries) {
164 u64 entries_read = 0;
165
166 while (entries_read < count && children_iterator != directory.children.cend()) {
167 const FileUtil::FSTEntry& file = *children_iterator;
168 const std::string& filename = file.virtualName;
169 Entry& entry = entries[entries_read];
170
171 LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
172 file.isDirectory);
173
174 // TODO(Link Mauve): use a proper conversion to UTF-16.
175 for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
176 entry.filename[j] = filename[j];
177 if (!filename[j])
178 break;
179 }
180
181 if (file.isDirectory) {
182 entry.file_size = 0;
183 entry.type = EntryType::Directory;
184 } else {
185 entry.file_size = file.size;
186 entry.type = EntryType::File;
187 }
188
189 ++entries_read;
190 ++children_iterator;
191 }
192 return entries_read;
159} 193}
160 194
161bool Disk_Directory::Close() const { 195u64 Disk_Directory::GetEntryCount() const {
162 LOG_WARNING(Service_FS, "(STUBBED) called"); 196 // We convert the children iterator into a const_iterator to allow template argument deduction
163 return true; 197 // in std::distance.
198 std::vector<FileUtil::FSTEntry>::const_iterator current = children_iterator;
199 return std::distance(current, directory.children.end());
164} 200}
165 201
166} // namespace FileSys 202} // namespace FileSys
diff --git a/src/core/file_sys/disk_filesystem.h b/src/core/file_sys/disk_filesystem.h
index 53767b949..29383dbf7 100644
--- a/src/core/file_sys/disk_filesystem.h
+++ b/src/core/file_sys/disk_filesystem.h
@@ -59,8 +59,26 @@ private:
59 59
60class Disk_Directory : public DirectoryBackend { 60class Disk_Directory : public DirectoryBackend {
61public: 61public:
62 u32 Read(const u32 count, Entry* entries) override; 62 Disk_Directory(const std::string& path);
63 bool Close() const override; 63
64 ~Disk_Directory() override {
65 Close();
66 }
67
68 u64 Read(const u64 count, Entry* entries) override;
69 u64 GetEntryCount() const override;
70
71 bool Close() const override {
72 return true;
73 }
74
75protected:
76 u32 total_entries_in_directory;
77 FileUtil::FSTEntry directory;
78
79 // We need to remember the last entry we returned, so a subsequent call to Read will continue
80 // from the next one. This iterator will always point to the next unread entry.
81 std::vector<FileUtil::FSTEntry>::iterator children_iterator;
64}; 82};
65 83
66} // namespace FileSys 84} // namespace FileSys
diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h
index 4c9993efa..5c91a46c2 100644
--- a/src/core/file_sys/filesystem.h
+++ b/src/core/file_sys/filesystem.h
@@ -27,7 +27,7 @@ enum LowPathType : u32 {
27 Wchar = 4, 27 Wchar = 4,
28}; 28};
29 29
30enum EntryType : u32 { 30enum EntryType : u8 {
31 Directory = 0, 31 Directory = 0,
32 File = 1, 32 File = 1,
33}; 33};
diff --git a/src/core/file_sys/romfs_filesystem.h b/src/core/file_sys/romfs_filesystem.h
index cedd70645..be52f20ef 100644
--- a/src/core/file_sys/romfs_filesystem.h
+++ b/src/core/file_sys/romfs_filesystem.h
@@ -70,7 +70,10 @@ private:
70 70
71class ROMFSDirectory : public DirectoryBackend { 71class ROMFSDirectory : public DirectoryBackend {
72public: 72public:
73 u32 Read(const u32 count, Entry* entries) override { 73 u64 Read(const u64 count, Entry* entries) override {
74 return 0;
75 }
76 u64 GetEntryCount() const override {
74 return 0; 77 return 0;
75 } 78 }
76 bool Close() const override { 79 bool Close() const override {