|
18 | 18 | class VDI: |
19 | 19 | """VirtualBox Virtual Disk Image (VDI) implementation. |
20 | 20 |
|
| 21 | + If provided with file-like objects, the caller is responsible for closing them. |
| 22 | + When provided with paths, the VDI class will manage the file handles. |
| 23 | +
|
21 | 24 | Args: |
22 | 25 | fh: File-like object or path of the VDI file. |
23 | | - parent: Optional file-like object for the parent disk (for differencing disks). |
| 26 | + parent: Optional file-like object or path for the parent disk (for differencing disks). |
24 | 27 | """ |
25 | 28 |
|
26 | | - def __init__(self, fh: BinaryIO | Path, parent: BinaryIO | None = None): |
| 29 | + def __init__(self, fh: BinaryIO | Path, parent: BinaryIO | Path | None = None): |
27 | 30 | if isinstance(fh, Path): |
28 | 31 | self.path = fh |
29 | 32 | self.fh = self.path.open("rb") |
30 | 33 | else: |
31 | 34 | self.path = None |
32 | 35 | self.fh = fh |
33 | 36 |
|
34 | | - self.parent = parent |
| 37 | + if isinstance(parent, Path): |
| 38 | + self.parent_path = parent |
| 39 | + self.parent = self.parent_path.open("rb") |
| 40 | + else: |
| 41 | + self.parent_path = None |
| 42 | + self.parent = parent |
35 | 43 |
|
36 | 44 | self.fh.seek(0) |
37 | 45 | self.preheader = c_vdi.VDIPREHEADER(self.fh) |
38 | 46 | if self.preheader.u32Signature != VDI_IMAGE_SIGNATURE: |
39 | | - print(self.preheader) |
40 | 47 | raise Error( |
41 | 48 | f"Invalid VDI signature, expected {VDI_IMAGE_SIGNATURE:#08X}, got {self.preheader.u32Signature:#08X}" |
42 | 49 | ) |
@@ -95,6 +102,9 @@ def close(self) -> None: |
95 | 102 | if self.path is not None: |
96 | 103 | self.fh.close() |
97 | 104 |
|
| 105 | + if self.parent_path is not None and self.parent is not None: |
| 106 | + self.parent.close() |
| 107 | + |
98 | 108 |
|
99 | 109 | class VDIStream(AlignedStream): |
100 | 110 | def __init__(self, vdi: VDI): |
|
0 commit comments