noodles_cram/io/reader/
container.rs1mod block;
2pub mod compression_header;
3pub mod header;
4pub mod slice;
5
6use std::{
7 io::{self, Read},
8 iter,
9};
10
11use self::{block::read_block_as, header::read_header};
12pub use self::{compression_header::read_compression_header, slice::read_slice, slice::Slice};
13use crate::container::{CompressionHeader, Header};
14
15#[derive(Default)]
17pub struct Container {
18 pub(crate) header: Header,
19 pub(crate) src: Vec<u8>,
20}
21
22impl Container {
23 pub fn header(&self) -> &Header {
25 &self.header
26 }
27
28 pub fn compression_header(&self) -> io::Result<CompressionHeader> {
30 let end = self
31 .header
32 .landmarks
33 .first()
34 .copied()
35 .unwrap_or(self.src.len());
36
37 let mut src = &self.src[..end];
38
39 read_compression_header(&mut src)
40 }
41
42 pub fn slices(&self) -> impl Iterator<Item = io::Result<Slice<'_>>> + '_ {
44 let landmarks = &self.header.landmarks;
45 let mut i = 0;
46
47 iter::from_fn(move || {
48 if i < landmarks.len() - 1 {
49 let (start, end) = (landmarks[i], landmarks[i + 1]);
50 i += 1;
51 let mut src = &self.src[start..end];
52 Some(read_slice(&mut src))
53 } else if i < landmarks.len() {
54 let start = landmarks[i];
55 i += 1;
56 let mut src = &self.src[start..];
57 Some(read_slice(&mut src))
58 } else {
59 None
60 }
61 })
62 }
63}
64
65pub fn read_container<R>(reader: &mut R, container: &mut Container) -> io::Result<usize>
66where
67 R: Read,
68{
69 match read_header(reader, &mut container.header)? {
70 0 => Ok(0),
71 len => {
72 container.src.resize(len, 0);
73 reader.read_exact(&mut container.src)?;
74 Ok(len)
75 }
76 }
77}