compiler/ lib/ examples/ std/ arch/ rv64/ tests/ abi.sizes.rad 3.4 KiB aggregate.return.rad 4.0 KiB arith.assignment.rad 580 B arith.basic.rad 176 B arith.modulo.rad 96 B arith.subword.rad 3.8 KiB arith.sum.rad 177 B arith.w64.rad 4.1 KiB array.assign.rad 221 B array.bounds.check.rad 321 B array.index.assign.rad 367 B array.index.rad 249 B array.length.rad 262 B array.math.rad 1.2 KiB array.nested.assign.rad 319 B array.nested.rad 325 B array.record.elements.rad 1.7 KiB array.repeat.edge.rad 548 B array.repeat.rad 828 B array.return.rad 330 B array.slice.empty.rad 108 B array.slice.gen.end.rad 126 B array.slice.gen.index.rad 139 B array.slice.gen.open.rad 125 B array.slice.gen.start.end.rad 127 B array.slice.gen.start.rad 126 B array.slice.rad 759 B as.precedence.rad 212 B assert.basic.rad 387 B assert.fail.rad 138 B assert.false.rad 140 B assert.true.rad 100 B assign.mutable.rad 6.1 KiB assign.rad 129 B assign.shadow.mutable.rad 461 B binop.bitwise.rad 1.2 KiB binop.cmp.rad 426 B bool.comparison.array.rad 688 B bool.comparison.nested.gen.rad 1.0 KiB bool.comparison.opt.rad 905 B bool.comparison.record.gen.rad 1.0 KiB bool.comparison.record.rad 1.1 KiB bool.comparison.slice.gen.rad 157 B bool.comparison.slice.rad 4.1 KiB bool.comparison.slice.record.gen.rad 2.0 KiB bool.comparison.slice.union.gen.rad 2.5 KiB bool.comparison.union.ctor.rad 690 B bool.comparison.union.gen.rad 1.2 KiB bool.comparison.union.record.gen.rad 1.5 KiB bool.comparison.union.simple.gen.rad 281 B bool.operators.complex.rad 384 B bool.operators.rad 831 B bool.short.circuit.rad 2.3 KiB bool.simple.rad 194 B bool.values.rad 772 B builtin.size.align.rad 1.3 KiB builtin.sliceof.mut.rad 606 B builtin.sliceof.rad 505 B call.arg.clobber.rad 717 B call.basic.rad 241 B call.clobber.rad 462 B cast.same.size.rad 1.0 KiB casting.numbers.rad 1.5 KiB char.literal.rad 165 B compound.assign.field.rad 285 B compound.assign.rad 1.1 KiB cond.assign.rad 723 B cond.expr.aggregate.rad 1.1 KiB cond.expr.rad 1.8 KiB cond.for.else.break.rad 326 B cond.for.indexed.rad 238 B cond.for.rad 165 B cond.for.range.indexed.rad 526 B cond.for.range.rad 171 B cond.for.unsigned.range.rad 644 B cond.forever.break.continue.rad 182 B cond.forever.break.rad 232 B cond.fused.rad 926 B cond.if.case.rad 2.2 KiB cond.if.else.min.rad 143 B cond.if.else.rad 225 B cond.if.elseif.rad 420 B cond.if.noelse.rad 120 B cond.if.rad 865 B cond.match.fallthrough.rad 369 B cond.match.guard.rad 1.4 KiB cond.match.guard.regalloc.rad 1.3 KiB cond.while.else.break.rad 282 B cond.while.rad 119 B const.array.copy.mutate.rad 386 B const.array.rad 195 B const.basic.rad 325 B const.char.rad 159 B const.fn.array.rad 664 B const.record.array.rad 1.2 KiB const.record.array.simple.rad 523 B const.record.ctor.rad 170 B const.record.fn.rad 353 B const.record.rad 182 B const.slice.param.rad 333 B const.union.payload.ctor.rad 349 B const.union.record.literal.rad 359 B data.array.rad 767 B data.bool.rad 216 B data.i16.rad 261 B data.i32.rad 281 B data.i8.rad 248 B data.record.rad 561 B data.simple.rad 436 B data.u16.rad 220 B data.u32.rad 240 B data.u8.rad 208 B data.union.rad 886 B debug.tag.rad 557 B edge.cases.2.rad 337 B edge.cases.3.rad 594 B edge.cases.4.rad 1.2 KiB edge.cases.5.rad 1.0 KiB edge.cases.6.rad 2.6 KiB edge.cases.7.addr.bug.rad 224 B edge.cases.8.bug.rad 508 B edge.cases.rad 223 B error.basic.rad 159 B error.catch.rad 1.6 KiB error.division.zero.rad 164 B error.modulo.zero.rad 162 B error.multi.basic.rad 672 B error.multi.catch.rad 772 B error.multi.catch.typed.binding.rad 791 B error.multi.catch.typed.catchall.rad 1.0 KiB error.multi.catch.typed.rad 1.1 KiB error.multi.propagate.multi.rad 953 B error.multi.propagate.rad 825 B error.multi.try.optional.rad 507 B error.slice.bounds.rad 219 B error.try.bang.success.rad 370 B error.try.catch.binding.rad 2.0 KiB error.try.optional.rad 1.8 KiB error.try.rad 4.0 KiB fn.block.scope.rad 508 B fn.callback.nested.rad 1.2 KiB fn.default.rad 131 B fn.local.rad 140 B fn.recursion.2.rad 239 B fn.void.rad 150 B for.else.continue.rad 1.1 KiB frame.large.rad 567 B if-let-mut.rad 1.1 KiB iflet.shadow.leak.rad 317 B integer.bitwise.basic.rad 693 B integer.overflow.rad 1.8 KiB large.blit.store.rad 2.1 KiB let.guard.rad 1.9 KiB literal.w64.rad 1.7 KiB loc.addr.offset.bug.rad 410 B loc.addr.opt.to.opt.rad 433 B loc.addr.optional.assign.rad 408 B loc.addr.record.assign.rad 443 B loop.complex.flow.rad 1007 B loop.sealblock.rad 911 B match.array.rad 3.4 KiB match.char.rad 1.6 KiB match.multi.seal.rad 987 B match.multi.survive.rad 1.6 KiB match.mutref.push.rad 1.0 KiB match.mutref.union.rad 662 B match.nested.call.rad 1.7 KiB match.nested.deep.rad 2.2 KiB match.nested.deref.rad 3.7 KiB match.nested.guard.rad 1.6 KiB match.nested.iflet.guard.rad 1.6 KiB match.nested.iflet.rad 1.4 KiB match.nested.letelse.rad 813 B match.nested.letelse.union.rad 1.3 KiB match.nested.literal.rad 3.1 KiB match.nested.multi.rad 2.4 KiB match.nested.pattern.rad 5.2 KiB match.nested.record.rad 2.0 KiB match.nested.union.rad 2.3 KiB match.nested.whilelet.rad 2.4 KiB match.string.rad 1.8 KiB match.value.copy.rad 2.0 KiB match.void.then.or.rad 1.6 KiB memzero.result.bug.rad 806 B memzero.union.bug.rad 576 B mutref.loop.bug.rad 1.8 KiB opt.assignment.bug.rad 1.3 KiB opt.bug.test.rad 1.4 KiB opt.if.let.complex.rad 6.2 KiB opt.if.let.guard.rad 809 B opt.if.let.rad 956 B opt.nil.check.rad 1.5 KiB opt.record.eq.rad 842 B opt.record.rad 655 B opt.return.array.rad 289 B opt.return.nested.rad 797 B opt.return.record.rad 344 B opt.slice.npo.rad 2.8 KiB opt.type.rad 200 B opt.while.let.complex.rad 404 B panic.rad 111 B placeholder.basic.rad 133 B placeholder.comprehensive.rad 562 B pointer.copy.edge.case.rad 1.3 KiB pointer.slice.index.rad 269 B pointer.slice.store.rad 881 B prog.ackermann.rad 5.0 KiB prog.bignum.rad 9.4 KiB prog.binsearch.rad 2.4 KiB prog.bubblesort.rad 2.0 KiB prog.cordic.rad 6.9 KiB prog.crc32.rad 2.7 KiB prog.dijkstra.rad 7.7 KiB prog.eval.rad 6.2 KiB prog.hanoi.rad 3.8 KiB prog.huffman.rad 9.3 KiB prog.hybridsort.rad 3.0 KiB prog.linkedlist.rad 5.8 KiB prog.lzw.rad 6.7 KiB prog.matmul.rad 2.9 KiB prog.mersenne.rad 5.2 KiB prog.nqueens.rad 3.4 KiB prog.rbtree.rad 8.2 KiB prog.regex.rad 10.2 KiB prog.sha256.rad 7.0 KiB prog.sieve.rad 2.8 KiB prog.symtab.rad 10.1 KiB prog.tokenizer.rad 13.8 KiB prog.vm.rad 17.4 KiB ptr.assign.rad 137 B ptr.deref.rad 622 B ptr.eq.rad 966 B ptr.mutate.rad 244 B ptr.opaque.rad 1.4 KiB record.access.rad 285 B record.alignment.rad 179 B record.array.elements.rad 1.7 KiB record.copy.rad 2.0 KiB record.field.assign.rad 184 B record.nested.calls.2.rad 612 B record.nested.calls.3.rad 734 B record.param.lit.rad 353 B record.ptr.access.rad 227 B record.ptr.mutate.rad 243 B record.shorthand.rad 1.5 KiB record.unlabeled.rad 407 B ref.if.bug.rad 519 B ref.immut.loop.bug.rad 670 B ref.mut.ptr.rad 261 B regalloc.callee.save.rad 1.5 KiB regalloc.spill.reuse.rad 473 B reserve.loop.rad 392 B result.void.success.rad 716 B slice.alloc.loop.rad 788 B slice.append.rad 3.3 KiB slice.cap.rad 941 B slice.delete.rad 971 B slice.of.rad 460 B slice.subslice.rad 1.4 KiB spill.blockarg.clobber.rad 3.5 KiB spill.loop.rad 1.6 KiB stack.local.corrupt.rad 320 B static.array.mutate.rad 387 B static.basic.rad 327 B static.fn.array.rad 628 B static.record.array.rad 503 B static.slice.index.assign.rad 408 B static.slice.offset.rad 668 B string.basic.rad 149 B string.escape.rad 349 B string.index.rad 116 B switch.blockargs.clobber.rad 1.3 KiB trait.aggregate.ret.rad 1.5 KiB trait.array.optional.rad 1.7 KiB trait.basic.rad 565 B trait.control.flow.rad 1.1 KiB trait.fn.param.rad 1.6 KiB trait.multiple.methods.rad 1.2 KiB trait.multiple.traits.rad 1.2 KiB trait.multiple.types.rad 1.3 KiB trait.supertrait.rad 2.5 KiB trait.throws.rad 1.0 KiB trait.writer.rad 2.6 KiB type.unify.rad 4.5 KiB undefined.rad 417 B union-tag.rad 911 B union.bitfield.rad 1.2 KiB union.discriminant.cast.rad 389 B union.edge.case.2.rad 679 B union.edge.case.3.rad 608 B union.mixed.assign.rad 977 B union.payload.mutref.rad 1.4 KiB union.payload.rad 580 B union.record.forward.rad 1.3 KiB union.void.match.rad 403 B union.void.rad 824 B unsigned.compare.rad 1.9 KiB var.align.rad 1013 B var.infer.rad 549 B decode.rad 14.6 KiB emit.rad 24.4 KiB encode.rad 19.9 KiB isel.rad 41.1 KiB printer.rad 13.0 KiB tests.rad 15.7 KiB rv64.rad 13.0 KiB collections/ lang/ sys/ arch.rad 65 B collections.rad 36 B fmt.rad 3.8 KiB intrinsics.rad 206 B io.rad 1.2 KiB lang.rad 222 B mem.rad 2.2 KiB sys.rad 167 B testing.rad 2.4 KiB tests.rad 11.6 KiB vec.rad 3.1 KiB std.rad 231 B scripts/ seed/ test/ vim/ .gitignore 353 B .gitsigners 112 B LICENSE 1.1 KiB Makefile 3.1 KiB README 2.5 KiB std.lib 987 B std.lib.test 252 B
lib/std/arch/rv64/tests/prog.huffman.rad 9.3 KiB raw
1
//! Huffman encoding.
2
//! Build a Huffman tree from character frequencies, generate prefix codes,
3
//! encode a message, decode it, and verify round-trip correctness.
4
5
6
const MAX_SYMBOLS: u32 = 32;
7
const MAX_NODES: u32 = 63;
8
const MAX_BITS: u32 = 512;
9
10
/// A node in the Huffman tree.
11
union HNodeKind {
12
    /// Leaf node with a symbol index.
13
    Leaf(u32),
14
    /// Interior node (no symbol).
15
    Interior,
16
}
17
18
record HNode {
19
    freq: u32,
20
    kind: HNodeKind,
21
    left: u32,
22
    right: u32,
23
}
24
25
const NIL: u32 = 0xFFFFFFFF;
26
27
record HuffState {
28
    nodes: *mut [HNode],
29
    nodeCount: u32,
30
    heap: *mut [u32],
31
    heapSize: u32,
32
    codeBits: *mut [u32],
33
    codeLen: *mut [u32],
34
    bitstream: *mut [u8],
35
    bitCount: u32,
36
}
37
38
fn newLeaf(s: *mut HuffState, freq: u32, symbol: u32) -> u32 {
39
    let idx: u32 = s.nodeCount;
40
    s.nodes[idx] = HNode { freq, kind: HNodeKind::Leaf(symbol), left: NIL, right: NIL };
41
    s.nodeCount += 1;
42
    return idx;
43
}
44
45
fn newInterior(s: *mut HuffState, freq: u32, left: u32, right: u32) -> u32 {
46
    let idx: u32 = s.nodeCount;
47
    s.nodes[idx] = HNode { freq, kind: HNodeKind::Interior, left, right };
48
    s.nodeCount += 1;
49
    return idx;
50
}
51
52
/// Get the symbol from a node, or nil if it's an interior node.
53
fn nodeSymbol(node: *HNode) -> ?u32 {
54
    match node.kind {
55
        case HNodeKind::Leaf(sym) => {
56
            return sym;
57
        }
58
        case HNodeKind::Interior => {
59
            return nil;
60
        }
61
    }
62
}
63
64
fn heapSwap(s: *mut HuffState, i: u32, j: u32) {
65
    let tmp: u32 = s.heap[i];
66
    s.heap[i] = s.heap[j];
67
    s.heap[j] = tmp;
68
}
69
70
fn heapFreq(s: *HuffState, i: u32) -> u32 {
71
    return s.nodes[s.heap[i]].freq;
72
}
73
74
fn siftUp(s: *mut HuffState, pos: u32) {
75
    let mut i: u32 = pos;
76
    while i > 0 {
77
        let parent: u32 = (i - 1) / 2;
78
        if heapFreq(s, i) < heapFreq(s, parent) {
79
            heapSwap(s, i, parent);
80
            i = parent;
81
        } else {
82
            return;
83
        }
84
    }
85
}
86
87
fn siftDown(s: *mut HuffState, pos: u32) {
88
    let mut i: u32 = pos;
89
    while true {
90
        let left: u32 = 2 * i + 1;
91
        let right: u32 = 2 * i + 2;
92
        let mut smallest: u32 = i;
93
94
        if left < s.heapSize and heapFreq(s, left) < heapFreq(s, smallest) {
95
            smallest = left;
96
        }
97
        if right < s.heapSize and heapFreq(s, right) < heapFreq(s, smallest) {
98
            smallest = right;
99
        }
100
        if smallest == i {
101
            return;
102
        }
103
        heapSwap(s, i, smallest);
104
        i = smallest;
105
    }
106
}
107
108
fn heapPush(s: *mut HuffState, nodeIdx: u32) {
109
    s.heap[s.heapSize] = nodeIdx;
110
    s.heapSize += 1;
111
    siftUp(s, s.heapSize - 1);
112
}
113
114
fn heapPop(s: *mut HuffState) -> u32 {
115
    let result: u32 = s.heap[0];
116
    s.heapSize -= 1;
117
    s.heap[0] = s.heap[s.heapSize];
118
    if s.heapSize > 0 {
119
        siftDown(s, 0);
120
    }
121
    return result;
122
}
123
124
fn buildTree(s: *mut HuffState, freqs: *[u32]) -> u32 {
125
    s.nodeCount = 0;
126
    s.heapSize = 0;
127
128
129
    for freq, sym in freqs {
130
        if freq > 0 {
131
            let idx: u32 = newLeaf(s, freq, sym);
132
            heapPush(s, idx);
133
        }
134
    }
135
136
    while s.heapSize > 1 {
137
        let left: u32 = heapPop(s);
138
        let right: u32 = heapPop(s);
139
        let combinedFreq: u32 = s.nodes[left].freq + s.nodes[right].freq;
140
        let parent: u32 = newInterior(s, combinedFreq, left, right);
141
        heapPush(s, parent);
142
    }
143
144
    return heapPop(s);
145
}
146
147
fn generateCodes(s: *mut HuffState, nodeIdx: u32, code: u32, depth: u32) {
148
    match s.nodes[nodeIdx].kind {
149
        case HNodeKind::Leaf(sym) => {
150
            s.codeBits[sym] = code;
151
            s.codeLen[sym] = depth;
152
        }
153
        case HNodeKind::Interior => {
154
            if s.nodes[nodeIdx].left != NIL {
155
                generateCodes(s, s.nodes[nodeIdx].left, code << 1, depth + 1);
156
            }
157
            if s.nodes[nodeIdx].right != NIL {
158
                generateCodes(s, s.nodes[nodeIdx].right, (code << 1) | 1, depth + 1);
159
            }
160
        }
161
    }
162
}
163
164
fn writeBit(s: *mut HuffState, bit: u32) {
165
    let byteIdx: u32 = s.bitCount / 8;
166
    let bitIdx: u32 = 7 - (s.bitCount % 8);
167
    if bit == 1 {
168
        s.bitstream[byteIdx] |= (1 as u8 << bitIdx as u8);
169
    }
170
    s.bitCount += 1;
171
}
172
173
fn readBit(s: *HuffState, pos: u32) -> u32 {
174
    let byteIdx: u32 = pos / 8;
175
    let bitIdx: u32 = 7 - (pos % 8);
176
    return (s.bitstream[byteIdx] >> bitIdx as u8) as u32 & 1;
177
}
178
179
fn encode(s: *mut HuffState, msg: *[u32]) {
180
    s.bitCount = 0;
181
    let mut i: u32 = 0;
182
    while i < MAX_BITS {
183
        s.bitstream[i] = 0;
184
        i += 1;
185
    }
186
187
188
    for sym in msg {
189
        let bits: u32 = s.codeBits[sym];
190
        let len: u32 = s.codeLen[sym];
191
        let mut b: u32 = 0;
192
        while b < len {
193
            let bit: u32 = (bits >> (len - 1 - b)) & 1;
194
            writeBit(s, bit);
195
            b += 1;
196
        }
197
    }
198
}
199
200
fn decode(s: *HuffState, root: u32, numSymbols: u32, out: *mut [u32]) -> u32 {
201
    let mut bitPos: u32 = 0;
202
    let mut decoded: u32 = 0;
203
204
    while decoded < numSymbols {
205
        let mut cur: u32 = root;
206
        // Walk the tree until we find a leaf.
207
        while nodeSymbol(&s.nodes[cur]) == nil {
208
            let bit: u32 = readBit(s, bitPos);
209
            bitPos += 1;
210
            if bit == 0 {
211
                cur = s.nodes[cur].left;
212
            } else {
213
                cur = s.nodes[cur].right;
214
            }
215
        }
216
        let sym = nodeSymbol(&s.nodes[cur]) else {
217
            return decoded;
218
        };
219
        out[decoded] = sym;
220
        decoded += 1;
221
    }
222
    return decoded;
223
}
224
225
fn resetCodes(s: *mut HuffState) {
226
    let mut i: u32 = 0;
227
    while i < MAX_SYMBOLS {
228
        s.codeBits[i] = 0;
229
        s.codeLen[i] = 0;
230
        i += 1;
231
    }
232
}
233
234
fn testBasic(s: *mut HuffState) -> i32 {
235
    let freqs: [u32; 5] = [5, 9, 12, 13, 16];
236
    let root: u32 = buildTree(s, &freqs[..]);
237
238
    assert s.nodes[root].freq == 55;
239
240
    resetCodes(s);
241
    generateCodes(s, root, 0, 0);
242
243
    // All symbols should have non-zero code lengths.
244
    let mut i: u32 = 0;
245
    while i < 5 {
246
        assert s.codeLen[i] != 0;
247
        i += 1;
248
    }
249
250
    // No two symbols at the same depth should have the same code.
251
    let mut a: u32 = 0;
252
    while a < 5 {
253
        let mut b: u32 = a + 1;
254
        while b < 5 {
255
            if s.codeLen[a] == s.codeLen[b] {
256
                assert s.codeBits[a] != s.codeBits[b];
257
            }
258
            b += 1;
259
        }
260
        a += 1;
261
    }
262
263
    return 0;
264
}
265
266
fn testRoundTrip(s: *mut HuffState) -> i32 {
267
    let freqs: [u32; 5] = [5, 9, 12, 13, 16];
268
    let root: u32 = buildTree(s, &freqs[..]);
269
270
    resetCodes(s);
271
    generateCodes(s, root, 0, 0);
272
273
    let msg: [u32; 16] = [4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 2, 2, 3, 3, 4, 4];
274
    encode(s, &msg[..]);
275
276
    let mut decoded: [u32; 16] = [0; 16];
277
    let count: u32 = decode(s, root, 16, &mut decoded[..]);
278
279
    assert count == 16;
280
281
    // Verify round-trip.
282
    for expected, i in msg {
283
        if decoded[i] != expected {
284
            return i as i32 + 2;
285
        }
286
    }
287
288
    return 0;
289
}
290
291
fn testSkewed(s: *mut HuffState) -> i32 {
292
    let freqs: [u32; 6] = [100, 1, 1, 1, 1, 1];
293
    let root: u32 = buildTree(s, &freqs[..]);
294
295
    resetCodes(s);
296
    generateCodes(s, root, 0, 0);
297
298
    // The most frequent symbol should have the shortest code.
299
    let mut shortestLen: u32 = 100;
300
    let mut shortestSym: u32 = 0;
301
    let mut i: u32 = 0;
302
    while i < 6 {
303
        if s.codeLen[i] > 0 and s.codeLen[i] < shortestLen {
304
            shortestLen = s.codeLen[i];
305
            shortestSym = i;
306
        }
307
        i += 1;
308
    }
309
    assert shortestSym == 0;
310
311
    let msg: [u32; 12] = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2];
