decode_slice.go 3.4 KB

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