110 lines
2.2 KiB
Go
110 lines
2.2 KiB
Go
|
package mstypes
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"encoding/binary"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
// Byte sizes of primitive types
|
||
|
const (
|
||
|
SizeBool = 1
|
||
|
SizeChar = 1
|
||
|
SizeUint8 = 1
|
||
|
SizeUint16 = 2
|
||
|
SizeUint32 = 4
|
||
|
SizeUint64 = 8
|
||
|
SizeEnum = 2
|
||
|
SizeSingle = 4
|
||
|
SizeDouble = 8
|
||
|
SizePtr = 4
|
||
|
)
|
||
|
|
||
|
// Reader reads simple byte stream data into a Go representations
|
||
|
type Reader struct {
|
||
|
r *bufio.Reader // source of the data
|
||
|
}
|
||
|
|
||
|
// NewReader creates a new instance of a simple Reader.
|
||
|
func NewReader(r io.Reader) *Reader {
|
||
|
reader := new(Reader)
|
||
|
reader.r = bufio.NewReader(r)
|
||
|
return reader
|
||
|
}
|
||
|
|
||
|
func (r *Reader) Read(p []byte) (n int, err error) {
|
||
|
return r.r.Read(p)
|
||
|
}
|
||
|
|
||
|
func (r *Reader) Uint8() (uint8, error) {
|
||
|
b, err := r.r.ReadByte()
|
||
|
if err != nil {
|
||
|
return uint8(0), err
|
||
|
}
|
||
|
return uint8(b), nil
|
||
|
}
|
||
|
|
||
|
func (r *Reader) Uint16() (uint16, error) {
|
||
|
b, err := r.ReadBytes(SizeUint16)
|
||
|
if err != nil {
|
||
|
return uint16(0), err
|
||
|
}
|
||
|
return binary.LittleEndian.Uint16(b), nil
|
||
|
}
|
||
|
|
||
|
func (r *Reader) Uint32() (uint32, error) {
|
||
|
b, err := r.ReadBytes(SizeUint32)
|
||
|
if err != nil {
|
||
|
return uint32(0), err
|
||
|
}
|
||
|
return binary.LittleEndian.Uint32(b), nil
|
||
|
}
|
||
|
|
||
|
func (r *Reader) Uint64() (uint64, error) {
|
||
|
b, err := r.ReadBytes(SizeUint64)
|
||
|
if err != nil {
|
||
|
return uint64(0), err
|
||
|
}
|
||
|
return binary.LittleEndian.Uint64(b), nil
|
||
|
}
|
||
|
|
||
|
func (r *Reader) FileTime() (f FileTime, err error) {
|
||
|
f.LowDateTime, err = r.Uint32()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
f.HighDateTime, err = r.Uint32()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// UTF16String returns a string that is UTF16 encoded in a byte slice. n is the number of bytes representing the string
|
||
|
func (r *Reader) UTF16String(n int) (str string, err error) {
|
||
|
//Length divided by 2 as each run is 16bits = 2bytes
|
||
|
s := make([]rune, n/2, n/2)
|
||
|
for i := 0; i < len(s); i++ {
|
||
|
var u uint16
|
||
|
u, err = r.Uint16()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
s[i] = rune(u)
|
||
|
}
|
||
|
str = string(s)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// readBytes returns a number of bytes from the NDR byte stream.
|
||
|
func (r *Reader) ReadBytes(n int) ([]byte, error) {
|
||
|
//TODO make this take an int64 as input to allow for larger values on all systems?
|
||
|
b := make([]byte, n, n)
|
||
|
m, err := r.r.Read(b)
|
||
|
if err != nil || m != n {
|
||
|
return b, fmt.Errorf("error reading bytes from stream: %v", err)
|
||
|
}
|
||
|
return b, nil
|
||
|
}
|