mirror of
				https://github.com/jakcron/nstool.git
				synced 2025-11-04 10:34:53 +00:00 
			
		
		
		
	Port PfsProcess to libtoolchain
This commit is contained in:
		
							parent
							
								
									ab2686fd78
								
							
						
					
					
						commit
						5f1e8b27de
					
				
							
								
								
									
										2
									
								
								deps/libnintendo-hac
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								deps/libnintendo-hac
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit 02c6703c9720d98197b3bb697fdab12008a9829e
 | 
			
		||||
Subproject commit 17c5c7177d8a899d01826091b3637e133b1f1c8e
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +1,16 @@
 | 
			
		|||
#include "PfsProcess.h"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
 | 
			
		||||
#include <fnd/SimpleFile.h>
 | 
			
		||||
#include <fnd/io.h>
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#include <nn/hac/PartitionFsUtil.h>
 | 
			
		||||
#include <tc/io/LocalStorage.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
nstool::PfsProcess::PfsProcess() :
 | 
			
		||||
	mModuleName("nstool::PfsProcess"),
 | 
			
		||||
	mFile(),
 | 
			
		||||
	mCliOutputMode(true, false, false, false),
 | 
			
		||||
	mVerify(false),
 | 
			
		||||
	mExtractPath(),
 | 
			
		||||
	mExtract(false),
 | 
			
		||||
	mMountName(),
 | 
			
		||||
	mListFs(false),
 | 
			
		||||
	mPfs()
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +29,7 @@ void nstool::PfsProcess::process()
 | 
			
		|||
	}
 | 
			
		||||
	if (mPfs.getFsType() == mPfs.TYPE_HFS0 && mVerify)
 | 
			
		||||
		validateHfs();
 | 
			
		||||
	if (mExtract)
 | 
			
		||||
	if (mExtractPath.isSet())
 | 
			
		||||
		extractFs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,9 +53,8 @@ void nstool::PfsProcess::setMountPointName(const std::string& mount_name)
 | 
			
		|||
	mMountName = mount_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::PfsProcess::setExtractPath(const std::string& path)
 | 
			
		||||
