From 28bef31ea80478fe58bc4eeaf1b245005f15b36a Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 25 Sep 2018 17:38:16 -0400
Subject: [PATCH] vfs_concat/vfs_layered: Remove friend declarations from
 ConcatenatedVfsFile

Given these are only added to the class to allow those functions to
access the private constructor, it's a better approach to just make them
static functions in the interface, to make the dependency explicit.
---
 src/core/core.cpp                      |  2 +-
 src/core/file_sys/patch_manager.cpp    |  5 +-
 src/core/file_sys/registered_cache.cpp |  2 +-
 src/core/file_sys/romfs.cpp            |  2 +-
 src/core/file_sys/vfs_concat.cpp       | 67 ++++++++++++++------------
 src/core/file_sys/vfs_concat.h         | 19 +++-----
 src/core/file_sys/vfs_layered.cpp      | 15 +++---
 src/core/file_sys/vfs_layered.h        |  8 ++-
 8 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/src/core/core.cpp b/src/core/core.cpp
index 50f0a42fb..7666354dc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -64,7 +64,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
         if (concat.empty())
             return nullptr;
 
-        return FileSys::ConcatenateFiles(concat, dir->GetName());
+        return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName());
     }
 
     return vfs->OpenFile(path, FileSys::Mode::Read);
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index af3f9a78f..561ad67a7 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -90,10 +90,9 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
 
             layers.push_back(std::move(extracted));
 
-            const auto layered = LayerDirectories(layers);
-
+            auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers));
             if (layered != nullptr) {
-                auto packed = CreateRomFS(layered);
+                auto packed = CreateRomFS(std::move(layered));
 
                 if (packed != nullptr) {
                     LOG_INFO(Loader, "    RomFS: LayeredFS patches applied successfully");
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 653ef2e7b..e9b040689 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -125,7 +125,7 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir,
             if (concat.empty())
                 return nullptr;
 
-            file = FileSys::ConcatenateFiles(concat, concat.front()->GetName());
+            file = ConcatenatedVfsFile::MakeConcatenatedFile(concat, concat.front()->GetName());
         }
 
         return file;
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 7804ef56d..5910f7046 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -134,7 +134,7 @@ VirtualFile CreateRomFS(VirtualDir dir) {
         return nullptr;
 
     RomFSBuildContext ctx{dir};
-    return ConcatenateFiles(0, ctx.Build(), dir->GetName());
+    return ConcatenatedVfsFile::MakeConcatenatedFile(0, ctx.Build(), dir->GetName());
 }
 
 } // namespace FileSys
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp
index 8a0df508e..16d801c0c 100644
--- a/src/core/file_sys/vfs_concat.cpp
+++ b/src/core/file_sys/vfs_concat.cpp
@@ -39,6 +39,41 @@ ConcatenatedVfsFile::ConcatenatedVfsFile(std::map<u64, VirtualFile> files_, std:
 
 ConcatenatedVfsFile::~ConcatenatedVfsFile() = default;
 
+VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(std::vector<VirtualFile> files,
+                                                      std::string name) {
+    if (files.empty())
+        return nullptr;
+    if (files.size() == 1)
+        return files[0];
+
+    return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
+}
+
+VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte,
+                                                      std::map<u64, VirtualFile> files,
+                                                      std::string name) {
+    if (files.empty())
+        return nullptr;
+    if (files.size() == 1)
+        return files.begin()->second;
+
+    const auto last_valid = --files.end();
+    for (auto iter = files.begin(); iter != last_valid;) {
+        const auto old = iter++;
+        if (old->first + old->second->GetSize() != iter->first) {
+            files.emplace(old->first + old->second->GetSize(),
+                          std::make_shared<StaticVfsFile>(filler_byte, iter->first - old->first -
+                                                                           old->second->GetSize()));
+        }
+    }
+
+    // Ensure the map starts at offset 0 (start of file), otherwise pad to fill.
+    if (files.begin()->first != 0)
+        files.emplace(0, std::make_shared<StaticVfsFile>(filler_byte, files.begin()->first));
+
+    return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
+}
+
 std::string ConcatenatedVfsFile::GetName() const {
     if (files.empty())
         return "";
@@ -101,36 +136,4 @@ bool ConcatenatedVfsFile::Rename(std::string_view name) {
     return false;
 }
 
-VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name) {
-    if (files.empty())
-        return nullptr;
-    if (files.size() == 1)
-        return files[0];
-
-    return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
-}
-
-VirtualFile ConcatenateFiles(u8 filler_byte, std::map<u64, VirtualFile> files, std::string name) {
-    if (files.empty())
-        return nullptr;
-    if (files.size() == 1)
-        return files.begin()->second;
-
-    const auto last_valid = --files.end();
-    for (auto iter = files.begin(); iter != last_valid;) {
-        const auto old = iter++;
-        if (old->first + old->second->GetSize() != iter->first) {
-            files.emplace(old->first + old->second->GetSize(),
-                          std::make_shared<StaticVfsFile>(filler_byte, iter->first - old->first -
-                                                                           old->second->GetSize()));
-        }
-    }
-
-    // Ensure the map starts at offset 0 (start of file), otherwise pad to fill.
-    if (files.begin()->first != 0)
-        files.emplace(0, std::make_shared<StaticVfsFile>(filler_byte, files.begin()->first));
-
-    return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
-}
-
 } // namespace FileSys
