Coverage Report

Created: 2025-12-20 06:48

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
8
pub fn skip_bytes(read: &mut impl Read, count: usize) -> IoResult<()> {
21
8
    let count = u64::try_from(count).unwrap();
22
23
8
    let skipped = std::io::copy(
24
8
        &mut read.by_ref().take(count),
25
8
        &mut std::io::sink()
26
0
    )?;
27
28
    // the reader may have ended before we skipped the desired number of bytes
29
8
    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
7
    }
35
36
7
    debug_assert_eq!(skipped, count, "skip bytes bug");
37
7
    Ok(())
38
8
}
exr::io::skip_bytes::<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>
Line
Count
Source
20
8
pub fn skip_bytes(read: &mut impl Read, count: usize) -> IoResult<()> {
21
8
    let count = u64::try_from(count).unwrap();
22
23
8
    let skipped = std::io::copy(
24
8
        &mut read.by_ref().take(count),
25
8
        &mut std::io::sink()
26
0
    )?;
27
28
    // the reader may have ended before we skipped the desired number of bytes
29
8
    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
7
    }
35
36
7
    debug_assert_eq!(skipped, count, "skip bytes bug");
37
7
    Ok(())
38
8
}
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
93.9k
    pub fn new(inner: T) -> Self {
104
93.9k
        Self { inner, peeked: None }
105
93.9k
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
103
6.13k
    pub fn new(inner: T) -> Self {
104
6.13k
        Self { inner, peeked: None }
105
6.13k
    }
<exr::io::PeekRead<&[u8]>>::new
Line
Count
Source
103
87.7k
    pub fn new(inner: T) -> Self {
104
87.7k
        Self { inner, peeked: None }
105
87.7k
    }
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
85
    pub fn new(inner: T) -> Self {
104
85
        Self { inner, peeked: None }
105
85
    }
106
107
    /// Read a single byte and return that without consuming it.
108
    /// The next `read` call will include that byte.
109
    #[inline]
110
1.91M
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
1.91M
        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.72M
        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
171k
        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
1.02k
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
1.91M
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
1.91M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::peek_u8
Line
Count
Source
110
1.74M
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
1.74M
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
1.74M
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
1.74M
    }
<exr::io::PeekRead<&[u8]>>::peek_u8
Line
Count
Source
110
171k
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
171k
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
171k
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
171k
    }
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
1.02k
    pub fn peek_u8(&mut self) -> &IoResult<u8> {
111
1.02k
        self.peeked = self.peeked.take().or_else(|| Some(u8::read_from_little_endian(&mut self.inner)));
112
1.02k
        self.peeked.as_ref().unwrap() // unwrap cannot fail because we just set it
113
1.02k
    }
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
1.91M
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
1.91M
        match self.peek_u8() {
121
1.91M
            Ok(peeked) if *peeked == value =>  {
122
77.1k
                self.peeked = None; // consume the byte
123
77.1k
                Ok(true)
124
            },
125
126
1.84M
            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
103
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
1.91M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_if_eq
Line
Count
Source
119
1.74M
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
1.74M
        match self.peek_u8() {
121
1.74M
            Ok(peeked) if *peeked == value =>  {
122
26.0k
                self.peeked = None; // consume the byte
123
26.0k
                Ok(true)
124
            },
125
126
1.72M
            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
100
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
1.74M
    }
<exr::io::PeekRead<&[u8]>>::skip_if_eq
Line
Count
Source
119
171k
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
171k
        match self.peek_u8() {
121
171k
            Ok(peeked) if *peeked == value =>  {
122
51.0k
                self.peeked = None; // consume the byte
123
51.0k
                Ok(true)
124
            },
125
126
119k
            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
3
            Err(_) => Err(self.peeked.take().unwrap().err().unwrap())
132
        }
133
171k
    }
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
1.02k
    pub fn skip_if_eq(&mut self, value: u8) -> IoResult<bool> {
120
1.02k
        match self.peek_u8() {
121
1.02k
            Ok(peeked) if *peeked == value =>  {
122
85
                self.peeked = None; // consume the byte
123
85
                Ok(true)
124
            },
125
126
935
            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
1.02k
    }
134
}
135
136
137
impl<T: Read> Read for PeekRead<T> {
138
46.7M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
46.7M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
46.7M
        }