void nstool::PfsProcess::setExtractPath(const tc::io::Path& path)
 | 
			
		||||
{
 | 
			
		||||
	mExtract = true;
 | 
			
		||||
	mExtractPath = path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -75,125 +70,126 @@ const nn::hac::PartitionFsHeader& nstool::PfsProcess::getPfsHeader() const
 | 
			
		|||
 | 
			
		||||
void nstool::PfsProcess::importHeader()
 | 
			
		||||
{
 | 
			
		||||
	if (mFile == nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		throw tc::Exception(mModuleName, "No file reader set.");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tc::ByteData scratch;
 | 
			
		||||
 | 
			
		||||
	if (*mFile == nullptr)
 | 
			
		||||
	// read base header to determine complete header size
 | 
			
		||||
	if (mFile->length() < tc::io::IOUtil::castSizeToInt64(sizeof(nn::hac::sPfsHeader)))
 | 
			
		||||
	{
 | 
			
		||||
		throw tc::Exception(kModuleName, "No file reader set.");
 | 
			
		||||
		throw tc::Exception(mModuleName, "Corrupt PartitionFs: File too small");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// open minimum header to get full header size
 | 
			
		||||
	scratch.alloc(sizeof(nn::hac::sPfsHeader));
 | 
			
		||||
	(*mFile)->read(scratch.data(), 0, scratch.size());
 | 
			
		||||
 | 
			
		||||
	scratch = tc::ByteData(sizeof(nn::hac::sPfsHeader));
 | 
			
		||||
	mFile->seek(0, tc::io::SeekOrigin::Begin);
 | 
			
		||||
	mFile->read(scratch.data(), scratch.size());
 | 
			
		||||
	if (validateHeaderMagic(((nn::hac::sPfsHeader*)scratch.data())) == false)
 | 
			
		||||
	{
 | 
			
		||||
		throw tc::Exception(kModuleName, "Corrupt Header");
 | 
			
		||||
		throw tc::Exception(mModuleName, "Corrupt PartitionFs: Header had incorrect struct magic.");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read complete size header
 | 
			
		||||
	size_t pfsHeaderSize = determineHeaderSize(((nn::hac::sPfsHeader*)scratch.data()));
 | 
			
		||||
	
 | 
			
		||||
	// open minimum header to get full header size
 | 
			
		||||
	scratch.alloc(pfsHeaderSize);
 | 
			
		||||
	(*mFile)->read(scratch.data(), 0, scratch.size());
 | 
			
		||||
	if (mFile->length() < tc::io::IOUtil::castSizeToInt64(pfsHeaderSize))
 | 
			
		||||
	{
 | 
			
		||||
		throw tc::Exception(mModuleName, "Corrupt PartitionFs: File too small");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scratch = tc::ByteData(pfsHeaderSize);
 | 
			
		||||
	mFile->seek(0, tc::io::SeekOrigin::Begin);
 | 
			
		||||
	mFile->read(scratch.data(), scratch.size());
 | 
			
		||||
 | 
			
		||||
	// process PFS
 | 
			
		||||
	mPfs.fromBytes(scratch.data(), scratch.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::PfsProcess::displayHeader()
 | 
			
		||||
{
 | 
			
		||||
	std::cout << "[PartitionFS]" << std::endl;
 | 
			
		||||
	std::cout << "  Type:        " << nn::hac::PartitionFsUtil::getFsTypeAsString(mPfs.getFsType()) << std::endl;
 | 
			
		||||
	std::cout << "  FileNum:     " << std::dec << mPfs.getFileList().size() << std::endl;
 | 
			
		||||
	fmt::print("[PartitionFS]\n");
 | 
			
		||||
	fmt::print("  Type:        {:s}\n", nn::hac::PartitionFsUtil::getFsTypeAsString(mPfs.getFsType()));
 | 
			
		||||
	fmt::print("  FileNum:     {:d}\n", mPfs.getFileList().size());
 | 
			
		||||
	if (mMountName.empty() == false)
 | 
			
		||||
	{
 | 
			
		||||
		std::cout << "  MountPoint:  " << mMountName;
 | 
			
		||||
		fmt::print("  MountPoint:  {:s}");
 | 
			
		||||
		if (mMountName.at(mMountName.length()-1) != '/')
 | 
			
		||||
			std::cout << "/";
 | 
			
		||||
		std::cout << std::endl;
 | 
			
		||||
			fmt::print("/");
 | 
			
		||||
		fmt::print("\n");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::PfsProcess::displayFs()
 | 
			
		||||
{	
 | 
			
		||||
	for (size_t i = 0; i < mPfs.getFileList().size(); i++)
 | 
			
		||||
	auto file_list = mPfs.getFileList();
 | 
			
		||||
	for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
 | 
			
		||||
	{
 | 
			
		||||
		const nn::hac::PartitionFsHeader::sFile& file = mPfs.getFileList()[i];
 | 
			
		||||
		std::cout << "    " << file.name;
 | 
			
		||||
		fmt::print("    {:s}", itr->name);
 | 
			
		||||
		if (mCliOutputMode.show_layout)
 | 
			
		||||
		{
 | 
			
		||||
			switch (mPfs.getFsType())
 | 
			
		||||
			{
 | 
			
		||||
			case (nn::hac::PartitionFsHeader::TYPE_PFS0):
 | 
			
		||||
				std::cout << std::hex << " (offset=0x" << file.offset << ", size=0x" << file.size << ")";
 | 
			
		||||
				fmt::print(" (offset=0x{:x}, size=0x{:x})", itr->offset, itr->size);
 | 
			
		||||
				break;
 | 
			
		||||
			case (nn::hac::PartitionFsHeader::TYPE_HFS0):
 | 
			
		||||
				std::cout << std::hex << " (offset=0x" << file.offset << ", size=0x" << file.size << ", hash_protected_size=0x" << file.hash_protected_size << ")";
 | 
			
		||||
				fmt::print(" (offset=0x{:x}, size=0x{:x}, hash_protected_size=0x{:x})", itr->offset, itr->size, itr->hash_protected_size);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		std::cout << std::endl;
 | 
			
		||||
		fmt::print("\n");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t nstool::PfsProcess::determineHeaderSize(const nn::hac::sPfsHeader* hdr)
 | 
			
		||||
{
 | 
			
		||||
	size_t fileEntrySize = 0;
 | 
			
		||||
	if (hdr->st_magic.get() == nn::hac::pfs::kPfsStructMagic)
 | 
			
		||||
	if (hdr->st_magic.unwrap() == nn::hac::pfs::kPfsStructMagic)
 | 
			
		||||
		fileEntrySize = sizeof(nn::hac::sPfsFile);
 | 
			
		||||
	else
 | 
			
		||||
		fileEntrySize = sizeof(nn::hac::sHashedPfsFile);
 | 
			
		||||
 | 
			
		||||
	return sizeof(nn::hac::sPfsHeader) + hdr->file_num.get() * fileEntrySize + hdr->name_table_size.get();
 | 
			
		||||
	return sizeof(nn::hac::sPfsHeader) + hdr->file_num.unwrap() * fileEntrySize + hdr->name_table_size.unwrap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool nstool::PfsProcess::validateHeaderMagic(const nn::hac::sPfsHeader* hdr)
 | 
			
		||||
{
 | 
			
		||||
	return hdr->st_magic.get() == nn::hac::pfs::kPfsStructMagic || hdr->st_magic.get() == nn::hac::pfs::kHashedPfsStructMagic;
 | 
			
		||||
	return hdr->st_magic.unwrap() == nn::hac::pfs::kPfsStructMagic || hdr->st_magic.unwrap() == nn::hac::pfs::kHashedPfsStructMagic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::PfsProcess::validateHfs()
 | 
			
		||||
{
 | 
			
		||||
	fnd::sha::sSha256Hash hash;
 | 
			
		||||
	const std::vector<nn::hac::PartitionFsHeader::sFile>& file = mPfs.getFileList();
 | 
			
		||||
	for (size_t i = 0; i < file.size(); i++)
 | 
			
		||||
	nn::hac::detail::sha256_hash_t hash;
 | 
			
		||||
	auto file_list = mPfs.getFileList();
 | 
			
		||||
	for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
 | 
			
		||||
	{
 | 
			
		||||
		mCache.alloc(file[i].hash_protected_size);
 | 
			
		||||
		(*mFile)->read(mCache.data(), file[i].offset, file[i].hash_protected_size);
 | 
			
		||||
		fnd::sha::Sha256(mCache.data(), file[i].hash_protected_size, hash.bytes);
 | 
			
		||||
		if (hash != file[i].hash)
 | 
			
		||||
		tc::ByteData cache = tc::ByteData(tc::io::IOUtil::castInt64ToSize(itr->hash_protected_size));
 | 
			
		||||
		mFile->seek(itr->offset, tc::io::SeekOrigin::Begin);
 | 
			
		||||
		mFile->read(cache.data(), cache.size());
 | 
			
		||||
		tc::crypto::GenerateSha256Hash(hash.data(), cache.data(), cache.size());
 | 
			
		||||
		if (hash != itr->hash)
 | 
			
		||||
		{
 | 
			
		||||
			printf("[WARNING] HFS0 %s%s%s: FAIL (bad hash)\n", !mMountName.empty()? mMountName.c_str() : "", (!mMountName.empty() && mMountName.at(mMountName.length()-1) != '/' )? "/" : "", file[i].name.c_str());
 | 
			
		||||
			fmt::print("[WARNING] HFS0 {:s}{:s}{:s}: FAIL (bad hash)\n", !mMountName.empty()? mMountName.c_str() : "", (!mMountName.empty() && mMountName.at(mMountName.length()-1) != '/' )? "/" : "", itr->name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::PfsProcess::extractFs()
 | 
			
		||||
{
 | 
			
		||||
	// allocate only when extractDir is invoked
 | 
			
		||||
	mCache.alloc(kCacheSize);
 | 
			
		||||
	// create extract directory
 | 
			
		||||
	tc::io::LocalStorage fs;
 | 
			
		||||
	fs.createDirectory(mExtractPath.get());
 | 
			
		||||
 | 
			
		||||
	// make extract dir
 | 
			
		||||
	fnd::io::makeDirectory(mExtractPath);
 | 
			
		||||
	// extract files
 | 
			
		||||
	tc::ByteData cache_for_extract = tc::ByteData(kCacheSize);
 | 
			
		||||
 | 
			
		||||
	fnd::SimpleFile outFile;
 | 
			
		||||
	const std::vector<nn::hac::PartitionFsHeader::sFile>& file = mPfs.getFileList();
 | 
			
		||||
 | 
			
		||||
	std::string file_path;
 | 
			
		||||
	for (size_t i = 0; i < file.size(); i++)
 | 
			
		||||
	auto file_list = mPfs.getFileList();
 | 
			
		||||
	for (auto itr = file_list.begin(); itr != file_list.end(); itr++)
 | 
			
		||||
	{
 | 
			
		||||
		file_path.clear();
 | 
			
		||||
		fnd::io::appendToPath(file_path, mExtractPath);
 | 
			
		||||
		fnd::io::appendToPath(file_path, file[i].name);
 | 
			
		||||
		tc::io::Path extract_path = mExtractPath.get() + itr->name;
 | 
			
		||||
 | 
			
		||||
		if (mCliOutputMode.show_basic_info)
 | 
			
		||||
			printf("extract=[%s]\n", file_path.c_str());
 | 
			
		||||
 | 
			
		||||
		outFile.open(file_path, outFile.Create);
 | 
			
		||||
		(*mFile)->seek(file[i].offset);
 | 
			
		||||
		for (size_t j = 0; j < ((file[i].size / kCacheSize) + ((file[i].size % kCacheSize) != 0)); j++)
 | 
			
		||||
		{
 | 
			
		||||
			(*mFile)->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
 | 
			
		||||
			outFile.write(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize));
 | 
			
		||||
		}		
 | 
			
		||||
		outFile.close();
 | 
			
		||||
		writeSubStreamToFile(mFile, itr->offset, itr->size, extract_path, cache_for_extract);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,9 +25,10 @@ public:
 | 
			
		|||
	const nn::hac::PartitionFsHeader& getPfsHeader() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	const std::string kModuleName = "PfsProcess";
 | 
			
		||||
	static const size_t kCacheSize = 0x10000;
 | 
			
		||||
 | 
			
		||||
	std::string mModuleName;
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<tc::io::IStream> mFile;
 | 
			
		||||
	CliOutputMode mCliOutputMode;
 | 
			
		||||
	bool mVerify;
 | 
			
		||||
| 
						 | 
				
			
			@ -36,8 +37,6 @@ private:
 | 
			
		|||
	std::string mMountName;
 | 
			
		||||
	bool mListFs;
 | 
			
		||||
 | 
			
		||||
	tc::ByteData mCache;
 | 
			
		||||
 | 
			
		||||
	nn::hac::PartitionFsHeader mPfs;
 | 
			
		||||
 | 
			
		||||
	void importHeader();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
//#include "GameCardProcess.h"
 | 
			
		||||
//#include "PfsProcess.h"
 | 
			
		||||
#include "PfsProcess.h"
 | 
			
		||||
//#include "RomfsProcess.h"
 | 
			
		||||
//#include "NcaProcess.h"
 | 
			
		||||
//#include "MetaProcess.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +50,7 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
 | 
			
		|||
 | 
			
		||||
			obj.process();
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
		/*
 | 
			
		||||
		else if (set.infile.filetype == nstool::Settings::FILE_TYPE_PARTITIONFS || set.infile.filetype == nstool::Settings::FILE_TYPE_NSP)
 | 
			
		||||
		else*/ if (set.infile.filetype == nstool::Settings::FILE_TYPE_PARTITIONFS || set.infile.filetype == nstool::Settings::FILE_TYPE_NSP)
 | 
			
		||||
		{
 | 
			
		||||
			nstool::PfsProcess obj;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +64,7 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
 | 
			
		|||
			
 | 
			
		||||
			obj.process();
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		else if (set.infile.filetype == nstool::Settings::FILE_TYPE_ROMFS)
 | 
			
		||||
		{
 | 
			
		||||
			nstool::RomfsProcess obj;
 | 
			
		||||
| 
						 | 
				
			
			@ -113,8 +112,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
 | 
			
		|||
 | 
			
		||||
			obj.process();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		else*/ if (set.infile.filetype == nstool::Settings::FILE_TYPE_CNMT)
 | 
			
		||||
		*/
 | 
			
		||||
		else if (set.infile.filetype == nstool::Settings::FILE_TYPE_CNMT)
 | 
			
		||||
		{
 | 
			
		||||
			nstool::CnmtProcess obj;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/util.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/util.cpp
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -66,21 +66,29 @@ void nstool::processResFile(const std::shared_ptr<tc::io::IStream>& file, std::m
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeSubStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, int64_t offset, int64_t length, const tc::io::Path& out_path, tc::ByteData& cache)
 | 
			
		||||
{
 | 
			
		||||
	writeStreamToStream(std::make_shared<tc::io::SubStream>(tc::io::SubStream(in_stream, offset, length)), std::make_shared<tc::io::FileStream>(tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write)), cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeSubStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, int64_t offset, int64_t length, const tc::io::Path& out_path, size_t cache_size)
 | 
			
		||||
{
 | 
			
		||||
	writeStreamToStream(std::make_shared<tc::io::SubStream>(tc::io::SubStream(in_stream, offset, length)), std::make_shared<tc::io::FileStream>(tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write)), cache_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, const tc::io::Path& out_path, tc::ByteData& cache)
 | 
			
		||||
{
 | 
			
		||||
	writeStreamToStream(in_stream, std::make_shared<tc::io::FileStream>(tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write)), cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, const tc::io::Path& out_path, size_t cache_size)
 | 
			
		||||
{
 | 
			
		||||
	writeStreamToStream(in_stream, std::make_shared<tc::io::FileStream>(tc::io::FileStream(out_path, tc::io::FileMode::OpenOrCreate, tc::io::FileAccess::Write)), cache_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stream, const std::shared_ptr<tc::io::IStream>& out_stream, size_t cache_size)
 | 
			
		||||
void nstool::writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stream, const std::shared_ptr<tc::io::IStream>& out_stream, tc::ByteData& cache)
 | 
			
		||||
{
 | 
			
		||||
	// iterate thru child files
 | 
			
		||||
	tc::ByteData cache = tc::ByteData(cache_size);
 | 
			
		||||
	size_t cache_read_len;
 | 
			
		||||
	
 | 
			
		||||
	in_stream->seek(0, tc::io::SeekOrigin::Begin);
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +107,12 @@ void nstool::writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stre
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nstool::writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stream, const std::shared_ptr<tc::io::IStream>& out_stream, size_t cache_size)
 | 
			
		||||
{
 | 
			
		||||
	tc::ByteData cache = tc::ByteData(cache_size);
 | 
			
		||||
	writeStreamToStream(in_stream, out_stream, cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string nstool::getTruncatedBytesString(const byte_t* data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	if (data == nullptr) { return fmt::format(""); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,10 +6,14 @@ namespace nstool
 | 
			
		|||
 | 
			
		||||
void processResFile(const std::shared_ptr<tc::io::IStream>& file, std::map<std::string, std::string>& dict);
 | 
			
		||||
 | 
			
		||||
void writeSubStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, int64_t offset, int64_t length, const tc::io::Path& out_path, tc::ByteData& cache);
 | 
			
		||||
void writeSubStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, int64_t offset, int64_t length, const tc::io::Path& out_path, size_t cache_size = 0x10000);
 | 
			
		||||
void writeStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, const tc::io::Path& out_path, tc::ByteData& cache);
 | 
			
		||||
void writeStreamToFile(const std::shared_ptr<tc::io::IStream>& in_stream, const tc::io::Path& out_path, size_t cache_size = 0x10000);
 | 
			
		||||
void writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stream, const std::shared_ptr<tc::io::IStream>& out_stream, tc::ByteData& cache);
 | 
			
		||||
void writeStreamToStream(const std::shared_ptr<tc::io::IStream>& in_stream, const std::shared_ptr<tc::io::IStream>& out_stream, size_t cache_size = 0x10000);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
std::string getTruncatedBytesString(const byte_t* data, size_t len);
 | 
			
		||||
std::string getTruncatedBytesString(const byte_t* data, size_t len, bool do_not_truncate);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue