#include "patch.h" namespace patch { namespace ups { //TODO: HEAVY cleanups needed here #define error(which) do { error=which; goto exit; } while(0) result apply(const file& patch_, const file& source_, file& target_) { if (patch_.size()<4+2+12) return e_broken; arrayview patchmem = patch_.mmap(); memstream patch = patchmem; arrayview inmem = source_.mmap(); memstream in = inmem; result error; if (true) { #define decodeto(var) \ do { \ safeint ret = patch.bpsnum(); \ if (!ret.valid()) error(e_too_big); \ var = ret.val(); \ } while(false) bool backwards=false; if (patch.u8()!='U') error(e_broken); if (patch.u8()!='P') error(e_broken); if (patch.u8()!='S') error(e_broken); if (patch.u8()!='1') error(e_broken); size_t inlen; size_t outlen; decodeto(inlen); decodeto(outlen); if (inlen!=in.size()) { size_t tmp=inlen; inlen=outlen; outlen=tmp; backwards=true; } if (inlen!=in.size()) error(e_not_this); array outmem; outmem.resize(outlen); membufwriter out = outmem; while (patch.remaining() > 12) { size_t skip; decodeto(skip); size_t skip_fast = min(skip, outlen-out.size(), in.remaining()); out.write(in.bytes(skip_fast)); skip -= skip_fast; while (skip>0) { uint8_t outb = in.u8_or(0); if (out.size()