Skip to content

Commit

Permalink
Removes Seek implementation from ClustersReader
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed Sep 28, 2024
1 parent 11c0274 commit d7dd811
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 44 deletions.
45 changes: 13 additions & 32 deletions src/cluster.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::disk::DiskPartition;
use crate::ExFat;
use std::cmp::min;
use std::io::{Seek, SeekFrom};
use std::sync::Arc;
use thiserror::Error;

Expand Down Expand Up @@ -73,6 +72,10 @@ impl<P: DiskPartition> ClustersReader<P> {
self.chain[(self.offset / self.exfat.params.cluster_size()) as usize]
}

pub fn data_length(&self) -> u64 {
self.data_length
}

pub fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
use std::io::{Error, ErrorKind};

Expand Down Expand Up @@ -123,44 +126,22 @@ impl<P: DiskPartition> ClustersReader<P> {

Ok(())
}
}

impl<P: DiskPartition> Seek for ClustersReader<P> {
fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
use std::io::{Error, ErrorKind};

self.offset = match pos {
SeekFrom::Start(v) => min(v, self.data_length),
SeekFrom::End(v) => {
if v >= 0 {
self.data_length
} else if let Some(v) = self.data_length.checked_sub(v.unsigned_abs()) {
v
} else {
return Err(Error::from(ErrorKind::InvalidInput));
}
}
SeekFrom::Current(v) => {
if v >= 0 {
min(self.offset + (v as u64), self.data_length)
} else if let Some(v) = self.offset.checked_sub(v.unsigned_abs()) {
v
} else {
return Err(Error::from(ErrorKind::InvalidInput));
}
}
};
pub fn seek(&mut self, off: u64) -> bool {
if off > self.data_length {
return false;
}

Ok(self.offset)
self.offset = off;
true
}

fn rewind(&mut self) -> std::io::Result<()> {
pub fn rewind(&mut self) {
self.offset = 0;
Ok(())
}

fn stream_position(&mut self) -> std::io::Result<u64> {
Ok(self.offset)
pub fn stream_position(&self) -> u64 {
self.offset
}
}

Expand Down
58 changes: 46 additions & 12 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::disk::DiskPartition;
use crate::entries::StreamEntry;
use crate::timestamp::Timestamps;
use crate::ExFat;
use core::cmp::min;
use std::io::{empty, Empty};
use std::io::{Read, Seek, SeekFrom};
use std::sync::Arc;
Expand Down Expand Up @@ -70,24 +71,57 @@ impl<P: DiskPartition> File<P> {

impl<P: DiskPartition> Seek for File<P> {
fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
match &mut self.reader {
Reader::Cluster(r) => r.seek(pos),
Reader::Empty(r) => r.seek(pos),
}
use std::io::{Error, ErrorKind};

// Check if empty file.
let r = match &mut self.reader {
Reader::Cluster(r) => r,
Reader::Empty(r) => return r.seek(pos),
};

// Get absolute offset.
let o = match pos {
SeekFrom::Start(v) => min(v, r.data_length()),
SeekFrom::End(v) => {
if v >= 0 {
r.data_length()
} else if let Some(v) = r.data_length().checked_sub(v.unsigned_abs()) {
v
} else {
return Err(Error::from(ErrorKind::InvalidInput));
}
}
SeekFrom::Current(v) => v.try_into().map_or_else(
|_| {
r.stream_position()
.checked_sub(v.unsigned_abs())
.ok_or_else(|| Error::from(ErrorKind::InvalidInput))
},
|v| Ok(min(r.stream_position().saturating_add(v), r.data_length())),
)?,
};

assert!(r.seek(o));

Ok(o)
}

fn rewind(&mut self) -> std::io::Result<()> {
match &mut self.reader {
Reader::Cluster(r) => r.rewind(),
Reader::Empty(r) => r.rewind(),
}
let r = match &mut self.reader {
Reader::Cluster(r) => r,
Reader::Empty(r) => return r.rewind(),
};

Ok(r.rewind())
}

fn stream_position(&mut self) -> std::io::Result<u64> {
match &mut self.reader {
Reader::Cluster(r) => r.stream_position(),
Reader::Empty(r) => r.stream_position(),
}
let r = match &mut self.reader {
Reader::Cluster(r) => r,
Reader::Empty(r) => return r.stream_position(),
};

Ok(r.stream_position())
}
}

Expand Down

0 comments on commit d7dd811

Please sign in to comment.