core2/io/cursor.rs
1use super::{BufRead, Error, ErrorKind, Read, Result, Seek, SeekFrom, Write};
2use core::cmp;
3
4/// A `Cursor` wraps an in-memory buffer and provides it with a
5/// [`Seek`] implementation.
6///
7/// `Cursor`s are used with in-memory buffers, anything implementing
8/// [`AsRef`]`<[u8]>`, to allow them to implement [`Read`] and/or [`Write`],
9/// allowing these buffers to be used anywhere you might use a reader or writer
10/// that does actual I/O.
11///
12/// The standard library implements some I/O traits on various types which
13/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
14/// `Cursor<`[`&[u8]`][bytes]`>`.
15///
16/// # Examples
17///
18/// We may want to write bytes to a [`File`] in our production
19/// code, but use an in-memory buffer in our tests. We can do this with
20/// `Cursor`:
21///
22/// [bytes]: crate::slice
23/// [`File`]: crate::fs::File
24///
25/// ```
26/// use std::io::prelude::*;
27/// use core2::io::{self, Seek, SeekFrom, Write};
28/// use std::fs::File;
29///
30/// // a library function we've written
31/// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> {
32/// writer.seek(SeekFrom::End(-10))?;
33///
34/// for i in 0..10 {
35/// writer.write(&[i])?;
36/// }
37///
38/// // all went well
39/// Ok(())
40/// }
41///
42/// # #[cfg(feature = "std")]
43/// # fn foo() -> io::Result<()> {
44/// // Here's some code that uses this library function.
45/// //
46/// // We might want to use a BufReader here for efficiency, but let's
47/// // keep this example focused.
48/// let mut file = File::create("foo.txt").map_err(|e| io::Error::from(e))?;
49///
50/// write_ten_bytes_at_end(&mut file)?;
51/// # Ok(())
52/// # }
53///
54/// // now let's write a test
55/// #[test]
56/// fn test_writes_bytes() {
57/// // setting up a real File is much slower than an in-memory buffer,
58/// // let's use a cursor instead
59/// use core2::io::Cursor;
60/// let mut buff = Cursor::new(vec![0; 15]);
61///
62/// write_ten_bytes_at_end(&mut buff).unwrap();
63///
64/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
65/// }
66/// ```
67#[derive(Clone, Debug, Default, Eq, PartialEq)]
68pub struct Cursor<T> {
69 inner: T,
70 pos: u64,
71}
72
73impl<T> Cursor<T> {
74 /// Creates a new cursor wrapping the provided underlying in-memory buffer.
75 ///
76 /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`])
77 /// is not empty. So writing to cursor starts with overwriting [`Vec`]
78 /// content, not with appending to it.
79 ///
80 /// # Examples
81 ///
82 /// ```
83 /// use core2::io::Cursor;
84 ///
85 /// let buff = Cursor::new(Vec::new());
86 /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
87 /// # force_inference(&buff);
88 /// ```
89 pub fn new(inner: T) -> Cursor<T> {
90 Cursor { pos: 0, inner }
91 }
92
93 /// Consumes this cursor, returning the underlying value.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use core2::io::Cursor;
99 ///
100 /// let buff = Cursor::new(Vec::new());
101 /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
102 /// # force_inference(&buff);
103 ///
104 /// let vec = buff.into_inner();
105 /// ```
106 pub fn into_inner(self) -> T {
107 self.inner
108 }
109
110 /// Gets a reference to the underlying value in this cursor.
111 ///
112 /// # Examples
113 ///
114 /// ```
115 /// use core2::io::Cursor;
116 ///
117 /// let buff = Cursor::new(Vec::new());
118 /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
119 /// # force_inference(&buff);
120 ///
121 /// let reference = buff.get_ref();
122 /// ```
123 pub fn get_ref(&self) -> &T {
124 &self.inner
125 }
126
127 /// Gets a mutable reference to the underlying value in this cursor.
128 ///
129 /// Care should be taken to avoid modifying the internal I/O state of the
130 /// underlying value as it may corrupt this cursor's position.
131 ///
132 /// # Examples
133 ///
134 /// ```
135 /// use core2::io::Cursor;
136 ///
137 /// let mut buff = Cursor::new(Vec::new());
138 /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
139 /// # force_inference(&buff);
140 ///
141 /// let reference = buff.get_mut();
142 /// ```
143 pub fn get_mut(&mut self) -> &mut T {
144 &mut self.inner
145 }
146
147 /// Returns the current position of this cursor.
148 ///
149 /// # Examples
150 ///
151 /// ```
152 /// use core2::io::{Cursor, Seek, SeekFrom};
153 /// use std::io::prelude::*;
154 ///
155 /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
156 ///
157 /// assert_eq!(buff.position(), 0);
158 ///
159 /// buff.seek(SeekFrom::Current(2)).unwrap();
160 /// assert_eq!(buff.position(), 2);
161 ///
162 /// buff.seek(SeekFrom::Current(-1)).unwrap();
163 /// assert_eq!(buff.position(), 1);
164 /// ```
165 pub fn position(&self) -> u64 {
166 self.pos
167 }
168
169 /// Sets the position of this cursor.
170 ///
171 /// # Examples
172 ///
173 /// ```
174 /// use core2::io::Cursor;
175 ///
176 /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
177 ///
178 /// assert_eq!(buff.position(), 0);
179 ///
180 /// buff.set_position(2);
181 /// assert_eq!(buff.position(), 2);
182 ///
183 /// buff.set_position(4);
184 /// assert_eq!(buff.position(), 4);
185 /// ```
186 pub fn set_position(&mut self, pos: u64) {
187 self.pos = pos;
188 }
189}
190
191impl<T> Seek for Cursor<T>
192where
193 T: AsRef<[u8]>,
194{
195 fn seek(&mut self, style: SeekFrom) -> Result<u64> {
196 let (base_pos, offset) = match style {
197 SeekFrom::Start(n) => {
198 self.pos = n;
199 return Ok(n);
200 }
201 SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
202 SeekFrom::Current(n) => (self.pos, n),
203 };
204 let new_pos = if offset >= 0 {
205 base_pos.checked_add(offset as u64)
206 } else {
207 base_pos.checked_sub((offset.wrapping_neg()) as u64)
208 };
209 match new_pos {
210 Some(n) => {
211 self.pos = n;
212 Ok(self.pos)
213 }
214 None => Err(Error::new(
215 ErrorKind::InvalidInput,
216 "invalid seek to a negative or overflowing position",
217 )),
218 }
219 }
220}
221
222impl<T> Read for Cursor<T>
223where
224 T: AsRef<[u8]>,
225{
226 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
227 let n = Read::read(&mut self.fill_buf()?, buf)?;
228 self.pos += n as u64;
229 Ok(n)
230 }
231
232 fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
233 let n = buf.len();
234 Read::read_exact(&mut self.fill_buf()?, buf)?;
235 self.pos += n as u64;
236 Ok(())
237 }
238}
239
240impl<T> BufRead for Cursor<T>
241where
242 T: AsRef<[u8]>,
243{
244 fn fill_buf(&mut self) -> Result<&[u8]> {
245 let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
246 Ok(&self.inner.as_ref()[(amt as usize)..])
247 }
248 fn consume(&mut self, amt: usize) {
249 self.pos += amt as u64;
250 }
251}
252
253// Non-resizing write implementation
254#[inline]
255fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result<usize> {
256 let pos = cmp::min(*pos_mut, slice.len() as u64);
257 let amt = (&mut slice[(pos as usize)..]).write(buf)?;
258 *pos_mut += amt as u64;
259 Ok(amt)
260}
261
262impl Write for Cursor<&mut [u8]> {
263 #[inline]
264 fn write(&mut self, buf: &[u8]) -> Result<usize> {
265 slice_write(&mut self.pos, self.inner, buf)
266 }
267
268 #[inline]
269 fn flush(&mut self) -> Result<()> {
270 Ok(())
271 }
272}