use std::fmt::Debug;
use std::ops::Range;
use async_trait::async_trait;
use bytes::Bytes;
use crate::error::AsyncTiffResult;
use crate::reader::{AsyncFileReader, EndianAwareReader, Endianness};
#[async_trait]
pub trait MetadataFetch: Debug + Send + Sync + 'static {
async fn fetch(&self, range: Range<u64>) -> AsyncTiffResult<Bytes>;
}
#[async_trait]
impl<T: AsyncFileReader> MetadataFetch for T {
async fn fetch(&self, range: Range<u64>) -> AsyncTiffResult<Bytes> {
self.get_bytes(range).await
}
}
pub(crate) struct MetadataCursor<'a, F: MetadataFetch> {
fetch: &'a F,
offset: u64,
endianness: Endianness,
}
impl<'a, F: MetadataFetch> MetadataCursor<'a, F> {
pub fn new(fetch: &'a F, endianness: Endianness) -> Self {
Self {
fetch,
offset: 0,
endianness,
}
}
pub fn new_with_offset(fetch: &'a F, endianness: Endianness, offset: u64) -> Self {
Self {
fetch,
offset,
endianness,
}
}
pub fn with_offset(mut self, offset: u64) -> Self {
self.offset = offset;
self
}
pub fn seek(&mut self, offset: u64) {
self.offset = offset;
}
pub(crate) fn advance(&mut self, amount: u64) {
self.offset += amount;
}
pub(crate) async fn read(&mut self, length: u64) -> AsyncTiffResult<EndianAwareReader> {
let range = self.offset as _..(self.offset + length) as _;
self.offset += length;
let bytes = self.fetch.fetch(range).await?;
Ok(EndianAwareReader::new(bytes, self.endianness))
}
pub(crate) async fn read_u8(&mut self) -> AsyncTiffResult<u8> {
self.read(1).await?.read_u8()
}
pub(crate) async fn read_i8(&mut self) -> AsyncTiffResult<i8> {
self.read(1).await?.read_i8()
}
pub(crate) async fn read_u16(&mut self) -> AsyncTiffResult<u16> {
self.read(2).await?.read_u16()
}
pub(crate) async fn read_i16(&mut self) -> AsyncTiffResult<i16> {
self.read(2).await?.read_i16()
}
pub(crate) async fn read_u32(&mut self) -> AsyncTiffResult<u32> {
self.read(4).await?.read_u32()
}
pub(crate) async fn read_i32(&mut self) -> AsyncTiffResult<i32> {
self.read(4).await?.read_i32()
}
pub(crate) async fn read_u64(&mut self) -> AsyncTiffResult<u64> {
self.read(8).await?.read_u64()
}
pub(crate) async fn read_i64(&mut self) -> AsyncTiffResult<i64> {
self.read(8).await?.read_i64()
}
pub(crate) async fn read_f32(&mut self) -> AsyncTiffResult<f32> {
self.read(4).await?.read_f32()
}
pub(crate) async fn read_f64(&mut self) -> AsyncTiffResult<f64> {
self.read(8).await?.read_f64()
}
}