142
143
46.7M
        match self.peeked.take() {
144
44.8M
            None => self.inner.read(target_buffer),
145
1.81M
            Some(peeked) => {
146
1.81M
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
1.81M
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
46.7M
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>> as std::io::Read>::read
Line
Count
Source
138
43.1M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
43.1M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
43.1M
        }
142
143
43.1M
        match self.peeked.take() {
144
41.4M
            None => self.inner.read(target_buffer),
145
1.69M
            Some(peeked) => {
146
1.69M
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
1.69M
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
43.1M
    }
<exr::io::PeekRead<&[u8]> as std::io::Read>::read
Line
Count
Source
138
1.37M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
1.37M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
1.37M
        }
142
143
1.37M
        match self.peeked.take() {
144
1.25M
            None => self.inner.read(target_buffer),
145
119k
            Some(peeked) => {
146
119k
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
119k
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
1.37M
    }
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
2.14M
    fn read(&mut self, target_buffer: &mut [u8]) -> IoResult<usize> {
139
2.14M
        if target_buffer.is_empty() {
140
0
            return Ok(0)
141
2.14M
        }
142
143
2.14M
        match self.peeked.take() {
144
2.14M
            None => self.inner.read(target_buffer),
145
935
            Some(peeked) => {
146
935
                target_buffer[0] = peeked?;
147
148
                // indexing [1..] is safe because an empty buffer already returned ok
149
935
                Ok(1 + self.inner.read(&mut target_buffer[1..])?)
150
            }
151
        }
152
2.14M
    }
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
362k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
362k
        self.inner.seek_read_to(position)?;
161
362k
        self.peeked = None;
162
362k
        Ok(())
163
362k
    }
<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>::skip_to
Line
Count
Source
159
7.78k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
7.78k
        self.inner.seek_read_to(position)?;
161
7.78k
        self.peeked = None;
162
7.78k
        Ok(())
163
7.78k
    }
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
354k
    pub fn skip_to(&mut self, position: usize) -> std::io::Result<()> {
160
354k
        self.inner.seek_read_to(position)?;
161
354k
        self.peeked = None;
162
354k
        Ok(())
163
354k
    }
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
47.0M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
47.0M
        let count = self.inner.read(buffer)?;
188
47.0M
        self.position += count;
189
47.0M
        Ok(count)
190
47.0M
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read
Line
Count
Source
186
44.9M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
44.9M
        let count = self.inner.read(buffer)?;
188
44.9M
        self.position += count;
189
44.9M
        Ok(count)
190
44.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
186
2.14M
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
187
2.14M
        let count = self.inner.read(buffer)?;
188
2.14M
        self.position += count;
189
2.14M
        Ok(count)
190
2.14M
    }
