-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdata_reader.go
More file actions
286 lines (255 loc) · 7.6 KB
/
data_reader.go
File metadata and controls
286 lines (255 loc) · 7.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
package msgpack
import (
"encoding/binary"
"errors"
"math"
)
// ErrRange is returned when attempting to read beyond the buffer boundaries.
var ErrRange = errors.New("range error")
// DataReader provides low-level buffer reading and writing operations.
// It manages a byte buffer with an offset for sequential access.
type DataReader struct {
buffer []byte
byteOffset uint32
err error
}
// NewDataReader creates a new DataReader with the provided buffer.
func NewDataReader(buffer []byte) DataReader {
return DataReader{
buffer: buffer,
}
}
// GetBytes reads a specified number of bytes from the buffer.
// Advances the read position by the number of bytes read.
func (d *DataReader) GetBytes(length uint32) ([]byte, error) {
if err := d.checkBufferSize(length); err != nil {
return nil, err
}
result := d.buffer[d.byteOffset : d.byteOffset+length]
d.byteOffset += length
return result, nil
}
// SetBytes writes bytes to the buffer at the current position.
// Advances the write position by the number of bytes written.
func (d *DataReader) SetBytes(src []byte) error {
srcLen := uint32(len(src))
if err := d.checkBufferSize(srcLen); err != nil {
return err
}
copy(d.buffer[d.byteOffset:], src)
d.byteOffset += srcLen
return nil
}
// PeekUint8 reads a uint8 value without advancing the read position.
func (d *DataReader) PeekUint8() (uint8, error) {
if err := d.checkBufferSize(1); err != nil {
return 0, err
}
return d.buffer[d.byteOffset], nil
}
// Discard advances the read position by the specified number of bytes.
func (d *DataReader) Discard(length uint32) error {
if err := d.checkBufferSize(length); err != nil {
return err
}
d.byteOffset += length
return nil
}
// GetFloat32 reads a float32 value from the buffer in big-endian format.
func (d *DataReader) GetFloat32() (float32, error) {
if err := d.checkBufferSize(4); err != nil {
return 0, err
}
v := binary.BigEndian.Uint32(d.buffer[d.byteOffset:])
d.byteOffset += 4
return math.Float32frombits(v), nil
}
// GetFloat64 reads a float64 value from the buffer in big-endian format.
func (d *DataReader) GetFloat64() (float64, error) {
if err := d.checkBufferSize(8); err != nil {
return 0, err
}
v := binary.BigEndian.Uint64(d.buffer[d.byteOffset:])
d.byteOffset += 8
return math.Float64frombits(v), nil
}
// GetInt8 reads an int8 value from the buffer.
func (d *DataReader) GetInt8() (int8, error) {
if err := d.checkBufferSize(1); err != nil {
return 0, err
}
result := d.buffer[d.byteOffset]
d.byteOffset++
return int8(result), nil
}
// GetInt16 reads an int16 value from the buffer in big-endian format.
func (d *DataReader) GetInt16() (int16, error) {
if err := d.checkBufferSize(2); err != nil {
return 0, err
}
result := binary.BigEndian.Uint16(d.buffer[d.byteOffset:])
d.byteOffset += 2
return int16(result), nil
}
// GetInt32 reads an int32 value from the buffer in big-endian format.
func (d *DataReader) GetInt32() (int32, error) {
if err := d.checkBufferSize(4); err != nil {
return 0, err
}
result := binary.BigEndian.Uint32(d.buffer[d.byteOffset:])
d.byteOffset += 4
return int32(result), nil
}
// GetInt64 reads an int64 value from the buffer in big-endian format.
func (d *DataReader) GetInt64() (int64, error) {
if err := d.checkBufferSize(8); err != nil {
return 0, err
}
result := binary.BigEndian.Uint64(d.buffer[d.byteOffset:])
d.byteOffset += 8
return int64(result), nil
}
// GetUint8 reads a uint8 value from the buffer.
func (d *DataReader) GetUint8() (uint8, error) {
if err := d.checkBufferSize(1); err != nil {
return 0, err
}
result := d.buffer[d.byteOffset]
d.byteOffset++
return result, nil
}
// GetUint16 reads a uint16 value from the buffer in big-endian format.
func (d *DataReader) GetUint16() (uint16, error) {
if err := d.checkBufferSize(2); err != nil {
return 0, err
}
result := binary.BigEndian.Uint16(d.buffer[d.byteOffset:])
d.byteOffset += 2
return result, nil
}
// GetUint32 reads a uint32 value from the buffer in big-endian format.
func (d *DataReader) GetUint32() (uint32, error) {
if err := d.checkBufferSize(4); err != nil {
return 0, err
}
result := binary.BigEndian.Uint32(d.buffer[d.byteOffset:])
d.byteOffset += 4
return result, nil
}
// GetUint64 reads a uint64 value from the buffer in big-endian format.
func (d *DataReader) GetUint64() (uint64, error) {
if err := d.checkBufferSize(8); err != nil {
return 0, err
}
result := binary.BigEndian.Uint64(d.buffer[d.byteOffset:])
d.byteOffset += 8
return result, nil
}
// SetFloat32 writes a float32 value to the buffer in big-endian format.
func (d *DataReader) SetFloat32(value float32) error {
if err := d.checkBufferSize(4); err != nil {
return err
}
bits := math.Float32bits(value)
binary.BigEndian.PutUint32(d.buffer[d.byteOffset:], bits)
d.byteOffset += 4
return nil
}
// SetFloat64 writes a float64 value to the buffer in big-endian format.
func (d *DataReader) SetFloat64(value float64) error {
if err := d.checkBufferSize(8); err != nil {
return err
}
bits := math.Float64bits(value)
binary.BigEndian.PutUint64(d.buffer[d.byteOffset:], bits)
d.byteOffset += 8
return nil
}
// SetInt8 writes an int8 value to the buffer.
func (d *DataReader) SetInt8(value int8) error {
if err := d.checkBufferSize(1); err != nil {
return err
}
d.buffer[d.byteOffset] = uint8(value)
d.byteOffset++
return nil
}
// SetInt16 writes an int16 value to the buffer in big-endian format.
func (d *DataReader) SetInt16(value int16) error {
if err := d.checkBufferSize(2); err != nil {
return err
}
binary.BigEndian.PutUint16(d.buffer[d.byteOffset:], uint16(value))
d.byteOffset += 2
return nil
}
// SetInt32 writes an int32 value to the buffer in big-endian format.
func (d *DataReader) SetInt32(value int32) error {
if err := d.checkBufferSize(4); err != nil {
return err
}
binary.BigEndian.PutUint32(d.buffer[d.byteOffset:], uint32(value))
d.byteOffset += 4
return nil
}
// SetInt64 writes an int64 value to the buffer in big-endian format.
func (d *DataReader) SetInt64(value int64) error {
if err := d.checkBufferSize(8); err != nil {
return err
}
binary.BigEndian.PutUint64(d.buffer[d.byteOffset:], uint64(value))
d.byteOffset += 8
return nil
}
// SetUint8 writes a uint8 value to the buffer.
func (d *DataReader) SetUint8(value uint8) error {
if err := d.checkBufferSize(1); err != nil {
return err
}
d.buffer[d.byteOffset] = value
d.byteOffset++
return nil
}
// SetUint16 writes a uint16 value to the buffer in big-endian format.
func (d *DataReader) SetUint16(value uint16) error {
if err := d.checkBufferSize(2); err != nil {
return err
}
binary.BigEndian.PutUint16(d.buffer[d.byteOffset:], value)
d.byteOffset += 2
return nil
}
// SetUint32 writes a uint32 value to the buffer in big-endian format.
func (d *DataReader) SetUint32(value uint32) error {
if err := d.checkBufferSize(4); err != nil {
return err
}
binary.BigEndian.PutUint32(d.buffer[d.byteOffset:], value)
d.byteOffset += 4
return nil
}
// SetUint64 writes a uint64 value to the buffer in big-endian format.
func (d *DataReader) SetUint64(value uint64) error {
if err := d.checkBufferSize(8); err != nil {
return err
}
binary.BigEndian.PutUint64(d.buffer[d.byteOffset:], value)
d.byteOffset += 8
return nil
}
// checkBufferSize verifies that the requested number of bytes is available.
// Returns ErrRange if the buffer is too small.
func (d *DataReader) checkBufferSize(length uint32) error {
if d.err != nil {
return d.err
}
if d.byteOffset+length > uint32(len(d.buffer)) {
d.err = ErrRange
return d.err
}
return nil
}
// Err returns any error that occurred during buffer operations.
func (d *DataReader) Err() error {
return d.err
}