(&mut self, buf: &mut [u8])
| 135 | |
| 136 | impl Read for RawFile { |
| 137 | fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { |
| 138 | if self.is_aligned(buf) { |
| 139 | match self.file.read(buf) { |
| 140 | Ok(r) => { |
| 141 | self.position = self.position.checked_add(r.try_into().unwrap()).unwrap(); |
| 142 | Ok(r) |
| 143 | } |
| 144 | Err(e) => Err(e), |
| 145 | } |
| 146 | } else { |
| 147 | let rounded_pos: u64 = self.round_down(self.position); |
| 148 | let file_offset: usize = self |
| 149 | .position |
| 150 | .checked_sub(rounded_pos) |
| 151 | .unwrap() |
| 152 | .try_into() |
| 153 | .unwrap(); |
| 154 | let buf_len: usize = buf.len(); |
| 155 | let rounded_len: usize = self |
| 156 | .round_up( |
| 157 | file_offset |
| 158 | .checked_add(buf_len) |
| 159 | .unwrap() |
| 160 | .try_into() |
| 161 | .unwrap(), |
| 162 | ) |
| 163 | .try_into() |
| 164 | .unwrap(); |
| 165 | |
| 166 | let layout = Layout::from_size_align(rounded_len, self.alignment).unwrap(); |
| 167 | // SAFETY: layout has non-zero size |
| 168 | let tmp_ptr = unsafe { alloc_zeroed(layout) }; |
| 169 | if tmp_ptr.is_null() { |
| 170 | return Err(io::Error::last_os_error()); |
| 171 | } |
| 172 | |
| 173 | // SAFETY: tmp_ptr is valid and at least rounded_len long |
| 174 | let tmp_buf = unsafe { slice::from_raw_parts_mut(tmp_ptr, rounded_len) }; |
| 175 | |
| 176 | // This can eventually replaced with read_at once its interface |
| 177 | // has been stabilized. |
| 178 | // SAFETY: FFI call. All parameters are valid. |
| 179 | let ret = unsafe { |
| 180 | ::libc::pread64( |
| 181 | self.file.as_raw_fd(), |
| 182 | tmp_buf.as_mut_ptr().cast(), |
| 183 | tmp_buf.len(), |
| 184 | rounded_pos.try_into().unwrap(), |
| 185 | ) |
| 186 | }; |
| 187 | if ret < 0 { |
| 188 | // SAFETY: tmp_ptr was allocated by alloc_zeroed with layout |
| 189 | unsafe { dealloc(tmp_ptr, layout) }; |
| 190 | return Err(io::Error::last_os_error()); |
| 191 | } |
| 192 | |
| 193 | let read: usize = ret.try_into().unwrap(); |
| 194 | if read < file_offset { |
nothing calls this directly
no test coverage detected