let raw_to_item () :
(raw_item, (Sam.item, _) Result.t) Biocaml_transform.t=
let name = "bam_item_parser" in
let raw_queue = Dequeue.create ~dummy:(`header "no") () 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.take_front_exn raw_queue 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.push_front raw_queue (`alignment a);
output_ok (`reference_sequence_dictionary !reference_information)
) else (
expand_alignment !reference_information a |! output_result
)
end
end
end
in
Biocaml_transform.make ~name ~feed:(Dequeue.push_back raw_queue) ()
~next