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