/rust/registry/src/index.crates.io-1949cf8c6b5b557f/exr-1.74.0/src/io.rs
Line | Count | Source |
1 | | |
2 | | //! Specialized binary input and output. |
3 | | //! Uses the error handling for this crate. |
4 | | |
5 | | #![doc(hidden)] |
6 | | pub use ::std::io::{Read, Write}; |
7 | | |
8 | | use half::slice::{HalfFloatSliceExt}; |
9 | | use lebe::prelude::*; |
10 | | use ::half::f16; |
11 | | use crate::error::{Error, Result, UnitResult, IoResult}; |
12 | | use std::io::{Seek, SeekFrom}; |
13 | | use std::path::Path; |
14 | | use std::fs::File; |
15 | | use std::convert::TryFrom; |
16 | | use smallvec::{Array, SmallVec}; |
17 | | |
18 | | /// Skip reading uninteresting bytes without allocating. |
19 | | #[inline] |
20 | 0 | pub fn skip_bytes(read: &mut impl Read, count: usize) -> IoResult<()> { |
21 | 0 | let count = u64::try_from(count).unwrap(); |
22 | | |
23 | 0 | let skipped = std::io::copy( |
24 | 0 | &mut read.by_ref().take(count), |
25 | 0 | &mut std::io::sink() |
26 | 0 | )?; |
27 | | |
28 | | // the reader may have ended before we skipped the desired number of bytes |
29 | 0 | if skipped < count { |
30 | 0 | return Err(std::io::Error::new( |
31 | 0 | std::io::ErrorKind::UnexpectedEof, |
32 | 0 | "cannot skip more bytes than exist" |
33 | 0 | )); |
34 | 0 | } |
35 | | |
36 | 0 | debug_assert_eq!(skipped, count, "skip bytes bug"); |
37 | 0 | Ok(()) |
38 | 0 | } Unexecuted instantiation: exr::io::skip_bytes::<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>> Unexecuted instantiation: exr::io::skip_bytes::<_> Unexecuted instantiation: exr::io::skip_bytes::<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> |
39 | | |
40 | | /// If an error occurs while writing, attempts to delete the partially written file. |
41 | | /// Creates a file just before the first write operation, not when this function is called. |
42 | | #[inline] |
43 | 0 | pub fn attempt_delete_file_on_write_error<'p>(path: &'p Path, write: impl FnOnce(LateFile<'p>) -> UnitResult) -> UnitResult { |
44 | 0 | match write(LateFile::from(path)) { |
45 | 0 | Err(error) => { // FIXME deletes existing file if creation of new file fails? |
46 | 0 | let _deleted = std::fs::remove_file(path); // ignore deletion errors |
47 | 0 | Err(error) |
48 | | }, |
49 | | |
50 | 0 | ok => ok, |
51 | | } |
52 | 0 | } |
53 | | |
54 | | #[derive(Debug)] |
55 | | pub struct LateFile<'p> { |
56 | | path: &'p Path, |
57 | | file: Option<File> |
58 | | } |
59 | | |
60 | | impl<'p> From<&'p Path> for LateFile<'p> { |
61 | 0 | fn from(path: &'p Path) -> Self { Self { path, file: None } } |
62 | | } |
63 | | |
64 | | impl<'p> LateFile<'p> { |
65 | 0 | fn file(&mut self) -> std::io::Result<&mut File> { |
66 | 0 | if self.file.is_none() { self.file = Some(File::create(self.path)?); } |
67 | 0 | Ok(self.file.as_mut().unwrap()) // will not be reached if creation fails |
68 | 0 | } |
69 | | } |
70 | | |
71 | | impl<'p> std::io::Write for LateFile<'p> { |
72 | 0 | fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> { |
73 | 0 | self.file()?.write(buffer) |
74 | 0 | } |
75 | | |
76 | 0 | fn flush(&mut self) -> std::io::Result<()> { |
77 | 0 | if let Some(file) = &mut self.file { file.flush() } |
78 | 0 | else { Ok(()) } |
79 | 0 | } |
80 | | } |
81 | | |
82 | | impl<'p> Seek for LateFile<'p> { |
83 | 0 | fn seek(&mut self, position: SeekFrom) -> std::io::Result<u64> { |
84 | 0 | self.file()?.seek(position) |
85 | 0 | } |
86 | | } |
87 | | |
88 | | |
89 | | /// Peek a single byte without consuming it. |
90 | | #[derive(Debug)] |
91 | | pub struct PeekRead<T> { |
92 | | |
93 | | /// Cannot be exposed as it will not contain peeked values anymore. |
94 | | inner: T, |
95 | | |
96 | | peeked: Option<IoResult<u8>>, |
97 | | } |
98 | | |
99 | | impl<T: Read> PeekRead<T> { |
100 | | |
101 | | /// Wrap a reader to make it peekable. |
102 | | #[inline] |
103 | 0 | pub fn new(inner: T) -> Self { |
104 | 0 | Self { inner, peeked: None } |
105 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::new Unexecuted instantiation: <exr::io::PeekRead<&[u8]>>::new Unexecuted instantiation: <exr::io::PeekRead<_>>::new Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::new |
106 | | |
107 | | /// Read a single byte and return that without consuming it. |
108 | | /// The next `read` call will include that byte. |
109 | | #[inline] |
110 | 0 | pub fn peek_u8(&mut self) -> &IoResult<u8> { |
111 | 0 | self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner))); Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::peek_u8::{closure#0}Unexecuted instantiation: <exr::io::PeekRead<&[u8]>>::peek_u8::{closure#0}Unexecuted instantiation: <exr::io::PeekRead<_>>::peek_u8::{closure#0}Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::peek_u8::{closure#0} |
112 | 0 | self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it |
113 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::peek_u8 Unexecuted instantiation: <exr::io::PeekRead<&[u8]>>::peek_u8 Unexecuted instantiation: <exr::io::PeekRead<_>>::peek_u8 Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::peek_u8 |
114 | | |
115 | | /// Skip a single byte if it equals the specified value. |
116 | | /// Returns whether the value was found. |
117 | | /// Consumes the peeked result if an error occurred. |
118 | | #[inline] |
119 | 0 | pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> { |
120 | 0 | match self.peek_u8() { |
121 | 0 | Ok(peeked) if *peeked == value => { |
122 | 0 | self.peeked = None; // consume the byte |
123 | 0 | Ok(true) |
124 | | }, |
125 | | |
126 | 0 | Ok(_) => Ok(false), |
127 | | |
128 | | // return the error otherwise. |
129 | | // unwrap is safe because this branch cannot be reached otherwise. |
130 | | // we need to take() from self because io errors cannot be cloned. |
131 | 0 | Err(_) => Err(self.peeked.take().unwrap().err().unwrap()) |
132 | | } |
133 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_if_eq Unexecuted instantiation: <exr::io::PeekRead<&[u8]>>::skip_if_eq Unexecuted instantiation: <exr::io::PeekRead<_>>::skip_if_eq Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::skip_if_eq |
134 | | } |
135 | | |
136 | | |
137 | | impl<T: Read> Read for PeekRead<T> { |
138 | 0 | fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> { |
139 | 0 | if target_buffer.is_empty() { |
140 | 0 | return Ok(0) |
141 | 0 | } |
142 | | |
143 | 0 | match self.peeked.take() { |
144 | 0 | None => self.inner.read(target_buffer), |
145 | 0 | Some(peeked) => { |
146 | 0 | target_buffer[0] = peeked?; |
147 | | |
148 | | // indexing [1..] is safe because an empty buffer already returned ok |
149 | 0 | Ok(1 + self.inner.read(&mut target_buffer[1..])?) |
150 | | } |
151 | | } |
152 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>> as std::io::Read>::read Unexecuted instantiation: <exr::io::PeekRead<&[u8]> as std::io::Read>::read Unexecuted instantiation: <exr::io::PeekRead<_> as std::io::Read>::read Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> as std::io::Read>::read |
153 | | } |
154 | | |
155 | | impl<T: Read + Seek> PeekRead<Tracking<T>> { |
156 | | |
157 | | /// Seek this read to the specified byte position. |
158 | | /// Discards any previously peeked value. |
159 | 0 | pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> { |
160 | 0 | self.inner.seek_read_to(position)?; |
161 | 0 | self.peeked = None; |
162 | 0 | Ok(()) |
163 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_to Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<_>>>::skip_to Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::skip_to |
164 | | } |
165 | | |
166 | | impl<T: Read> PeekRead<Tracking<T>> { |
167 | | |
168 | | /// Current number of bytes read. |
169 | 0 | pub fn byte_position(&self) -> usize { |
170 | 0 | self.inner.byte_position() |
171 | 0 | } Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::byte_position Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<_>>>::byte_position Unexecuted instantiation: <exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::byte_position |
172 | | } |
173 | | |
174 | | /// Keep track of what byte we are at. |
175 | | /// Used to skip back to a previous place after writing some information. |
176 | | #[derive(Debug)] |
177 | | pub struct Tracking<T> { |
178 | | |
179 | | /// Do not expose to prevent seeking without updating position |
180 | | inner: T, |
181 | | |
182 | | position: usize, |
183 | | } |
184 | | |
185 | | impl<T: Read> Read for Tracking<T> { |
186 | 0 | fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> { |
187 | 0 | let count = self.inner.read(buffer)?; |
188 | 0 | self.position += count; |
189 | 0 | Ok(count) |
190 | 0 | } Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read Unexecuted instantiation: <exr::io::Tracking<_> as std::io::Read>::read Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>> as std::io::Read>::read |
191 | | } |
192 | | |
193 | | impl<T: Write> Write for Tracking<T> { |
194 | 0 | fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> { |
195 | 0 | let count = self.inner.write(buffer)?; |
196 | 0 | self.position += count; |
197 | 0 | Ok(count) |
198 | 0 | } Unexecuted instantiation: <exr::io::Tracking<_> as std::io::Write>::write Unexecuted instantiation: <exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>> as std::io::Write>::write Unexecuted instantiation: <exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>> as std::io::Write>::write |
199 | | |
200 | 0 | fn flush(&mut self) -> std::io::Result<()> { |
201 | 0 | self.inner.flush() |
202 | 0 | } Unexecuted instantiation: <exr::io::Tracking<_> as std::io::Write>::flush Unexecuted instantiation: <exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>> as std::io::Write>::flush Unexecuted instantiation: <exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>> as std::io::Write>::flush |
203 | | } |
204 | | |
205 | | impl<T> Tracking<T> { |
206 | | |
207 | | /// If `inner` is a reference, if must never be seeked directly, |
208 | | /// but only through this `Tracking` instance. |
209 | 0 | pub fn new(inner: T) -> Self { |
210 | 0 | Tracking { inner, position: 0 } |
211 | 0 | } Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::new Unexecuted instantiation: <exr::io::Tracking<_>>::new Unexecuted instantiation: <exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new Unexecuted instantiation: <exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>::new |
212 | | |
213 | | /// Current number of bytes written or read. |
214 | 0 | pub fn byte_position(&self) -> usize { |
215 | 0 | self.position |
216 | 0 | } Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::byte_position Unexecuted instantiation: <exr::io::Tracking<_>>::byte_position Unexecuted instantiation: <exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::byte_position Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::byte_position Unexecuted instantiation: <exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>::byte_position |
217 | | } |
218 | | |
219 | | impl<T: Read + Seek> Tracking<T> { |
220 | | |
221 | | /// Set the reader to the specified byte position. |
222 | | /// If it is only a couple of bytes, no seek system call is performed. |
223 | 0 | pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> { |
224 | 0 | let delta = target_position as i128 - self.position as i128; // FIXME panicked at 'attempt to subtract with overflow' |
225 | 0 | debug_assert!(delta.abs() < usize::MAX as i128); |
226 | | |
227 | 0 | if delta > 0 && delta < 16 { // TODO profile that this is indeed faster than a syscall! (should be because of bufread buffer discard) |
228 | 0 | skip_bytes(self, delta as usize)?; |
229 | 0 | self.position += delta as usize; |
230 | | } |
231 | 0 | else if delta != 0 { |
232 | 0 | self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?; |
233 | 0 | self.position = target_position; |
234 | 0 | } |
235 | | |
236 | 0 | Ok(()) |
237 | 0 | } Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::seek_read_to Unexecuted instantiation: <exr::io::Tracking<_>>::seek_read_to Unexecuted instantiation: <exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::seek_read_to |
238 | | } |
239 | | |
240 | | impl<T: Write + Seek> Tracking<T> { |
241 | | |
242 | | /// Move the writing cursor to the specified target byte index. |
243 | | /// If seeking forward, this will write zeroes. |
244 | 0 | pub fn seek_write_to(&mut self, target_position: usize) -> std::io::Result<()> { |
245 | 0 | if target_position < self.position { |
246 | 0 | self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?; |
247 | | } |
248 | 0 | else if target_position > self.position { |
249 | 0 | std::io::copy( |
250 | 0 | &mut std::io::repeat(0).take(u64::try_from(target_position - self.position).unwrap()), |
251 | 0 | self |
252 | 0 | )?; |
253 | 0 | } |
254 | | |
255 | 0 | self.position = target_position; |
256 | 0 | Ok(()) |
257 | 0 | } Unexecuted instantiation: <exr::io::Tracking<_>>::seek_write_to Unexecuted instantiation: <exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::seek_write_to Unexecuted instantiation: <exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>::seek_write_to |
258 | | } |
259 | | |
260 | | |
261 | | /// Generic trait that defines common binary operations such as reading and writing for this type. |
262 | | pub trait Data: Sized + Default + Clone { |
263 | | |
264 | | /// Number of bytes this would consume in an exr file. |
265 | | const BYTE_SIZE: usize = ::std::mem::size_of::<Self>(); |
266 | | |
267 | | /// Read a value of type `Self` from a little-endian source. |
268 | | fn read_le(read: &mut impl Read) -> Result<Self>; |
269 | | |
270 | | /// Read a value of type `Self` from a **native-endian** source (no conversion). |
271 | | fn read_ne(read: &mut impl Read) -> Result<Self>; |
272 | | |
273 | | /// Read as many values of type `Self` as fit into the specified slice, from a little-endian source. |
274 | | /// If the slice cannot be filled completely, returns `Error::Invalid`. |
275 | | fn read_slice_le(read: &mut impl Read, slice: &mut[Self]) -> UnitResult; |
276 | | |
277 | | /// Read as many values of type `Self` as fit into the specified slice, from a **native-endian** source (no conversion). |
278 | | /// If the slice cannot be filled completely, returns `Error::Invalid`. |
279 | | fn read_slice_ne(read: &mut impl Read, slice: &mut[Self]) -> UnitResult; |
280 | | |
281 | | /// Read as many values of type `Self` as specified with `data_size`. |
282 | | /// |
283 | | /// This method will not allocate more memory than `soft_max` at once. |
284 | | /// If `hard_max` is specified, it will never read any more than that. |
285 | | /// Returns `Error::Invalid` if the reader does not contain the desired number of elements. |
286 | | /// Reads from little-endian byte source. |
287 | | #[inline] |
288 | 0 | fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) |
289 | 0 | -> Result<Vec<Self>> |
290 | | { |
291 | 0 | if let Some(max) = hard_max { |
292 | 0 | if data_size > max { |
293 | 0 | return Err(Error::invalid(purpose)) |
294 | 0 | } |
295 | 0 | } |
296 | | |
297 | 0 | let mut vec = Vec::with_capacity(data_size.min(soft_max)); |
298 | 0 | Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?; |
299 | 0 | Ok(vec) |
300 | 0 | } Unexecuted instantiation: <i8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <i8 as exr::io::Data>::read_vec_le::<&[u8]> Unexecuted instantiation: <u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<&[u8]>> Unexecuted instantiation: <u8 as exr::io::Data>::read_vec_le::<&[u8]> Unexecuted instantiation: <u64 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <_ as exr::io::Data>::read_vec_le::<_> Unexecuted instantiation: <i8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <u64 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> |
301 | | |
302 | | /// Write this value to the writer, converting to little-endian format. |
303 | | fn write_le(self, write: &mut impl Write) -> UnitResult; |
304 | | |
305 | | /// Write this value to the writer, in **native-endian** format (no conversion). |
306 | | fn write_ne(self, write: &mut impl Write) -> UnitResult; |
307 | | |
308 | | /// Write all values of that slice to the writer, converting to little-endian format. |
309 | | fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> UnitResult; |
310 | | |
311 | | /// Write all values of that slice to the writer, in **native-endian** format (no conversion). |
312 | | fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> UnitResult; |
313 | | |
314 | | |
315 | | /// Read as many values of type `Self` as specified with `data_size` into the provided vector. |
316 | | /// |
317 | | /// This method will not allocate more memory than `soft_max` at once. |
318 | | /// If `hard_max` is specified, it will never read any more than that. |
319 | | /// Returns `Error::Invalid` if reader does not contain the desired number of elements. |
320 | | #[inline] |
321 | 0 | fn read_into_vec_le( |
322 | 0 | read: &mut impl Read, |
323 | 0 | data: &mut impl ResizableVec<Self>, |
324 | 0 | data_size: usize, soft_max: usize, hard_max: Option<usize>, |
325 | 0 | purpose: &'static str |
326 | 0 | ) -> UnitResult { |
327 | 0 | if let Some(max) = hard_max { |
328 | 0 | if data_size > max { |
329 | 0 | return Err(Error::invalid(purpose)) |
330 | 0 | } |
331 | 0 | } |
332 | | |
333 | 0 | let soft_max = hard_max.unwrap_or(soft_max).min(soft_max); |
334 | 0 | let end = data.len() + data_size; |
335 | | |
336 | | // do not allocate more than $chunks memory at once |
337 | | // (most of the time, this loop will run only once) |
338 | 0 | while data.len() < end { |
339 | 0 | let chunk_start = data.len(); |
340 | 0 | let chunk_end = (chunk_start + soft_max).min(data_size); |
341 | | |
342 | 0 | data.resize(chunk_end, Self::default()); |
343 | 0 | Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)` |
344 | | } |
345 | | |
346 | 0 | Ok(()) |
347 | 0 | } Unexecuted instantiation: <i8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>, alloc::vec::Vec<i8>> Unexecuted instantiation: <i8 as exr::io::Data>::read_into_vec_le::<&[u8], alloc::vec::Vec<i8>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>, smallvec::SmallVec<[u8; 64]>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>, alloc::vec::Vec<u8>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<&[u8]>, alloc::vec::Vec<u8>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<&[u8], alloc::vec::Vec<u8>> Unexecuted instantiation: <u64 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>, alloc::vec::Vec<u64>> Unexecuted instantiation: <_ as exr::io::Data>::read_into_vec_le::<_, _> Unexecuted instantiation: <i8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>, alloc::vec::Vec<i8>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>, alloc::vec::Vec<u8>> Unexecuted instantiation: <u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>, smallvec::SmallVec<[u8; 64]>> Unexecuted instantiation: <u64 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>, alloc::vec::Vec<u64>> |
348 | | |
349 | | /// Write the length of the slice and then its contents, converting to little-endian format. |
350 | | #[inline] |
351 | 0 | fn write_i32_sized_slice_le<W: Write>(write: &mut W, slice: &[Self]) -> UnitResult { |
352 | 0 | i32::try_from(slice.len())?.write_le(write)?; |
353 | 0 | Self::write_slice_le(write, slice) |
354 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::write_i32_sized_slice_le::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u8 as exr::io::Data>::write_i32_sized_slice_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u8 as exr::io::Data>::write_i32_sized_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> |
355 | | |
356 | | /// Read the desired element count and then read that many items into a vector. |
357 | | /// |
358 | | /// This method will not allocate more memory than `soft_max` at once. |
359 | | /// If `hard_max` is specified, it will never read any more than that. |
360 | | /// Returns `Error::Invalid` if reader does not contain the desired number of elements. |
361 | | #[inline] |
362 | 0 | fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> { |
363 | 0 | let size = usize::try_from(i32::read_le(read)?)?; |
364 | 0 | Self::read_vec_le(read, size, soft_max, hard_max, purpose) |
365 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::read_i32_sized_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <_ as exr::io::Data>::read_i32_sized_vec_le::<_> Unexecuted instantiation: <u8 as exr::io::Data>::read_i32_sized_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> |
366 | | |
367 | | /// Fill the slice with this value. |
368 | | #[inline] |
369 | 0 | fn fill_slice(self, slice: &mut [Self]) where Self: Copy { |
370 | | // hopefully compiles down to a single memset call |
371 | 0 | for value in slice { |
372 | 0 | *value = self; |
373 | 0 | } |
374 | 0 | } |
375 | | } |
376 | | |
377 | | /// A unifying trait that is implemented for Vec and SmallVec, |
378 | | /// focused on resizing capabilities. |
379 | | pub trait ResizableVec<T>: AsMut<[T]> { |
380 | | fn resize(&mut self, new_len: usize, value: T); |
381 | | fn len(&self) -> usize; |
382 | | } |
383 | | |
384 | | impl<T: Clone> ResizableVec<T> for Vec<T> { |
385 | 0 | fn resize(&mut self, new_len: usize, value: T) { |
386 | 0 | Vec::resize(self, new_len, value) |
387 | 0 | } Unexecuted instantiation: <alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::resize Unexecuted instantiation: <alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::resize Unexecuted instantiation: <alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::resize Unexecuted instantiation: <alloc::vec::Vec<_> as exr::io::ResizableVec<_>>::resize |
388 | 0 | fn len(&self) -> usize { |
389 | 0 | Vec::len(self) |
390 | 0 | } Unexecuted instantiation: <alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::len Unexecuted instantiation: <alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::len Unexecuted instantiation: <alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::len Unexecuted instantiation: <alloc::vec::Vec<_> as exr::io::ResizableVec<_>>::len |
391 | | } |
392 | | |
393 | | impl<T: Clone, A: Array<Item=T>> ResizableVec<T> for SmallVec<A> { |
394 | 0 | fn resize(&mut self, new_len: usize, value: T) { |
395 | 0 | SmallVec::resize(self, new_len, value) |
396 | 0 | } Unexecuted instantiation: <smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::resize Unexecuted instantiation: <smallvec::SmallVec<_> as exr::io::ResizableVec<_>>::resize |
397 | 0 | fn len(&self) -> usize { |
398 | 0 | SmallVec::len(self) |
399 | 0 | } Unexecuted instantiation: <smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::len Unexecuted instantiation: <smallvec::SmallVec<_> as exr::io::ResizableVec<_>>::len |
400 | | } |
401 | | |
402 | | |
403 | | |
404 | | macro_rules! implement_data_for_primitive { |
405 | | ($kind: ident) => { |
406 | | impl Data for $kind { |
407 | | #[inline] |
408 | 0 | fn read_le(read: &mut impl Read) -> Result<Self> { |
409 | 0 | Ok(read.read_from_little_endian()?) |
410 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <u8 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>> Unexecuted instantiation: <u8 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <u32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <i32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <i32 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>> Unexecuted instantiation: <u64 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <f32 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <f64 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <u16 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <u32 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <i32 as exr::io::Data>::read_le::<&[u8]> Unexecuted instantiation: <u8 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <i8 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <i16 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <i64 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <u64 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <f32 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <f64 as exr::io::Data>::read_le::<_> Unexecuted instantiation: <u8 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <u32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <i32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <u64 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> |
411 | | |
412 | | #[inline] |
413 | 0 | fn read_ne(read: &mut impl Read) -> Result<Self> { |
414 | 0 | Ok(read.read_from_native_endian()?) |
415 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::read_ne::<&[u8]> Unexecuted instantiation: <i8 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <i16 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <u16 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <u32 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <i32 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <i64 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <u64 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <f32 as exr::io::Data>::read_ne::<_> Unexecuted instantiation: <f64 as exr::io::Data>::read_ne::<_> |
416 | | |
417 | | #[inline] |
418 | 0 | fn write_le(self, write: &mut impl Write) -> Result<()> { |
419 | 0 | write.write_as_little_endian(&self)?; |
420 | 0 | Ok(()) |
421 | 0 | } Unexecuted instantiation: <u16 as exr::io::Data>::write_le::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u32 as exr::io::Data>::write_le::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>> Unexecuted instantiation: <i32 as exr::io::Data>::write_le::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u8 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <i8 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <i16 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <i64 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <u64 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <f32 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <f64 as exr::io::Data>::write_le::<_> Unexecuted instantiation: <u8 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <i32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u64 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f64 as exr::io::Data>::write_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u8 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <i32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u64 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f64 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> |
422 | | |
423 | | #[inline] |
424 | 0 | fn write_ne(self, write: &mut impl Write) -> Result<()> { |
425 | 0 | write.write_as_native_endian(&self)?; |
426 | 0 | Ok(()) |
427 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <i8 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <i16 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <u16 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <u32 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <i32 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <i64 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <u64 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <f32 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <f64 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <u16 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <u32 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <f32 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <u16 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <u32 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <f32 as exr::io::Data>::write_ne::<&mut [u8]> |
428 | | |
429 | | #[inline] |
430 | 0 | fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> { |
431 | 0 | read.read_from_little_endian_into(slice)?; |
432 | 0 | Ok(()) |
433 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<&[u8]>> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_le::<&[u8]> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<&[u8]>> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_le::<&[u8]> Unexecuted instantiation: <u64 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <f32 as exr::io::Data>::read_slice_le::<&[u8]> Unexecuted instantiation: <u16 as exr::io::Data>::read_slice_le::<&[u8]> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <i16 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <u32 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <i32 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <i64 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <u64 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <f32 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <f64 as exr::io::Data>::read_slice_le::<_> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> Unexecuted instantiation: <u64 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> |
434 | | |
435 | | #[inline] |
436 | 0 | fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> { |
437 | 0 | read.read_from_native_endian_into(slice)?; |
438 | 0 | Ok(()) |
439 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_ne::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>> Unexecuted instantiation: <u16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]> Unexecuted instantiation: <u32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]> Unexecuted instantiation: <f32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_ne::<&[u8]> Unexecuted instantiation: <u16 as exr::io::Data>::read_slice_ne::<std::io::cursor::Cursor<&[u8]>> Unexecuted instantiation: <u32 as exr::io::Data>::read_slice_ne::<std::io::cursor::Cursor<&[u8]>> Unexecuted instantiation: <f32 as exr::io::Data>::read_slice_ne::<std::io::cursor::Cursor<&[u8]>> Unexecuted instantiation: <i8 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <i16 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <i32 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <i64 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <u64 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <f64 as exr::io::Data>::read_slice_ne::<_> Unexecuted instantiation: <u8 as exr::io::Data>::read_slice_ne::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>> |
440 | | |
441 | | #[inline] |
442 | 0 | fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> { |
443 | 0 | write.write_as_little_endian(slice)?; |
444 | 0 | Ok(()) |
445 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_le::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u16 as exr::io::Data>::write_slice_le::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u32 as exr::io::Data>::write_slice_le::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>> Unexecuted instantiation: <i8 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <i16 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <i32 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <i64 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <u64 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <f32 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <f64 as exr::io::Data>::write_slice_le::<_> Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <i8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u64 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f32 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <i8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u64 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> Unexecuted instantiation: <f32 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> |
446 | | |
447 | | #[inline] |
448 | 0 | fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> { |
449 | 0 | write.write_as_native_endian(slice)?; |
450 | 0 | Ok(()) |
451 | 0 | } Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_ne::<alloc::vec::Vec<u8>> Unexecuted instantiation: <u16 as exr::io::Data>::write_slice_ne::<std::io::cursor::Cursor<&mut [u8]>> Unexecuted instantiation: <u32 as exr::io::Data>::write_slice_ne::<std::io::cursor::Cursor<&mut [u8]>> Unexecuted instantiation: <f32 as exr::io::Data>::write_slice_ne::<std::io::cursor::Cursor<&mut [u8]>> Unexecuted instantiation: <i8 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <i16 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <i32 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <i64 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <u64 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <f64 as exr::io::Data>::write_slice_ne::<_> Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_ne::<exr::io::Tracking<&mut &mut std::io::cursor::Cursor<alloc::vec::Vec<u8>>>> Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_ne::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>> |
452 | | } |
453 | | }; |
454 | | } |
455 | | |
456 | | implement_data_for_primitive!(u8); |
457 | | implement_data_for_primitive!(i8); |
458 | | implement_data_for_primitive!(i16); |
459 | | implement_data_for_primitive!(u16); |
460 | | implement_data_for_primitive!(u32); |
461 | | implement_data_for_primitive!(i32); |
462 | | implement_data_for_primitive!(i64); |
463 | | implement_data_for_primitive!(u64); |
464 | | implement_data_for_primitive!(f32); |
465 | | implement_data_for_primitive!(f64); |
466 | | |
467 | | |
468 | | impl Data for f16 { |
469 | | #[inline] |
470 | 0 | fn read_le(read: &mut impl Read) -> Result<Self> { |
471 | 0 | u16::read_le(read).map(f16::from_bits) |
472 | 0 | } |
473 | | |
474 | | #[inline] |
475 | 0 | fn read_ne(read: &mut impl Read) -> Result<Self> { |
476 | 0 | u16::read_ne(read).map(f16::from_bits) |
477 | 0 | } |
478 | | |
479 | | #[inline] |
480 | 0 | fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> { |
481 | 0 | let bits_mut = slice.reinterpret_cast_mut(); |
482 | 0 | u16::read_slice_le(read, bits_mut) |
483 | 0 | } |
484 | | |
485 | | #[inline] |
486 | 0 | fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> { |
487 | 0 | let bits_mut = slice.reinterpret_cast_mut(); |
488 | 0 | u16::read_slice_ne(read, bits_mut) |
489 | 0 | } Unexecuted instantiation: <half::binary16::f16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]> Unexecuted instantiation: <half::binary16::f16 as exr::io::Data>::read_slice_ne::<std::io::cursor::Cursor<&[u8]>> |
490 | | |
491 | | #[inline] |
492 | 0 | fn write_le(self, write: &mut impl Write) -> Result<()> { |
493 | 0 | self.to_bits().write_le(write) |
494 | 0 | } |
495 | | |
496 | | #[inline] |
497 | 0 | fn write_ne(self, write: &mut impl Write) -> Result<()> { |
498 | 0 | self.to_bits().write_ne(write) |
499 | 0 | } Unexecuted instantiation: <half::binary16::f16 as exr::io::Data>::write_ne::<_> Unexecuted instantiation: <half::binary16::f16 as exr::io::Data>::write_ne::<&mut [u8]> Unexecuted instantiation: <half::binary16::f16 as exr::io::Data>::write_ne::<&mut [u8]> |
500 | | |
501 | | #[inline] |
502 | 0 | fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> { |
503 | 0 | let bits = slice.reinterpret_cast(); |
504 | 0 | u16::write_slice_le(write, bits) |
505 | 0 | } |
506 | | |
507 | | #[inline] |
508 | 0 | fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> { |
509 | 0 | let bits = slice.reinterpret_cast(); |
510 | 0 | u16::write_slice_ne(write, bits) |
511 | 0 | } |
512 | | } |
513 | | |
514 | | |
515 | | #[cfg(test)] |
516 | | mod test { |
517 | | use crate::io::PeekRead; |
518 | | use std::io::Read; |
519 | | |
520 | | #[test] |
521 | | fn peek(){ |
522 | | use lebe::prelude::*; |
523 | | let buffer: &[u8] = &[0,1,2,3]; |
524 | | let mut peek = PeekRead::new(buffer); |
525 | | |
526 | | assert_eq!(peek.peek_u8().as_ref().unwrap(), &0); |
527 | | assert_eq!(peek.peek_u8().as_ref().unwrap(), &0); |
528 | | assert_eq!(peek.peek_u8().as_ref().unwrap(), &0); |
529 | | assert_eq!(u8::read_from_little_endian(&mut peek).unwrap(), 0_u8); |
530 | | |
531 | | assert_eq!(peek.read(&mut [0,0]).unwrap(), 2); |
532 | | |
533 | | assert_eq!(peek.peek_u8().as_ref().unwrap(), &3); |
534 | | assert_eq!(u8::read_from_little_endian(&mut peek).unwrap(), 3_u8); |
535 | | |
536 | | assert!(peek.peek_u8().is_err()); |
537 | | assert!(peek.peek_u8().is_err()); |
538 | | assert!(peek.peek_u8().is_err()); |
539 | | assert!(peek.peek_u8().is_err()); |
540 | | |
541 | | assert!(u8::read_from_little_endian(&mut peek).is_err()); |
542 | | } |
543 | | } |
544 | | |
545 | | |