| 38 | #include "file_access_gdre.h" |
| 39 | |
| 40 | Error FileAccessPatchedGDRE::_apply_patch() const { |
| 41 | ERR_FAIL_COND_V(!is_open(), FAILED); |
| 42 | |
| 43 | String path = old_file->get_path(); |
| 44 | Vector<PackedData::PackedFile> delta_patches = GDREPackedData::get_singleton()->get_delta_patches(path); |
| 45 | Vector<uint8_t> old_file_data = old_file->get_buffer(old_file->get_length()); |
| 46 | |
| 47 | for (int i = 0; i < delta_patches.size(); ++i) { |
| 48 | const PackedData::PackedFile &delta_patch = delta_patches[i]; |
| 49 | ERR_FAIL_COND_V(delta_patch.bundle, FAILED); |
| 50 | |
| 51 | Error err = OK; |
| 52 | |
| 53 | uint64_t total_usec_start = OS::get_singleton()->get_ticks_usec(); |
| 54 | uint64_t io_usec_start = OS::get_singleton()->get_ticks_usec(); |
| 55 | |
| 56 | Ref<FileAccess> patch_file = FileAccess::open(delta_patch.pack, FileAccess::READ, &err); |
| 57 | ERR_FAIL_COND_V(err != OK, err); |
| 58 | |
| 59 | patch_file->seek(delta_patch.offset); |
| 60 | ERR_FAIL_COND_V(patch_file->get_error() != OK, patch_file->get_error()); |
| 61 | |
| 62 | Vector<uint8_t> patch_data = patch_file->get_buffer(delta_patch.size); |
| 63 | ERR_FAIL_COND_V(patch_data.is_empty(), ERR_FILE_CANT_READ); |
| 64 | |
| 65 | uint64_t io_usec_end = OS::get_singleton()->get_ticks_usec(); |
| 66 | uint64_t decode_usec_start = OS::get_singleton()->get_ticks_usec(); |
| 67 | |
| 68 | Vector<uint8_t> new_file_data; |
| 69 | err = DeltaEncoding::decode_delta(old_file_data, patch_data, new_file_data); |
| 70 | ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Failed to apply delta patch (%d of %d) to \"%s\".", i + 1, delta_patches.size(), path)); |
| 71 | |
| 72 | uint64_t decode_usec_end = OS::get_singleton()->get_ticks_usec(); |
| 73 | |
| 74 | old_file_data = new_file_data; |
| 75 | |
| 76 | uint64_t total_usec_end = OS::get_singleton()->get_ticks_usec(); |
| 77 | |
| 78 | print_verbose(vformat(U"Applied delta patch to \"%s\" from \"%s\" in %d μs (%d μs I/O, %d μs decoding).", path, delta_patch.pack.get_file(), total_usec_end - total_usec_start, io_usec_end - io_usec_start, decode_usec_end - decode_usec_start)); |
| 79 | } |
| 80 | |
| 81 | patched_file_data = old_file_data; |
| 82 | patched_file.instantiate(); |
| 83 | return patched_file->open_custom(patched_file_data.ptr(), patched_file_data.size()); |
| 84 | } |
| 85 | |
| 86 | bool FileAccessPatchedGDRE::_try_apply_patch() const { |
| 87 | if (last_error != OK) { |
nothing calls this directly
no test coverage detected