| 239 | |
| 240 | #[inline(always)] |
| 241 | fn copy_within(&mut self, dst: usize, src: usize, len: usize) -> Option<()> { |
| 242 | self.checked_end(src, len)?; |
| 243 | self.checked_end(dst, len)?; |
| 244 | |
| 245 | if len == 0 || dst == src { |
| 246 | return Some(()); |
| 247 | } |
| 248 | |
| 249 | if self.copy_within_single_chunk(dst, src, len) { |
| 250 | return Some(()); |
| 251 | } |
| 252 | |
| 253 | let mut buf = [0u8; 256]; |
| 254 | |
| 255 | if dst < src || dst >= src + len { |
| 256 | let mut copied = 0; |
| 257 | while copied < len { |
| 258 | let chunk_len = min(buf.len(), len - copied); |
| 259 | self.read_exact(src + copied, &mut buf[..chunk_len])?; |
| 260 | self.write_all(dst + copied, &buf[..chunk_len])?; |
| 261 | copied += chunk_len; |
| 262 | } |
| 263 | } else { |
| 264 | let mut remaining = len; |
| 265 | while remaining > 0 { |
| 266 | let chunk_len = min(buf.len(), remaining); |
| 267 | let chunk_start = remaining - chunk_len; |
| 268 | self.read_exact(src + chunk_start, &mut buf[..chunk_len])?; |
| 269 | self.write_all(dst + chunk_start, &buf[..chunk_len])?; |
| 270 | remaining = chunk_start; |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | Some(()) |
| 275 | } |
| 276 | |
| 277 | #[inline(always)] |
| 278 | fn read_8(&self, base: u64, offset: u64) -> core::result::Result<u8, crate::Trap> { |