(kind: &mut BackingKind, address: u64, buf: &mut [u8])
| 290 | } |
| 291 | |
| 292 | fn read_at_inner(kind: &mut BackingKind, address: u64, buf: &mut [u8]) -> std::io::Result<()> { |
| 293 | match kind { |
| 294 | BackingKind::Raw(file) => { |
| 295 | file.seek(SeekFrom::Start(address))?; |
| 296 | file.read_exact(buf) |
| 297 | } |
| 298 | #[cfg(test)] |
| 299 | BackingKind::QcowFile(qcow) => { |
| 300 | qcow.seek(SeekFrom::Start(address))?; |
| 301 | qcow.read_exact(buf) |
| 302 | } |
| 303 | BackingKind::Qcow { inner, backing } => { |
| 304 | let has_backing = backing.is_some(); |
| 305 | let cluster_size = inner.raw_file.cluster_size(); |
| 306 | let mut pos = 0usize; |
| 307 | while pos < buf.len() { |
| 308 | let curr_addr = address + pos as u64; |
| 309 | let intra = inner.raw_file.cluster_offset(curr_addr) as usize; |
| 310 | let count = min(buf.len() - pos, cluster_size as usize - intra); |
| 311 | let mapping = inner.map_cluster_read(curr_addr, count, has_backing)?; |
| 312 | match mapping { |
| 313 | ClusterReadMapping::Zero { length } => { |
| 314 | buf[pos..pos + length as usize].fill(0); |
| 315 | } |
| 316 | ClusterReadMapping::Allocated { |
| 317 | offset: host_off, |
| 318 | length, |
| 319 | } => { |
| 320 | inner.raw_file.file_mut().seek(SeekFrom::Start(host_off))?; |
| 321 | inner |
| 322 | .raw_file |
| 323 | .file_mut() |
| 324 | .read_exact(&mut buf[pos..pos + length as usize])?; |
| 325 | } |
| 326 | ClusterReadMapping::Compressed { |
| 327 | host_offset, |
| 328 | compressed_size, |
| 329 | cluster_offset, |
| 330 | length, |
| 331 | } => { |
| 332 | let mut compressed = vec![0u8; compressed_size]; |
| 333 | inner |
| 334 | .raw_file |
| 335 | .file_mut() |
| 336 | .seek(SeekFrom::Start(host_offset))?; |
| 337 | inner.raw_file.file_mut().read_exact(&mut compressed)?; |
| 338 | let decompressed = decompress_cluster( |
| 339 | &compressed, |
| 340 | cluster_size as usize, |
| 341 | &*inner.header.get_decoder(), |
| 342 | )?; |
| 343 | buf[pos..pos + length].copy_from_slice( |
| 344 | &decompressed[cluster_offset..cluster_offset + length], |
| 345 | ); |
| 346 | } |
| 347 | ClusterReadMapping::Backing { |
| 348 | offset: backing_off, |
| 349 | length, |
nothing calls this directly
no test coverage detected