real_decoder.go 3.6 KB

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