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 }