// Encoder dump for scripts/diff_encode.py (not a public API).
// stdout records: LZMA_MBT_DIFF_V1, CASEā¦END, DONE.
///|
fn hex_digit(n : Int) -> Char {
if n < 10 {
(48 + n).unsafe_to_char()
} else {
(87 + n).unsafe_to_char()
}
}
///|
fn to_hex(data : Bytes) -> String {
let sb = StringBuilder(size_hint=data.length() * 2)
for b in data {
let v = b.to_int()
sb.write_char(hex_digit(v >> 4))
sb.write_char(hex_digit(v & 15))
}
sb.to_string()
}
///|
fn mix_byte(i : Int) -> Byte {
let n = i.reinterpret_as_uint()
(((n * 13U) ^ (n >> 3)) & 0xFFU).reinterpret_as_int().to_byte()
}
///|
fn mixed_bytes(n : Int) -> Bytes {
let arr = Array(capacity=n)
for i in 0.. String {
match c {
None => "none"
Crc32 => "crc32"
Crc64 => "crc64"
Sha256 => "sha256"
}
}
///|
fn push_u32_le(a : Array[Byte], v : UInt) -> Unit {
a.push((v & 0xFFU).reinterpret_as_int().to_byte())
a.push(((v >> 8) & 0xFFU).reinterpret_as_int().to_byte())
a.push(((v >> 16) & 0xFFU).reinterpret_as_int().to_byte())
a.push(((v >> 24) & 0xFFU).reinterpret_as_int().to_byte())
}
///|
/// Deterministic x86-laden payload (adjacent/overlapping E8/E9 with 0x00/0xFF
/// top-byte immediates) for the container x86 BCJ encode differential.
fn bcj_payload() -> Bytes {
let a = Array()
let vals = [
0U, 1U, 0xFFFFFFFFU, 5U, 0xFFFFFFFBU, 0x7FFFFFFFU, 0x80000000U, 100U, 0xFFFFFF9CU,
0x10U, 0xFFFFFFF0U, 0x4000U,
]
for i in 0..<40 {
let op = if i % 2 == 0 { b'\xE8' } else { b'\xE9' }
a.push(op)
push_u32_le(a, vals[i % 12])
for _ in 0..<(i % 3) {
a.push(b'\x90')
}
}
let seg = b"\xE8\xE8\x00\x00\x00\xE8\xE9\x00\x00\x00\xE9\xE8\xFF\xFF\xFF\x90\x90"
for _ in 0..<30 {
for b in seg[:] {
a.push(b)
}
}
for n in 0..<256 {
a.push(n.to_byte())
}
Bytes::from_array(a[:])
}
///|
/// Deterministic ARM-laden payload (32-bit words with a `0xEB` top byte).
fn arm_payload() -> Bytes {
let a = Array()
for k in 0..<300 {
let off = (k.reinterpret_as_uint() * 0xABCDU) & 0xFFFFFFU
push_u32_le(a, 0xEB000000U | off)
}
for _ in 0..<30 {
push_u32_le(a, 0xEBFFFFFFU)
push_u32_le(a, 0x12345678U)
}
a.push(b'\xEB')
a.push(b'\x01')
Bytes::from_array(a[:])
}
///|
/// Deterministic ARM64-laden payload (BL and ADRP instructions) plus a
/// trailing partial word.
fn arm64_payload() -> Bytes {
b"\x00\x00\x00\x94\xCD\xAB\x00\x94\x9A\x57\x01\x94\x67\x03\x02\x94\x34\xAF\x02\x94\x01\x5B\x03\x94\xCE\x06\x04\x94\x9B\xB2\x04\x94\x68\x5E\x05\x94\x35\x0A\x06\x94\x02\xB6\x06\x94\xCF\x61\x07\x94\x9C\x0D\x08\x94\x69\xB9\x08\x94\x36\x65\x09\x94\x03\x11\x0A\x94\xD0\xBC\x0A\x94\x9D\x68\x0B\x94\x6A\x14\x0C\x94\x37\xC0\x0C\x94\x04\x6C\x0D\x94\xD1\x17\x0E\x94\x9E\xC3\x0E\x94\x6B\x6F\x0F\x94\x38\x1B\x10\x94\x05\xC7\x10\x94\xD2\x72\x11\x94\x9F\x1E\x12\x94\x6C\xCA\x12\x94\x39\x76\x13\x94\x06\x22\x14\x94\xD3\xCD\x14\x94\xA0\x79\x15\x94\x6D\x25\x16\x94\x3A\xD1\x16\x94\x07\x7D\x17\x94\xD4\x28\x18\x94\xA1\xD4\x18\x94\x6E\x80\x19\x94\x3B\x2C\x1A\x94\x00\x00\x00\x90\x81\x28\x00\xB0\x02\x51\x00\xD0\x83\x79\x00\xF0\x24\xA2\x00\x90\xA5\xCA\x00\xB0\x26\xF3\x00\xD0\xA7\x1B\x01\xF0\x48\x44\x01\x90\xC9\x6C\x01\xB0\x4A\x95\x01\xD0\xCB\xBD\x01\xF0\x6C\xE6\x01\x90\xED\x0E\x02\xB0\x6E\x37\x02\xD0\xEF\x5F\x02\xF0\x90\x88\x02\x90\x11\xB1\x02\xB0\x92\xD9\x02\xD0\x13\x02\x03\xF0\xC0\x03\x5F\xD6\x94"
}
///|
/// Deterministic ARM-Thumb-laden payload (Thumb BL pairs plus a trailing
/// partial pair).
fn armthumb_payload() -> Bytes {
b"\x00\xF0\x00\xF8\x37\xF1\x5B\xF8\x6E\xF2\xB6\xF8\xA5\xF3\x11\xF8\xDC\xF4\x6C\xF8\x13\xF5\xC7\xF8\x4A\xF6\x22\xF8\x81\xF7\x7D\xF8\xB8\xF0\xD8\xF9\xEF\xF1\x33\xF9\x26\xF2\x8E\xF9\x5D\xF3\xE9\xF9\x94\xF4\x44\xF9\xCB\xF5\x9F\xF9\x02\xF6\xFA\xF9\x39\xF7\x55\xF9\x70\xF0\xB0\xFA\xA7\xF1\x0B\xFA\xDE\xF2\x66\xFA\x15\xF3\xC1\xFA\x4C\xF4\x1C\xFA\x83\xF5\x77\xFA\xBA\xF6\xD2\xFA\xF1\xF7\x2D\xFA\x28\xF0\x88\xFB\x5F\xF1\xE3\xFB\x96\xF2\x3E\xFB\xCD\xF3\x99\xFB\x04\xF4\xF4\xFB\x3B\xF5\x4F\xFB\x72\xF6\xAA\xFB\xA9\xF7\x05\xFB\xE0\xF0\x60\xFC\x17\xF1\xBB\xFC\x4E\xF2\x16\xFC\x85\xF3\x71\xFC\xBC\xF4\xCC\xFC\xF3\xF5\x27\xFC\x2A\xF6\x82\xFC\x61\xF7\xDD\xFC\x98\xF0\x38\xFD\xCF\xF1\x93\xFD\x06\xF2\xEE\xFD\x3D\xF3\x49\xFD\x74\xF4\xA4\xFD\xAB\xF5\xFF\xFD\xE2\xF6\x5A\xFD\x19\xF7\xB5\xFD\x50\xF0\x10\xFE\x87\xF1\x6B\xFE\x11\xF8\x22\xF0\xF0\x01\xF8"
}
///|
/// Deterministic PowerPC-laden payload (big-endian branch words plus
/// near-miss words).
fn powerpc_payload() -> Bytes {
b"\x48\x00\x00\x01\x49\x37\x5B\x9D\x4A\x6E\xB6\x39\x4B\xA5\x11\xD5\x48\xDC\x6C\x75\x49\x13\xC7\x11\x4A\x4A\x22\xAD\x4B\x81\x7D\x49\x48\xB8\xD8\xE9\x49\xEF\x33\x85\x4A\x26\x8E\x21\x4B\x5D\xE9\xBD\x48\x94\x44\x5D\x49\xCB\x9F\xF9\x4A\x02\xFA\x95\x4B\x39\x55\x31\x48\x70\xB0\xD1\x49\xA7\x0B\x6D\x4A\xDE\x66\x09\x4B\x15\xC1\xA5\x48\x4C\x1C\x45\x49\x83\x77\xE1\x4A\xBA\xD2\x7D\x4B\xF1\x2D\x19\x48\x28\x88\xB9\x49\x5F\xE3\x55\x4A\x96\x3E\xF1\x4B\xCD\x99\x8D\x48\x04\xF4\x2D\x49\x3B\x4F\xC9\x4A\x72\xAA\x65\x4B\xA9\x05\x01\x48\xE0\x60\xA1\x49\x17\xBB\x3D\x4A\x4E\x16\xD9\x4B\x85\x71\x75\x48\xBC\xCC\x15\x49\xF3\x27\xB1\x4A\x2A\x82\x4D\x4B\x61\xDD\xE9\x48\x98\x38\x89\x49\xCF\x93\x25\x4A\x06\xEE\xC1\x4B\x3D\x49\x5D\x48\x74\xA4\xFD\x49\xAB\xFF\x99\x4A\xE2\x5A\x35\x4B\x19\xB5\xD1\x48\x50\x10\x71\x49\x87\x6B\x0D\x48\x11\x22\x00\x4C\x11\x22\x01\x48\x01"
}
///|
/// Deterministic IA-64-laden payload (bundles exercising all three branch
/// slots plus a trailing partial bundle).
fn ia64_payload() -> Bytes {
b"\x16\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x28\x1A\x01\x28\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x8A\x06\x50\x16\x00\x70\xDA\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\xA0\x68\x04\x28\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE0\x5A\x10\x58\x16\x00\xE0\xB4\x01\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x18\xB7\x07\x2C\x00\x00\x00\x00\x00\x16\x01\x02"
}
///|
/// Deterministic SPARC-laden payload (big-endian call words plus near-miss
/// words).
fn sparc_payload() -> Bytes {
b"\x40\x00\x00\x00\x7F\xFD\x5B\x9D\x40\x2E\xB6\x3A\x7F\xF7\x11\xD7\x40\x1C\x6C\x74\x7F\xF1\xC7\x11\x40\x0A\x22\xAE\x7F\xEB\x7D\x4B\x40\x38\xD8\xE8\x7F\xE5\x33\x85\x40\x26\x8E\x22\x7F\xDF\xE9\xBF\x40\x14\x44\x5C\x7F\xD9\x9F\xF9\x40\x02\xFA\x96\x7F\xD3\x55\x33\x40\x30\xB0\xD0\x7F\xCD\x0B\x6D\x40\x1E\x66\x0A\x7F\xC7\xC1\xA7\x40\x0C\x1C\x44\x7F\xC1\x77\xE1\x40\x3A\xD2\x7E\x7F\xFB\x2D\x1B\x40\x28\x88\xB8\x7F\xF5\xE3\x55\x40\x16\x3E\xF2\x7F\xEF\x99\x8F\x40\x04\xF4\x2C\x7F\xE9\x4F\xC9\x40\x32\xAA\x66\x7F\xE3\x05\x03\x40\x20\x60\xA0\x7F\xDD\xBB\x3D\x40\x0E\x16\xDA\x7F\xD7\x71\x77\x40\x3C\xCC\x14\x7F\xD1\x27\xB1\x40\x2A\x82\x4E\x7F\xCB\xDD\xEB\x40\x18\x38\x88\x7F\xC5\x93\x25\x40\x06\xEE\xC2\x7F\xFF\x49\x5F\x40\x34\xA4\xFC\x7F\xF9\xFF\x99\x40\x22\x5A\x36\x7F\xF3\xB5\xD3\x40\x10\x10\x70\x7F\xED\x6B\x0D\x40\xC0\x11\x22\x7F\x00\x33\x44\x40\x00\x11"
}
///|
fn format_name(f : @lzma.Format) -> String {
match f {
Auto => "auto"
Lzma => "lzma"
Lzma2 => "lzma2"
Xz => "xz"
}
}
///|
fn emit_case(
name : String,
payload : Bytes,
format : @lzma.Format,
preset : Int,
check : @lzma.Check,
) -> Unit raise @lzma.LzmaError {
let options : @lzma.EncodeOptions = {
format,
preset: { level: preset, extreme: false, },
check,
props: None,
filters: [],
}
let props = options.resolved_props()
let encoded = @lzma.encode(payload[:], options~)
println("CASE \{name}")
println("format=\{format_name(format)}")
println("preset=\{preset}")
println("check=\{check_name(check)}")
println("dict=\{props.dict_size}")
println("plain_len=\{payload.length()}")
println("plain_hex=\{to_hex(payload)}")
println("comp_hex=\{to_hex(encoded)}")
println("END")
}
///|
fn emit_xz_delta_case(
name : String,
payload : Bytes,
preset : Int,
check : @lzma.Check,
delta_distance : Int,
) -> Unit raise @lzma.LzmaError {
let options : @lzma.EncodeOptions = {
format: Xz,
preset: { level: preset, extreme: false, },
check,
props: None,
filters: [],
}
let props = options.resolved_props()
let check_id = match check {
None => 0
Crc32 => 1
Crc64 => 4
Sha256 => 10
}
let encoded = @xz.encode_xz(
payload[:],
props.lc,
props.lp,
props.pb,
props.dict_size,
check_id~,
delta_distance~,
) catch {
@coder.Data => {
println("ERROR DataError")
return
}
@coder.Eof => {
println("ERROR UnexpectedEof")
return
}
@coder.Limit => {
println("ERROR MemoryLimit")
return
}
@coder.Unsupported => {
println("ERROR UnsupportedFeature")
return
}
}
println("CASE \{name}")
println("format=xz")
println("preset=\{preset}")
println("check=\{check_name(check)}")
println("dict=\{props.dict_size}")
println("plain_len=\{payload.length()}")
println("plain_hex=\{to_hex(payload)}")
println("comp_hex=\{to_hex(encoded)}")
println("END")
}
///|
fn emit_xz_bcj_case(
name : String,
payload : Bytes,
preset : Int,
check : @lzma.Check,
bcj : String,
) -> Unit raise @lzma.LzmaError {
let options : @lzma.EncodeOptions = {
format: Xz,
preset: { level: preset, extreme: false, },
check,
props: None,
filters: [],
}
let props = options.resolved_props()
let check_id = match check {
None => 0
Crc32 => 1
Crc64 => 4
Sha256 => 10
}
let encoded = @xz.encode_xz(
payload[:],
props.lc,
props.lp,
props.pb,
props.dict_size,
check_id~,
bcj_x86=bcj == "x86",
bcj_arm=bcj == "arm",
bcj_arm64=bcj == "arm64",
bcj_armthumb=bcj == "armthumb",
bcj_powerpc=bcj == "powerpc",
bcj_ia64=bcj == "ia64",
bcj_sparc=bcj == "sparc",
) catch {
@coder.Data => {
println("ERROR DataError")
return
}
@coder.Eof => {
println("ERROR UnexpectedEof")
return
}
@coder.Limit => {
println("ERROR MemoryLimit")
return
}
@coder.Unsupported => {
println("ERROR UnsupportedFeature")
return
}
}
println("CASE \{name}")
println("format=xz")
println("preset=\{preset}")
println("check=\{check_name(check)}")
println("dict=\{props.dict_size}")
println("plain_len=\{payload.length()}")
println("plain_hex=\{to_hex(payload)}")
println("comp_hex=\{to_hex(encoded)}")
println("END")
}
///|
fn main {
println("LZMA_MBT_DIFF_V1")
try {
let empty = b""
let short = b"hello lzma"
let run64 = Bytes::make(64, b'\xAA')
let incomp256 = mixed_bytes(256)
let incomp64k = mixed_bytes(65536)
let over64k = Bytes::make(70000, b'\x33')
emit_case(
"empty_xz_p6_crc64",
empty,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case("empty_lzma_p6", empty, @lzma.Format::Lzma, 6, @lzma.Check::Crc64)
emit_case(
"empty_lzma2_p6",
empty,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"short_xz_p6_crc64",
short,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case("short_lzma_p6", short, @lzma.Format::Lzma, 6, @lzma.Check::Crc64)
emit_case(
"short_lzma2_p6",
short,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"short_xz_p0_crc64",
short,
@lzma.Format::Xz,
0,
@lzma.Check::Crc64,
)
emit_case("short_lzma_p0", short, @lzma.Format::Lzma, 0, @lzma.Check::Crc64)
emit_case(
"short_lzma2_p0",
short,
@lzma.Format::Lzma2,
0,
@lzma.Check::Crc64,
)
emit_case(
"short_xz_p6_crc32",
short,
@lzma.Format::Xz,
6,
@lzma.Check::Crc32,
)
emit_case("short_xz_p6_none", short, @lzma.Format::Xz, 6, @lzma.Check::None)
emit_case(
"short_xz_p6_sha256",
short,
@lzma.Format::Xz,
6,
@lzma.Check::Sha256,
)
emit_xz_delta_case(
"short_xz_delta_d1_p6_crc64",
short,
6,
@lzma.Check::Crc64,
1,
)
emit_xz_bcj_case(
"short_xz_bcj_p6_crc64",
bcj_payload(),
6,
@lzma.Check::Crc64,
"x86",
)
emit_xz_bcj_case(
"short_xz_arm_p6_crc64",
arm_payload(),
6,
@lzma.Check::Crc64,
"arm",
)
emit_xz_bcj_case(
"short_xz_arm64_p6_crc64",
arm64_payload(),
6,
@lzma.Check::Crc64,
"arm64",
)
emit_xz_bcj_case(
"short_xz_armthumb_p6_crc64",
armthumb_payload(),
6,
@lzma.Check::Crc64,
"armthumb",
)
emit_xz_bcj_case(
"short_xz_powerpc_p6_crc64",
powerpc_payload(),
6,
@lzma.Check::Crc64,
"powerpc",
)
emit_xz_bcj_case(
"short_xz_ia64_p6_crc64",
ia64_payload(),
6,
@lzma.Check::Crc64,
"ia64",
)
emit_xz_bcj_case(
"short_xz_sparc_p6_crc64",
sparc_payload(),
6,
@lzma.Check::Crc64,
"sparc",
)
emit_case(
"empty_xz_p6_crc32",
empty,
@lzma.Format::Xz,
6,
@lzma.Check::Crc32,
)
emit_case("empty_xz_p6_none", empty, @lzma.Format::Xz, 6, @lzma.Check::None)
emit_case(
"run64_xz_p6_crc64",
run64,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case("run64_lzma_p6", run64, @lzma.Format::Lzma, 6, @lzma.Check::Crc64)
emit_case(
"run64_lzma2_p6",
run64,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"incomp256_xz_p6_crc64",
incomp256,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case(
"incomp256_lzma_p6",
incomp256,
@lzma.Format::Lzma,
6,
@lzma.Check::Crc64,
)
emit_case(
"incomp256_lzma2_p6",
incomp256,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"over64k_xz_p6_crc64",
over64k,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case(
"over64k_lzma_p6",
over64k,
@lzma.Format::Lzma,
6,
@lzma.Check::Crc64,
)
emit_case(
"over64k_lzma2_p6",
over64k,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"over64k_xz_p0_crc64",
over64k,
@lzma.Format::Xz,
0,
@lzma.Check::Crc64,
)
emit_case(
"incomp64k_lzma2_p6",
incomp64k,
@lzma.Format::Lzma2,
6,
@lzma.Check::Crc64,
)
emit_case(
"incomp64k_xz_p6_crc64",
incomp64k,
@lzma.Format::Xz,
6,
@lzma.Check::Crc64,
)
emit_case(
"incomp64k_lzma_p6",
incomp64k,
@lzma.Format::Lzma,
6,
@lzma.Check::Crc64,
)
println("DONE")
} catch {
err => {
let tag = match err {
InvalidInput(_) => "InvalidInput"
UnexpectedEof => "UnexpectedEof"
InvalidConfiguration(_) => "InvalidConfiguration"
UnsupportedFeature(_) => "UnsupportedFeature"
MemoryLimit => "MemoryLimit"
DataError => "DataError"
BufferTooSmall => "BufferTooSmall"
FormatError => "FormatError"
}
println("ERROR \{tag}")
}
}
}