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