mirror of
https://github.com/Alcaro/Flips.git
synced 2026-04-24 23:10:45 -05:00
Modernize patch::bps::info::parse
This commit is contained in:
parent
086498bf01
commit
56cd2b4ca6
|
|
@ -51,8 +51,8 @@ void _test_skip(cstring why);
|
|||
#else
|
||||
|
||||
#define test(...) static void MAYBE_UNUSED JOIN(_testfunc_, __LINE__)()
|
||||
#define assert(x)
|
||||
#define assert_eq(x,y)
|
||||
#define assert(x) ((void)(x))
|
||||
#define assert_eq(x,y) ((void)(x==y))
|
||||
#define testcall(x) x
|
||||
#define test_skip(x) return
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ result apply(arrayview<byte> patchmem, arrayview<byte> inmem, array<byte>& outme
|
|||
#define error(which) do { error=which; goto exit; } while(0)
|
||||
#define decodeto(var) \
|
||||
do { \
|
||||
if (!patch.bpsnum(var)) error(e_too_big); \
|
||||
if (!patch.bpsnum(&var)) error(e_too_big); \
|
||||
} while(false)
|
||||
|
||||
if (patch.u8()!='B') error(e_broken);
|
||||
|
|
@ -168,47 +168,33 @@ exit:
|
|||
|
||||
|
||||
|
||||
/*
|
||||
result info::parse(const file& patch, bool changefrac)
|
||||
result info::parse(arrayview<byte> data, bool changefrac)
|
||||
{
|
||||
size_t len = patch.size();
|
||||
size_t len = data.size();
|
||||
if (len<4+3+12) return e_broken;
|
||||
|
||||
uint8_t top[256];
|
||||
size_t toplen = len>256 ? 256 : len;
|
||||
if (patch.read(arrayvieww<byte>(top, toplen), 0) < toplen) return e_io;
|
||||
if (memcmp(top, "BPS1", 4)!=0) return e_broken;
|
||||
memstream patch = data.slice(0, data.size()-12);
|
||||
if (!patch.signature("BPS1")) return e_broken;
|
||||
|
||||
const uint8_t* patchdat=top+4;
|
||||
if (!decodenum(patchdat, this->size_in)) return e_too_big;
|
||||
if (!decodenum(patchdat, this->size_out)) return e_too_big;
|
||||
if (!patch.bpsnum(&this->size_in)) return e_too_big;
|
||||
if (!patch.bpsnum(&this->size_out)) return e_too_big;
|
||||
|
||||
uint8_t checksums[12];
|
||||
if (patch.read(arrayvieww<byte>(checksums), len-12) < 12) return e_io;
|
||||
this->crc_in = read32(checksums+0);
|
||||
this->crc_out = read32(checksums+4);
|
||||
//this->crc_patch=read32(checksums+8);
|
||||
size_t metasize;
|
||||
if (!patch.bpsnum(&metasize)) return e_too_big;
|
||||
this->metadata = patch.bytes(metasize);
|
||||
|
||||
if (changefrac && this->size_in>0)
|
||||
{
|
||||
//algorithm: each command adds its length to the numerator, unless it's above 32, in which case
|
||||
// it adds 32; or if it's SourceRead, in which case it adds 0
|
||||
//denominator is just input length
|
||||
array<byte> patchbytes = patch.read();
|
||||
size_t outpos=0; // position in the output file
|
||||
size_t changeamt=0; // change score
|
||||
const uint8_t* patchat=patchbytes.ptr()+(patchdat-top);
|
||||
|
||||
size_t metasize;
|
||||
if (!decodenum(patchat, metasize)) return e_too_big;
|
||||
patchat+=metasize;
|
||||
|
||||
const uint8_t* patchend=patchbytes.ptr()+len-12;
|
||||
|
||||
while (patchat<patchend && outpos<this->size_in)
|
||||
while (patch.remaining())
|
||||
{
|
||||
size_t thisinstr;
|
||||
decodenum(patchat, thisinstr);
|
||||
patch.bpsnum(&thisinstr);
|
||||
size_t length=(thisinstr>>2)+1;
|
||||
int action=(thisinstr&3);
|
||||
int min_len_32 = (length<32 ? length : 32);
|
||||
|
|
@ -223,7 +209,7 @@ result info::parse(const file& patch, bool changefrac)
|
|||
case TargetRead:
|
||||
{
|
||||
changeamt+=min_len_32;
|
||||
patchat+=length;
|
||||
patch.bytes(length);
|
||||
}
|
||||
break;
|
||||
case SourceCopy:
|
||||
|
|
@ -231,13 +217,13 @@ result info::parse(const file& patch, bool changefrac)
|
|||
{
|
||||
changeamt+=min_len_32;
|
||||
size_t ignore;
|
||||
decodenum(patchat, ignore);
|
||||
patch.bpsnum(&ignore);
|
||||
}
|
||||
break;
|
||||
}
|
||||
outpos+=length;
|
||||
}
|
||||
if (patchat>patchend || outpos>this->size_out) return e_broken;
|
||||
if (outpos>this->size_out) return e_broken;
|
||||
this->change_num = (changeamt<this->size_in ? changeamt : this->size_in);
|
||||
this->change_denom = this->size_in;
|
||||
}
|
||||
|
|
@ -248,9 +234,12 @@ result info::parse(const file& patch, bool changefrac)
|
|||
this->change_denom=1;
|
||||
}
|
||||
|
||||
memstream checks = data.slice(data.size()-12, 12);
|
||||
this->crc_in = checks.u32();
|
||||
this->crc_out = checks.u32();
|
||||
|
||||
return e_ok;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ public:
|
|||
|
||||
//if the bpsnum is too big, number of read bytes is undefined
|
||||
//does not do bounds checks, there must be at least 10 unread bytes in the buffer
|
||||
bool bpsnum(size_t& out)
|
||||
bool bpsnum(size_t* out)
|
||||
{
|
||||
//similar to uleb128, but bpsnum adds another 1<<shift for every byte except the first
|
||||
//this ensures there's only one way to encode an integer
|
||||
|
|
@ -192,7 +192,7 @@ public:
|
|||
uint8_t b = *(at++);
|
||||
if (LIKELY(b&0x80))
|
||||
{
|
||||
out = b ^ (1<<7);
|
||||
*out = b ^ (1<<7);
|
||||
return true;
|
||||
}
|
||||
size_t tmp = b;
|
||||
|
|
@ -200,7 +200,7 @@ public:
|
|||
tmp |= b<<7;
|
||||
if (LIKELY(b&0x80))
|
||||
{
|
||||
out = tmp + (1<<7) - (1<<7<<7);
|
||||
*out = tmp + (1<<7) - (1<<7<<7);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ public:
|
|||
if (next&0x80) break;
|
||||
shift+=7;
|
||||
}
|
||||
out = ret;
|
||||
*out = ret;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ result apply(arrayview<byte> patchmem, const file& in, array<byte>& outmem)
|
|||
#define error(which) do { error=which; goto exit; } while(0)
|
||||
#define decodeto(var) \
|
||||
do { \
|
||||
if (!patch.bpsnum(var)) error(e_too_big); \
|
||||
if (!patch.bpsnum(&var)) error(e_too_big); \
|
||||
} while(false)
|
||||
|
||||
bool backwards=false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user