mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-13 04:51:38 -10:00
A streamed IPS patch built its target as the source arrived: a second buffer the size of the ROM, taken at open, every byte of the source copied into it, then the records laid over it, and the source freed. The target of an IPS patch is the source with the records on it, and the source is the content buffer the load already owns. patch_stream_finish_into() finishes a stream whose source the caller owns (malloc'd, given to patch_stream_set_source()): an IPS patch puts its records on that buffer in place, growing it with realloc() only when the target is longer, and any other format hands back its target in the buffer's place. On failure the buffer is still the unpatched source, as before. Fed in place, IPS copies nothing while the source arrives; a chunk fed from elsewhere copies what came before through to the target and carries on as before. The target is no longer taken at open but by the first copy-through, so the in-place path never takes one. The content load finishes its patch with finish_into(). A 16 MiB ROM with a 2000-record IPS patch, first touch: 6.7 ms -> 0.05 ms to apply, and 16 MiB less heap during the load. The patch_stream test finishes every in-place and fallback comparison with finish_into() on a buffer of its own, and checks a 4 MiB IPS source is patched where it lies without being moved or copied. Leaving the grown tail unzeroed, skipping the records in place or in the catch-up, copying nothing in the catch-up, or copying through while fed in place each fail it.