let parse_cigar ?(pos=0) ?len buf =
let len =
match len with Some s -> s | None -> String.length buf in
begin match len mod 4 with
| 0 -> return (len / 4)
| n -> fail (`wrong_cigar_length len)
end
>>= fun n_cigar_op ->
begin
try
return (Array.init n_cigar_op (fun i ->
let open Int64 in
let int64 =
let int8 pos =
Binary_packing.unpack_unsigned_8 ~buf ~pos |! Int64.of_int in
int8 Int.(pos + i * 4)
+ shift_left (int8 Int.(pos + i * 4 + 1)) 8
+ shift_left (int8 Int.(pos + i * 4 + 2)) 16
+ shift_left (int8 Int.(pos + i * 4 + 3)) 24
in
let op_len = shift_right int64 4 |! Int64.to_int_exn in
let op =
match bit_and int64 0x0fL with
| 0L -> `M op_len
| 1L -> `I op_len
| 2L -> `D op_len
| 3L -> `N op_len
| 4L -> `S op_len
| 5L -> `H op_len
| 6L -> `P op_len
| 7L -> `Eq op_len
| 8L -> `X op_len
| any -> failwithf "OP:%Ld" any () in
op))
with
| e ->
fail (`wrong_cigar
String.(sub buf pos (pos + n_cigar_op * 4)))
end