real_decoder.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package kafka
  2. import (
  3. "encoding/binary"
  4. "math"
  5. )
  6. type realDecoder struct {
  7. raw []byte
  8. off int
  9. stack []pushDecoder
  10. }
  11. func (rd *realDecoder) remaining() int {
  12. return len(rd.raw) - rd.off
  13. }
  14. func (rd *realDecoder) getInt8() (int8, error) {
  15. if rd.remaining() < 1 {
  16. return -1, DecodingError{}
  17. }
  18. tmp := int8(rd.raw[rd.off])
  19. rd.off += 1
  20. return tmp, nil
  21. }
  22. func (rd *realDecoder) getInt16() (int16, error) {
  23. if rd.remaining() < 2 {
  24. return -1, DecodingError{}
  25. }
  26. tmp := int16(binary.BigEndian.Uint16(rd.raw[rd.off:]))
  27. rd.off += 2
  28. return tmp, nil
  29. }
  30. func (rd *realDecoder) getInt32() (int32, error) {
  31. if rd.remaining() < 4 {
  32. return -1, DecodingError{}
  33. }
  34. tmp := int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  35. rd.off += 4
  36. return tmp, nil
  37. }
  38. func (rd *realDecoder) getInt64() (int64, error) {
  39. if rd.remaining() < 8 {
  40. return -1, DecodingError{}
  41. }
  42. tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  43. rd.off += 8
  44. return tmp, nil
  45. }
  46. func (rd *realDecoder) getError() (KError, error) {
  47. val, err := rd.getInt16()
  48. return KError(val), err
  49. }
  50. func (rd *realDecoder) getString() (*string, error) {
  51. tmp, err := rd.getInt16()
  52. if err != nil {
  53. return nil, err
  54. }
  55. n := int(tmp)
  56. switch {
  57. case n < -1:
  58. return nil, DecodingError{}
  59. case n == -1:
  60. return nil, nil
  61. case n == 0:
  62. return new(string), nil
  63. case n > rd.remaining():
  64. return nil, DecodingError{}
  65. default:
  66. tmp := new(string)
  67. *tmp = string(rd.raw[rd.off : rd.off+n])
  68. rd.off += n
  69. return tmp, nil
  70. }
  71. }
  72. func (rd *realDecoder) getBytes() (*[]byte, error) {
  73. tmp, err := rd.getInt32()
  74. if err != nil {
  75. return nil, err
  76. }
  77. n := int(tmp)
  78. switch {
  79. case n < -1:
  80. return nil, DecodingError{}
  81. case n == -1:
  82. return nil, nil
  83. case n == 0:
  84. tmp := make([]byte, 0)
  85. return &tmp, nil
  86. case n > rd.remaining():
  87. return nil, DecodingError{}
  88. default:
  89. tmp := rd.raw[rd.off : rd.off+n]
  90. rd.off += n
  91. return &tmp, nil
  92. }
  93. }
  94. func (rd *realDecoder) getArrayCount() (int, error) {
  95. if rd.remaining() < 4 {
  96. return -1, DecodingError{}
  97. }
  98. tmp := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  99. rd.off += 4
  100. if tmp > rd.remaining() || tmp > 2*math.MaxUint16 {
  101. return -1, DecodingError{}
  102. }
  103. return tmp, nil
  104. }
  105. func (rd *realDecoder) push(in pushDecoder) error {
  106. in.saveOffset(rd.off)
  107. if rd.remaining() < in.reserveLength() {
  108. return DecodingError{}
  109. }
  110. rd.stack = append(rd.stack, in)
  111. return nil
  112. }
  113. func (rd *realDecoder) pushLength32() error {
  114. return rd.push(&length32Decoder{})
  115. }
  116. func (rd *realDecoder) pushCRC32() error {
  117. return rd.push(&crc32Decoder{})
  118. }
  119. func (rd *realDecoder) pop() error {
  120. // this is go's ugly pop pattern (the inverse of append)
  121. in := rd.stack[len(rd.stack)-1]
  122. rd.stack = rd.stack[:len(rd.stack)-1]
  123. return in.check(rd.off, rd.raw)
  124. }