real_decoder.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. package sarama
  2. import (
  3. "encoding/binary"
  4. "math"
  5. )
  6. type realDecoder struct {
  7. raw []byte
  8. off int
  9. stack []pushDecoder
  10. }
  11. // primitives
  12. func (rd *realDecoder) getInt8() (int8, error) {
  13. if rd.remaining() < 1 {
  14. rd.off = len(rd.raw)
  15. return -1, ErrInsufficientData
  16. }
  17. tmp := int8(rd.raw[rd.off])
  18. rd.off += 1
  19. return tmp, nil
  20. }
  21. func (rd *realDecoder) getInt16() (int16, error) {
  22. if rd.remaining() < 2 {
  23. rd.off = len(rd.raw)
  24. return -1, ErrInsufficientData
  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. rd.off = len(rd.raw)
  33. return -1, ErrInsufficientData
  34. }
  35. tmp := int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  36. rd.off += 4
  37. return tmp, nil
  38. }
  39. func (rd *realDecoder) getInt64() (int64, error) {
  40. if rd.remaining() < 8 {
  41. rd.off = len(rd.raw)
  42. return -1, ErrInsufficientData
  43. }
  44. tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  45. rd.off += 8
  46. return tmp, nil
  47. }
  48. func (rd *realDecoder) getArrayLength() (int, error) {
  49. if rd.remaining() < 4 {
  50. rd.off = len(rd.raw)
  51. return -1, ErrInsufficientData
  52. }
  53. tmp := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  54. rd.off += 4
  55. if tmp > rd.remaining() {
  56. rd.off = len(rd.raw)
  57. return -1, ErrInsufficientData
  58. } else if tmp > 2*math.MaxUint16 {
  59. return -1, PacketDecodingError{"invalid array length"}
  60. }
  61. return tmp, nil
  62. }
  63. // collections
  64. func (rd *realDecoder) getBytes() ([]byte, error) {
  65. tmp, err := rd.getInt32()
  66. if err != nil {
  67. return nil, err
  68. }
  69. n := int(tmp)
  70. switch {
  71. case n < -1:
  72. return nil, PacketDecodingError{"invalid byteslice length"}
  73. case n == -1:
  74. return nil, nil
  75. case n == 0:
  76. return make([]byte, 0), nil
  77. case n > rd.remaining():
  78. rd.off = len(rd.raw)
  79. return nil, ErrInsufficientData
  80. }
  81. tmpStr := rd.raw[rd.off : rd.off+n]
  82. rd.off += n
  83. return tmpStr, nil
  84. }
  85. func (rd *realDecoder) getString() (string, error) {
  86. tmp, err := rd.getInt16()
  87. if err != nil {
  88. return "", err
  89. }
  90. n := int(tmp)
  91. switch {
  92. case n < -1:
  93. return "", PacketDecodingError{"invalid string length"}
  94. case n == -1:
  95. return "", nil
  96. case n == 0:
  97. return "", nil
  98. case n > rd.remaining():
  99. rd.off = len(rd.raw)
  100. return "", ErrInsufficientData
  101. }
  102. tmpStr := string(rd.raw[rd.off : rd.off+n])
  103. rd.off += n
  104. return tmpStr, nil
  105. }
  106. func (rd *realDecoder) getInt32Array() ([]int32, error) {
  107. if rd.remaining() < 4 {
  108. rd.off = len(rd.raw)
  109. return nil, ErrInsufficientData
  110. }
  111. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  112. rd.off += 4
  113. if rd.remaining() < 4*n {
  114. rd.off = len(rd.raw)
  115. return nil, ErrInsufficientData
  116. }
  117. if n == 0 {
  118. return nil, nil
  119. }
  120. if n < 0 {
  121. return nil, PacketDecodingError{"invalid array length"}
  122. }
  123. ret := make([]int32, n)
  124. for i := range ret {
  125. ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  126. rd.off += 4
  127. }
  128. return ret, nil
  129. }
  130. func (rd *realDecoder) getInt64Array() ([]int64, error) {
  131. if rd.remaining() < 4 {
  132. rd.off = len(rd.raw)
  133. return nil, ErrInsufficientData
  134. }
  135. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  136. rd.off += 4
  137. if rd.remaining() < 8*n {
  138. rd.off = len(rd.raw)
  139. return nil, ErrInsufficientData
  140. }
  141. if n == 0 {
  142. return nil, nil
  143. }
  144. if n < 0 {
  145. return nil, PacketDecodingError{"invalid array length"}
  146. }
  147. ret := make([]int64, n)
  148. for i := range ret {
  149. ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  150. rd.off += 8
  151. }
  152. return ret, nil
  153. }
  154. // subsets
  155. func (rd *realDecoder) remaining() int {
  156. return len(rd.raw) - rd.off
  157. }
  158. func (rd *realDecoder) getSubset(length int) (packetDecoder, error) {
  159. if length < 0 {
  160. return nil, PacketDecodingError{"invalid subset size"}
  161. } else if length > rd.remaining() {
  162. rd.off = len(rd.raw)
  163. return nil, ErrInsufficientData
  164. }
  165. start := rd.off
  166. rd.off += length
  167. return &realDecoder{raw: rd.raw[start:rd.off]}, nil
  168. }
  169. // stacks
  170. func (rd *realDecoder) push(in pushDecoder) error {
  171. in.saveOffset(rd.off)
  172. reserve := in.reserveLength()
  173. if rd.remaining() < reserve {
  174. rd.off = len(rd.raw)
  175. return ErrInsufficientData
  176. }
  177. rd.stack = append(rd.stack, in)
  178. rd.off += reserve
  179. return nil
  180. }
  181. func (rd *realDecoder) pop() error {
  182. // this is go's ugly pop pattern (the inverse of append)
  183. in := rd.stack[len(rd.stack)-1]
  184. rd.stack = rd.stack[:len(rd.stack)-1]
  185. return in.check(rd.off, rd.raw)
  186. }