nx_pileup_test.nx source
↩ module page · 427 lines · 19647 B
1// nx_pileup_test.nx -- KAT for CIGAR walking + query-pos-at-ref.
2//
3// expect_exit: 0
4//
5// license_tier: ORIGINAL
6
7import "nx_syscalls.nx"
8import "nx_const.nx"
9import "nx_cigar.nx"
10import "nx_sequence.nx"
11import "nx_sequence_ambig.nx"
12import "nx_pileup.nx"
13
14func main() -> i64 {
15
16 let codes: *u8 = sys_mmap(32)
17 let lens: *i64 = sys_mmap(64) as *i64
18 let q_out: *i64 = sys_mmap(16) as *i64
19 let g_out: *i64 = sys_mmap(16) as *i64
20
21 // ============================================================
22 // Section A -- consume helpers.
23 // ============================================================
24
25 if nx_cigar_consumes_query(NX_CIGAR_M) != 1 { return 1 }
26 if nx_cigar_consumes_query(NX_CIGAR_I) != 1 { return 2 }
27 if nx_cigar_consumes_query(NX_CIGAR_D) != 0 { return 3 }
28 if nx_cigar_consumes_query(NX_CIGAR_N) != 0 { return 4 }
29 if nx_cigar_consumes_query(NX_CIGAR_S) != 1 { return 5 }
30 if nx_cigar_consumes_query(NX_CIGAR_H) != 0 { return 6 }
31 if nx_cigar_consumes_query(NX_CIGAR_P) != 0 { return 7 }
32 if nx_cigar_consumes_query(NX_CIGAR_EQ) != 1 { return 8 }
33 if nx_cigar_consumes_query(NX_CIGAR_X) != 1 { return 9 }
34
35 if nx_cigar_consumes_ref(NX_CIGAR_M) != 1 { return 10 }
36 if nx_cigar_consumes_ref(NX_CIGAR_I) != 0 { return 11 }
37 if nx_cigar_consumes_ref(NX_CIGAR_D) != 1 { return 12 }
38 if nx_cigar_consumes_ref(NX_CIGAR_N) != 1 { return 13 }
39 if nx_cigar_consumes_ref(NX_CIGAR_S) != 0 { return 14 }
40 if nx_cigar_consumes_ref(NX_CIGAR_H) != 0 { return 15 }
41 if nx_cigar_consumes_ref(NX_CIGAR_P) != 0 { return 16 }
42 if nx_cigar_consumes_ref(NX_CIGAR_EQ) != 1 { return 17 }
43 if nx_cigar_consumes_ref(NX_CIGAR_X) != 1 { return 18 }
44
45 // ============================================================
46 // Section B -- simplest case: "5M" starting at ref 100.
47 // ref 100,101,102,103,104 <-> query 0,1,2,3,4
48 // target_r=102 -> q_pos=2, in_gap=0
49 // target_r=100 -> q_pos=0
50 // target_r=104 -> q_pos=4
51 // target_r= 99 -> -1 (before start)
52 // target_r=105 -> -1 (past end)
53 // ============================================================
54
55 codes[0] = NX_CIGAR_M & 0xff
56 lens[0] = 5
57 if cigar_query_pos_at_ref(codes, lens, 1, 100, 102, q_out, g_out) != 0 { return 20 }
58 if q_out[0] != 2 { return 21 }
59 if g_out[0] != 0 { return 22 }
60
61 if cigar_query_pos_at_ref(codes, lens, 1, 100, 100, q_out, g_out) != 0 { return 23 }
62 if q_out[0] != 0 { return 24 }
63
64 if cigar_query_pos_at_ref(codes, lens, 1, 100, 104, q_out, g_out) != 0 { return 25 }
65 if q_out[0] != 4 { return 26 }
66
67 if cigar_query_pos_at_ref(codes, lens, 1, 100, 99, q_out, g_out) != -1 { return 27 }
68 if cigar_query_pos_at_ref(codes, lens, 1, 100, 105, q_out, g_out) != -1 { return 28 }
69
70 // ============================================================
71 // Section C -- deletion in middle: "3M1D2M" starting at ref 100.
72 // 3M: ref 100,101,102 <-> query 0,1,2
73 // 1D: ref 103 (no query)
74 // 2M: ref 104,105 <-> query 3,4
75 // target_r=102 -> q_pos=2, in_gap=0
76 // target_r=103 -> q_pos=-1, in_gap=1
77 // target_r=104 -> q_pos=3, in_gap=0
78 // target_r=105 -> q_pos=4
79 // target_r=106 -> -1
80 // ============================================================
81
82 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
83 codes[1] = NX_CIGAR_D & 0xff; lens[1] = 1
84 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 2
85 if cigar_query_pos_at_ref(codes, lens, 3, 100, 102, q_out, g_out) != 0 { return 30 }
86 if q_out[0] != 2 { return 31 }
87 if g_out[0] != 0 { return 32 }
88
89 if cigar_query_pos_at_ref(codes, lens, 3, 100, 103, q_out, g_out) != 0 { return 33 }
90 if q_out[0] != -1 { return 34 }
91 if g_out[0] != 1 { return 35 }
92
93 if cigar_query_pos_at_ref(codes, lens, 3, 100, 104, q_out, g_out) != 0 { return 36 }
94 if q_out[0] != 3 { return 37 }
95 if g_out[0] != 0 { return 38 }
96
97 if cigar_query_pos_at_ref(codes, lens, 3, 100, 105, q_out, g_out) != 0 { return 39 }
98 if q_out[0] != 4 { return 40 }
99
100 if cigar_query_pos_at_ref(codes, lens, 3, 100, 106, q_out, g_out) != -1 { return 41 }
101
102 // ============================================================
103 // Section D -- insertion shifts query: "3M2I3M" starting at ref 100.
104 // 3M: ref 100,101,102 <-> query 0,1,2
105 // 2I: query 3,4 inserted (ref unchanged)
106 // 3M: ref 103,104,105 <-> query 5,6,7
107 // target_r=103 -> q_pos=5
108 // target_r=104 -> q_pos=6
109 // target_r=105 -> q_pos=7
110 // target_r=102 -> q_pos=2
111 // ============================================================
112
113 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
114 codes[1] = NX_CIGAR_I & 0xff; lens[1] = 2
115 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 3
116 if cigar_query_pos_at_ref(codes, lens, 3, 100, 103, q_out, g_out) != 0 { return 50 }
117 if q_out[0] != 5 { return 51 }
118
119 if cigar_query_pos_at_ref(codes, lens, 3, 100, 104, q_out, g_out) != 0 { return 52 }
120 if q_out[0] != 6 { return 53 }
121
122 if cigar_query_pos_at_ref(codes, lens, 3, 100, 105, q_out, g_out) != 0 { return 54 }
123 if q_out[0] != 7 { return 55 }
124
125 if cigar_query_pos_at_ref(codes, lens, 3, 100, 102, q_out, g_out) != 0 { return 56 }
126 if q_out[0] != 2 { return 57 }
127
128 // ============================================================
129 // Section E -- soft clip at start: "2S5M" starting at ref 100.
130 // 2S: query 0,1 soft-clipped (no ref consumption)
131 // 5M: ref 100,101,102,103,104 <-> query 2,3,4,5,6
132 // target_r=100 -> q_pos=2 (soft-clipped bases shift query offset)
133 // target_r=104 -> q_pos=6
134 // ============================================================
135
136 codes[0] = NX_CIGAR_S & 0xff; lens[0] = 2
137 codes[1] = NX_CIGAR_M & 0xff; lens[1] = 5
138 if cigar_query_pos_at_ref(codes, lens, 2, 100, 100, q_out, g_out) != 0 { return 60 }
139 if q_out[0] != 2 { return 61 }
140
141 if cigar_query_pos_at_ref(codes, lens, 2, 100, 104, q_out, g_out) != 0 { return 62 }
142 if q_out[0] != 6 { return 63 }
143
144 // ============================================================
145 // Section F -- bad input.
146 // ============================================================
147
148 if cigar_query_pos_at_ref(codes, lens, -1, 100, 100, q_out, g_out) != -1 { return 70 }
149 if cigar_query_pos_at_ref(codes, lens, 2, 100, 50, q_out, g_out) != -1 { return 71 } // before start
150
151 // ============================================================
152 // Section G -- pileup_contribute_one_read end-to-end.
153 // Read "ACNGT" (5 bases, N at pos 2) packed via dna_pack_ambig.
154 // CIGAR "5M" starting at ref 200.
155 // ref 200 <-> query 0 (A) -> BASE A=0
156 // ref 201 <-> query 1 (C) -> BASE C=1
157 // ref 202 <-> query 2 (N) -> N flag
158 // ref 203 <-> query 3 (G) -> BASE G=2
159 // ref 204 <-> query 4 (T) -> BASE T=3
160 // ref 205 -> OUT (-1)
161 // ============================================================
162
163 let asc: *u8 = sys_mmap(8)
164 let r_bases: *u8 = sys_mmap(8)
165 let r_nbits: *u8 = sys_mmap(8)
166 asc[0]=0x41; asc[1]=0x43; asc[2]=NX_ASCII_DNA_N & 0xff; asc[3]=0x47; asc[4]=0x54
167 dna_pack_ambig(asc, 5, r_bases, r_nbits)
168
169 codes[0] = NX_CIGAR_M & 0xff
170 lens[0] = 5
171
172 let base_out: *i64 = sys_mmap(16) as *i64
173 let flag_out: *i64 = sys_mmap(16) as *i64
174
175 // ref 200 -> A
176 if pileup_contribute_one_read(codes, lens, 1, 200, 200,
177 r_bases, r_nbits, base_out, flag_out) != 0 { return 80 }
178 if base_out[0] != NX_DNA_A { return 81 }
179 if flag_out[0] != NX_PILEUP_FLAG_BASE { return 82 }
180
181 // ref 201 -> C
182 if pileup_contribute_one_read(codes, lens, 1, 200, 201,
183 r_bases, r_nbits, base_out, flag_out) != 0 { return 83 }
184 if base_out[0] != NX_DNA_C { return 84 }
185 if flag_out[0] != NX_PILEUP_FLAG_BASE { return 85 }
186
187 // ref 202 -> N (ambiguous; flag = N regardless of underlying code)
188 if pileup_contribute_one_read(codes, lens, 1, 200, 202,
189 r_bases, r_nbits, base_out, flag_out) != 0 { return 86 }
190 if flag_out[0] != NX_PILEUP_FLAG_N { return 87 }
191
192 // ref 203 -> G
193 if pileup_contribute_one_read(codes, lens, 1, 200, 203,
194 r_bases, r_nbits, base_out, flag_out) != 0 { return 88 }
195 if base_out[0] != NX_DNA_G { return 89 }
196 if flag_out[0] != NX_PILEUP_FLAG_BASE { return 90 }
197
198 // ref 204 -> T
199 if pileup_contribute_one_read(codes, lens, 1, 200, 204,
200 r_bases, r_nbits, base_out, flag_out) != 0 { return 91 }
201 if base_out[0] != NX_DNA_T { return 92 }
202
203 // ref 205 -> OUT
204 if pileup_contribute_one_read(codes, lens, 1, 200, 205,
205 r_bases, r_nbits, base_out, flag_out) != -1 { return 93 }
206 if flag_out[0] != NX_PILEUP_FLAG_OUT { return 94 }
207
208 // ============================================================
209 // Section H -- deletion through pileup_contribute_one_read.
210 // CIGAR "2M1D2M" starting at ref 300, query "ACGT" (no N).
211 // ref 300 <-> q 0 (A) -> BASE
212 // ref 301 <-> q 1 (C) -> BASE
213 // ref 302 -> D -> DEL flag
214 // ref 303 <-> q 2 (G) -> BASE
215 // ref 304 <-> q 3 (T) -> BASE
216 // ============================================================
217
218 let r2_bases: *u8 = sys_mmap(8)
219 let r2_nbits: *u8 = sys_mmap(8)
220 asc[0]=0x41; asc[1]=0x43; asc[2]=0x47; asc[3]=0x54
221 dna_pack_ambig(asc, 4, r2_bases, r2_nbits)
222
223 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 2
224 codes[1] = NX_CIGAR_D & 0xff; lens[1] = 1
225 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 2
226
227 if pileup_contribute_one_read(codes, lens, 3, 300, 302,
228 r2_bases, r2_nbits, base_out, flag_out) != 0 { return 100 }
229 if flag_out[0] != NX_PILEUP_FLAG_DEL { return 101 }
230 if base_out[0] != -1 { return 102 }
231
232 if pileup_contribute_one_read(codes, lens, 3, 300, 303,
233 r2_bases, r2_nbits, base_out, flag_out) != 0 { return 103 }
234 if base_out[0] != NX_DNA_G { return 104 }
235 if flag_out[0] != NX_PILEUP_FLAG_BASE { return 105 }
236
237 // ============================================================
238 // Section I -- pileup_insertion_after_ref (G2.3a).
239 // ============================================================
240
241 let ins_len: *i64 = sys_mmap(16) as *i64
242 let ins_qp: *i64 = sys_mmap(16) as *i64
243
244 // Case 1: "5M" starting at ref 200, no I op anywhere.
245 // Any target should return 1 (no insertion).
246 codes[0] = NX_CIGAR_M & 0xff
247 lens[0] = 5
248 if pileup_insertion_after_ref(codes, lens, 1, 200, 202, ins_len, ins_qp) != 1 { return 110 }
249 if pileup_insertion_after_ref(codes, lens, 1, 200, 204, ins_len, ins_qp) != 1 { return 111 }
250 if pileup_insertion_after_ref(codes, lens, 1, 200, 205, ins_len, ins_qp) != -1 { return 112 } // past end
251 if pileup_insertion_after_ref(codes, lens, 1, 200, 199, ins_len, ins_qp) != -1 { return 113 } // before start
252
253 // Case 2: "3M2I3M" starting at ref 100.
254 // 3M: ref 100,101,102 <-> q 0,1,2
255 // 2I: q 3,4 inserted (no ref advance)
256 // 3M: ref 103,104,105 <-> q 5,6,7
257 // INS event reported at ref 102 (last M before I), length=2, q_pos=3.
258 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
259 codes[1] = NX_CIGAR_I & 0xff; lens[1] = 2
260 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 3
261
262 if pileup_insertion_after_ref(codes, lens, 3, 100, 102, ins_len, ins_qp) != 0 { return 120 }
263 if ins_len[0] != 2 { return 121 }
264 if ins_qp[0] != 3 { return 122 }
265
266 // Other positions: no insertion at THIS position.
267 if pileup_insertion_after_ref(codes, lens, 3, 100, 100, ins_len, ins_qp) != 1 { return 123 }
268 if pileup_insertion_after_ref(codes, lens, 3, 100, 101, ins_len, ins_qp) != 1 { return 124 }
269 if pileup_insertion_after_ref(codes, lens, 3, 100, 103, ins_len, ins_qp) != 1 { return 125 }
270 if pileup_insertion_after_ref(codes, lens, 3, 100, 105, ins_len, ins_qp) != 1 { return 126 }
271 if pileup_insertion_after_ref(codes, lens, 3, 100, 106, ins_len, ins_qp) != -1 { return 127 }
272
273 // Case 3: "3M1D2M" -- last M of first 3M is followed by D, NOT I.
274 // Should NOT report an insertion event.
275 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
276 codes[1] = NX_CIGAR_D & 0xff; lens[1] = 1
277 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 2
278
279 if pileup_insertion_after_ref(codes, lens, 3, 100, 102, ins_len, ins_qp) != 1 { return 130 }
280 // target_r=103 is in the D op (deletion gap), not an insertion event:
281 if pileup_insertion_after_ref(codes, lens, 3, 100, 103, ins_len, ins_qp) != 1 { return 131 }
282
283 // Case 4: longer insertion "2M5I2M" -- last M at ref 101, INS length=5.
284 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 2
285 codes[1] = NX_CIGAR_I & 0xff; lens[1] = 5
286 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 2
287
288 if pileup_insertion_after_ref(codes, lens, 3, 100, 101, ins_len, ins_qp) != 0 { return 140 }
289 if ins_len[0] != 5 { return 141 }
290 if ins_qp[0] != 2 { return 142 } // q_pos: after 2 matched bases (q 0,1), insertion starts at q=2
291
292 // ============================================================
293 // Section J -- indel_count_insertions_by_length aggregator (G2.3b).
294 // 5 reads: ins_lens = [0, 1, 1, 2, 5], max_len = 6.
295 // Expected histogram out_counts[0..6] = [1, 2, 1, 0, 0, 1, 0]
296 // Returns 4 (number of reads with ins_len > 0).
297 // ============================================================
298
299 let ins_lens5: *i64 = sys_mmap(64) as *i64
300 ins_lens5[0]=0; ins_lens5[1]=1; ins_lens5[2]=1; ins_lens5[3]=2; ins_lens5[4]=5
301 let hist: *i64 = sys_mmap(128) as *i64
302 let total_ins: i64 = indel_count_insertions_by_length(ins_lens5, 5, hist, 6)
303 if total_ins != 4 { return 150 }
304 if hist[0] != 1 { return 151 }
305 if hist[1] != 2 { return 152 }
306 if hist[2] != 1 { return 153 }
307 if hist[3] != 0 { return 154 }
308 if hist[4] != 0 { return 155 }
309 if hist[5] != 1 { return 156 }
310 if hist[6] != 0 { return 157 }
311
312 // Bucket-overflow: ins_len > max_len collapses into out_counts[max_len].
313 let ins_lens_big: *i64 = sys_mmap(64) as *i64
314 ins_lens_big[0]=10; ins_lens_big[1]=12; ins_lens_big[2]=3
315 let hist2: *i64 = sys_mmap(128) as *i64
316 let total2: i64 = indel_count_insertions_by_length(ins_lens_big, 3, hist2, 5)
317 if total2 != 3 { return 160 }
318 if hist2[3] != 1 { return 161 } // 3-bp ins
319 if hist2[5] != 2 { return 162 } // both 10 and 12 collapse to bucket 5
320
321 // Empty / no-ins.
322 let ins_lens_zero: *i64 = sys_mmap(64) as *i64
323 ins_lens_zero[0]=0; ins_lens_zero[1]=0; ins_lens_zero[2]=0
324 let hist3: *i64 = sys_mmap(128) as *i64
325 let total3: i64 = indel_count_insertions_by_length(ins_lens_zero, 3, hist3, 4)
326 if total3 != 0 { return 170 }
327 if hist3[0] != 3 { return 171 }
328
329 if indel_count_insertions_by_length(ins_lens5, 0, hist, 4) != 0 { return 180 }
330 if indel_count_insertions_by_length(ins_lens5, -1, hist, 4) != -1 { return 181 }
331 if indel_count_insertions_by_length(ins_lens5, 1, hist, -1) != -1 { return 182 }
332
333 // ============================================================
334 // Section K -- pileup_deletion_after_ref (G2.3d).
335 // ============================================================
336
337 let del_len: *i64 = sys_mmap(16) as *i64
338
339 // Case 1: "5M" no D anywhere -> all positions return 1 (no deletion).
340 codes[0] = NX_CIGAR_M & 0xff
341 lens[0] = 5
342 if pileup_deletion_after_ref(codes, lens, 1, 100, 102, del_len) != 1 { return 190 }
343 if pileup_deletion_after_ref(codes, lens, 1, 100, 104, del_len) != 1 { return 191 }
344 if pileup_deletion_after_ref(codes, lens, 1, 100, 105, del_len) != -1 { return 192 }
345 if pileup_deletion_after_ref(codes, lens, 1, 100, 99, del_len) != -1 { return 193 }
346
347 // Case 2: "3M3D2M" starting at ref 100 -- DEL event at target_r=102.
348 // 3M: ref 100,101,102; 3D: ref 103,104,105; 2M: ref 106,107
349 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
350 codes[1] = NX_CIGAR_D & 0xff; lens[1] = 3
351 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 2
352
353 if pileup_deletion_after_ref(codes, lens, 3, 100, 102, del_len) != 0 { return 200 }
354 if del_len[0] != 3 { return 201 }
355
356 // Other positions: no deletion event AT this position.
357 if pileup_deletion_after_ref(codes, lens, 3, 100, 100, del_len) != 1 { return 202 }
358 if pileup_deletion_after_ref(codes, lens, 3, 100, 101, del_len) != 1 { return 203 }
359 if pileup_deletion_after_ref(codes, lens, 3, 100, 103, del_len) != 1 { return 204 } // in D range; not "starts at"
360 if pileup_deletion_after_ref(codes, lens, 3, 100, 106, del_len) != 1 { return 205 }
361 if pileup_deletion_after_ref(codes, lens, 3, 100, 107, del_len) != 1 { return 206 }
362 if pileup_deletion_after_ref(codes, lens, 3, 100, 108, del_len) != -1 { return 207 }
363
364 // Case 3: "3M2I3M" with I (not D) after last M -- should NOT report deletion.
365 codes[0] = NX_CIGAR_M & 0xff; lens[0] = 3
366 codes[1] = NX_CIGAR_I & 0xff; lens[1] = 2
367 codes[2] = NX_CIGAR_M & 0xff; lens[2] = 3
368 if pileup_deletion_after_ref(codes, lens, 3, 100, 102, del_len) != 1 { return 210 }
369
370 // ============================================================
371 // Section L -- ins_event_to_hash + ins_event_decode_hash (G2.3e).
372 // ============================================================
373
374 // Build a read containing "GT" at query positions 0..1 via dna_pack.
375 let r_asc: *u8 = sys_mmap(8)
376 let r_bs: *u8 = sys_mmap(8)
377 r_asc[0]=0x47; r_asc[1]=0x54 // GT
378 dna_pack(r_asc, 2, r_bs)
379
380 // "GT" length=2: G(10) at bit 2-3, T(11) at bit 0-1 -> bases = 0b1011 = 0xB
381 // hash = (2 << 56) | 0xB
382 let h_gt: i64 = ins_event_to_hash(r_bs, 0, 2)
383 if h_gt != (2 << 56) | 0x0B { return 220 }
384
385 // Different allele: build "GA" and confirm different hash.
386 let r_asc2: *u8 = sys_mmap(8)
387 let r_bs2: *u8 = sys_mmap(8)
388 r_asc2[0]=0x47; r_asc2[1]=0x41 // GA
389 dna_pack(r_asc2, 2, r_bs2)
390 let h_ga: i64 = ins_event_to_hash(r_bs2, 0, 2)
391 if h_ga == h_gt { return 221 }
392 // "GA": G(10) at bit 2-3, A(00) at bit 0-1 -> bases = 0b1000 = 0x8
393 if h_ga != (2 << 56) | 0x08 { return 222 }
394
395 // Same allele from a different position in another read -> same hash.
396 // Build "XXGT" (don't care, don't care, G, T) and hash starting at q_pos=2.
397 let r_asc3: *u8 = sys_mmap(8)
398 let r_bs3: *u8 = sys_mmap(8)
399 r_asc3[0]=0x41; r_asc3[1]=0x43; r_asc3[2]=0x47; r_asc3[3]=0x54 // AC GT
400 dna_pack(r_asc3, 4, r_bs3)
401 let h_gt2: i64 = ins_event_to_hash(r_bs3, 2, 2)
402 if h_gt2 != h_gt { return 223 }
403
404 // Single-base insertion "G".
405 let h_g: i64 = ins_event_to_hash(r_bs3, 2, 1)
406 // length=1, base = G(10) at bit 0-1 -> bases = 0b10 = 0x2
407 if h_g != (1 << 56) | 0x02 { return 224 }
408
409 // Decode round-trip.
410 let dec_packed: *i64 = sys_mmap(16) as *i64
411 if ins_event_decode_hash(h_gt, dec_packed) != 2 { return 230 }
412 if dec_packed[0] != 0x0B { return 231 }
413 if ins_event_decode_hash(h_ga, dec_packed) != 2 { return 232 }
414 if dec_packed[0] != 0x08 { return 233 }
415 if ins_event_decode_hash(h_g, dec_packed) != 1 { return 234 }
416 if dec_packed[0] != 0x02 { return 235 }
417
418 // Bad input rejection.
419 if ins_event_to_hash(r_bs, -1, 2) != -1 { return 240 }
420 if ins_event_to_hash(r_bs, 0, 0) != -1 { return 241 }
421 if ins_event_to_hash(r_bs, 0, 29) != -1 { return 242 }
422
423 if ins_event_decode_hash(0, dec_packed) != -1 { return 250 } // length=0
424 if ins_event_decode_hash(99 << 56, dec_packed) != -1 { return 251 } // length=99 > 28
425
426 return 0
427}