diff --git a/sphaira/CMakeLists.txt b/sphaira/CMakeLists.txt index 1f3b307..ec7ec4f 100644 --- a/sphaira/CMakeLists.txt +++ b/sphaira/CMakeLists.txt @@ -91,7 +91,6 @@ add_executable(sphaira source/yati/container/nsp.cpp source/yati/container/xci.cpp source/yati/source/file.cpp - source/yati/source/stdio.cpp source/yati/source/usb.cpp source/yati/source/stream.cpp source/yati/source/stream_file.cpp diff --git a/sphaira/include/yati/source/file.hpp b/sphaira/include/yati/source/file.hpp index c3a5ce8..bc1f395 100644 --- a/sphaira/include/yati/source/file.hpp +++ b/sphaira/include/yati/source/file.hpp @@ -3,17 +3,20 @@ #include "base.hpp" #include "fs.hpp" #include +#include namespace sphaira::yati::source { struct File final : Base { File(FsFileSystem* fs, const fs::FsPath& path); + File(const fs::FsPath& path); ~File(); Result Read(void* buf, s64 off, s64 size, u64* bytes_read) override; private: - FsFile m_file{}; + std::unique_ptr m_fs{}; + fs::File m_file{}; }; } // namespace sphaira::yati::source diff --git a/sphaira/include/yati/source/stdio.hpp b/sphaira/include/yati/source/stdio.hpp deleted file mode 100644 index a6c73c1..0000000 --- a/sphaira/include/yati/source/stdio.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "base.hpp" -#include "fs.hpp" -#include -#include - -namespace sphaira::yati::source { - -struct Stdio final : Base { - Stdio(const fs::FsPath& path); - ~Stdio(); - - Result Read(void* buf, s64 off, s64 size, u64* bytes_read) override; - -private: - std::FILE* m_file{}; -}; - -} // namespace sphaira::yati::source diff --git a/sphaira/include/yati/source/stream_file.hpp b/sphaira/include/yati/source/stream_file.hpp index a6398e0..0ba6c25 100644 --- a/sphaira/include/yati/source/stream_file.hpp +++ b/sphaira/include/yati/source/stream_file.hpp @@ -5,17 +5,20 @@ #include "stream.hpp" #include "fs.hpp" #include +#include namespace sphaira::yati::source { struct StreamFile final : Stream { StreamFile(FsFileSystem* fs, const fs::FsPath& path); + StreamFile(const fs::FsPath& path); ~StreamFile(); Result ReadChunk(void* buf, s64 size, u64* bytes_read) override; private: - FsFile m_file{}; + std::unique_ptr m_fs{}; + fs::File m_file{}; s64 m_offset{}; }; diff --git a/sphaira/include/yati/yati.hpp b/sphaira/include/yati/yati.hpp index 4a92f28..7404e04 100644 --- a/sphaira/include/yati/yati.hpp +++ b/sphaira/include/yati/yati.hpp @@ -130,7 +130,7 @@ struct ConfigOverride { }; Result InstallFromFile(ui::ProgressBox* pbox, FsFileSystem* fs, const fs::FsPath& path, const ConfigOverride& override = {}); -Result InstallFromStdioFile(ui::ProgressBox* pbox, const fs::FsPath& path, const ConfigOverride& override = {}); +Result InstallFromFile(ui::ProgressBox* pbox, const fs::FsPath& path, const ConfigOverride& override = {}); Result InstallFromSource(ui::ProgressBox* pbox, std::shared_ptr source, const fs::FsPath& path, const ConfigOverride& override = {}); Result InstallFromContainer(ui::ProgressBox* pbox, std::shared_ptr container, const ConfigOverride& override = {}); Result InstallFromCollections(ui::ProgressBox* pbox, std::shared_ptr source, const container::Collections& collections, const ConfigOverride& override = {}); diff --git a/sphaira/source/dumper.cpp b/sphaira/source/dumper.cpp index ca29a23..dae62f9 100644 --- a/sphaira/source/dumper.cpp +++ b/sphaira/source/dumper.cpp @@ -102,89 +102,54 @@ private: s64 m_pull_offset{}; }; -Result DumpToFile(ui::ProgressBox* pbox, BaseSource* source, std::span paths) { - static constexpr fs::FsPath DUMP_PATH{"/dumps/NSP"}; +Result DumpToFile(ui::ProgressBox* pbox, fs::Fs* fs, const fs::FsPath& root, BaseSource* source, std::span paths) { + const auto DUMP_PATH = fs::AppendPath(root, "/dumps/NSP"); constexpr s64 BIG_FILE_SIZE = 1024ULL*1024ULL*1024ULL*4ULL; - fs::FsNativeSd fs{}; - R_TRY(fs.GetFsOpenResult()); - for (auto path : paths) { const auto file_size = source->GetSize(path); pbox->SetTitle(source->GetName(path)); pbox->NewTransfer(path); const auto temp_path = fs::AppendPath(DUMP_PATH, path + ".temp"); - fs.CreateDirectoryRecursivelyWithPath(temp_path); - fs.DeleteFile(temp_path); + fs->CreateDirectoryRecursivelyWithPath(temp_path); + fs->DeleteFile(temp_path); const auto flags = file_size >= BIG_FILE_SIZE ? FsCreateOption_BigFile : 0; - R_TRY(fs.CreateFile(temp_path, file_size, flags)); - ON_SCOPE_EXIT(fs.DeleteFile(temp_path)); + R_TRY(fs->CreateFile(temp_path, file_size, flags)); + ON_SCOPE_EXIT(fs->DeleteFile(temp_path)); { - FsFile file; - R_TRY(fs.OpenFile(temp_path, FsOpenMode_Write, &file)); - ON_SCOPE_EXIT(fsFileClose(&file)); + fs::File file; + R_TRY(fs->OpenFile(temp_path, FsOpenMode_Write, &file)); + ON_SCOPE_EXIT(fs->FileClose(&file)); R_TRY(thread::Transfer(pbox, file_size, [&](void* data, s64 off, s64 size, u64* bytes_read) -> Result { return source->Read(path, data, off, size, bytes_read); }, [&](const void* data, s64 off, s64 size) -> Result { - return fsFileWrite(&file, off, data, size, FsWriteOption_None); + return fs->FileWrite(&file, off, data, size, FsWriteOption_None); } )); } path = fs::AppendPath(DUMP_PATH, path); - fs.DeleteFile(path); - R_TRY(fs.RenameFile(temp_path, path)); + fs->DeleteFile(path); + R_TRY(fs->RenameFile(temp_path, path)); } R_SUCCEED(); } +Result DumpToFileNative(ui::ProgressBox* pbox, BaseSource* source, std::span paths) { + fs::FsNative fs{}; + return DumpToFile(pbox, &fs, "/", source, paths); +} + Result DumpToStdio(ui::ProgressBox* pbox, const location::StdioEntry& loc, BaseSource* source, std::span paths) { - const fs::FsPath DUMP_PATH = loc.mount + "/dumps/NSP"; - fs::FsStdio fs{}; - - for (auto path : paths) { - const auto file_size = source->GetSize(path); - pbox->SetTitle(source->GetName(path)); - pbox->NewTransfer(path); - - const auto temp_path = fs::AppendPath(DUMP_PATH, path + ".temp"); - fs.CreateDirectoryRecursivelyWithPath(temp_path); - fs.DeleteFile(temp_path); - - R_TRY(fs.CreateFile(temp_path, file_size)); - ON_SCOPE_EXIT(fs.DeleteFile(temp_path)); - - { - auto file = std::fopen(temp_path, "wb"); - R_UNLESS(file, 0x1); - ON_SCOPE_EXIT(std::fclose(file)); - - R_TRY(thread::Transfer(pbox, file_size, - [&](void* data, s64 off, s64 size, u64* bytes_read) -> Result { - return source->Read(path, data, off, size, bytes_read); - }, - [&](const void* data, s64 off, s64 size) -> Result { - const auto written = std::fwrite(data, 1, size, file); - R_UNLESS(written >= 1, 0x1); - R_SUCCEED(); - } - )); - } - - path = fs::AppendPath(DUMP_PATH, path); - fs.DeleteFile(path); - R_TRY(fs.RenameFile(temp_path, path)); - } - - R_SUCCEED(); + return DumpToFile(pbox, &fs, loc.mount, source, paths); } Result DumpToUsbS2SStream(ui::ProgressBox* pbox, UsbTest* usb, std::span paths) { @@ -389,7 +354,7 @@ void Dump(std::shared_ptr source, const std::vector& pat } else if (dump_entry.type == DumpLocationType_Stdio) { R_TRY(DumpToStdio(pbox, stdio_locations[dump_entry.index], source.get(), paths)); } else if (dump_entry.type == DumpLocationType_SdCard) { - R_TRY(DumpToFile(pbox, source.get(), paths)); + R_TRY(DumpToFileNative(pbox, source.get(), paths)); } else if (dump_entry.type == DumpLocationType_UsbS2S) { R_TRY(DumpToUsbS2S(pbox, source.get(), paths)); } else if (dump_entry.type == DumpLocationType_DevNull) { diff --git a/sphaira/source/fs.cpp b/sphaira/source/fs.cpp index cab0558..d2015f4 100644 --- a/sphaira/source/fs.cpp +++ b/sphaira/source/fs.cpp @@ -465,9 +465,9 @@ Result OpenFile(fs::Fs* fs, const fs::FsPath& path, u32 mode, File* f) { // todo: R_THROW(0x1); } else if (mode & FsOpenMode_Read) { - f->m_stdio = fopen(path, "rb"); + f->m_stdio = std::fopen(path, "rb"); } else if (mode & FsOpenMode_Write) { - f->m_stdio = fopen(path, "wb"); + f->m_stdio = std::fopen(path, "wb"); } R_UNLESS(f->m_stdio, 0x1); diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index b05159a..dc408cf 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -931,7 +931,7 @@ void Menu::InstallFiles() { if (m_fs->IsNative()) { R_TRY(yati::InstallFromFile(pbox, &GetNative()->m_fs, GetNewPath(e))); } else { - R_TRY(yati::InstallFromStdioFile(pbox, GetNewPath(e))); + R_TRY(yati::InstallFromFile(pbox, GetNewPath(e))); } App::Notify("Installed " + e.GetName()); } diff --git a/sphaira/source/yati/source/file.cpp b/sphaira/source/yati/source/file.cpp index 100c5ef..2133d01 100644 --- a/sphaira/source/yati/source/file.cpp +++ b/sphaira/source/yati/source/file.cpp @@ -3,18 +3,28 @@ namespace sphaira::yati::source { File::File(FsFileSystem* fs, const fs::FsPath& path) { - m_open_result = fsFsOpenFile(fs, path, FsOpenMode_Read, std::addressof(m_file)); + if (fs) { + m_fs = std::make_unique(fs, false); + } else { + m_fs = std::make_unique(); + } + + m_open_result = m_fs->OpenFile(path, FsOpenMode_Read, std::addressof(m_file)); +} + +File::File(const fs::FsPath& path) : File{nullptr, path} { + } File::~File() { if (R_SUCCEEDED(GetOpenResult())) { - fsFileClose(std::addressof(m_file)); + m_fs->FileClose(std::addressof(m_file)); } } Result File::Read(void* buf, s64 off, s64 size, u64* bytes_read) { R_TRY(GetOpenResult()); - return fsFileRead(std::addressof(m_file), off, buf, size, 0, bytes_read); + return m_fs->FileRead(std::addressof(m_file), off, buf, size, 0, bytes_read); } } // namespace sphaira::yati::source diff --git a/sphaira/source/yati/source/stdio.cpp b/sphaira/source/yati/source/stdio.cpp deleted file mode 100644 index 6a4880e..0000000 --- a/sphaira/source/yati/source/stdio.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "yati/source/stdio.hpp" - -namespace sphaira::yati::source { - -Stdio::Stdio(const fs::FsPath& path) { - m_file = std::fopen(path, "rb"); - if (!m_file) { - m_open_result = fsdevGetLastResult(); - } -} - -Stdio::~Stdio() { - if (R_SUCCEEDED(GetOpenResult())) { - std::fclose(m_file); - } -} - -Result Stdio::Read(void* buf, s64 off, s64 size, u64* bytes_read) { - R_TRY(GetOpenResult()); - - std::fseek(m_file, off, SEEK_SET); - R_TRY(fsdevGetLastResult()); - - *bytes_read = std::fread(buf, 1, size, m_file); - return fsdevGetLastResult(); -} - -} // namespace sphaira::yati::source diff --git a/sphaira/source/yati/source/stream_file.cpp b/sphaira/source/yati/source/stream_file.cpp index d662afa..68066f0 100644 --- a/sphaira/source/yati/source/stream_file.cpp +++ b/sphaira/source/yati/source/stream_file.cpp @@ -4,18 +4,28 @@ namespace sphaira::yati::source { StreamFile::StreamFile(FsFileSystem* fs, const fs::FsPath& path) { - m_open_result = fsFsOpenFile(fs, path, FsOpenMode_Read, std::addressof(m_file)); + if (fs) { + m_fs = std::make_unique(fs, false); + } else { + m_fs = std::make_unique(); + } + + m_open_result = m_fs->OpenFile(path, FsOpenMode_Read, std::addressof(m_file)); +} + +StreamFile::StreamFile(const fs::FsPath& path) : StreamFile{nullptr, path} { + } StreamFile::~StreamFile() { if (R_SUCCEEDED(GetOpenResult())) { - fsFileClose(std::addressof(m_file)); + m_fs->FileClose(std::addressof(m_file)); } } Result StreamFile::ReadChunk(void* buf, s64 size, u64* bytes_read) { R_TRY(GetOpenResult()); - const auto rc = fsFileRead(std::addressof(m_file), m_offset, buf, size, 0, bytes_read); + const auto rc = m_fs->FileRead(std::addressof(m_file), m_offset, buf, size, 0, bytes_read); m_offset += *bytes_read; return rc; } diff --git a/sphaira/source/yati/yati.cpp b/sphaira/source/yati/yati.cpp index f98a896..d8f27d8 100644 --- a/sphaira/source/yati/yati.cpp +++ b/sphaira/source/yati/yati.cpp @@ -1,7 +1,6 @@ #include "yati/yati.hpp" #include "yati/source/file.hpp" #include "yati/source/stream_file.hpp" -#include "yati/source/stdio.hpp" #include "yati/container/nsp.hpp" #include "yati/container/xci.hpp" @@ -1393,8 +1392,8 @@ Result InstallFromFile(ui::ProgressBox* pbox, FsFileSystem* fs, const fs::FsPath // return InstallFromSource(pbox, std::make_shared(fs, path), path, override); } -Result InstallFromStdioFile(ui::ProgressBox* pbox, const fs::FsPath& path, const ConfigOverride& override) { - return InstallFromSource(pbox, std::make_shared(path), path, override); +Result InstallFromFile(ui::ProgressBox* pbox, const fs::FsPath& path, const ConfigOverride& override) { + return InstallFromFile(pbox, nullptr, path, override); } Result InstallFromSource(ui::ProgressBox* pbox, std::shared_ptr source, const fs::FsPath& path, const ConfigOverride& override) {