blob: 7eb1d1afbf0a3f2803779a28af13285993ca2e20 [file] [log] [blame]
Scott Bakered4efab2020-01-13 19:12:25 -08001package 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}