code wiki / (root) / nx_pileup_test.nx

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}