191
}
192
193
impl<T: Write> Write for Tracking<T> {
194
2.13M
    fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> {
195
2.13M
        let count = self.inner.write(buffer)?;
196
2.13M
        self.position += count;
197
2.13M
        Ok(count)
198
2.13M
    }
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
2.13M
    fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> {
195
2.13M
        let count = self.inner.write(buffer)?;
196
2.13M
        self.position += count;
197
2.13M
        Ok(count)
198
2.13M
    }
199
200
85
    fn flush(&mut self) -> std::io::Result<()> {
201
85
        self.inner.flush()
202
85
    }
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
85
    fn flush(&mut self) -> std::io::Result<()> {
201
85
        self.inner.flush()
202
85
    }
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
6.30k
    pub fn new(inner: T) -> Self {
210
6.30k
        Tracking { inner, position: 0 }
211
6.30k
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
209
6.13k
    pub fn new(inner: T) -> Self {
210
6.13k
        Tracking { inner, position: 0 }
211
6.13k
    }
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
85
    pub fn new(inner: T) -> Self {
210
85
        Tracking { inner, position: 0 }
211
85
    }
<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>::new
Line
Count
Source
209
85
    pub fn new(inner: T) -> Self {
210
85
        Tracking { inner, position: 0 }
211
85
    }
212
213
    /// Current number of bytes written or read.
214
354k
    pub fn byte_position(&self) -> usize {
215
354k
        self.position
216
354k
    }
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
354k
    pub fn byte_position(&self) -> usize {
215
354k
        self.position
216
354k
    }
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
362k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
362k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
362k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
362k
        if delta > 0 && delta < 16 { // TODO profile that this is indeed faster than a syscall! (should be because of bufread buffer discard)
228
8
            skip_bytes(self, delta as usize)?;
229
7
            self.position += delta as usize;
230
        }
231
362k
        else if delta != 0 {
232
3.52k
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
3.52k
            self.position = target_position;
234
358k
        }
235
236
362k
        Ok(())
237
362k
    }
<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>::seek_read_to
Line
Count
Source
223
7.78k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
7.78k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
7.78k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
7.78k
        if delta > 0 && delta < 16 { // TODO profile that this is indeed faster than a syscall! (should be because of bufread buffer discard)
228
8
            skip_bytes(self, delta as usize)?;
229
7
            self.position += delta as usize;
230
        }
231
7.77k
        else if delta != 0 {
232
3.52k
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
3.52k
            self.position = target_position;
234
4.25k
        }
235
236
7.78k
        Ok(())
237
7.78k
    }
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
354k
    pub fn seek_read_to(&mut self, target_position: usize) -> std::io::Result<()> {
224
354k
        let delta = target_position as i128 - self.position as i128; // FIXME  panicked at 'attempt to subtract with overflow'
225
354k
        debug_assert!(delta.abs() < usize::MAX as i128);
226
227
354k
        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
354k
        else if delta != 0 {
232
0
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
233
0
            self.position = target_position;
234
354k
        }
235
236
354k
        Ok(())
237
354k
    }
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
170
    pub fn seek_write_to(&mut self, target_position: usize) -> std::io::Result<()> {
245
170
        if target_position < self.position {
246
85
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
247
        }
248
85
        else if target_position > self.position {
249
85
            std::io::copy(
250
85
                &mut std::io::repeat(0).take(u64::try_from(target_position - self.position).unwrap()),
251
85
                self
252
0
            )?;
253
0
        }
254
255
170
        self.position = target_position;
256
170
        Ok(())
257
170
    }
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
170
    pub fn seek_write_to(&mut self, target_position: usize) -> std::io::Result<()> {
245
170
        if target_position < self.position {
246
85
            self.inner.seek(SeekFrom::Start(u64::try_from(target_position).unwrap()))?;
247
        }
248
85
        else if target_position > self.position {
249
85
            std::io::copy(
250
85
                &mut std::io::repeat(0).take(u64::try_from(target_position - self.position).unwrap()),
251
85
                self
252
0
            )?;
253
0
        }
254
255
170
        self.position = target_position;
256
170
        Ok(())
257
170
    }
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
433k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
433k
        -> Result<Vec<Self>>
290
    {
291
433k
        if let Some(max) = hard_max {
292
389k
            if data_size > max {
293
97
                return Err(Error::invalid(purpose))
294
389k
            }
295
43.9k
        }
296
297
433k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
433k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
432k
        Ok(vec)
300
433k
    }
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
6.15k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
6.15k
        -> Result<Vec<Self>>
290
    {
291
6.15k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
6.15k
        }
296
297
6.15k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
6.15k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
6.15k
        Ok(vec)
300
6.15k
    }
<u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
288
6.19k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
6.19k
        -> Result<Vec<Self>>
290
    {
291
6.19k
        if let Some(max) = hard_max {
292
6.19k
            if data_size > max {
293
90
                return Err(Error::invalid(purpose))
294
6.10k
            }
295
0
        }
296
297
6.10k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
6.10k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
6.01k
        Ok(vec)
300
6.19k
    }
<u8 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
288
28.6k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
28.6k
        -> Result<Vec<Self>>
290
    {
291
28.6k
        if let Some(max) = hard_max {
292
28.6k
            if data_size > max {
293
7
                return Err(Error::invalid(purpose))
294
28.6k
            }
295
0
        }
296
297
28.6k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
28.6k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
28.6k
        Ok(vec)
300
28.6k
    }
<u8 as exr::io::Data>::read_vec_le::<&[u8]>
Line
Count
Source
288
27.5k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
27.5k
        -> Result<Vec<Self>>
290
    {
291
27.5k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
27.5k
        }
296
297
27.5k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
27.5k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
27.5k
        Ok(vec)
300
27.5k
    }
<u64 as exr::io::Data>::read_vec_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
288
10.2k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
10.2k
        -> Result<Vec<Self>>
290
    {
291
10.2k
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
10.2k
        }
296
297
10.2k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
10.2k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
10.0k
        Ok(vec)
300
10.2k
    }
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
354k
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
354k
        -> Result<Vec<Self>>
290
    {
291
354k
        if let Some(max) = hard_max {
292
354k
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
354k
            }
295
0
        }
296
297
354k
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
354k
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
354k
        Ok(vec)
300
354k
    }
<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
85
    fn read_vec_le(read: &mut impl Read, data_size: usize, soft_max: usize, hard_max: Option<usize>, purpose: &'static str)
289
85
        -> Result<Vec<Self>>
290
    {
291
85
        if let Some(max) = hard_max {
292
0
            if data_size > max {
293
0
                return Err(Error::invalid(purpose))
294
0
            }
295
85
        }
296
297
85
        let mut vec = Vec::with_capacity(data_size.min(soft_max));
298
85
        Self::read_into_vec_le(read, &mut vec, data_size, soft_max, hard_max, purpose)?;
299
85
        Ok(vec)
300
85
    }
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.12M
    fn read_into_vec_le(
322
2.12M
        read: &mut impl Read,
323
2.12M
        data: &mut impl ResizableVec<Self>,
324
2.12M
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
2.12M
        purpose: &'static str
326
2.12M
    ) -> UnitResult {
327
2.12M
        if let Some(max) = hard_max {
328
389k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
389k
            }
331
1.74M
        }
332
333
2.12M
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
2.12M
        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
2.01M
            let chunk_start = data.len();
340
2.01M
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
2.01M
            data.resize(chunk_end, Self::default());
343
2.01M
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
2.12M
        Ok(())
347
2.12M
    }
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
6.15k
    fn read_into_vec_le(
322
6.15k
        read: &mut impl Read,
323
6.15k
        data: &mut impl ResizableVec<Self>,
324
6.15k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
6.15k
        purpose: &'static str
326
6.15k
    ) -> UnitResult {
327
6.15k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
6.15k
        }
332
333
6.15k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
6.15k
        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
8.36k
        while data.len() < end {
339
2.21k
            let chunk_start = data.len();
340
2.21k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
2.21k
            data.resize(chunk_end, Self::default());
343
2.21k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
6.15k
        Ok(())
347
6.15k
    }
<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.69M
    fn read_into_vec_le(
322
1.69M
        read: &mut impl Read,
323
1.69M
        data: &mut impl ResizableVec<Self>,
324
1.69M
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
1.69M
        purpose: &'static str
326
1.69M
    ) -> UnitResult {
327
1.69M
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
1.69M
        }
332
333
1.69M
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
1.69M
        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.29M
        while data.len() < end {
339
1.60M
            let chunk_start = data.len();
340
1.60M
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
1.60M
            data.resize(chunk_end, Self::default());
343
1.60M
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
1.69M
        Ok(())
347
1.69M
    }
<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
6.10k
    fn read_into_vec_le(
322
6.10k
        read: &mut impl Read,
323
6.10k
        data: &mut impl ResizableVec<Self>,
324
6.10k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
6.10k
        purpose: &'static str
326
6.10k
    ) -> UnitResult {
327
6.10k
        if let Some(max) = hard_max {
328
6.10k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
6.10k
            }
331
0
        }
332
333
6.10k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
6.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
11.9k
        while data.len() < end {
339
5.98k
            let chunk_start = data.len();
340
5.98k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
5.98k
            data.resize(chunk_end, Self::default());
343
5.98k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
6.01k
        Ok(())
347
6.10k
    }
