simplify stdio/native file paths by sharing the same code.
This commit is contained in:
@@ -102,89 +102,54 @@ private:
|
||||
s64 m_pull_offset{};
|
||||
};
|
||||
|
||||
Result DumpToFile(ui::ProgressBox* pbox, BaseSource* source, std::span<const fs::FsPath> 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<const fs::FsPath> 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<const fs::FsPath> paths) {
|
||||
fs::FsNative fs{};
|
||||
return DumpToFile(pbox, &fs, "/", source, paths);
|
||||
}
|
||||
|
||||
Result DumpToStdio(ui::ProgressBox* pbox, const location::StdioEntry& loc, BaseSource* source, std::span<const fs::FsPath> 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<const fs::FsPath> paths) {
|
||||
@@ -389,7 +354,7 @@ void Dump(std::shared_ptr<BaseSource> source, const std::vector<fs::FsPath>& 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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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::FsNative>(fs, false);
|
||||
} else {
|
||||
m_fs = std::make_unique<fs::FsStdio>();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -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::FsNative>(fs, false);
|
||||
} else {
|
||||
m_fs = std::make_unique<fs::FsStdio>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<source::StreamFile>(fs, path), path, override);
|
||||
}
|
||||
|
||||
Result InstallFromStdioFile(ui::ProgressBox* pbox, const fs::FsPath& path, const ConfigOverride& override) {
|
||||
return InstallFromSource(pbox, std::make_shared<source::Stdio>(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::Base> source, const fs::FsPath& path, const ConfigOverride& override) {
|
||||
|
||||
Reference in New Issue
Block a user