1package ndr
2
3import (
4	"bytes"
5	"encoding/binary"
6	"math"
7)
8
9// Byte sizes of primitive types
10const (
11	SizeBool   = 1
12	SizeChar   = 1
13	SizeUint8  = 1
14	SizeUint16 = 2
15	SizeUint32 = 4
16	SizeUint64 = 8
17	SizeEnum   = 2
18	SizeSingle = 4
19	SizeDouble = 8
20	SizePtr    = 4
21)
22
23// Bool is an NDR Boolean which is a logical quantity that assumes one of two values: TRUE or FALSE.
24// NDR represents a Boolean as one octet.
25// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
26// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
27
28// Char is an NDR character.
29// NDR represents a character as one octet.
30// Characters have two representation formats: ASCII and EBCDIC.
31
32// USmall is an unsigned 8 bit integer
33
34// UShort is an unsigned 16 bit integer
35
36// ULong is an unsigned 32 bit integer
37
38// UHyper is an unsigned 64 bit integer
39
40// Small is an signed 8 bit integer
41
42// Short is an signed 16 bit integer
43
44// Long is an signed 32 bit integer
45
46// Hyper is an signed 64 bit integer
47
48// Enum is the NDR representation of enumerated types as signed short integers (2 octets)
49
50// Single is an NDR defined single-precision floating-point data type
51
52// Double is an NDR defined double-precision floating-point data type
53
54// readBool reads a byte representing a boolean.
55// NDR represents a Boolean as one octet.
56// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
57// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
58func (dec *Decoder) readBool() (bool, error) {
59	i, err := dec.readUint8()
60	if err != nil {
61		return false, err
62	}
63	if i != 0 {
64		return true, nil
65	}
66	return false, nil
67}
68
69// readChar reads bytes representing a 8bit ASCII integer cast to a rune.
70func (dec *Decoder) readChar() (rune, error) {
71	var r rune
72	a, err := dec.readUint8()
73	if err != nil {
74		return r, err
75	}
76	return rune(a), nil
77}
78
79// readUint8 reads bytes representing a 8bit unsigned integer.
80func (dec *Decoder) readUint8() (uint8, error) {
81	b, err := dec.r.ReadByte()
82	if err != nil {
83		return uint8(0), err
84	}
85	return uint8(b), nil
86}
87
88// readUint16 reads bytes representing a 16bit unsigned integer.
89func (dec *Decoder) readUint16() (uint16, error) {
90	dec.ensureAlignment(SizeUint16)
91	b, err := dec.readBytes(SizeUint16)
92	if err != nil {
93		return uint16(0), err
94	}
95	return dec.ch.Endianness.Uint16(b), nil
96}
97
98// readUint32 reads bytes representing a 32bit unsigned integer.
99func (dec *Decoder) readUint32() (uint32, error) {
100	dec.ensureAlignment(SizeUint32)
101	b, err := dec.readBytes(SizeUint32)
102	if err != nil {
103		return uint32(0), err
104	}
105	return dec.ch.Endianness.Uint32(b), nil
106}
107
108// readUint32 reads bytes representing a 32bit unsigned integer.
109func (dec *Decoder) readUint64() (uint64, error) {
110	dec.ensureAlignment(SizeUint64)
111	b, err := dec.readBytes(SizeUint64)
112	if err != nil {
113		return uint64(0), err
114	}
115	return dec.ch.Endianness.Uint64(b), nil
116}
117
118func (dec *Decoder) readInt8() (int8, error) {
119	dec.ensureAlignment(SizeUint8)
120	b, err := dec.readBytes(SizeUint8)
121	if err != nil {
122		return 0, err
123	}
124	var i int8
125	buf := bytes.NewReader(b)
126	err = binary.Read(buf, dec.ch.Endianness, &i)
127	if err != nil {
128		return 0, err
129	}
130	return i, nil
131}
132
133func (dec *Decoder) readInt16() (int16, error) {
134	dec.ensureAlignment(SizeUint16)
135	b, err := dec.readBytes(SizeUint16)
136	if err != nil {
137		return 0, err
138	}
139	var i int16
140	buf := bytes.NewReader(b)
141	err = binary.Read(buf, dec.ch.Endianness, &i)
142	if err != nil {
143		return 0, err
144	}
145	return i, nil
146}
147
148func (dec *Decoder) readInt32() (int32, error) {
149	dec.ensureAlignment(SizeUint32)
150	b, err := dec.readBytes(SizeUint32)
151	if err != nil {
152		return 0, err
153	}
154	var i int32
155	buf := bytes.NewReader(b)
156	err = binary.Read(buf, dec.ch.Endianness, &i)
157	if err != nil {
158		return 0, err
159	}
160	return i, nil
161}
162
163func (dec *Decoder) readInt64() (int64, error) {
164	dec.ensureAlignment(SizeUint64)
165	b, err := dec.readBytes(SizeUint64)
166	if err != nil {
167		return 0, err
168	}
169	var i int64
170	buf := bytes.NewReader(b)
171	err = binary.Read(buf, dec.ch.Endianness, &i)
172	if err != nil {
173		return 0, err
174	}
175	return i, nil
176}
177
178// https://en.wikipedia.org/wiki/IEEE_754-1985
179func (dec *Decoder) readFloat32() (f float32, err error) {
180	dec.ensureAlignment(SizeSingle)
181	b, err := dec.readBytes(SizeSingle)
182	if err != nil {
183		return
184	}
185	bits := dec.ch.Endianness.Uint32(b)
186	f = math.Float32frombits(bits)
187	return
188}
189
190func (dec *Decoder) readFloat64() (f float64, err error) {
191	dec.ensureAlignment(SizeDouble)
192	b, err := dec.readBytes(SizeDouble)
193	if err != nil {
194		return
195	}
196	bits := dec.ch.Endianness.Uint64(b)
197	f = math.Float64frombits(bits)
198	return
199}
200
201// NDR enforces NDR alignment of primitive data; that is, any primitive of size n octets is aligned at a octet stream
202// 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
203// the number of an octet in an octet stream when octets are numbered, beginning with 0, from the first octet in the
204// stream. Where necessary, an alignment gap, consisting of octets of unspecified value, precedes the representation
205// of a primitive. The gap is of the smallest size sufficient to align the primitive.
206func (dec *Decoder) ensureAlignment(n int) {
207	p := dec.size - dec.r.Buffered()
208	if s := p % n; s != 0 {
209		dec.r.Discard(n - s)
210	}
211}
212