real_decoder.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package encoding
  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, InsufficientData
  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, InsufficientData
  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, InsufficientData
  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, InsufficientData
  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, InsufficientData
  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, InsufficientData
  58. } else if tmp > 2*math.MaxUint16 {
  59. return -1, DecodingError
  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, DecodingError
  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, InsufficientData
  80. default:
  81. tmp := rd.raw[rd.off : rd.off+n]
  82. rd.off += n
  83. return tmp, nil
  84. }
  85. }
  86. func (rd *realDecoder) GetString() (string, error) {
  87. tmp, err := rd.GetInt16()
  88. if err != nil {
  89. return "", err
  90. }
  91. n := int(tmp)
  92. switch {
  93. case n < -1:
  94. return "", DecodingError
  95. case n == -1:
  96. return "", nil
  97. case n == 0:
  98. return "", nil
  99. case n > rd.Remaining():
  100. rd.off = len(rd.raw)
  101. return "", InsufficientData
  102. default:
  103. tmp := string(rd.raw[rd.off : rd.off+n])
  104. rd.off += n
  105. return tmp, nil
  106. }
  107. }
  108. func (rd *realDecoder) GetInt32Array() ([]int32, error) {
  109. if rd.Remaining() < 4 {
  110. rd.off = len(rd.raw)
  111. return nil, InsufficientData
  112. }
  113. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  114. rd.off += 4
  115. var ret []int32 = nil
  116. if rd.Remaining() < 4*n {
  117. rd.off = len(rd.raw)
  118. return nil, InsufficientData
  119. } else if n > 0 {
  120. ret = make([]int32, n)
  121. for i := range ret {
  122. ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  123. rd.off += 4
  124. }
  125. }
  126. return ret, nil
  127. }
  128. func (rd *realDecoder) GetInt64Array() ([]int64, error) {
  129. if rd.Remaining() < 4 {
  130. rd.off = len(rd.raw)
  131. return nil, InsufficientData
  132. }
  133. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  134. rd.off += 4
  135. var ret []int64 = nil
  136. if rd.Remaining() < 8*n {
  137. rd.off = len(rd.raw)
  138. return nil, InsufficientData
  139. } else if n > 0 {
  140. ret = make([]int64, n)
  141. for i := range ret {
  142. ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  143. rd.off += 8
  144. }
  145. }
  146. return ret, nil
  147. }
  148. // subsets
  149. func (rd *realDecoder) Remaining() int {
  150. return len(rd.raw) - rd.off
  151. }
  152. func (rd *realDecoder) GetSubset(length int) (PacketDecoder, error) {
  153. if length > rd.Remaining() {
  154. rd.off = len(rd.raw)
  155. return nil, InsufficientData
  156. }
  157. start := rd.off
  158. rd.off += length
  159. return &realDecoder{raw: rd.raw[start:rd.off]}, nil
  160. }
  161. // stacks
  162. func (rd *realDecoder) Push(in PushDecoder) error {
  163. in.SaveOffset(rd.off)
  164. reserve := in.ReserveLength()
  165. if rd.Remaining() < reserve {
  166. rd.off = len(rd.raw)
  167. return InsufficientData
  168. }
  169. rd.stack = append(rd.stack, in)
  170. rd.off += reserve
  171. return nil
  172. }
  173. func (rd *realDecoder) Pop() error {
  174. // this is go's ugly pop pattern (the inverse of append)
  175. in := rd.stack[len(rd.stack)-1]
  176. rd.stack = rd.stack[:len(rd.stack)-1]
  177. return in.Check(rd.off, rd.raw)
  178. }