312
    encode(s, &msg[..]);
313
314
    let mut decoded: [u32; 12] = [0; 12];
315
    let count: u32 = decode(s, root, 12, &mut decoded[..]);
316
    assert count == 12;
317
318
    for expected, i in msg {
319
        assert decoded[i] == expected;
320
    }
321
322
    return 0;
323
}
324
325
fn testUniform(s: *mut HuffState) -> i32 {
326
    let freqs: [u32; 8] = [10, 10, 10, 10, 10, 10, 10, 10];
327
    let root: u32 = buildTree(s, &freqs[..]);
328
329
    assert s.nodes[root].freq == 80;
330
331
    resetCodes(s);
332
    generateCodes(s, root, 0, 0);
333
334
    // All 8 symbols should have code length 3 (8 = 2^3).
335
    let mut i: u32 = 0;
336
    while i < 8 {
337
        assert s.codeLen[i] == 3;
338
        i += 1;
339
    }
340
341
    let msg: [u32; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
342
    encode(s, &msg[..]);
343
344
    assert s.bitCount == 24;
345
346
    let mut decoded: [u32; 8] = [0; 8];
347
    let count: u32 = decode(s, root, 8, &mut decoded[..]);
348
    assert count == 8;
349
    for expected, i in msg {
350
        assert decoded[i] == expected;
351
    }
352
353
    return 0;
354
}
355
356
@default fn main() -> i32 {
357
    let mut nodes: [HNode; 63] = [HNode { freq: 0, kind: HNodeKind::Interior, left: 0xFFFFFFFF, right: 0xFFFFFFFF }; 63];
358
    let mut heap: [u32; 63] = [0; 63];
359
    let mut codeBits: [u32; 32] = [0; 32];
360
    let mut codeLen: [u32; 32] = [0; 32];
361
    let mut bitstream: [u8; 512] = [0; 512];
362
363
    let mut s: HuffState = HuffState {
364
        nodes: &mut nodes[..],
365
        nodeCount: 0,
366
        heap: &mut heap[..],
367
        heapSize: 0,
368
        codeBits: &mut codeBits[..],
369
        codeLen: &mut codeLen[..],
370
        bitstream: &mut bitstream[..],
371
        bitCount: 0,
372
    };
373
374
    let r1: i32 = testBasic(&mut s);
375
    if r1 != 0 {
376
        return 10 + r1;
377
    }
378
379
    let r2: i32 = testRoundTrip(&mut s);
380
    if r2 != 0 {
381
        return 20 + r2;
382
    }
383
384
    let r3: i32 = testSkewed(&mut s);
385
    if r3 != 0 {
386
        return 30 + r3;
387
    }
388
389
    let r4: i32 = testUniform(&mut s);
390
    if r4 != 0 {
391
        return 40 + r4;
392
    }
393
394
    return 0;
395
}