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  }