mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
PKG: Pack multiple PKGs into fast+efficient install (#13147)
This commit is contained in:
parent
7423abb136
commit
7c2d6f8a23
4 changed files with 364 additions and 266 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <span>
|
||||
#include <deque>
|
||||
|
||||
// Constants
|
||||
enum : u32
|
||||
|
|
@ -305,24 +306,57 @@ enum class package_error
|
|||
|
||||
class package_reader
|
||||
{
|
||||
struct thread_key
|
||||
{
|
||||
const usz unique_num = umax;
|
||||
};
|
||||
|
||||
struct install_entry
|
||||
{
|
||||
typename std::map<std::string, install_entry*>::value_type* weak_reference{};
|
||||
std::string name;
|
||||
|
||||
u64 file_offset{};
|
||||
u64 file_size{};
|
||||
u32 type{};
|
||||
u32 pad{};
|
||||
|
||||
// Check if the entry is the same one registered in entries to install
|
||||
bool is_dominating() const
|
||||
{
|
||||
return weak_reference->second == this;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
package_reader(const std::string& path);
|
||||
~package_reader();
|
||||
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
package_error check_target_app_version() const;
|
||||
bool extract_data(atomic_t<double>& sync);
|
||||
static bool extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
|
||||
psf::registry get_psf() const { return m_psf; }
|
||||
|
||||
std::string try_get_bootable_file_path_if_created_new() const
|
||||
int get_progress(int maximum = 100) const
|
||||
{
|
||||
return m_bootable_file_path;
|
||||
const usz wr = m_written_bytes;
|
||||
|
||||
return wr >= m_header.data_size ? maximum : ::narrow<int>(wr * maximum / m_header.data_size);
|
||||
}
|
||||
|
||||
struct thread_key
|
||||
void abort_extract()
|
||||
{
|
||||
const usz unique_num = umax;
|
||||
};
|
||||
m_entry_indexer.fetch_op([this](usz& v)
|
||||
{
|
||||
if (v < m_install_entries.size())
|
||||
{
|
||||
v = m_install_entries.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
bool read_header();
|
||||
|
|
@ -331,11 +365,18 @@ private:
|
|||
bool decrypt_data();
|
||||
void archive_seek(s64 new_offset, const fs::seek_mode damode = fs::seek_set);
|
||||
u64 archive_read(void* data_ptr, u64 num_bytes);
|
||||
bool fill_data(std::map<std::string, install_entry*>& all_install_entries);
|
||||
std::span<const char> archive_read_block(u64 offset, void* data_ptr, u64 num_bytes);
|
||||
std::span<const char> decrypt(u64 offset, u64 size, const uchar* key, thread_key thread_data_key = {0});
|
||||
usz extract_worker(const std::string& dir, bool was_null, atomic_t<double>& sync, thread_key thread_data_key, atomic_t<usz>& entry_indexer, std::vector<PKGEntry>& entries);
|
||||
usz extract_worker(thread_key thread_data_key, std::map<std::string, install_entry*>& all_install_entries);
|
||||
|
||||
const usz BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
std::deque<install_entry> m_install_entries;
|
||||
std::string m_install_path;
|
||||
atomic_t<usz> m_entry_indexer = 0;
|
||||
atomic_t<usz> m_written_bytes = 0;
|
||||
bool m_was_null = false;
|
||||
|
||||
static constexpr usz BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
|
||||
bool m_is_valid = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue