Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions core/io/pck_packer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static int _get_pad(int p_alignment, int p_n) {
void PCKPacker::_bind_methods() {
ClassDB::bind_method(D_METHOD("pck_start", "pck_path", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file", "target_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file_from_buffer", "target_path", "data", "encrypt"), &PCKPacker::add_file_from_buffer, DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file_removal", "target_path"), &PCKPacker::add_file_removal);
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
}
Expand Down Expand Up @@ -152,19 +153,29 @@ Error PCKPacker::add_file(const String &p_target_path, const String &p_source_pa
if (f.is_null()) {
return ERR_FILE_CANT_OPEN;
}
Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_source_path);

return _add_file(p_target_path, p_source_path, data, p_encrypt);
}

Error PCKPacker::add_file_from_buffer(const String &p_target_path, const Vector<uint8_t> &p_data, bool p_encrypt) {
return _add_file(p_target_path, "<PackedByteArray>", p_data, p_encrypt);
}

Error PCKPacker::_add_file(const String &p_target_path, const String &p_source_path, const Vector<uint8_t> &p_data, bool p_encrypt) {
ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use.");

File pf;
// Simplify path here and on every 'files' access so that paths that have extra '/'
// symbols or 'res://' in them still match the MD5 hash for the saved path.
pf.path = p_target_path.simplify_path().trim_prefix("res://");
pf.src_path = p_source_path;
pf.ofs = file->get_position();
pf.size = f->get_length();
pf.size = p_data.size();

Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_source_path);
{
unsigned char hash[16];
CryptoCore::md5(data.ptr(), data.size(), hash);
CryptoCore::md5(p_data.ptr(), p_data.size(), hash);
pf.md5.resize(16);
for (int i = 0; i < 16; i++) {
pf.md5.write[i] = hash[i];
Expand All @@ -184,7 +195,7 @@ Error PCKPacker::add_file(const String &p_target_path, const String &p_source_pa
ftmp = fae;
}

ftmp->store_buffer(data);
ftmp->store_buffer(p_data);

if (fae.is_valid()) {
ftmp.unref();
Expand Down Expand Up @@ -256,7 +267,7 @@ Error PCKPacker::flush(bool p_verbose) {
fhead->store_32(flags);

if (p_verbose) {
print_line(vformat("[%d/%d - %d%%] PCKPacker flush: %s -> %s", i, file_num, float(i) / file_num * 100, files[i].src_path, files[i].path));
print_line(vformat("[%d/%d - %d%%] PCKPacker flush: %s -> %s", i + 1, file_num, float(i + 1) / file_num * 100, files[i].src_path, files[i].path));
}
}

Expand Down
3 changes: 3 additions & 0 deletions core/io/pck_packer.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ class PCKPacker : public RefCounted {
};
Vector<File> files;

Error _add_file(const String &p_target_path, const String &p_source_path, const Vector<uint8_t> &p_data, bool p_encrypt = false);

public:
Error pck_start(const String &p_pck_path, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
Error add_file(const String &p_target_path, const String &p_source_path, bool p_encrypt = false);
Error add_file_from_buffer(const String &p_target_path, const Vector<uint8_t> &p_data, bool p_encrypt = false);
Error add_file_removal(const String &p_target_path);
Error flush(bool p_verbose = false);

Expand Down
9 changes: 9 additions & 0 deletions doc/classes/PCKPacker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
Adds the [param source_path] file to the current PCK package at the [param target_path] internal path. The [code]res://[/code] prefix for [param target_path] is optional and stripped internally. File content is immediately written to the PCK.
</description>
</method>
<method name="add_file_from_buffer">
<return type="int" enum="Error" />
<param index="0" name="target_path" type="String" />
<param index="1" name="data" type="PackedByteArray" />
<param index="2" name="encrypt" type="bool" default="false" />
<description>
Adds the [param data] to the current PCK package at the [param target_path] internal path. The [code]res://[/code] prefix for [param target_path] is optional and stripped internally. File content is immediately written to the PCK.
</description>
</method>
<method name="add_file_removal">
<return type="int" enum="Error" />
<param index="0" name="target_path" type="String" />
Expand Down
3 changes: 3 additions & 0 deletions tests/core/io/test_pck_packer.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") {
CHECK_MESSAGE(
pck_packer.add_file("some/directories with spaces/to/create/icon.png", base_dir.path_join("../logo.png")) == OK,
"Overriding a non-flushed file to an existing subdirectory in the PCK should return an OK error code.");
CHECK_MESSAGE(
pck_packer.add_file_from_buffer("buffer/new.txt", String("Hello world!").to_utf8_buffer()) == OK,
"Adding a file from a buffer to the PCK in a new subdirectory should return an OK error code.");
CHECK_MESSAGE(
pck_packer.flush() == OK,
"Flushing the PCK should return an OK error code.");
Expand Down
Loading