You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
3.3 KiB

  1. package msgpack
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/vmihailenco/msgpack/codes"
  6. )
  7. const sliceElemsAllocLimit = 1e4
  8. var sliceStringPtrType = reflect.TypeOf((*[]string)(nil))
  9. func (d *Decoder) DecodeArrayLen() (int, error) {
  10. c, err := d.readCode()
  11. if err != nil {
  12. return 0, err
  13. }
  14. return d.arrayLen(c)
  15. }
  16. func (d *Decoder) arrayLen(c codes.Code) (int, error) {
  17. if c == codes.Nil {
  18. return -1, nil
  19. } else if c >= codes.FixedArrayLow && c <= codes.FixedArrayHigh {
  20. return int(c & codes.FixedArrayMask), nil
  21. }
  22. switch c {
  23. case codes.Array16:
  24. n, err := d.uint16()
  25. return int(n), err
  26. case codes.Array32:
  27. n, err := d.uint32()
  28. return int(n), err
  29. }
  30. return 0, fmt.Errorf("msgpack: invalid code=%x decoding array length", c)
  31. }
  32. func decodeStringSliceValue(d *Decoder, v reflect.Value) error {
  33. ptr := v.Addr().Convert(sliceStringPtrType).Interface().(*[]string)
  34. return d.decodeStringSlicePtr(ptr)
  35. }
  36. func (d *Decoder) decodeStringSlicePtr(ptr *[]string) error {
  37. n, err := d.DecodeArrayLen()
  38. if err != nil {
  39. return err
  40. }
  41. if n == -1 {
  42. return nil
  43. }
  44. ss := setStringsCap(*ptr, n)
  45. for i := 0; i < n; i++ {
  46. s, err := d.DecodeString()
  47. if err != nil {
  48. return err
  49. }
  50. ss = append(ss, s)
  51. }
  52. *ptr = ss
  53. return nil
  54. }
  55. func setStringsCap(s []string, n int) []string {
  56. if n > sliceElemsAllocLimit {
  57. n = sliceElemsAllocLimit
  58. }
  59. if s == nil {
  60. return make([]string, 0, n)
  61. }
  62. if cap(s) >= n {
  63. return s[:0]
  64. }
  65. s = s[:cap(s)]
  66. s = append(s, make([]string, n-len(s))...)
  67. return s[:0]
  68. }
  69. func decodeSliceValue(d *Decoder, v reflect.Value) error {
  70. n, err := d.DecodeArrayLen()
  71. if err != nil {
  72. return err
  73. }
  74. if n == -1 {
  75. v.Set(reflect.Zero(v.Type()))
  76. return nil
  77. }
  78. if n == 0 && v.IsNil() {
  79. v.Set(reflect.MakeSlice(v.Type(), 0, 0))
  80. return nil
  81. }
  82. if v.Cap() >= n {
  83. v.Set(v.Slice(0, n))
  84. } else if v.Len() < v.Cap() {
  85. v.Set(v.Slice(0, v.Cap()))
  86. }
  87. for i := 0; i < n; i++ {
  88. if i >= v.Len() {
  89. v.Set(growSliceValue(v, n))
  90. }
  91. sv := v.Index(i)
  92. if err := d.DecodeValue(sv); err != nil {
  93. return err
  94. }
  95. }
  96. return nil
  97. }
  98. func growSliceValue(v reflect.Value, n int) reflect.Value {
  99. diff := n - v.Len()
  100. if diff > sliceElemsAllocLimit {
  101. diff = sliceElemsAllocLimit
  102. }
  103. v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff))
  104. return v
  105. }
  106. func decodeArrayValue(d *Decoder, v reflect.Value) error {
  107. n, err := d.DecodeArrayLen()
  108. if err != nil {
  109. return err
  110. }
  111. if n == -1 {
  112. return nil
  113. }
  114. if n > v.Len() {
  115. return fmt.Errorf("%s len is %d, but msgpack has %d elements", v.Type(), v.Len(), n)
  116. }
  117. for i := 0; i < n; i++ {
  118. sv := v.Index(i)
  119. if err := d.DecodeValue(sv); err != nil {
  120. return err
  121. }
  122. }
  123. return nil
  124. }
  125. func (d *Decoder) DecodeSlice() ([]interface{}, error) {
  126. c, err := d.readCode()
  127. if err != nil {
  128. return nil, err
  129. }
  130. return d.decodeSlice(c)
  131. }
  132. func (d *Decoder) decodeSlice(c codes.Code) ([]interface{}, error) {
  133. n, err := d.arrayLen(c)
  134. if err != nil {
  135. return nil, err
  136. }
  137. if n == -1 {
  138. return nil, nil
  139. }
  140. s := make([]interface{}, 0, min(n, sliceElemsAllocLimit))
  141. for i := 0; i < n; i++ {
  142. v, err := d.DecodeInterface()
  143. if err != nil {
  144. return nil, err
  145. }
  146. s = append(s, v)
  147. }
  148. return s, nil
  149. }
  150. func (d *Decoder) skipSlice(c codes.Code) error {
  151. n, err := d.arrayLen(c)
  152. if err != nil {
  153. return err
  154. }
  155. for i := 0; i < n; i++ {
  156. if err := d.Skip(); err != nil {
  157. return err
  158. }
  159. }
  160. return nil
  161. }