| 481 | } |
| 482 | |
| 483 | fn get_contents_ext( |
| 484 | &self, |
| 485 | node: GraphNode<Option<Hash>>, |
| 486 | buf: &mut [u8], |
| 487 | ) -> Result<usize, Self::Error> { |
| 488 | // Handle empty vertices or no hash |
| 489 | if node.end <= node.start { |
| 490 | return Ok(0); |
| 491 | } |
| 492 | |
| 493 | let hash = match node.change { |
| 494 | Some(h) => h, |
| 495 | None => return Ok(0), |
| 496 | }; |
| 497 | |
| 498 | // Load the change |
| 499 | let changes = self.changes.read().unwrap(); |
| 500 | let change = changes |
| 501 | .get(&hash) |
| 502 | .ok_or_else(|| MemoryStoreError::NotFound(hash.to_base32()))?; |
| 503 | |
| 504 | // Extract the content range |
| 505 | let start = node.start.0.as_u64() as usize; |
| 506 | let end = node.end.0.as_u64() as usize; |
| 507 | |
| 508 | if end > change.contents.len() { |
| 509 | return Err(MemoryStoreError::OutOfBounds { |
| 510 | start: start as u64, |
| 511 | end: end as u64, |
| 512 | len: change.contents.len(), |
| 513 | }); |
| 514 | } |
| 515 | |
| 516 | let content = &change.contents[start..end]; |
| 517 | let len = content.len().min(buf.len()); |
| 518 | buf[..len].copy_from_slice(&content[..len]); |
| 519 | |
| 520 | Ok(len) |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | // TESTS |