aboutsummaryrefslogtreecommitdiff
path: root/packet_reader/rle.ha
blob: af9f0805ef3a2495a38c03ed8d5b6b2bd431c0ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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]);