diff --git a/src/core/file_sys/vfs_concat.h b/src/core/file_sys/vfs_concat.h
index 17fa40ade..c90f9d5d1 100644
--- a/src/core/file_sys/vfs_concat.h
+++ b/src/core/file_sys/vfs_concat.h
@@ -14,16 +14,20 @@ namespace FileSys {
 // Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently
 // read-only.
 class ConcatenatedVfsFile : public VfsFile {
-    friend VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name);
-    friend VirtualFile ConcatenateFiles(u8 filler_byte, std::map<u64, VirtualFile> files,
-                                        std::string name);
-
     ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name);
     ConcatenatedVfsFile(std::map<u64, VirtualFile> files, std::string name);
 
 public:
     ~ConcatenatedVfsFile() override;
 
+    /// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases.
+    static VirtualFile MakeConcatenatedFile(std::vector<VirtualFile> files, std::string name);
+
+    /// Convenience function that turns a map of offsets to files into a concatenated file, filling
+    /// gaps with a given filler byte.
+    static VirtualFile MakeConcatenatedFile(u8 filler_byte, std::map<u64, VirtualFile> files,
+                                            std::string name);
+
     std::string GetName() const override;
     std::size_t GetSize() const override;
     bool Resize(std::size_t new_size) override;
@@ -40,11 +44,4 @@ private:
     std::string name;
 };
 
-// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases.
-VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name);
-
-// Convenience function that turns a map of offsets to files into a concatenated file, filling gaps
-// with a given filler byte.
-VirtualFile ConcatenateFiles(u8 filler_byte, std::map<u64, VirtualFile> files, std::string name);
-
 } // namespace FileSys
diff --git a/src/core/file_sys/vfs_layered.cpp b/src/core/file_sys/vfs_layered.cpp
index 45563d7ae..bfee01725 100644
--- a/src/core/file_sys/vfs_layered.cpp
+++ b/src/core/file_sys/vfs_layered.cpp
@@ -8,7 +8,13 @@
 
 namespace FileSys {
 
-VirtualDir LayerDirectories(std::vector<VirtualDir> dirs, std::string name) {
+LayeredVfsDirectory::LayeredVfsDirectory(std::vector<VirtualDir> dirs, std::string name)
+    : dirs(std::move(dirs)), name(std::move(name)) {}
+
+LayeredVfsDirectory::~LayeredVfsDirectory() = default;
+
+VirtualDir LayeredVfsDirectory::MakeLayeredDirectory(std::vector<VirtualDir> dirs,
+                                                     std::string name) {
     if (dirs.empty())
         return nullptr;
     if (dirs.size() == 1)
@@ -17,11 +23,6 @@ VirtualDir LayerDirectories(std::vector<VirtualDir> dirs, std::string name) {
     return std::shared_ptr<VfsDirectory>(new LayeredVfsDirectory(std::move(dirs), std::move(name)));
 }
 
-LayeredVfsDirectory::LayeredVfsDirectory(std::vector<VirtualDir> dirs, std::string name)
-    : dirs(std::move(dirs)), name(std::move(name)) {}
-
-LayeredVfsDirectory::~LayeredVfsDirectory() = default;
-
 std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFileRelative(std::string_view path) const {
     for (const auto& layer : dirs) {
         const auto file = layer->GetFileRelative(path);
@@ -41,7 +42,7 @@ std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetDirectoryRelative(
             out.push_back(std::move(dir));
     }
 
-    return LayerDirectories(std::move(out));
+    return MakeLayeredDirectory(std::move(out));
 }
 
 std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFile(std::string_view name) const {
diff --git a/src/core/file_sys/vfs_layered.h b/src/core/file_sys/vfs_layered.h
index 4f6e341ab..d85310f57 100644
--- a/src/core/file_sys/vfs_layered.h
+++ b/src/core/file_sys/vfs_layered.h
@@ -9,20 +9,18 @@
 
 namespace FileSys {
 
-// Wrapper function to allow for more efficient handling of dirs.size() == 0, 1 cases.
-VirtualDir LayerDirectories(std::vector<VirtualDir> dirs, std::string name = "");
-
 // Class that stacks multiple VfsDirectories on top of each other, attempting to read from the first
 // one and falling back to the one after. The highest priority directory (overwrites all others)
 // should be element 0 in the dirs vector.
 class LayeredVfsDirectory : public VfsDirectory {
-    friend VirtualDir LayerDirectories(std::vector<VirtualDir> dirs, std::string name);
-
     LayeredVfsDirectory(std::vector<VirtualDir> dirs, std::string name);
 
 public:
     ~LayeredVfsDirectory() override;
 
+    /// Wrapper function to allow for more efficient handling of dirs.size() == 0, 1 cases.
+    static VirtualDir MakeLayeredDirectory(std::vector<VirtualDir> dirs, std::string name = "");
+
     std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
     std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
     std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;