Coverage Report

Created: 2026-05-30 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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