anni_flac/blocks/
seek_table.rs1use crate::error::FlacError;
2use crate::prelude::*;
3use crate::utils::*;
4use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
5use std::fmt;
6use std::io::{Read, Write};
7
8pub struct BlockSeekTable {
9 pub seek_points: Vec<SeekPoint>,
10}
11
12#[derive(Debug)]
18pub struct SeekPoint {
19 pub sample_number: u64,
21 pub stream_offset: u64,
23 pub frame_samples: u16,
25}
26
27impl SeekPoint {
28 pub fn is_placeholder(&self) -> bool {
29 self.sample_number == 0xFFFFFFFFFFFFFFFF
30 }
31}
32
33impl Decode for BlockSeekTable {
34 fn from_reader<R: Read>(reader: &mut R) -> Result<Self> {
35 let buf = take_to_end(reader)?;
36 let size = buf.len();
37 let mut reader = std::io::Cursor::new(buf);
38
39 let points = size / 18;
41 let remaining = size % 18;
42 if remaining != 0 {
43 return Err(FlacError::InvalidSeekTableSize);
44 }
45
46 let mut seek_points = Vec::with_capacity(points);
47 for _ in 0..points {
48 let sample_number = ReadBytesExt::read_u64::<BigEndian>(&mut reader)?;
49 let stream_offset = ReadBytesExt::read_u64::<BigEndian>(&mut reader)?;
50 let frame_samples = ReadBytesExt::read_u16::<BigEndian>(&mut reader)?;
51 seek_points.push(SeekPoint {
52 sample_number,
53 stream_offset,
54 frame_samples,
55 });
56 }
57
58 Ok(BlockSeekTable { seek_points })
59 }
60}
61
62#[cfg(feature = "async")]
63#[async_trait::async_trait]
64impl AsyncDecode for BlockSeekTable {
65 async fn from_async_reader<R>(reader: &mut R) -> Result<Self>
66 where
67 R: AsyncRead + Unpin + Send,
68 {
69 let buf = take_to_end_async(reader).await?;
70 let size = buf.len();
71 let mut reader = std::io::Cursor::new(buf);
72
73 let points = size / 18;
75 let remaining = size % 18;
76 if remaining != 0 {
77 return Err(FlacError::InvalidSeekTableSize);
78 }
79
80 let mut seek_points = Vec::with_capacity(points);
81 for _ in 0..points {
82 let sample_number = AsyncReadExt::read_u64(&mut reader).await?;
83 let stream_offset = AsyncReadExt::read_u64(&mut reader).await?;
84 let frame_samples = AsyncReadExt::read_u16(&mut reader).await?;
85 seek_points.push(SeekPoint {
86 sample_number,
87 stream_offset,
88 frame_samples,
89 });
90 }
91
92 Ok(BlockSeekTable { seek_points })
93 }
94}
95
96impl Encode for BlockSeekTable {
97 fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
98 for point in self.seek_points.iter() {
99 writer.write_u64::<BigEndian>(point.sample_number)?;
100 writer.write_u64::<BigEndian>(point.stream_offset)?;
101 writer.write_u16::<BigEndian>(point.frame_samples)?;
102 }
103 Ok(())
104 }
105}
106
107impl fmt::Debug for BlockSeekTable {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 let mut prefix = "".to_owned();
110 if let Some(width) = f.width() {
111 prefix = " ".repeat(width);
112 }
113 writeln!(
114 f,
115 "{prefix}seek points: {}",
116 self.seek_points.len(),
117 prefix = prefix
118 )?;
119 for (i, p) in self.seek_points.iter().enumerate() {
120 if p.is_placeholder() {
121 writeln!(f, "{prefix}point {}: PLACEHOLDER", i, prefix = prefix)?;
122 } else {
123 writeln!(
124 f,
125 "{prefix}point {}: sample_number={}, stream_offset={}, frame_samples={}",
126 i,
127 p.sample_number,
128 p.stream_offset,
129 p.frame_samples,
130 prefix = prefix
131 )?;
132 }
133 }
134 Ok(())
135 }
136}