hff_async_std/read/
async_std_reader.rs1use super::ReadSeek;
2use async_std::{
3 io::{prelude::SeekExt, ReadExt},
4 sync::{Mutex, MutexGuard},
5};
6use hff_core::{
7 byteorder::ReadBytesExt, ByteOrder, Chunk, ChunkCache, ContentInfo, Ecc, Endian, Error, Header,
8 Result, Table, Version, BE, LE,
9};
10use std::mem::size_of;
11
12pub struct AsyncStdReader {
14 source: Mutex<Box<dyn ReadSeek>>,
15}
16
17impl std::fmt::Debug for AsyncStdReader {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 write!(f, "AsyncStdReader")
20 }
21}
22
23impl AsyncStdReader {
24 pub fn new(source: impl ReadSeek + 'static) -> Self {
26 Self {
27 source: Mutex::new(Box::new(source)),
28 }
29 }
30
31 pub async fn read(&self, content: &dyn ContentInfo) -> Result<Vec<u8>> {
33 let mut source = self.source.lock().await;
34 source
35 .seek(std::io::SeekFrom::Start(content.offset()))
36 .await?;
37 let mut result = vec![0; content.len() as usize];
38 source.read_exact(result.as_mut_slice()).await?;
39 Ok(result)
40 }
41
42 pub async fn reader(
44 &self,
45 content: impl ContentInfo,
46 ) -> Result<MutexGuard<'_, Box<dyn ReadSeek>>> {
47 let mut source = self.source.lock().await;
48 source
49 .seek(std::io::SeekFrom::Start(content.offset()))
50 .await?;
51 Ok(source)
52 }
53
54 pub(super) async fn read_header(
56 reader: &mut (dyn async_std::io::Read + std::marker::Unpin),
57 ) -> Result<Header> {
58 let mut header = [0_u8; Header::SIZE];
60 reader.read_exact(&mut header).await?;
61
62 let reader: &mut dyn std::io::Read = &mut header.as_slice();
64
65 let magic = reader.read_u64::<LE>()?;
67
68 match Ecc::HFF_MAGIC.endian(magic.into()) {
73 Some(endian) => match endian {
74 Endian::Little => Ok(Header::with(
75 magic.into(),
76 Version::read::<LE>(reader)?,
77 reader.read_u32::<LE>()?,
78 Ecc::read::<LE>(reader)?,
79 reader.read_u32::<LE>()?,
80 reader.read_u32::<LE>()?,
81 )),
82 Endian::Big => Ok(Header::with(
83 magic.into(),
84 Version::read::<BE>(reader)?,
85 reader.read_u32::<BE>()?,
86 Ecc::read::<BE>(reader)?,
87 reader.read_u32::<BE>()?,
88 reader.read_u32::<BE>()?,
89 )),
90 },
91 None => Err(Error::Invalid("Not an HFF file.".into())),
92 }
93 }
94
95 pub(super) async fn read_tables<E: ByteOrder>(
97 reader: &mut (dyn async_std::io::Read + std::marker::Unpin),
98 count: u32,
99 ) -> Result<Vec<Table>> {
100 if count > 0 {
101 let mut buffer = vec![0; count as usize * std::mem::size_of::<Table>()];
103 reader.read_exact(&mut buffer.as_mut_slice()).await?;
104
105 let mut tables = vec![];
107 let reader: &mut dyn std::io::Read = &mut buffer.as_slice();
108 for _ in 0..count {
109 let table = Table::read::<E>(reader)?;
110 tables.push(table);
111 }
112
113 Ok(tables)
114 } else {
115 Ok(vec![])
117 }
118 }
119
120 pub(super) async fn read_chunks<E: ByteOrder>(
122 reader: &mut (dyn async_std::io::Read + std::marker::Unpin),
123 count: u32,
124 ) -> Result<Vec<Chunk>> {
125 if count > 0 {
126 let mut buffer = vec![0; count as usize * std::mem::size_of::<Chunk>()];
128 reader.read_exact(&mut buffer.as_mut_slice()).await?;
129
130 let mut chunks = vec![];
132 let reader: &mut dyn std::io::Read = &mut buffer.as_slice();
133 for _ in 0..count {
134 let chunk = Chunk::read::<E>(reader)?;
135 chunks.push(chunk);
136 }
137 Ok(chunks)
138 } else {
139 Ok(vec![])
142 }
143 }
144
145 pub(super) async fn read_body(
148 reader: &mut (dyn async_std::io::Read + std::marker::Unpin),
149 tables: usize,
150 chunks: usize,
151 ) -> Result<ChunkCache> {
152 let mut buffer = vec![];
153 reader.read_to_end(&mut buffer).await?;
154
155 let offset = Header::SIZE + size_of::<Table>() * tables + size_of::<Chunk>() * chunks;
156 Ok(ChunkCache::new(offset, buffer))
157 }
158}