PKG: Simplify files management

This commit is contained in:
Eladash 2021-09-27 09:53:28 +03:00 committed by Ivan
parent 55ec4808f1
commit 056d43eca7
2 changed files with 33 additions and 63 deletions

View file

@ -15,14 +15,12 @@ LOG_CHANNEL(pkg_log, "PKG");
package_reader::package_reader(const std::string& path)
: m_path(path)
{
if (!fs::is_file(path))
if (!m_file.open(path))
{
pkg_log.error("PKG file not found!");
return;
}
m_filelist.emplace_back(fs::file{path});
m_is_valid = read_header();
if (!m_is_valid)
@ -51,7 +49,7 @@ package_reader::~package_reader()
bool package_reader::read_header()
{
if (m_path.empty() || m_filelist.empty())
if (m_path.empty() || !m_file)
{
pkg_log.error("Reading PKG header: no file to read!");
return false;
@ -131,7 +129,7 @@ bool package_reader::read_header()
}
}
if (m_header.pkg_size > m_filelist[0].size())
if (m_header.pkg_size > m_file.size())
{
// Check if multi-files pkg
if (!m_path.ends_with("_00.pkg"))
@ -140,11 +138,15 @@ bool package_reader::read_header()
return false;
}
std::vector<fs::file> filelist;
filelist.emplace_back(std::move(m_file));
const std::string name_wo_number = m_path.substr(0, m_path.size() - 7);
u64 cursize = m_filelist[0].size();
u64 cursize = m_file.size();
while (cursize < m_header.pkg_size)
{
const std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, m_filelist.size());
const std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
fs::file archive_file(archive_filename);
if (!archive_file)
@ -153,9 +155,20 @@ bool package_reader::read_header()
return false;
}
cursize += archive_file.size();
m_filelist.emplace_back(std::move(archive_file));
const usz add_size = archive_file.size();
if (!add_size)
{
pkg_log.error("%s is empty, cannot read PKG", archive_filename);
return false;
}
cursize += add_size;
filelist.emplace_back(std::move(archive_file));
}
// Gather files
m_file = fs::make_gather(std::move(filelist));
}
if (m_header.data_size + m_header.data_offset > m_header.pkg_size)
@ -510,10 +523,10 @@ bool package_reader::read_param_sfo()
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
const std::string_view name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
// We're looking for the PARAM.SFO file, if there is any
if (name != "PARAM.SFO")
if (usz ndelim = name.find_first_not_of('/'); ndelim == umax || name.substr(ndelim) != "PARAM.SFO")
{
continue;
}
@ -542,6 +555,12 @@ bool package_reader::read_param_sfo()
m_psf = psf::load_object(tmp);
if (m_psf.empty())
{
// Invalid
continue;
}
return true;
}
else
@ -897,58 +916,12 @@ bool package_reader::extract_data(atomic_t<double>& sync)
void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damode)
{
if (damode == fs::seek_set)
m_cur_offset = new_offset;
else if (damode == fs::seek_cur)
m_cur_offset += new_offset;
u64 _offset = 0;
for (usz i = 0; i < m_filelist.size(); i++)
{
if (m_cur_offset < (_offset + m_filelist[i].size()))
{
m_cur_file = i;
m_cur_file_offset = m_cur_offset - _offset;
m_filelist[i].seek(m_cur_file_offset);
break;
}
_offset += m_filelist[i].size();
}
if (m_file) m_file.seek(new_offset, damode);
};
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
{
ensure(m_filelist.size() > m_cur_file && m_filelist[m_cur_file]);
const u64 num_bytes_left = m_filelist[m_cur_file].size() - m_cur_file_offset;
// check if it continues in another file
if (num_bytes > num_bytes_left)
{
m_filelist[m_cur_file].read(data_ptr, num_bytes_left);
if ((m_cur_file + 1) < m_filelist.size())
{
++m_cur_file;
}
else
{
m_cur_offset += num_bytes_left;
m_cur_file_offset = m_filelist[m_cur_file].size();
return num_bytes_left;
}
const u64 num_read = m_filelist[m_cur_file].read(static_cast<u8*>(data_ptr) + num_bytes_left, num_bytes - num_bytes_left);
m_cur_offset += (num_read + num_bytes_left);
m_cur_file_offset = num_read;
return (num_read + num_bytes_left);
}
const u64 num_read = m_filelist[m_cur_file].read(data_ptr, num_bytes);
m_cur_offset += num_read;
m_cur_file_offset += num_read;
return num_read;
return m_file ? m_file.read(data_ptr, num_bytes) : 0;
};
u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)

View file

@ -327,10 +327,7 @@ private:
std::string m_path{};
std::string m_install_dir{};
std::vector<fs::file> m_filelist{};
usz m_cur_file = 0;
u64 m_cur_offset = 0;
u64 m_cur_file_offset = 0;
fs::file m_file{};
std::unique_ptr<u128[]> m_buf{};
std::array<uchar, 16> m_dec_key{};