cubefs
461 строка · 8.7 Кб
1package sarama
2
3import (
4"encoding/binary"
5"math"
6)
7
8var (
9errInvalidArrayLength = PacketDecodingError{"invalid array length"}
10errInvalidByteSliceLength = PacketDecodingError{"invalid byteslice length"}
11errInvalidStringLength = PacketDecodingError{"invalid string length"}
12errVarintOverflow = PacketDecodingError{"varint overflow"}
13errUVarintOverflow = PacketDecodingError{"uvarint overflow"}
14errInvalidBool = PacketDecodingError{"invalid bool"}
15)
16
17type realDecoder struct {
18raw []byte
19off int
20stack []pushDecoder
21}
22
23// primitives
24
25func (rd *realDecoder) getInt8() (int8, error) {
26if rd.remaining() < 1 {
27rd.off = len(rd.raw)
28return -1, ErrInsufficientData
29}
30tmp := int8(rd.raw[rd.off])
31rd.off++
32return tmp, nil
33}
34
35func (rd *realDecoder) getInt16() (int16, error) {
36if rd.remaining() < 2 {
37rd.off = len(rd.raw)
38return -1, ErrInsufficientData
39}
40tmp := int16(binary.BigEndian.Uint16(rd.raw[rd.off:]))
41rd.off += 2
42return tmp, nil
43}
44
45func (rd *realDecoder) getInt32() (int32, error) {
46if rd.remaining() < 4 {
47rd.off = len(rd.raw)
48return -1, ErrInsufficientData
49}
50tmp := int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
51rd.off += 4
52return tmp, nil
53}
54
55func (rd *realDecoder) getInt64() (int64, error) {
56if rd.remaining() < 8 {
57rd.off = len(rd.raw)
58return -1, ErrInsufficientData
59}
60tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
61rd.off += 8
62return tmp, nil
63}
64
65func (rd *realDecoder) getVarint() (int64, error) {
66tmp, n := binary.Varint(rd.raw[rd.off:])
67if n == 0 {
68rd.off = len(rd.raw)
69return -1, ErrInsufficientData
70}
71if n < 0 {
72rd.off -= n
73return -1, errVarintOverflow
74}
75rd.off += n
76return tmp, nil
77}
78
79func (rd *realDecoder) getUVarint() (uint64, error) {
80tmp, n := binary.Uvarint(rd.raw[rd.off:])
81if n == 0 {
82rd.off = len(rd.raw)
83return 0, ErrInsufficientData
84}
85
86if n < 0 {
87rd.off -= n
88return 0, errUVarintOverflow
89}
90
91rd.off += n
92return tmp, nil
93}
94
95func (rd *realDecoder) getFloat64() (float64, error) {
96if rd.remaining() < 8 {
97rd.off = len(rd.raw)
98return -1, ErrInsufficientData
99}
100tmp := math.Float64frombits(binary.BigEndian.Uint64(rd.raw[rd.off:]))
101rd.off += 8
102return tmp, nil
103}
104
105func (rd *realDecoder) getArrayLength() (int, error) {
106if rd.remaining() < 4 {
107rd.off = len(rd.raw)
108return -1, ErrInsufficientData
109}
110tmp := int(int32(binary.BigEndian.Uint32(rd.raw[rd.off:])))
111rd.off += 4
112if tmp > rd.remaining() {
113rd.off = len(rd.raw)
114return -1, ErrInsufficientData
115} else if tmp > 2*math.MaxUint16 {
116return -1, errInvalidArrayLength
117}
118return tmp, nil
119}
120
121func (rd *realDecoder) getCompactArrayLength() (int, error) {
122n, err := rd.getUVarint()
123if err != nil {
124return 0, err
125}
126
127if n == 0 {
128return 0, nil
129}
130
131return int(n) - 1, nil
132}
133
134func (rd *realDecoder) getBool() (bool, error) {
135b, err := rd.getInt8()
136if err != nil || b == 0 {
137return false, err
138}
139if b != 1 {
140return false, errInvalidBool
141}
142return true, nil
143}
144
145func (rd *realDecoder) getEmptyTaggedFieldArray() (int, error) {
146tagCount, err := rd.getUVarint()
147if err != nil {
148return 0, err
149}
150
151// skip over any tagged fields without deserializing them
152// as we don't currently support doing anything with them
153for i := uint64(0); i < tagCount; i++ {
154// fetch and ignore tag identifier
155_, err := rd.getUVarint()
156if err != nil {
157return 0, err
158}
159length, err := rd.getUVarint()
160if err != nil {
161return 0, err
162}
163if _, err := rd.getRawBytes(int(length)); err != nil {
164return 0, err
165}
166}
167
168return 0, nil
169}
170
171// collections
172
173func (rd *realDecoder) getBytes() ([]byte, error) {
174tmp, err := rd.getInt32()
175if err != nil {
176return nil, err
177}
178if tmp == -1 {
179return nil, nil
180}
181
182return rd.getRawBytes(int(tmp))
183}
184
185func (rd *realDecoder) getVarintBytes() ([]byte, error) {
186tmp, err := rd.getVarint()
187if err != nil {
188return nil, err
189}
190if tmp == -1 {
191return nil, nil
192}
193
194return rd.getRawBytes(int(tmp))
195}
196
197func (rd *realDecoder) getCompactBytes() ([]byte, error) {
198n, err := rd.getUVarint()
199if err != nil {
200return nil, err
201}
202
203length := int(n - 1)
204return rd.getRawBytes(length)
205}
206
207func (rd *realDecoder) getStringLength() (int, error) {
208length, err := rd.getInt16()
209if err != nil {
210return 0, err
211}
212
213n := int(length)
214
215switch {
216case n < -1:
217return 0, errInvalidStringLength
218case n > rd.remaining():
219rd.off = len(rd.raw)
220return 0, ErrInsufficientData
221}
222
223return n, nil
224}
225
226func (rd *realDecoder) getString() (string, error) {
227n, err := rd.getStringLength()
228if err != nil || n == -1 {
229return "", err
230}
231
232tmpStr := string(rd.raw[rd.off : rd.off+n])
233rd.off += n
234return tmpStr, nil
235}
236
237func (rd *realDecoder) getNullableString() (*string, error) {
238n, err := rd.getStringLength()
239if err != nil || n == -1 {
240return nil, err
241}
242
243tmpStr := string(rd.raw[rd.off : rd.off+n])
244rd.off += n
245return &tmpStr, err
246}
247
248func (rd *realDecoder) getCompactString() (string, error) {
249n, err := rd.getUVarint()
250if err != nil {
251return "", err
252}
253
254length := int(n - 1)
255if length < 0 {
256return "", errInvalidByteSliceLength
257}
258tmpStr := string(rd.raw[rd.off : rd.off+length])
259rd.off += length
260return tmpStr, nil
261}
262
263func (rd *realDecoder) getCompactNullableString() (*string, error) {
264n, err := rd.getUVarint()
265if err != nil {
266return nil, err
267}
268
269length := int(n - 1)
270
271if length < 0 {
272return nil, err
273}
274
275tmpStr := string(rd.raw[rd.off : rd.off+length])
276rd.off += length
277return &tmpStr, err
278}
279
280func (rd *realDecoder) getCompactInt32Array() ([]int32, error) {
281n, err := rd.getUVarint()
282if err != nil {
283return nil, err
284}
285
286if n == 0 {
287return nil, nil
288}
289
290arrayLength := int(n) - 1
291
292ret := make([]int32, arrayLength)
293
294for i := range ret {
295ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
296rd.off += 4
297}
298return ret, nil
299}
300
301func (rd *realDecoder) getInt32Array() ([]int32, error) {
302if rd.remaining() < 4 {
303rd.off = len(rd.raw)
304return nil, ErrInsufficientData
305}
306n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
307rd.off += 4
308
309if rd.remaining() < 4*n {
310rd.off = len(rd.raw)
311return nil, ErrInsufficientData
312}
313
314if n == 0 {
315return nil, nil
316}
317
318if n < 0 {
319return nil, errInvalidArrayLength
320}
321
322ret := make([]int32, n)
323for i := range ret {
324ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
325rd.off += 4
326}
327return ret, nil
328}
329
330func (rd *realDecoder) getInt64Array() ([]int64, error) {
331if rd.remaining() < 4 {
332rd.off = len(rd.raw)
333return nil, ErrInsufficientData
334}
335n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
336rd.off += 4
337
338if rd.remaining() < 8*n {
339rd.off = len(rd.raw)
340return nil, ErrInsufficientData
341}
342
343if n == 0 {
344return nil, nil
345}
346
347if n < 0 {
348return nil, errInvalidArrayLength
349}
350
351ret := make([]int64, n)
352for i := range ret {
353ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
354rd.off += 8
355}
356return ret, nil
357}
358
359func (rd *realDecoder) getStringArray() ([]string, error) {
360if rd.remaining() < 4 {
361rd.off = len(rd.raw)
362return nil, ErrInsufficientData
363}
364n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
365rd.off += 4
366
367if n == 0 {
368return nil, nil
369}
370
371if n < 0 {
372return nil, errInvalidArrayLength
373}
374
375ret := make([]string, n)
376for i := range ret {
377str, err := rd.getString()
378if err != nil {
379return nil, err
380}
381
382ret[i] = str
383}
384return ret, nil
385}
386
387// subsets
388
389func (rd *realDecoder) remaining() int {
390return len(rd.raw) - rd.off
391}
392
393func (rd *realDecoder) getSubset(length int) (packetDecoder, error) {
394buf, err := rd.getRawBytes(length)
395if err != nil {
396return nil, err
397}
398return &realDecoder{raw: buf}, nil
399}
400
401func (rd *realDecoder) getRawBytes(length int) ([]byte, error) {
402if length < 0 {
403return nil, errInvalidByteSliceLength
404} else if length > rd.remaining() {
405rd.off = len(rd.raw)
406return nil, ErrInsufficientData
407}
408
409start := rd.off
410rd.off += length
411return rd.raw[start:rd.off], nil
412}
413
414func (rd *realDecoder) peek(offset, length int) (packetDecoder, error) {
415if rd.remaining() < offset+length {
416return nil, ErrInsufficientData
417}
418off := rd.off + offset
419return &realDecoder{raw: rd.raw[off : off+length]}, nil
420}
421
422func (rd *realDecoder) peekInt8(offset int) (int8, error) {
423const byteLen = 1
424if rd.remaining() < offset+byteLen {
425return -1, ErrInsufficientData
426}
427return int8(rd.raw[rd.off+offset]), nil
428}
429
430// stacks
431
432func (rd *realDecoder) push(in pushDecoder) error {
433in.saveOffset(rd.off)
434
435var reserve int
436if dpd, ok := in.(dynamicPushDecoder); ok {
437if err := dpd.decode(rd); err != nil {
438return err
439}
440} else {
441reserve = in.reserveLength()
442if rd.remaining() < reserve {
443rd.off = len(rd.raw)
444return ErrInsufficientData
445}
446}
447
448rd.stack = append(rd.stack, in)
449
450rd.off += reserve
451
452return nil
453}
454
455func (rd *realDecoder) pop() error {
456// this is go's ugly pop pattern (the inverse of append)
457in := rd.stack[len(rd.stack)-1]
458rd.stack = rd.stack[:len(rd.stack)-1]
459
460return in.check(rd.off, rd.raw)
461}
462