mirror of
https://github.com/jakcron/nstool
synced 2024-12-26 22:51:11 +00:00
Add FsProcess
This commit is contained in:
parent
5f1e8b27de
commit
7a9ef48a38
2 changed files with 164 additions and 0 deletions
129
src/FsProcess.cpp
Normal file
129
src/FsProcess.cpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
#include "FsProcess.h"
|
||||
#include <iostream>
|
||||
|
||||
nstool::FsProcess::FsProcess() :
|
||||
mModuleLabel("nstool::FsProcess"),
|
||||
mInputFs(),
|
||||
mShowFs(false),
|
||||
mExtractPath()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void nstool::FsProcess::setInputFileSystem(const std::shared_ptr<tc::io::IStorage>& input_fs)
|
||||
{
|
||||
mInputFs = input_fs;
|
||||
}
|
||||
|
||||
void nstool::FsProcess::setFsLabel(const std::string& fs_label)
|
||||
{
|
||||
mFsLabel = fs_label;
|
||||
}
|
||||
|
||||
void nstool::FsProcess::setCliOutputMode(bool show_fs)
|
||||
{
|
||||
mShowFs = show_fs;
|
||||
}
|
||||
|
||||
void nstool::FsProcess::setExtractPath(const tc::io::Path& extract_path)
|
||||
{
|
||||
mExtractPath = extract_path;
|
||||
}
|
||||
|
||||
void nstool::FsProcess::process()
|
||||
{
|
||||
if (mInputFs == nullptr)
|
||||
{
|
||||
throw tc::InvalidOperationException(mModuleLabel, "No input filesystem");
|
||||
}
|
||||
|
||||
if (mShowFs)
|
||||
printFs();
|
||||
|
||||
if (mExtractPath.isSet())
|
||||
extractFs();
|
||||
}
|
||||
|
||||
void nstool::FsProcess::printFs()
|
||||
{
|
||||
fmt::print("[{:s}FsTree]\n", (mFsLabel.isSet() ? (mFsLabel.get() + "/") : ""));
|
||||
visitDir(tc::io::Path("/"), tc::io::Path("/"), false, true);
|
||||
}
|
||||
|
||||
void nstool::FsProcess::extractFs()
|
||||
{
|
||||
fmt::print("[{:s}FsExtract]\n", (mFsLabel.isSet() ? (mFsLabel.get() + "/") : ""));
|
||||
visitDir(tc::io::Path("/"), mExtractPath.get(), true, false);
|
||||
}
|
||||
|
||||
void nstool::FsProcess::visitDir(const tc::io::Path& v_path, const tc::io::Path& l_path, bool extract_fs, bool print_fs)
|
||||
{
|
||||
tc::io::LocalStorage local_fs;
|
||||
|
||||
// get listing for directory
|
||||
tc::io::sDirectoryListing info;
|
||||
mInputFs->getDirectoryListing(v_path, info);
|
||||
|
||||
if (print_fs)
|
||||
{
|
||||
for (size_t i = 0; i < v_path.size(); i++)
|
||||
fmt::print(" ");;
|
||||
|
||||
fmt::print("{:s}/\n", ((v_path.size() == 1) ? "Root:" : v_path.back()));
|
||||
}
|
||||
if (extract_fs)
|
||||
{
|
||||
// create local dir
|
||||
local_fs.createDirectory(l_path);
|
||||
}
|
||||
|
||||
// iterate thru child files
|
||||
tc::ByteData cache = tc::ByteData(0x10000);
|
||||
size_t cache_read_len;
|
||||
tc::io::Path out_path;
|
||||
std::string out_path_str;
|
||||
std::shared_ptr<tc::io::IStream> in_stream;
|
||||
std::shared_ptr<tc::io::IStream> out_stream;
|
||||
for (auto itr = info.file_list.begin(); itr != info.file_list.end(); itr++)
|
||||
{
|
||||
if (print_fs)
|
||||
{
|
||||
for (size_t i = 0; i < v_path.size(); i++)
|
||||
fmt::print(" ");
|
||||
fmt::print(" {:s}\n", *itr);
|
||||
}
|
||||
if (extract_fs)
|
||||
{
|
||||
// build out path
|
||||
out_path = l_path + *itr;
|
||||
tc::io::PathUtil::pathToUnixUTF8(out_path, out_path_str);
|
||||
|
||||
fmt::print("Saving {:s}...\n", out_path_str);
|
||||
|
||||
// begin export
|
||||
mInputFs->openFile(v_path + *itr, tc::io::FileMode::Open, tc::io::FileAccess::Read, in_stream);
|
||||
local_fs.openFile(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write, out_stream);
|
||||
|
||||
in_stream->seek(0, tc::io::SeekOrigin::Begin);
|
||||
out_stream->seek(0, tc::io::SeekOrigin::Begin);
|
||||
for (int64_t remaining_data = in_stream->length(); remaining_data > 0;)
|
||||
{
|
||||
cache_read_len = in_stream->read(cache.data(), cache.size());
|
||||
if (cache_read_len == 0)
|
||||
{
|
||||
throw tc::io::IOException(mModuleLabel, fmt::format("Failed to read from {:s}file.", (mFsLabel.isSet() ? (mFsLabel.get() + " ") : "")));
|
||||
}
|
||||
|
||||
out_stream->write(cache.data(), cache_read_len);
|
||||
|
||||
remaining_data -= int64_t(cache_read_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate thru child dirs
|
||||
for (auto itr = info.dir_list.begin(); itr != info.dir_list.end(); itr++)
|
||||
{
|
||||
visitDir(v_path + *itr, l_path + *itr, extract_fs, print_fs);
|
||||
}
|
||||
}
|
35
src/FsProcess.h
Normal file
35
src/FsProcess.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
#include <tc/Optional.h>
|
||||
#include <tc/io.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace nstool
|
||||
{
|
||||
|
||||
class FsProcess
|
||||
{
|
||||
public:
|
||||
FsProcess();
|
||||
|
||||
void setInputFileSystem(const std::shared_ptr<tc::io::IStorage>& input_fs);
|
||||
void setFsLabel(const std::string& fs_label);
|
||||
void setCliOutputMode(bool show_fs);
|
||||
void setExtractPath(const tc::io::Path& extract_path);
|
||||
|
||||
void process();
|
||||
private:
|
||||
std::string mModuleLabel;
|
||||
|
||||
std::shared_ptr<tc::io::IStorage> mInputFs;
|
||||
tc::Optional<std::string> mFsLabel;
|
||||
bool mShowFs;
|
||||
tc::Optional<tc::io::Path> mExtractPath;
|
||||
|
||||
void printFs();
|
||||
void extractFs();
|
||||
|
||||
void visitDir(const tc::io::Path& v_path, const tc::io::Path& l_path, bool extract_fs, bool print_fs);
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue