Coverage Report

Created: 2026-03-20 07:09

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
17
pub fn skip_bytes(read: &mut impl Read, count: usize) -> IoResult<()> {
21
17
    let count = u64::try_from(count).unwrap();
22
23
17
    let skipped = std::io::copy(
24
17
        &mut read.by_ref().take(count),
25
17
        &mut std::io::sink()
26
0
    )?;
27
28
    // the reader may have ended before we skipped the desired number of bytes
29
17
    if skipped < count {
30
1
        return Err(std::io::Error::new(
31
1
            std::io::ErrorKind::UnexpectedEof,
32
1
            "cannot skip more bytes than exist"
33
1
        ));
34
16
    }
35
36
16
    debug_assert_eq!(skipped, count, "skip bytes bug");
37
16
    Ok(())
38
17
}
exr::io::skip_bytes::<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>
Line
Count
Source
20
17
pub fn skip_bytes(read: &mut impl Read, count: usize) -> IoResult<()> {
21
17
    let count = u64::try_from(count).unwrap();
22
23
17
    let skipped = std::io::copy(
24
17
        &mut read.by_ref().take(count),
25
17
        &mut std::io::sink()
26
0
    )?;
27
28
    // the reader may have ended before we skipped the desired number of bytes
29
17
    if skipped < count {
30
1
        return Err(std::io::Error::new(
31
1
            std::io::ErrorKind::UnexpectedEof,
32
1
            "cannot skip more bytes than exist"
33
1
        ));
34
16
    }
35
36
16
    debug_assert_eq!(skipped, count, "skip bytes bug");
37
16
    Ok(())
38
17
}
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
103k
    pub fn new(inner: T) -> Self {
104
103k
        Self { inner, peeked: None }
105
103k
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
103
7.98k
    pub fn new(inner: T) -> Self {
104
7.98k
        Self { inner, peeked: None }
105
7.98k
    }
<exr::io::PeekRead<&[u8]>>::new
Line
Count
Source
103
95.5k
    pub fn new(inner: T) -> Self {
104
95.5k
        Self { inner, peeked: None }
105
95.5k
    }
Unexecuted instantiation: <exr::io::PeekRead<_>>::new
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>::new
Line
Count
Source
103
62
    pub fn new(inner: T) -> Self {
104
62
        Self { inner, peeked: None }
105
62
    }
106
107
    /// Read a single byte and return that without consuming it.
108
    /// The next `read` call will include that byte.
109
    #[inline]
110
2.05M
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
2.05M
        self.peeked = 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
111
1.81M
        self.peeked = 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
111
210k
        self.peeked = 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
111
744
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
2.05M
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
2.05M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::peek_u8
Line
Count
Source
110
1.84M
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
1.84M
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
1.84M
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
1.84M
    }
<exr::io::PeekRead<&[u8]>>::peek_u8
Line
Count
Source
110
210k
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
210k
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
210k
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
210k
    }
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
110
744
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
744
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
744
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
744
    }
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
2.05M
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
2.05M
        match self.peek_u8() {
121
2.05M
            Ok(peeked) if *peeked == value =>  {
122
92.8k
                self.peeked = None; // consume the byte
123
92.8k
                Ok(true)
124
            },
125
126
1.96M
            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
348
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
2.05M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_if_eq
Line
Count
Source
119
1.84M
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
1.84M
        match self.peek_u8() {
121
1.84M
            Ok(peeked) if *peeked == value =>  {
122
31.1k
                self.peeked = None; // consume the byte
123
31.1k
                Ok(true)
124
            },
125
126
1.81M
            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
344
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
1.84M
    }
<exr::io::PeekRead<&[u8]>>::skip_if_eq
Line
Count
Source
119
210k
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
210k
        match self.peek_u8() {
121
210k
            Ok(peeked) if *peeked == value =>  {
122
61.5k
                self.peeked = None; // consume the byte
123
61.5k
                Ok(true)
124
            },
125
126
149k
            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
4
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
210k
    }
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
119
744
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
744
        match self.peek_u8() {
121
744
            Ok(peeked) if *peeked == value =>  {
122
62
                self.peeked = None; // consume the byte
123
62
                Ok(true)
124
            },
125
126
682
            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
744
    }
134
}
135
136
137
impl<T: Read> Read for PeekRead<T> {
138
48.1M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
48.1M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
48.1M
        }
142
143
48.1M
        match self.peeked.take() {
144
46.1M
            None => self.inner.read(target_buffer),
145
1.93M
            Some(peeked) => {
146
1.93M
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
1.93M
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
48.1M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>> as std::io::Read>::read
Line
Count
Source
138
44.6M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
44.6M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
44.6M
        }
142
143
44.6M
        match self.peeked.take() {
144
42.9M
            None => self.inner.read(target_buffer),
145
1.78M
            Some(peeked) => {
146
1.78M
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
1.78M
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
44.6M
    }
<exr::io::PeekRead<&[u8]> as std::io::Read>::read
Line
Count
Source
138
1.76M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
1.76M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
1.76M
        }
142
143
1.76M
        match self.peeked.take() {
144
1.61M
            None => self.inner.read(target_buffer),
145
149k
            Some(peeked) => {
146
149k
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
149k
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
1.76M
    }
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
138
1.64M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
1.64M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
1.64M
        }
142
143
1.64M
        match self.peeked.take() {
144
1.64M
            None => self.inner.read(target_buffer),
145
682
            Some(peeked) => {
146
682
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
682
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
1.64M
    }
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
281k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
281k
        self.inner.seek_read_to(position)?;
161
281k
        self.peeked = None;
162
281k
        Ok(())
163
281k
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_to
Line
Count
Source
159
10.1k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
10.1k
        self.inner.seek_read_to(position)?;
161
10.1k
        self.peeked = None;
162
10.1k
        Ok(())
163
10.1k
    }
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
159
271k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
271k
        self.inner.seek_read_to(position)?;
161
271k
        self.peeked = None;
162
271k
        Ok(())
163
271k
    }
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
48.1M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
48.1M
        let count = self.inner.read(buffer)?;
188
48.1M
        self.position += count;
189
48.1M
        Ok(count)
190
48.1M
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read
Line
Count
Source
186
46.5M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
46.5M
        let count = self.inner.read(buffer)?;
188
46.5M
        self.position += count;
189
46.5M
        Ok(count)
190
46.5M
    }
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
186
1.64M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
1.64M
        let count = self.inner.read(buffer)?;
188
1.64M
        self.position += count;
189
1.64M
        Ok(count)
190
1.64M
    }
191
}
192
193
impl<T: Write> Write for Tracking<T> {
194
1.63M
    fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> {
195
1.63M
        let count = self.inner.write(buffer)?;
196
1.63M
        self.position += count;
197
1.63M
        Ok(count)
198
1.63M
    }
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
194
1.63M
    fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> {
195
1.63M
        let count = self.inner.write(buffer)?;
196
1.63M
        self.position += count;
197
1.63M
        Ok(count)
198
1.63M
    }
199
200
62
    fn flush(&mut self) -> std::io::Result<()> {
201
62
        self.inner.flush()
202
62
    }
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
200
62
    fn flush(&mut self) -> std::io::Result<()> {
201
62
        self.inner.flush()
202
62
    }
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
8.11k
    pub fn new(inner: T) -> Self {
210
8.11k
        Tracking { inner, position: 0 }
211
8.11k
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
209
7.98k
    pub fn new(inner: T) -> Self {
210
7.98k
        Tracking { inner, position: 0 }
211
7.98k
    }
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
209
62
    pub fn new(inner: T) -> Self {
210
62
        Tracking { inner, position: 0 }
211
62
    }
<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>::new
Line
Count
Source
209
62
    pub fn new(inner: T) -> Self {
210
62
        Tracking { inner, position: 0 }
211
62
    }
212
213
    /// Current number of bytes written or read.
214
271k
    pub fn byte_position(&self) -> usize {
215
271k
        self.position
216
271k
    }
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
214
271k
    pub fn byte_position(&self) -> usize {
215
271k
        self.position
216
271k
    }
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
281k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
281k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
281k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
281k
        if delta > 0 && delta < 16 { // TODO profile that this is indeed faster than a syscall! (should be because of bufread buffer discard)
228
17
            skip_bytes(self, delta as usize)?;
229
16
            self.position += delta as usize;
230
        }
231
281k
        else if delta != 0 {
232
4.74k
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
4.74k
            self.position = target_position;
234
277k
        }
235
236
281k
        Ok(())
237
281k
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::seek_read_to
Line
Count
Source
223
10.1k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
10.1k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
10.1k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
10.1k
        if delta > 0 && delta < 16 { // TODO profile that this is indeed faster than a syscall! (should be because of bufread buffer discard)
228
17
            skip_bytes(self, delta as usize)?;
229
16
            self.position += delta as usize;
230
        }
231
10.0k
        else if delta != 0 {
232
4.74k
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
4.74k
            self.position = target_position;
234
5.34k
        }
235
236
10.1k
        Ok(())
237
10.1k
    }
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
223
271k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
271k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
271k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
271k
        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
271k
        else if delta != 0 {
232
0
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
0
            self.position = target_position;
234
271k
        }
235
236
271k
        Ok(())
237
271k
    }
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
124
    pub fn seek_write_to(&mut self, target_position: usize) -> std::io::Result<()> {
245
124
        if target_position < self.position {
246
62
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
247
        }
248
62
        else if target_position > self.position {
249
62
            std::io::copy(
250
62
                &mut std::io::repeat(0).take(u64::try_from(target_position - self.position).unwrap()),
251
62
                self
252
0
            )?;
253
0
        }
254
255
124
        self.position = target_position;
256
124
        Ok(())
257
124
    }
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
244
124
    pub fn seek_write_to(&mut self, target_position: usize) -> std::io::Result<()> {
245
124
        if target_position < self.position {
246
62
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
247
        }
248
62
        else if target_position > self.position {
249
62
            std::io::copy(
250
62
                &mut std::io::repeat(0).take(u64::try_from(target_position - self.position).unwrap()),
251
62
                self
252
0
            )?;
253
0
        }
254
255
124
        self.position = target_position;
256
124
        Ok(())
257
124
    }
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
358k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
358k
        -> Result<Vec<Self>>
290
    {
291
358k
        if let Some(max) = hard_max {
292
308k
            if data_size > max {
293
114
                return Err(Error::invalid(purpose))
294
308k
            }
295
49.1k
        }
296
297
357k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
357k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
357k
        Ok(vec)
300
358k
    }
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
288
4.66k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
4.66k
        -> Result<Vec<Self>>
290
    {
291
4.66k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
4.66k
        }
296
297
4.66k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
4.66k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
4.66k
        Ok(vec)
300
4.66k
    }
<u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
288
8.21k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
8.21k
        -> Result<Vec<Self>>
290
    {
291
8.21k
        if let Some(max) = hard_max {
292
8.21k
            if data_size > max {
293
108
                return Err(Error::invalid(purpose))
294
8.10k
            }
295
0
        }
296
297
8.10k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
8.10k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
8.00k
        Ok(vec)
300
8.21k
    }
<u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
288
28.9k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
28.9k
        -> Result<Vec<Self>>
290
    {
291
28.9k
        if let Some(max) = hard_max {
292
28.9k
            if data_size > max {
293
6
                return Err(Error::invalid(purpose))
294
28.9k
            }
295
0
        }
296
297
28.9k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
28.9k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
28.9k
        Ok(vec)
300
28.9k
    }
<u8 as exr::io::Data>::read_vec_le::<&[u8]>
Line
Count
Source
288
30.6k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
30.6k
        -> Result<Vec<Self>>
290
    {
291
30.6k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
30.6k
        }
296
297
30.6k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
30.6k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
30.6k
        Ok(vec)
300
30.6k
    }
<u64 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
288
13.7k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
13.7k
        -> Result<Vec<Self>>
290
    {
291
13.7k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
13.7k
        }
296
297
13.7k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
13.7k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
13.4k
        Ok(vec)
300
13.7k
    }
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
288
271k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
271k
        -> Result<Vec<Self>>
290
    {
291
271k
        if let Some(max) = hard_max {
292
271k
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
271k
            }
295
0
        }
296
297
271k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
271k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
271k
        Ok(vec)
300
271k
    }
<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
288
62
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
62
        -> Result<Vec<Self>>
290
    {
291
62
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
62
        }
296
297
62
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
62
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
62
        Ok(vec)
300
62
    }
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
2.14M
    fn read_into_vec_le(
322
2.14M
        read: &mut impl Read,
323
2.14M
        data: &mut impl ResizableVec<Self>,
324
2.14M
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
2.14M
        purpose: &'static str
326
2.14M
    ) -> UnitResult {
327
2.14M
        if let Some(max) = hard_max {
328
308k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
308k
            }
331
1.83M
        }
332
333
2.14M
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
2.14M
        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
4.13M
        while data.len() < end {
339
1.99M
            let chunk_start = data.len();
340
1.99M
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
1.99M
            data.resize(chunk_end, Self::default());
343
1.99M
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
2.13M
        Ok(())
347
2.14M
    }
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
321
4.66k
    fn read_into_vec_le(
322
4.66k
        read: &mut impl Read,
323
4.66k
        data: &mut impl ResizableVec<Self>,
324
4.66k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
4.66k
        purpose: &'static str
326
4.66k
    ) -> UnitResult {
327
4.66k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
4.66k
        }
332
333
4.66k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
4.66k
        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
6.67k
        while data.len() < end {
339
2.01k
            let chunk_start = data.len();
340
2.01k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
2.01k
            data.resize(chunk_end, Self::default());
343
2.01k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
4.66k
        Ok(())
347
4.66k
    }
<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
321
1.78M
    fn read_into_vec_le(
322
1.78M
        read: &mut impl Read,
323
1.78M
        data: &mut impl ResizableVec<Self>,
324
1.78M
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
1.78M
        purpose: &'static str
326
1.78M
    ) -> UnitResult {
327
1.78M
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
1.78M
        }
332
333
1.78M
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
1.78M
        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
3.44M
        while data.len() < end {
339
1.66M
            let chunk_start = data.len();
340
1.66M
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
1.66M
            data.resize(chunk_end, Self::default());
343
1.66M
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
1.78M
        Ok(())
347
1.78M
    }
<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
321
8.10k
    fn read_into_vec_le(
322
8.10k
        read: &mut impl Read,
323
8.10k
        data: &mut impl ResizableVec<Self>,
324
8.10k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
8.10k
        purpose: &'static str
326
8.10k
    ) -> UnitResult {
327
8.10k
        if let Some(max) = hard_max {
328
8.10k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
8.10k
            }
331
0
        }
332
333
8.10k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
8.10k
        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
15.9k
        while data.len() < end {
339
7.93k
            let chunk_start = data.len();
340
7.93k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
7.93k
            data.resize(chunk_end, Self::default());
343
7.93k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
8.00k
        Ok(())
347
8.10k
    }
<u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<&[u8]>, alloc::vec::Vec<u8>>
Line
Count
Source
321
28.9k
    fn read_into_vec_le(
322
28.9k
        read: &mut impl Read,
323
28.9k
        data: &mut impl ResizableVec<Self>,
324
28.9k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
28.9k
        purpose: &'static str
326
28.9k
    ) -> UnitResult {
327
28.9k
        if let Some(max) = hard_max {
328
28.9k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
28.9k
            }
331
0
        }
332
333
28.9k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
28.9k
        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
30.4k
        while data.len() < end {
339
1.54k
            let chunk_start = data.len();
340
1.54k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
1.54k
            data.resize(chunk_end, Self::default());
343
1.54k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
28.9k
        Ok(())
347
28.9k
    }
<u8 as exr::io::Data>::read_into_vec_le::<&[u8], alloc::vec::Vec<u8>>
Line
Count
Source
321
30.6k
    fn read_into_vec_le(
322
30.6k
        read: &mut impl Read,
323
30.6k
        data: &mut impl ResizableVec<Self>,
324
30.6k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
30.6k
        purpose: &'static str
326
30.6k
    ) -> UnitResult {
327
30.6k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
30.6k
        }
332
333
30.6k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
30.6k
        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
62.6k
        while data.len() < end {
339
32.0k
            let chunk_start = data.len();
340
32.0k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
32.0k
            data.resize(chunk_end, Self::default());
343
32.0k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
30.6k
        Ok(())
347
30.6k
    }
<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
321
13.7k
    fn read_into_vec_le(
322
13.7k
        read: &mut impl Read,
323
13.7k
        data: &mut impl ResizableVec<Self>,
324
13.7k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
13.7k
        purpose: &'static str
326
13.7k
    ) -> UnitResult {
327
13.7k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
13.7k
        }
332
333
13.7k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
13.7k
        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
27.2k
        while data.len() < end {
339
13.7k
            let chunk_start = data.len();
340
13.7k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
13.7k
            data.resize(chunk_end, Self::default());
343
13.7k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
13.4k
        Ok(())
347
13.7k
    }
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
321
271k
    fn read_into_vec_le(
322
271k
        read: &mut impl Read,
323
271k
        data: &mut impl ResizableVec<Self>,
324
271k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
271k
        purpose: &'static str
326
271k
    ) -> UnitResult {
327
271k
        if let Some(max) = hard_max {
328
271k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
271k
            }
331
0
        }
332
333
271k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
271k
        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
543k
        while data.len() < end {
339
271k
            let chunk_start = data.len();
340
271k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
271k
            data.resize(chunk_end, Self::default());
343
271k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
271k
        Ok(())
347
271k
    }
<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
321
682
    fn read_into_vec_le(
322
682
        read: &mut impl Read,
323
682
        data: &mut impl ResizableVec<Self>,
324
682
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
682
        purpose: &'static str
326
682
    ) -> UnitResult {
327
682
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
682
        }
332
333
682
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
682
        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
1.42k
        while data.len() < end {
339
744
            let chunk_start = data.len();
340
744
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
744
            data.resize(chunk_end, Self::default());
343
744
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
682
        Ok(())
347
682
    }
<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
321
62
    fn read_into_vec_le(
322
62
        read: &mut impl Read,
323
62
        data: &mut impl ResizableVec<Self>,
324
62
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
62
        purpose: &'static str
326
62
    ) -> UnitResult {
327
62
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
62
        }
332
333
62
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
62
        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
124
        while data.len() < end {
339
62
            let chunk_start = data.len();
340
62
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
62
            data.resize(chunk_end, Self::default());
343
62
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
62
        Ok(())
347
62
    }
348
349
    /// Write the length of the slice and then its contents, converting to little-endian format.
350
    #[inline]
351
271k
    fn write_i32_sized_slice_le<W: Write>(write: &mut W, slice: &[Self]) -> UnitResult {
352
271k
        i32::try_from(slice.len())?.write_le(write)?;
353
271k
        Self::write_slice_le(write, slice)
354
271k
    }
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
351
271k
    fn write_i32_sized_slice_le<W: Write>(write: &mut W, slice: &[Self]) -> UnitResult {
352
271k
        i32::try_from(slice.len())?.write_le(write)?;
353
271k
        Self::write_slice_le(write, slice)
354
271k
    }
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
280k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
280k
        let size = usize::try_from(i32::read_le(read)?)?;
364
280k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
280k
    }
<u8 as exr::io::Data>::read_i32_sized_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
362
8.28k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
8.28k
        let size = usize::try_from(i32::read_le(read)?)?;
364
8.21k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
8.28k
    }
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
362
271k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
271k
        let size = usize::try_from(i32::read_le(read)?)?;
364
271k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
271k
    }
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
329k
    fn resize(&mut self, new_len: usize, value: T) {
386
329k
        Vec::resize(self, new_len, value)
387
329k
    }
<alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::resize
Line
Count
Source
385
2.01k
    fn resize(&mut self, new_len: usize, value: T) {
386
2.01k
        Vec::resize(self, new_len, value)
387
2.01k
    }
<alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::resize
Line
Count
Source
385
313k
    fn resize(&mut self, new_len: usize, value: T) {
386
313k
        Vec::resize(self, new_len, value)
387
313k
    }
<alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::resize
Line
Count
Source
385
13.8k
    fn resize(&mut self, new_len: usize, value: T) {
386
13.8k
        Vec::resize(self, new_len, value)
387
13.8k
    }
Unexecuted instantiation: <alloc::vec::Vec<_> as exr::io::ResizableVec<_>>::resize
388
1.37M
    fn len(&self) -> usize {
389
1.37M
        Vec::len(self)
390
1.37M
    }
<alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::len
Line
Count
Source
388
13.3k
    fn len(&self) -> usize {
389
13.3k
        Vec::len(self)
390
13.3k
    }
<alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::len
Line
Count
Source
388
1.30M
    fn len(&self) -> usize {
389
1.30M
        Vec::len(self)
390
1.30M
    }
<alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::len
Line
Count
Source
388
54.9k
    fn len(&self) -> usize {
389
54.9k
        Vec::len(self)
390
54.9k
    }
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
1.66M
    fn resize(&mut self, new_len: usize, value: T) {
395
1.66M
        SmallVec::resize(self, new_len, value)
396
1.66M
    }
<smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::resize
Line
Count
Source
394
1.66M
    fn resize(&mut self, new_len: usize, value: T) {
395
1.66M
        SmallVec::resize(self, new_len, value)
396
1.66M
    }
Unexecuted instantiation: <smallvec::SmallVec<_> as exr::io::ResizableVec<_>>::resize
397
6.90M
    fn len(&self) -> usize {
398
6.90M
        SmallVec::len(self)
399
6.90M
    }
<smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::len
Line
Count
Source
397
6.90M
    fn len(&self) -> usize {
398
6.90M
        SmallVec::len(self)
399
6.90M
    }
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
47.1M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
47.1M
                Ok(read.read_from_little_endian()?)
410
47.1M
            }
<u8 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
41.1M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
41.1M
                Ok(read.read_from_little_endian()?)
410
41.1M
            }
<u8 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
408
1.13M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
1.13M
                Ok(read.read_from_little_endian()?)
410
1.13M
            }
<u8 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
84.6k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
84.6k
                Ok(read.read_from_little_endian()?)
410
84.6k
            }
<u32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
7.98k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
7.98k
                Ok(read.read_from_little_endian()?)
410
7.98k
            }
<i32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
1.80M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
1.80M
                Ok(read.read_from_little_endian()?)
410
1.80M
            }
<i32 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
408
475k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
475k
                Ok(read.read_from_little_endian()?)
410
475k
            }
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
408
351k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
351k
                Ok(read.read_from_little_endian()?)
410
351k
            }
<f64 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
2.21k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
2.21k
                Ok(read.read_from_little_endian()?)
410
2.21k
            }
<u16 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
78
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
78
                Ok(read.read_from_little_endian()?)
410
78
            }
<u32 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
125k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
125k
                Ok(read.read_from_little_endian()?)
410
125k
            }
<i32 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
634k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
634k
                Ok(read.read_from_little_endian()?)
410
634k
            }
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::<_>
<u8 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>
Line
Count
Source
408
12.9k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
12.9k
                Ok(read.read_from_little_endian()?)
410
12.9k
            }
<u32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>
Line
Count
Source
408
62
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
62
                Ok(read.read_from_little_endian()?)
410
62
            }
<i32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>>
Line
Count
Source
408
1.35M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
1.35M
                Ok(read.read_from_little_endian()?)
410
1.35M
            }
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
347k
            fn read_ne(read: &mut impl Read) -> Result<Self> {
414
347k
                Ok(read.read_from_native_endian()?)
415
347k
            }
<u8 as exr::io::Data>::read_ne::<&[u8]>
Line
Count
Source
413
347k
            fn read_ne(read: &mut impl Read) -> Result<Self> {
414
347k
                Ok(read.read_from_native_endian()?)
415
347k
            }
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
1.36M
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
1.36M
                write.write_as_little_endian(&self)?;
420
1.36M
                Ok(())
421
1.36M
            }
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>>>>
<u8 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
418
2.17k
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
2.17k
                write.write_as_little_endian(&self)?;
420
2.17k
                Ok(())
421
2.17k
            }
<u32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
418
186
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
186
                write.write_as_little_endian(&self)?;
420
186
                Ok(())
421
186
            }
<i32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
418
1.36M
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
1.36M
                write.write_as_little_endian(&self)?;
420
1.36M
                Ok(())
421
1.36M
            }
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
418
248
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
248
                write.write_as_little_endian(&self)?;
420
248
                Ok(())
421
248
            }
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
103M
            fn write_ne(self, write: &mut impl Write) -> Result<()> {
425
103M
                write.write_as_native_endian(&self)?;
426
103M
                Ok(())
427
103M
            }
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
424
103M
            fn write_ne(self, write: &mut impl Write) -> Result<()> {
425
103M
                write.write_as_native_endian(&self)?;
426
103M
                Ok(())
427
103M
            }
428
429
            #[inline]
430
2.17M
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
2.17M
                read.read_from_little_endian_into(slice)?;
432
2.17M
                Ok(())
433
2.17M
            }
<u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
430
1.67M
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
1.67M
                read.read_from_little_endian_into(slice)?;
432
1.67M
                Ok(())
433
1.67M
            }
<u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
430
1.54k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
1.54k
                read.read_from_little_endian_into(slice)?;
432
1.54k
                Ok(())
433
1.54k
            }
<u8 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
32.0k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
32.0k
                read.read_from_little_endian_into(slice)?;
432
32.0k
                Ok(())
433
32.0k
            }
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
430
148k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
148k
                read.read_from_little_endian_into(slice)?;
432
148k
                Ok(())
433
148k
            }
<i8 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
2.01k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
2.01k
                read.read_from_little_endian_into(slice)?;
432
2.00k
                Ok(())
433
2.01k
            }
<u64 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
430
13.7k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
13.7k
                read.read_from_little_endian_into(slice)?;
432
13.4k
                Ok(())
433
13.7k
            }
<f32 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
26.5k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
26.5k
                read.read_from_little_endian_into(slice)?;
432
26.5k
                Ok(())
433
26.5k
            }
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::<_>
<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
430
272k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
272k
                read.read_from_little_endian_into(slice)?;
432
272k
                Ok(())
433
272k
            }
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
430
62
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
62
                read.read_from_little_endian_into(slice)?;
432
62
                Ok(())
433
62
            }
434
435
            #[inline]
436
55.6M
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
55.6M
                read.read_from_native_endian_into(slice)?;
438
55.6M
                Ok(())
439
55.6M
            }
<u8 as exr::io::Data>::read_slice_ne::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
436
7.98k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
7.98k
                read.read_from_native_endian_into(slice)?;
438
7.98k
                Ok(())
439
7.98k
            }
<u16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
98.0k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
98.0k
                read.read_from_native_endian_into(slice)?;
438
98.0k
                Ok(())
439
98.0k
            }
<u32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
67.7k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
67.7k
                read.read_from_native_endian_into(slice)?;
438
67.7k
                Ok(())
439
67.7k
            }
<f32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
55.4M
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
55.4M
                read.read_from_native_endian_into(slice)?;
438
55.4M
                Ok(())
439
55.4M
            }
<u8 as exr::io::Data>::read_slice_ne::<&[u8]>
Line
Count
Source
436
28
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
28
                read.read_from_native_endian_into(slice)?;
438
28
                Ok(())
439
28
            }
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::<_>
<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
436
62
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
62
                read.read_from_native_endian_into(slice)?;
438
62
                Ok(())
439
62
            }
440
441
            #[inline]
442
273k
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
273k
                write.write_as_little_endian(slice)?;
444
273k
                Ok(())
445
273k
            }
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>>>>
<u8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
442
273k
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
273k
                write.write_as_little_endian(slice)?;
444
273k
                Ok(())
445
273k
            }
<i8 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
442
248
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
248
                write.write_as_little_endian(slice)?;
444
248
                Ok(())
445
248
            }
<u64 as exr::io::Data>::write_slice_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
442
62
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
62
                write.write_as_little_endian(slice)?;
444
62
                Ok(())
445
62
            }
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
350
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
350
                write.write_as_native_endian(slice)?;
450
350
                Ok(())
451
350
            }
<u8 as exr::io::Data>::write_slice_ne::<alloc::vec::Vec<u8>>
Line
Count
Source
448
288
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
288
                write.write_as_native_endian(slice)?;
450
288
                Ok(())
451
288
            }
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>>>>
<u8 as exr::io::Data>::write_slice_ne::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
448
62
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
62
                write.write_as_native_endian(slice)?;
450
62
                Ok(())
451
62
            }
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
98.0k
    fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
487
98.0k
        let bits_mut = slice.reinterpret_cast_mut();
488
98.0k
        u16::read_slice_ne(read, bits_mut)
489
98.0k
    }
<half::binary16::f16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
486
98.0k
    fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
487
98.0k
        let bits_mut = slice.reinterpret_cast_mut();
488
98.0k
        u16::read_slice_ne(read, bits_mut)
489
98.0k
    }
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