UPS (binary patch format)
(I guess this is not applicable after all. This is a complete description.) |
m |
||
(One intermediate revision by one user not shown) | |||
Line 8: | Line 8: | ||
A UPS patch file starts with the magic number {{magic|"UPS1"}}, followed by the size of the source file and the size of the destination file, both stored as variable-width integers (see below). | A UPS patch file starts with the magic number {{magic|"UPS1"}}, followed by the size of the source file and the size of the destination file, both stored as variable-width integers (see below). | ||
− | After that, a series of hunks follows. Each hunk consists of a variable-width integer indicating the number of bytes which should be skipped (copied verbatim from the source file), followed by a block of bytes which should be XORed with the source file to obtain a corresponding block of bytes in the destination file. The XOR block is terminated with a zero byte; the zero byte also counts against the file pointer. If the source and destination file sizes differ, the source file is treated as if it had an infinite number of zero bytes after its actual last byte. | + | After that, a series of hunks follows. Each hunk consists of a variable-width integer indicating the number of bytes which should be skipped (copied verbatim from the source file), followed by a block of bytes which should be [[Exclusive Or|XORed]] with the source file to obtain a corresponding block of bytes in the destination file. The XOR block is terminated with a zero byte; the zero byte also counts against the file pointer. If the source and destination file sizes differ, the source file is treated as if it had an infinite number of zero bytes after its actual last byte. |
− | At the end of the file, there are three CRC32 checksums: of the source file, of the destination file, and of the patch (i.e. everything in the patch before this final checksum itself). Each checksum is stored as a little-endian 32-bit integer. | + | At the end of the file, there are three [[CRC-32|CRC32]] checksums: of the source file, of the destination file, and of the patch (i.e. everything in the patch before this final checksum itself). Each checksum is stored as a little-endian 32-bit integer. |
=== Variable-width integers === | === Variable-width integers === |
Latest revision as of 22:03, 4 June 2017
UPS is a binary patch format. It was designed as a replacement for IPS.
[edit] Structure
A UPS patch file starts with the magic number "UPS1"
, followed by the size of the source file and the size of the destination file, both stored as variable-width integers (see below).
After that, a series of hunks follows. Each hunk consists of a variable-width integer indicating the number of bytes which should be skipped (copied verbatim from the source file), followed by a block of bytes which should be XORed with the source file to obtain a corresponding block of bytes in the destination file. The XOR block is terminated with a zero byte; the zero byte also counts against the file pointer. If the source and destination file sizes differ, the source file is treated as if it had an infinite number of zero bytes after its actual last byte.
At the end of the file, there are three CRC32 checksums: of the source file, of the destination file, and of the patch (i.e. everything in the patch before this final checksum itself). Each checksum is stored as a little-endian 32-bit integer.
[edit] Variable-width integers
The following C function will read a single variable-width integer in UPS format. (Note lack of error checking; this is just a sample.)
static uintmax_t read_vuint(void) { uintmax_t result = 0, shift = 0; for (;;) { uint8_t octet = getchar(); if (octet & 0x80) { result += (octet & 0x7f) << shift; break; } result += (octet | 0x80) << shift; shift += 7; } return result; }
[edit] External links
- Patch.cpp in the VBA-M repository (contains UPS and IPS patchers)
- Specification at romhacking.net