From 11c8b134d7de3d7b2249d74b26a87bc9d6acc27d Mon Sep 17 00:00:00 2001 From: ubq323 Date: Mon, 22 Apr 2024 00:34:20 +0100 Subject: rle --- packet_reader/rle.ha | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 packet_reader/rle.ha (limited to 'packet_reader/rle.ha') diff --git a/packet_reader/rle.ha b/packet_reader/rle.ha new file mode 100644 index 0000000..af9f080 --- /dev/null +++ b/packet_reader/rle.ha @@ -0,0 +1,65 @@ + +use fmt; + +fn item_encode(count: int, val: u32) u32 = + ((count-1)<<24):u32 | (val&0xffffff); +fn item_decode(c: u32) (int, u32) = + ((((c&0xff000000)>>24)+1):int, c&0xffffff); + +// caller freeeee +export fn rle_encode(d: []u32) []u32 = { + let out: []u32 = []; + let start = 0z; + for (start < len(d)) { + let this = d[start]; + let ix = start + 1; + for (ix < len(d) && d[ix] == this) ix += 1; + const val = this; + let count = (ix - start): int; + fmt::printfln("#{:_06x} x{}",val, count)!; + for (count > 0) { + append(out, item_encode(count%256, val)); + count -= 256; + }; + start = ix; + }; + return out; +}; + +// ooooo caller freeeeeee meee +export fn rle_decode(d: []u32) []u32 = { + let out: []u32 = []; + for (const k .. d) { + const (count, val) = item_decode(k); + append(out, [val...], count: size); + }; + return out; +}; + +fn dotest(eu: []u32) void = { + const ee = rle_encode(eu); + defer free(ee); + // for (const k .. ee) { + // const (count, val) = item_decode(k); + // fmt::printfln("0x{:_08x} | #{:_06x} x{}", k, val, count)!; + // }; + + const dd = rle_decode(ee); + defer free(dd); + + assert(len(eu) == len(dd), "length mismatch??"); + let good = true; + for (let i = 0z; i < len(eu); i += 1) { + assert(eu[i] == dd[i], "value wrong"); + // fmt::printfln("{} vs {}",eu[i], dd[i])!; + // if (eu[i] != dd[i]) { good=false; fmt::println("uh oh")!; }; + }; + // if (good) fmt::printfln("good yay")!; + +}; + +@test fn euou() void = dotest([1,1,1,1,1,2,2,2,3,3,3,3,3,4,4,5,5,5,666,69,9,9]); +@test fn oeuoeu2() void = dotest([1,2,3,4,5]); +@test fn oeuoeu2() void = dotest([1,1,1]); +@test fn oeuoeu2() void = dotest([1,6]); +@test fn oeuoeu2() void = dotest([1]); -- cgit v1.2.3