Coverage Report

Created: 2026-10-17 08:02

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