real_decoder.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package protocol
  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. // primitives
  15. func (rd *realDecoder) getInt8() (int8, error) {
  16. if rd.remaining() < 1 {
  17. return -1, InsufficientData(1)
  18. }
  19. tmp := int8(rd.raw[rd.off])
  20. rd.off += 1
  21. return tmp, nil
  22. }
  23. func (rd *realDecoder) getInt16() (int16, error) {
  24. if rd.remaining() < 2 {
  25. return -1, InsufficientData(2 - rd.remaining())
  26. }
  27. tmp := int16(binary.BigEndian.Uint16(rd.raw[rd.off:]))
  28. rd.off += 2
  29. return tmp, nil
  30. }
  31. func (rd *realDecoder) getInt32() (int32, error) {
  32. if rd.remaining() < 4 {
  33. return -1, InsufficientData(4 - rd.remaining())
  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. return -1, InsufficientData(8 - rd.remaining())
  42. }
  43. tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  44. rd.off += 8
  45. return tmp, nil
  46. }
  47. // arrays
  48. func (rd *realDecoder) getInt32Array() ([]int32, error) {
  49. if rd.remaining() < 4 {
  50. return nil, InsufficientData(4 - rd.remaining())
  51. }
  52. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  53. rd.off += 4
  54. var ret []int32 = nil
  55. if rd.remaining() < 4*n {
  56. return nil, InsufficientData(4*n - rd.remaining())
  57. } else if n > 0 {
  58. ret = make([]int32, n)
  59. for i := range ret {
  60. ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  61. rd.off += 4
  62. }
  63. }
  64. return ret, nil
  65. }
  66. func (rd *realDecoder) getInt64Array() ([]int64, error) {
  67. if rd.remaining() < 4 {
  68. return nil, InsufficientData(4 - rd.remaining())
  69. }
  70. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  71. rd.off += 4
  72. var ret []int64 = nil
  73. if rd.remaining() < 8*n {
  74. return nil, InsufficientData(8*n - rd.remaining())
  75. } else if n > 0 {
  76. ret = make([]int64, n)
  77. for i := range ret {
  78. ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  79. rd.off += 8
  80. }
  81. }
  82. return ret, nil
  83. }
  84. func (rd *realDecoder) getArrayCount() (int, error) {
  85. if rd.remaining() < 4 {
  86. return -1, InsufficientData(4 - rd.remaining())
  87. }
  88. tmp := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  89. rd.off += 4
  90. if tmp > rd.remaining() {
  91. return -1, InsufficientData(tmp - rd.remaining())
  92. } else if tmp > 2*math.MaxUint16 {
  93. return -1, DecodingError("Array absurdly long in getArrayCount.")
  94. }
  95. return tmp, nil
  96. }
  97. // misc
  98. func (rd *realDecoder) getError() (KError, error) {
  99. val, err := rd.getInt16()
  100. return KError(val), err
  101. }
  102. func (rd *realDecoder) getString() (string, error) {
  103. tmp, err := rd.getInt16()
  104. if err != nil {
  105. return "", err
  106. }
  107. n := int(tmp)
  108. switch {
  109. case n < -1:
  110. return "", DecodingError("Negative string length in getString.")
  111. case n == -1:
  112. return "", nil
  113. case n == 0:
  114. return "", nil
  115. case n > rd.remaining():
  116. return "", InsufficientData(rd.remaining() - n)
  117. default:
  118. tmp := string(rd.raw[rd.off : rd.off+n])
  119. rd.off += n
  120. return tmp, nil
  121. }
  122. }
  123. func (rd *realDecoder) getBytes() ([]byte, error) {
  124. tmp, err := rd.getInt32()
  125. if err != nil {
  126. return nil, err
  127. }
  128. n := int(tmp)
  129. switch {
  130. case n < -1:
  131. return nil, DecodingError("Negative byte length in getBytes.")
  132. case n == -1:
  133. return nil, nil
  134. case n == 0:
  135. return make([]byte, 0), nil
  136. case n > rd.remaining():
  137. return nil, InsufficientData(rd.remaining() - n)
  138. default:
  139. tmp := rd.raw[rd.off : rd.off+n]
  140. rd.off += n
  141. return tmp, nil
  142. }
  143. }
  144. func (rd *realDecoder) getSubset(length int) (packetDecoder, error) {
  145. if length > rd.remaining() {
  146. return nil, InsufficientData(length - rd.remaining())
  147. }
  148. return &realDecoder{raw: rd.raw[rd.off : rd.off+length]}, nil
  149. }
  150. // stackable
  151. func (rd *realDecoder) push(in pushDecoder) error {
  152. in.saveOffset(rd.off)
  153. reserve := in.reserveLength()
  154. if rd.remaining() < reserve {
  155. return DecodingError("Insufficient data while reserving for push.")
  156. }
  157. rd.stack = append(rd.stack, in)
  158. rd.off += reserve
  159. return nil
  160. }
  161. func (rd *realDecoder) pushLength32() error {
  162. return rd.push(&length32Decoder{})
  163. }
  164. func (rd *realDecoder) pushCRC32() error {
  165. return rd.push(&crc32Decoder{})
  166. }
  167. func (rd *realDecoder) pop() error {
  168. // this is go's ugly pop pattern (the inverse of append)
  169. in := rd.stack[len(rd.stack)-1]
  170. rd.stack = rd.stack[:len(rd.stack)-1]
  171. return in.check(rd.off, rd.raw)
  172. }