Skip to content

Commit c49296a

Browse files
Add support for iterating directories in graphics pack content folders. (#1288)
1 parent a6d8c0f commit c49296a

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

src/Cafe/Filesystem/FST/fstUtil.h

+61-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <boost/container/small_vector.hpp>
55

6+
#include "../fsc.h"
7+
68
// path parser and utility class for Wii U paths
79
// optimized to be allocation-free for common path lengths
810
class FSCPath
@@ -119,9 +121,7 @@ class FSCPath
119121
template<typename F>
120122
class FSAFileTree
121123
{
122-
public:
123-
124-
private:
124+
private:
125125

126126
enum NODETYPE : uint8
127127
{
@@ -133,6 +133,7 @@ class FSAFileTree
133133
{
134134
std::string name;
135135
std::vector<node_t*> subnodes;
136+
size_t fileSize;
136137
F* custom;
137138
NODETYPE type;
138139
};
@@ -179,13 +180,54 @@ class FSAFileTree
179180
return newNode;
180181
}
181182

183+
class DirectoryIterator : public FSCVirtualFile
184+
{
185+
public:
186+
DirectoryIterator(node_t* node)
187+
: m_node(node), m_subnodeIndex(0)
188+
{
189+
}
190+
191+
sint32 fscGetType() override
192+
{
193+
return FSC_TYPE_DIRECTORY;
194+
}
195+
196+
bool fscDirNext(FSCDirEntry* dirEntry) override
197+
{
198+
if (m_subnodeIndex >= m_node->subnodes.size())
199+
return false;
200+
201+
const node_t* subnode = m_node->subnodes[m_subnodeIndex];
202+
203+
strncpy(dirEntry->path, subnode->name.c_str(), sizeof(dirEntry->path) - 1);
204+
dirEntry->path[sizeof(dirEntry->path) - 1] = '\0';
205+
dirEntry->isDirectory = subnode->type == FSAFileTree::NODETYPE_DIRECTORY;
206+
dirEntry->isFile = subnode->type == FSAFileTree::NODETYPE_FILE;
207+
dirEntry->fileSize = subnode->type == FSAFileTree::NODETYPE_FILE ? subnode->fileSize : 0;
208+
209+
++m_subnodeIndex;
210+
return true;
211+
}
212+
213+
bool fscRewindDir() override
214+
{
215+
m_subnodeIndex = 0;
216+
return true;
217+
}
218+
219+
private:
220+
node_t* m_node;
221+
size_t m_subnodeIndex;
222+
};
223+
182224
public:
183225
FSAFileTree()
184226
{
185227
rootNode.type = NODETYPE_DIRECTORY;
186228
}
187229

188-
bool addFile(std::string_view path, F* custom)
230+
bool addFile(std::string_view path, size_t fileSize, F* custom)
189231
{
190232
FSCPath p(path);
191233
if (p.GetNodeCount() == 0)
@@ -196,6 +238,7 @@ class FSAFileTree
196238
return false; // node already exists
197239
// add file node
198240
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
241+
fileNode->fileSize = fileSize;
199242
fileNode->custom = custom;
200243
return true;
201244
}
@@ -214,6 +257,20 @@ class FSAFileTree
214257
return true;
215258
}
216259

260+
bool getDirectory(std::string_view path, FSCVirtualFile*& dirIterator)
261+
{
262+
FSCPath p(path);
263+
if (p.GetNodeCount() == 0)
264+
return false;
265+
node_t* node = getByNodePath(p, p.GetNodeCount(), false);
266+
if (node == nullptr)
267+
return false;
268+
if (node->type != NODETYPE_DIRECTORY)
269+
return false;
270+
dirIterator = new DirectoryIterator(node);
271+
return true;
272+
}
273+
217274
bool removeFile(std::string_view path)
218275
{
219276
FSCPath p(path);

src/Cafe/Filesystem/fsc.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,4 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg
212212

213213
// redirect device
214214
void fscDeviceRedirect_map();
215-
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority);
215+
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority);

src/Cafe/Filesystem/fscDeviceRedirect.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct RedirectEntry
1111

1212
FSAFileTree<RedirectEntry> redirectTree;
1313

14-
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority)
14+
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority)
1515
{
1616
// check if source already has a redirection
1717
RedirectEntry* existingEntry;
@@ -24,16 +24,23 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t
2424
delete existingEntry;
2525
}
2626
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
27-
redirectTree.addFile(virtualSourcePath, entry);
27+
redirectTree.addFile(virtualSourcePath, fileSize, entry);
2828
}
2929

3030
class fscDeviceTypeRedirect : public fscDeviceC
3131
{
3232
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
3333
{
3434
RedirectEntry* redirectionEntry;
35-
if (redirectTree.getFile(path, redirectionEntry))
35+
36+
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && redirectTree.getFile(path, redirectionEntry))
3637
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
38+
39+
FSCVirtualFile* dirIterator;
40+
41+
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR) && redirectTree.getDirectory(path, dirIterator))
42+
return dirIterator;
43+
3744
return nullptr;
3845
}
3946

src/Cafe/GraphicPack/GraphicPack2.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC
830830
{
831831
virtualMountPath = fs::path("vol/content/") / virtualMountPath;
832832
}
833-
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.path().generic_string(), m_fs_priority);
833+
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.file_size(), it.path().generic_string(), m_fs_priority);
834834
}
835835
}
836836
}

0 commit comments

Comments
 (0)