real_decoder.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. 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
  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
  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
  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
  42. }
  43. tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  44. rd.off += 8
  45. return tmp, nil
  46. }
  47. func (rd *realDecoder) GetArrayLength() (int, error) {
  48. if rd.remaining() < 4 {
  49. return -1, InsufficientData
  50. }
  51. tmp := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  52. rd.off += 4
  53. if tmp > rd.remaining() {
  54. return -1, InsufficientData
  55. } else if tmp > 2*math.MaxUint16 {
  56. return -1, DecodingError
  57. }
  58. return tmp, nil
  59. }
  60. // collections
  61. func (rd *realDecoder) GetBytes() ([]byte, error) {
  62. tmp, err := rd.GetInt32()
  63. if err != nil {
  64. return nil, err
  65. }
  66. n := int(tmp)
  67. switch {
  68. case n < -1:
  69. return nil, DecodingError
  70. case n == -1:
  71. return nil, nil
  72. case n == 0:
  73. return make([]byte, 0), nil
  74. case n > rd.remaining():
  75. return nil, InsufficientData
  76. default:
  77. tmp := rd.raw[rd.off : rd.off+n]
  78. rd.off += n
  79. return tmp, nil
  80. }
  81. }
  82. func (rd *realDecoder) GetString() (string, error) {
  83. tmp, err := rd.GetInt16()
  84. if err != nil {
  85. return "", err
  86. }
  87. n := int(tmp)
  88. switch {
  89. case n < -1:
  90. return "", DecodingError
  91. case n == -1:
  92. return "", nil
  93. case n == 0:
  94. return "", nil
  95. case n > rd.remaining():
  96. return "", InsufficientData
  97. default:
  98. tmp := string(rd.raw[rd.off : rd.off+n])
  99. rd.off += n
  100. return tmp, nil
  101. }
  102. }
  103. func (rd *realDecoder) GetInt32Array() ([]int32, error) {
  104. if rd.remaining() < 4 {
  105. return nil, InsufficientData
  106. }
  107. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  108. rd.off += 4
  109. var ret []int32 = nil
  110. if rd.remaining() < 4*n {
  111. return nil, InsufficientData
  112. } else if n > 0 {
  113. ret = make([]int32, n)
  114. for i := range ret {
  115. ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  116. rd.off += 4
  117. }
  118. }
  119. return ret, nil
  120. }
  121. func (rd *realDecoder) GetInt64Array() ([]int64, error) {
  122. if rd.remaining() < 4 {
  123. return nil, InsufficientData
  124. }
  125. n := int(binary.BigEndian.Uint32(rd.raw[rd.off:]))
  126. rd.off += 4
  127. var ret []int64 = nil
  128. if rd.remaining() < 8*n {
  129. return nil, InsufficientData
  130. } else if n > 0 {
  131. ret = make([]int64, n)
  132. for i := range ret {
  133. ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:]))
  134. rd.off += 8
  135. }
  136. }
  137. return ret, nil
  138. }
  139. func (rd *realDecoder) GetSubset(length int) (PacketDecoder, error) {
  140. if length > rd.remaining() {
  141. return nil, InsufficientData
  142. }
  143. return &realDecoder{raw: rd.raw[rd.off : rd.off+length]}, nil
  144. }
  145. // stacks
  146. func (rd *realDecoder) Push(in PushDecoder) error {
  147. in.SaveOffset(rd.off)
  148. reserve := in.ReserveLength()
  149. if rd.remaining() < reserve {
  150. return DecodingError
  151. }
  152. rd.stack = append(rd.stack, in)
  153. rd.off += reserve
  154. return nil
  155. }
  156. func (rd *realDecoder) Pop() error {
  157. // this is go's ugly pop pattern (the inverse of append)
  158. in := rd.stack[len(rd.stack)-1]
  159. rd.stack = rd.stack[:len(rd.stack)-1]
  160. return in.Check(rd.off, rd.raw)
  161. }