Copies `len` bytes from `src` to `dst` within the same memory.
(&mut self, dst: usize, src: usize, len: usize)
| 90 | |
| 91 | /// Copies `len` bytes from `src` to `dst` within the same memory. |
| 92 | fn copy_within(&mut self, dst: usize, src: usize, len: usize) -> Option<()> { |
| 93 | let src_end = src.checked_add(len)?; |
| 94 | let dst_end = dst.checked_add(len)?; |
| 95 | if src_end > self.len() || dst_end > self.len() { |
| 96 | return None; |
| 97 | } |
| 98 | |
| 99 | if len == 0 || dst == src { |
| 100 | return Some(()); |
| 101 | } |
| 102 | |
| 103 | // If the source and destination ranges are disjoint, we can copy forward without a temporary buffer. |
| 104 | if dst < src || dst >= src_end { |
| 105 | let mut offset = 0; |
| 106 | while offset < len { |
| 107 | let chunk_len = min(len - offset, 1024); |
| 108 | let mut chunk = vec![0; chunk_len]; |
| 109 | self.read_exact(src + offset, &mut chunk)?; |
| 110 | self.write_all(dst + offset, &chunk)?; |
| 111 | offset += chunk_len; |
| 112 | } |
| 113 | } else { |
| 114 | // Otherwise, we need to copy backward to avoid overwriting the source data before it's read. |
| 115 | let mut offset = len; |
| 116 | while offset > 0 { |
| 117 | let chunk_len = min(offset, 1024); |
| 118 | offset -= chunk_len; |
| 119 | let mut chunk = vec![0; chunk_len]; |
| 120 | self.read_exact(src + offset, &mut chunk)?; |
| 121 | self.write_all(dst + offset, &chunk)?; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | Some(()) |
| 126 | } |
| 127 | |
| 128 | /// Reads exactly `dst.len()` bytes starting at `addr`. |
| 129 | fn read_exact(&self, addr: usize, dst: &mut [u8]) -> Option<()> { |