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