multi_readers/_impl/
seek.rs1use crate::MultiReaders;
2
3use std::io::{Seek, SeekFrom};
4impl<T: Seek> MultiReaders<T> {
5 fn len(&mut self) -> std::io::Result<u64> {
6 if self.len == 0 {
7 for r in &mut self.inner {
8 self.len += r.len()?;
9 }
10 }
11 Ok(self.len)
12 }
13
14 fn position(&mut self) -> std::io::Result<u64> {
15 let mut pos = 0;
16 for item in &mut self.inner[..self.pos] {
17 pos += item.len()?;
18 }
19 pos += self.inner[self.pos].stream_position()?;
20 Ok(pos)
21 }
22}
23
24impl<T: Seek> Seek for MultiReaders<T> {
25 fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
26 if self.inner.len() == self.pos {
27 return Ok(0);
28 }
29 match pos {
30 SeekFrom::Start(s) => seek_start(self, s),
31 SeekFrom::End(e) => seek_end(self, e),
32 SeekFrom::Current(c) => seek_current(self, c),
33 }
34 }
35}
36
37fn seek_start<T: Seek>(r: &mut MultiReaders<T>, start: u64) -> std::io::Result<u64> {
38 let mut len = 0;
39 for i in 0..r.inner.len() {
40 let tmp = len;
41 len += r.inner[i].len()?;
42 if len >= start {
43 r.pos = i;
44 r.inner[i].seek(SeekFrom::Start(start - tmp))?;
45 for j in r.pos + 1..r.inner.len() {
46 r.inner[j].seek(SeekFrom::Start(0))?;
47 }
48 return Ok(start);
49 } else {
50 r.inner[i].seek(SeekFrom::End(0))?;
51 }
52 }
53 Ok(len)
54}
55
56fn seek_to_end<T: Seek>(r: &mut MultiReaders<T>) -> std::io::Result<u64> {
57 for item in &mut r.inner {
58 item.seek(SeekFrom::End(0))?;
59 }
60 r.len()
61}
62
63fn seek_end<T: Seek>(r: &mut MultiReaders<T>, end: i64) -> std::io::Result<u64> {
64 if end >= 0 {
65 seek_to_end(r)
66 } else {
67 let len = r.len()? as i64;
68 seek_start(r, (len + end) as _)
69 }
70}
71
72fn seek_current<T: Seek>(r: &mut MultiReaders<T>, current: i64) -> std::io::Result<u64> {
73 if current == 0 {
74 r.position()
75 } else {
76 let n = r.position()? as i64 + current;
77 let len = r.len()? as i64;
78 let n = n.max(0).min(len);
79 seek_start(r, n as u64)
80 }
81}