github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/reader/vhdReader.go (about)

     1  package reader
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"time"
     7  	"unsafe"
     8  
     9  	"github.com/Microsoft/azure-vhd-utils/vhdcore"
    10  )
    11  
    12  // VhdReader is the reader used by various components responsible for reading different
    13  // segments of VHD such as header, footer, BAT, block, bitmap and sector.
    14  //
    15  type VhdReader struct {
    16  	*BinaryReader
    17  }
    18  
    19  // NewVhdReader creates new instance of the VhdReader, that reads from the underlying
    20  // source, size is the size of the source in bytes.
    21  //
    22  func NewVhdReader(source ReadAtReader, size int64) *VhdReader {
    23  	var order binary.ByteOrder
    24  	if isLittleEndian() {
    25  		order = binary.BigEndian
    26  	} else {
    27  		order = binary.LittleEndian
    28  	}
    29  	return &VhdReader{NewBinaryReader(source, order, size)}
    30  }
    31  
    32  // NewVhdReaderFromByteSlice creates a new instance of VhdReader, that uses the given
    33  // byte slice as the underlying source to read from.
    34  //
    35  func NewVhdReaderFromByteSlice(b []byte) *VhdReader {
    36  	source := bytes.NewReader(b)
    37  	return NewVhdReader(source, int64(len(b)))
    38  }
    39  
    40  // ReadDateTime reads an encoded vhd timestamp from underlying source starting at byte
    41  // offset off and return it as a time.Time.
    42  //
    43  func (r *VhdReader) ReadDateTime(off int64) (*time.Time, error) {
    44  	d, err := r.ReadUInt32(off)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	vhdDateTime := vhdcore.NewVhdTimeStampFromSeconds(d).ToDateTime()
    49  	return &vhdDateTime, nil
    50  }
    51  
    52  // isLittleEndian returns true if the host machine is little endian, false for
    53  // big endian
    54  //
    55  func isLittleEndian() bool {
    56  	var i int32 = 0x01020304
    57  	u := unsafe.Pointer(&i)
    58  	pb := (*byte)(u)
    59  	b := *pb
    60  	return (b == 0x04)
    61  }