123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- package ndr
- import (
- "bytes"
- "encoding/binary"
- "math"
- )
- // 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
- )
- // Bool is an NDR Boolean which is a logical quantity that assumes one of two values: TRUE or FALSE.
- // NDR represents a Boolean as one octet.
- // It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
- // It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
- // Char is an NDR character.
- // NDR represents a character as one octet.
- // Characters have two representation formats: ASCII and EBCDIC.
- // USmall is an unsigned 8 bit integer
- // UShort is an unsigned 16 bit integer
- // ULong is an unsigned 32 bit integer
- // UHyper is an unsigned 64 bit integer
- // Small is an signed 8 bit integer
- // Short is an signed 16 bit integer
- // Long is an signed 32 bit integer
- // Hyper is an signed 64 bit integer
- // Enum is the NDR representation of enumerated types as signed short integers (2 octets)
- // Single is an NDR defined single-precision floating-point data type
- // Double is an NDR defined double-precision floating-point data type
- // readBool reads a byte representing a boolean.
- // NDR represents a Boolean as one octet.
- // It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
- // It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
- func (dec *Decoder) readBool() (bool, error) {
- i, err := dec.readUint8()
- if err != nil {
- return false, err
- }
- if i != 0 {
- return true, nil
- }
- return false, nil
- }
- // readChar reads bytes representing a 8bit ASCII integer cast to a rune.
- func (dec *Decoder) readChar() (rune, error) {
- var r rune
- a, err := dec.readUint8()
- if err != nil {
- return r, err
- }
- return rune(a), nil
- }
- // readUint8 reads bytes representing a 8bit unsigned integer.
- func (dec *Decoder) readUint8() (uint8, error) {
- b, err := dec.r.ReadByte()
- if err != nil {
- return uint8(0), err
- }
- return uint8(b), nil
- }
- // readUint16 reads bytes representing a 16bit unsigned integer.
- func (dec *Decoder) readUint16() (uint16, error) {
- dec.ensureAlignment(SizeUint16)
- b, err := dec.readBytes(SizeUint16)
- if err != nil {
- return uint16(0), err
- }
- return dec.ch.Endianness.Uint16(b), nil
- }
- // readUint32 reads bytes representing a 32bit unsigned integer.
- func (dec *Decoder) readUint32() (uint32, error) {
- dec.ensureAlignment(SizeUint32)
- b, err := dec.readBytes(SizeUint32)
- if err != nil {
- return uint32(0), err
- }
- return dec.ch.Endianness.Uint32(b), nil
- }
- // readUint32 reads bytes representing a 32bit unsigned integer.
- func (dec *Decoder) readUint64() (uint64, error) {
- dec.ensureAlignment(SizeUint64)
- b, err := dec.readBytes(SizeUint64)
- if err != nil {
- return uint64(0), err
- }
- return dec.ch.Endianness.Uint64(b), nil
- }
- func (dec *Decoder) readInt8() (int8, error) {
- dec.ensureAlignment(SizeUint8)
- b, err := dec.readBytes(SizeUint8)
- if err != nil {
- return 0, err
- }
- var i int8
- buf := bytes.NewReader(b)
- err = binary.Read(buf, dec.ch.Endianness, &i)
- if err != nil {
- return 0, err
- }
- return i, nil
- }
- func (dec *Decoder) readInt16() (int16, error) {
- dec.ensureAlignment(SizeUint16)
- b, err := dec.readBytes(SizeUint16)
- if err != nil {
- return 0, err
- }
- var i int16
- buf := bytes.NewReader(b)
- err = binary.Read(buf, dec.ch.Endianness, &i)
- if err != nil {
- return 0, err
- }
- return i, nil
- }
- func (dec *Decoder) readInt32() (int32, error) {
- dec.ensureAlignment(SizeUint32)
- b, err := dec.readBytes(SizeUint32)
- if err != nil {
- return 0, err
- }
- var i int32
- buf := bytes.NewReader(b)
- err = binary.Read(buf, dec.ch.Endianness, &i)
- if err != nil {
- return 0, err
- }
- return i, nil
- }
- func (dec *Decoder) readInt64() (int64, error) {
- dec.ensureAlignment(SizeUint64)
- b, err := dec.readBytes(SizeUint64)
- if err != nil {
- return 0, err
- }
- var i int64
- buf := bytes.NewReader(b)
- err = binary.Read(buf, dec.ch.Endianness, &i)
- if err != nil {
- return 0, err
- }
- return i, nil
- }
- // https://en.wikipedia.org/wiki/IEEE_754-1985
- func (dec *Decoder) readFloat32() (f float32, err error) {
- dec.ensureAlignment(SizeSingle)
- b, err := dec.readBytes(SizeSingle)
- if err != nil {
- return
- }
- bits := dec.ch.Endianness.Uint32(b)
- f = math.Float32frombits(bits)
- return
- }
- func (dec *Decoder) readFloat64() (f float64, err error) {
- dec.ensureAlignment(SizeDouble)
- b, err := dec.readBytes(SizeDouble)
- if err != nil {
- return
- }
- bits := dec.ch.Endianness.Uint64(b)
- f = math.Float64frombits(bits)
- return
- }
- // NDR enforces NDR alignment of primitive data; that is, any primitive of size n octets is aligned at a octet stream
- // index that is a multiple of n. (In this version of NDR, n is one of {1, 2, 4, 8}.) An octet stream index indicates
- // the number of an octet in an octet stream when octets are numbered, beginning with 0, from the first octet in the
- // stream. Where necessary, an alignment gap, consisting of octets of unspecified value, precedes the representation
- // of a primitive. The gap is of the smallest size sufficient to align the primitive.
- func (dec *Decoder) ensureAlignment(n int) {
- p := dec.size - dec.r.Buffered()
- if s := p % n; s != 0 {
- dec.r.Discard(n - s)
- }
- }
|