let raw_to_item () :
(raw_item, (Sam.item, _) Result.t) Biocaml_transform.t=
let name = "bam_item_parser" in
let raw_queue = Dequeue.create () in
let raw_items_count = ref 0 in
let header_items = ref [] in
let reference_information = ref [| |] in
let first_alignment = ref true in
let rec next stopped =
dbg "header_items: %d raw_queue: %d raw_items_count: %d"
(List.length !header_items) (Dequeue.length raw_queue) !raw_items_count;
begin match !header_items with
| h :: t -> header_items := t; `output (Ok h)
| [] ->
begin match Dequeue.is_empty raw_queue, stopped with
| true, true ->`end_of_stream
| true, false -> `not_ready
| false, _ ->
incr raw_items_count;
begin match Dequeue.dequeue_exn raw_queue `front with
| `header s ->
begin match parse_sam_header s with
| Ok h -> header_items := h; next stopped
| Error e -> `output (Error e)
end
| `reference_information ri ->
let make_ref_info (s, i) = Sam.reference_sequence s i in
reference_information := Array.map ri ~f:make_ref_info;
next stopped
| `alignment a ->
if !first_alignment then (
first_alignment := false;
Dequeue.enqueue raw_queue `front (`alignment a);
`output (Ok (`reference_sequence_dictionary !reference_information))
) else (
expand_alignment !reference_information a |> (fun x -> `output x)
)
end
end
end
in
Biocaml_transform.make ~name ~feed:(Dequeue.enqueue raw_queue `back) ()
~next