<u8 as exr::io::Data>::read_into_vec_le::<exr::io::PeekRead<&[u8]>, alloc::vec::Vec<u8>>
Line
Count
Source
321
28.6k
    fn read_into_vec_le(
322
28.6k
        read: &mut impl Read,
323
28.6k
        data: &mut impl ResizableVec<Self>,
324
28.6k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
28.6k
        purpose: &'static str
326
28.6k
    ) -> UnitResult {
327
28.6k
        if let Some(max) = hard_max {
328
28.6k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
28.6k
            }
331
0
        }
332
333
28.6k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
28.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
31.1k
        while data.len() < end {
339
2.48k
            let chunk_start = data.len();
340
2.48k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
2.48k
            data.resize(chunk_end, Self::default());
343
2.48k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
28.6k
        Ok(())
347
28.6k
    }
<u8 as exr::io::Data>::read_into_vec_le::<&[u8], alloc::vec::Vec<u8>>
Line
Count
Source
321
27.5k
    fn read_into_vec_le(
322
27.5k
        read: &mut impl Read,
323
27.5k
        data: &mut impl ResizableVec<Self>,
324
27.5k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
27.5k
        purpose: &'static str
326
27.5k
    ) -> UnitResult {
327
27.5k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
27.5k
        }
332
333
27.5k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
27.5k
        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
56.5k
        while data.len() < end {
339
29.0k
            let chunk_start = data.len();
340
29.0k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
29.0k
            data.resize(chunk_end, Self::default());
343
29.0k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
27.5k
        Ok(())
347
27.5k
    }
<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
10.2k
    fn read_into_vec_le(
322
10.2k
        read: &mut impl Read,
323
10.2k
        data: &mut impl ResizableVec<Self>,
324
10.2k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
10.2k
        purpose: &'static str
326
10.2k
    ) -> UnitResult {
327
10.2k
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
10.2k
        }
332
333
10.2k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
10.2k
        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
20.2k
        while data.len() < end {
339
10.2k
            let chunk_start = data.len();
340
10.2k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
10.2k
            data.resize(chunk_end, Self::default());
343
10.2k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
10.0k
        Ok(())
347
10.2k
    }
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
354k
    fn read_into_vec_le(
322
354k
        read: &mut impl Read,
323
354k
        data: &mut impl ResizableVec<Self>,
324
354k
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
354k
        purpose: &'static str
326
354k
    ) -> UnitResult {
327
354k
        if let Some(max) = hard_max {
328
354k
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
354k
            }
331
0
        }
332
333
354k
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
354k
        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
709k
        while data.len() < end {
339
354k
            let chunk_start = data.len();
340
354k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
354k
            data.resize(chunk_end, Self::default());
343
354k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
354k
        Ok(())
347
354k
    }
<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
935
    fn read_into_vec_le(
322
935
        read: &mut impl Read,
323
935
        data: &mut impl ResizableVec<Self>,
324
935
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
935
        purpose: &'static str
326
935
    ) -> UnitResult {
327
935
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
935
        }
332
333
935
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
935
        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.95k
        while data.len() < end {
339
1.02k
            let chunk_start = data.len();
340
1.02k
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
1.02k
            data.resize(chunk_end, Self::default());
343
1.02k
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
935
        Ok(())
347
935
    }
<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
85
    fn read_into_vec_le(
322
85
        read: &mut impl Read,
323
85
        data: &mut impl ResizableVec<Self>,
324
85
        data_size: usize, soft_max: usize, hard_max: Option<usize>,
325
85
        purpose: &'static str
326
85
    ) -> UnitResult {
327
85
        if let Some(max) = hard_max {
328
0
            if data_size > max {
329
0
                return Err(Error::invalid(purpose))
330
0
            }
331
85
        }
332
333
85
        let soft_max = hard_max.unwrap_or(soft_max).min(soft_max);
334
85
        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
170
        while data.len() < end {
339
85
            let chunk_start = data.len();
340
85
            let chunk_end = (chunk_start + soft_max).min(data_size);
341
342
85
            data.resize(chunk_end, Self::default());
343
85
            Self::read_slice_le(read, &mut data.as_mut()[chunk_start .. chunk_end])?; // safe because of `min(data_size)`
344
        }
345
346
85
        Ok(())
347
85
    }
348
349
    /// Write the length of the slice and then its contents, converting to little-endian format.
350
    #[inline]
351
354k
    fn write_i32_sized_slice_le<W: Write>(write: &mut W, slice: &[Self]) -> UnitResult {
352
354k
        i32::try_from(slice.len())?.write_le(write)?;
353
354k
        Self::write_slice_le(write, slice)
354
354k
    }
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
354k
    fn write_i32_sized_slice_le<W: Write>(write: &mut W, slice: &[Self]) -> UnitResult {
352
354k
        i32::try_from(slice.len())?.write_le(write)?;
353
354k
        Self::write_slice_le(write, slice)
354
354k
    }
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
360k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
360k
        let size = usize::try_from(i32::read_le(read)?)?;
364
360k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
360k
    }
<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
6.27k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
6.27k
        let size = usize::try_from(i32::read_le(read)?)?;
364
6.19k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
6.27k
    }
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
354k
    fn read_i32_sized_vec_le(read: &mut impl Read, soft_max: usize, hard_max: Option<usize>, purpose: &'static str) -> Result<Vec<Self>> {
363
354k
        let size = usize::try_from(i32::read_le(read)?)?;
364
354k
        Self::read_vec_le(read, size, soft_max, hard_max, purpose)
365
354k
    }
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
404k
    fn resize(&mut self, new_len: usize, value: T) {
386
404k
        Vec::resize(self, new_len, value)
387
404k
    }
<alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::resize
Line
Count
Source
385
2.21k
    fn resize(&mut self, new_len: usize, value: T) {
386
2.21k
        Vec::resize(self, new_len, value)
387
2.21k
    }
<alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::resize
Line
Count
Source
385
392k
    fn resize(&mut self, new_len: usize, value: T) {
386
392k
        Vec::resize(self, new_len, value)
387
392k
    }
<alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::resize
Line
Count
Source
385
10.3k
    fn resize(&mut self, new_len: usize, value: T) {
386
10.3k
        Vec::resize(self, new_len, value)
387
10.3k
    }
Unexecuted instantiation: <alloc::vec::Vec<_> as exr::io::ResizableVec<_>>::resize
388
1.67M
    fn len(&self) -> usize {
389
1.67M
        Vec::len(self)
390
1.67M
    }
<alloc::vec::Vec<i8> as exr::io::ResizableVec<i8>>::len
Line
Count
Source
388
16.7k
    fn len(&self) -> usize {
389
16.7k
        Vec::len(self)
390
16.7k
    }
<alloc::vec::Vec<u8> as exr::io::ResizableVec<u8>>::len
Line
Count
Source
388
1.61M
    fn len(&self) -> usize {
389
1.61M
        Vec::len(self)
390
1.61M
    }
<alloc::vec::Vec<u64> as exr::io::ResizableVec<u64>>::len
Line
Count
Source
388
41.0k
    fn len(&self) -> usize {
389
41.0k
        Vec::len(self)
390
41.0k
    }
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.60M
    fn resize(&mut self, new_len: usize, value: T) {
395
1.60M
        SmallVec::resize(self, new_len, value)
396
1.60M
    }
<smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::resize
Line
Count
Source
394
1.60M
    fn resize(&mut self, new_len: usize, value: T) {
395
1.60M
        SmallVec::resize(self, new_len, value)
396
1.60M
    }
Unexecuted instantiation: <smallvec::SmallVec<_> as exr::io::ResizableVec<_>>::resize
397
6.60M
    fn len(&self) -> usize {
398
6.60M
        SmallVec::len(self)
399
6.60M
    }
<smallvec::SmallVec<[u8; 64]> as exr::io::ResizableVec<u8>>::len
Line
Count
Source
397
6.60M
    fn len(&self) -> usize {
398
6.60M
        SmallVec::len(self)
399
6.60M
    }
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
45.7M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
45.7M
                Ok(read.read_from_little_endian()?)
410
45.7M
            }
<u8 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
39.8M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
39.8M
                Ok(read.read_from_little_endian()?)
410
39.8M
            }
<u8 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
408
865k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
865k
                Ok(read.read_from_little_endian()?)
410
865k
            }
<u8 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
79.4k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
79.4k
                Ok(read.read_from_little_endian()?)
410
79.4k
            }
<u32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
6.13k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
6.13k
                Ok(read.read_from_little_endian()?)
410
6.13k
            }
<i32 as exr::io::Data>::read_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
408
1.71M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
1.71M
                Ok(read.read_from_little_endian()?)
410
1.71M
            }
<i32 as exr::io::Data>::read_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
408
388k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
388k
                Ok(read.read_from_little_endian()?)
410
388k
            }
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
365k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
365k
                Ok(read.read_from_little_endian()?)
410
365k
            }
<f64 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
638
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
638
                Ok(read.read_from_little_endian()?)
410
638
            }
<u16 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
144
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
144
                Ok(read.read_from_little_endian()?)
410
144
            }
<u32 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
144k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
144k
                Ok(read.read_from_little_endian()?)
410
144k
            }
<i32 as exr::io::Data>::read_le::<&[u8]>
Line
Count
Source
408
587k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
587k
                Ok(read.read_from_little_endian()?)
410
587k
            }
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
17.7k
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
17.7k
                Ok(read.read_from_little_endian()?)
410
17.7k
            }
<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
85
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
85
                Ok(read.read_from_little_endian()?)
410
85
            }
<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.77M
            fn read_le(read: &mut impl Read) -> Result<Self> {
409
1.77M
                Ok(read.read_from_little_endian()?)
410
1.77M
            }
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
644k
            fn read_ne(read: &mut impl Read) -> Result<Self> {
414
644k
                Ok(read.read_from_native_endian()?)
415
644k
            }
<u8 as exr::io::Data>::read_ne::<&[u8]>
Line
Count
Source
413
644k
            fn read_ne(read: &mut impl Read) -> Result<Self> {
414
644k
                Ok(read.read_from_native_endian()?)
415
644k
            }
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.77M
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
1.77M
                write.write_as_little_endian(&self)?;
420
1.77M
                Ok(())
421
1.77M
            }
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.97k
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
2.97k
                write.write_as_little_endian(&self)?;
420
2.97k
                Ok(())
421
2.97k
            }
<u32 as exr::io::Data>::write_le::<exr::io::Tracking<&mut std::io::cursor::Cursor<&mut alloc::vec::Vec<u8>>>>
Line
Count
Source
418
255
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
255
                write.write_as_little_endian(&self)?;
420
255
                Ok(())
421
255
            }
<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.77M
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
1.77M
                write.write_as_little_endian(&self)?;
420
1.77M
                Ok(())
421
1.77M
            }
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
340
            fn write_le(self, write: &mut impl Write) -> Result<()> {
419
340
                write.write_as_little_endian(&self)?;
420
340
                Ok(())
421
340
            }
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
146M
            fn write_ne(self, write: &mut impl Write) -> Result<()> {
425
146M
                write.write_as_native_endian(&self)?;
426
146M
                Ok(())
427
146M
            }
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
146M
            fn write_ne(self, write: &mut impl Write) -> Result<()> {
425
146M
                write.write_as_native_endian(&self)?;
426
146M
                Ok(())
427
146M
            }
428
429
            #[inline]
430
2.15M
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
2.15M
                read.read_from_little_endian_into(slice)?;
432
2.15M
                Ok(())
433
2.15M
            }
<u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
430
1.61M
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
1.61M
                read.read_from_little_endian_into(slice)?;
432
1.60M
                Ok(())
433
1.61M
            }
<u8 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<&[u8]>>
Line
Count
Source
430
2.48k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
2.48k
                read.read_from_little_endian_into(slice)?;
432
2.48k
                Ok(())
433
2.48k
            }
<u8 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
29.0k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
29.0k
                read.read_from_little_endian_into(slice)?;
432
29.0k
                Ok(())
433
29.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
119k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
119k
                read.read_from_little_endian_into(slice)?;
432
119k
                Ok(())
433
119k
            }
<i8 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
2.21k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
2.21k
                read.read_from_little_endian_into(slice)?;
432
2.21k
                Ok(())
433
2.21k
            }
<u64 as exr::io::Data>::read_slice_le::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
430
10.2k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
10.2k
                read.read_from_little_endian_into(slice)?;
432
10.0k
                Ok(())
433
10.2k
            }
<f32 as exr::io::Data>::read_slice_le::<&[u8]>
Line
Count
Source
430
22.6k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
22.6k
                read.read_from_little_endian_into(slice)?;
432
22.6k
                Ok(())
433
22.6k
            }
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
355k
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
355k
                read.read_from_little_endian_into(slice)?;
432
355k
                Ok(())
433
355k
            }
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
85
            fn read_slice_le(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
431
85
                read.read_from_little_endian_into(slice)?;
432
85
                Ok(())
433
85
            }
434
435
            #[inline]
436
67.5M
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
67.5M
                read.read_from_native_endian_into(slice)?;
438
67.5M
                Ok(())
439
67.5M
            }
<u8 as exr::io::Data>::read_slice_ne::<exr::io::PeekRead<exr::io::Tracking<std::io::cursor::Cursor<&[u8]>>>>
Line
Count
Source
436
6.13k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
6.13k
                read.read_from_native_endian_into(slice)?;
438
6.13k
                Ok(())
439
6.13k
            }
<u16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
151k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
151k
                read.read_from_native_endian_into(slice)?;
438
151k
                Ok(())
439
151k
            }
<u32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
89.4k
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
89.4k
                read.read_from_native_endian_into(slice)?;
438
89.4k
                Ok(())
439
89.4k
            }
<f32 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
436
67.3M
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
67.3M
                read.read_from_native_endian_into(slice)?;
438
67.3M
                Ok(())
439
67.3M
            }
<u8 as exr::io::Data>::read_slice_ne::<&[u8]>
Line
Count
Source
436
61
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
61
                read.read_from_native_endian_into(slice)?;
438
61
                Ok(())
439
61
            }
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
85
            fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
437
85
                read.read_from_native_endian_into(slice)?;
438
85
                Ok(())
439
85
            }
440
441
            #[inline]
442
357k
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
357k
                write.write_as_little_endian(slice)?;
444
357k
                Ok(())
445
357k
            }
Unexecuted instantiation: <u8 as exr::io::Data>::write_slice_le::<alloc::vec::Vec<u8>>
<u16 as exr::io::Data>::write_slice_le::<alloc::vec::Vec<u8>>
Line
Count
Source
442
192
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
192
                write.write_as_little_endian(slice)?;
444
192
                Ok(())
445
192
            }
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
356k
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
356k
                write.write_as_little_endian(slice)?;
444
356k
                Ok(())
445
356k
            }
<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
340
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
340
                write.write_as_little_endian(slice)?;
444
340
                Ok(())
445
340
            }
<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
85
            fn write_slice_le(write: &mut impl Write, slice: &[Self]) -> Result<()> {
443
85
                write.write_as_little_endian(slice)?;
444
85
                Ok(())
445
85
            }
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
397
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
397
                write.write_as_native_endian(slice)?;
450
397
                Ok(())
451
397
            }
<u8 as exr::io::Data>::write_slice_ne::<alloc::vec::Vec<u8>>
Line
Count
Source
448
312
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
312
                write.write_as_native_endian(slice)?;
450
312
                Ok(())
451
312
            }
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
85
            fn write_slice_ne(write: &mut impl Write, slice: &[Self]) -> Result<()> {
449
85
                write.write_as_native_endian(slice)?;
450
85
                Ok(())
451
85
            }
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
151k
    fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
487
151k
        let bits_mut = slice.reinterpret_cast_mut();
488
151k
        u16::read_slice_ne(read, bits_mut)
489
151k
    }
<half::binary16::f16 as exr::io::Data>::read_slice_ne::<&mut &mut &[u8]>
Line
Count
Source
486
151k
    fn read_slice_ne(read: &mut impl Read, slice: &mut [Self]) -> Result<()> {
487
151k
        let bits_mut = slice.reinterpret_cast_mut();
488
151k
        u16::read_slice_ne(read, bits_mut)
489
151k
    }
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