github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/block/dynamicDiskBlockReader.go (about) 1 package block 2 3 import ( 4 "io" 5 6 "github.com/Microsoft/azure-vhd-utils/vhdcore/bat" 7 "github.com/Microsoft/azure-vhd-utils/vhdcore/footer" 8 "github.com/Microsoft/azure-vhd-utils/vhdcore/reader" 9 ) 10 11 // DynamicDiskBlockReader type satisfies BlockDataReader interface, 12 // implementation of BlockDataReader::Read by this type can read the 'data' section 13 // of a dynamic disk's block. 14 // 15 type DynamicDiskBlockReader struct { 16 vhdReader *reader.VhdReader 17 blockAllocationTable *bat.BlockAllocationTable 18 blockSizeInBytes uint32 19 emptyBlockData []byte 20 } 21 22 // NewDynamicDiskBlockReader create a new instance of DynamicDiskBlockReader which read 23 // the 'data' section of dynamic disk block. 24 // The parameter vhdReader is the reader to read the disk 25 // The parameter blockAllocationTable represents the disk's BAT 26 // The parameter blockSizeInBytes is the size of the dynamic disk block 27 // 28 func NewDynamicDiskBlockReader(vhdReader *reader.VhdReader, blockAllocationTable *bat.BlockAllocationTable, blockSizeInBytes uint32) *DynamicDiskBlockReader { 29 30 return &DynamicDiskBlockReader{ 31 vhdReader: vhdReader, 32 blockAllocationTable: blockAllocationTable, 33 blockSizeInBytes: blockSizeInBytes, 34 emptyBlockData: nil, 35 } 36 } 37 38 // Read reads the data in a block of a dynamic disk 39 // The parameter block represents the block whose 'data' section to read 40 // 41 func (r *DynamicDiskBlockReader) Read(block *Block) ([]byte, error) { 42 blockIndex := block.BlockIndex 43 if !r.blockAllocationTable.HasData(blockIndex) { 44 if r.emptyBlockData == nil { 45 r.emptyBlockData = make([]byte, r.blockSizeInBytes) 46 } 47 return r.emptyBlockData, nil 48 } 49 50 blockDataByteOffset := r.blockAllocationTable.GetBlockDataAddress(blockIndex) 51 blockDataBuffer := make([]byte, r.blockSizeInBytes) 52 n, err := r.vhdReader.ReadBytes(blockDataByteOffset, blockDataBuffer) 53 if err == io.ErrUnexpectedEOF { 54 return blockDataBuffer[:n], nil 55 } 56 57 if err != nil { 58 return nil, NewDataReadError(blockIndex, footer.DiskTypeDynamic, err) 59 } 60 61 return blockDataBuffer, nil 62 }