diff options
author | Alexandre Garand <alexandre.garand@fretlink.com> | 2019-08-09 15:59:15 +0200 |
---|---|---|
committer | Alexandre Garand <alexandre.garand@fretlink.com> | 2019-08-09 16:39:21 +0200 |
commit | 863486a6b71ed0e562a3965bed56465d007b1418 (patch) | |
tree | e93f6a687695af86d54237ec9f575d4ef104222d /vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go | |
parent | 49c1c7b4dc69ffb9ab52330e6dc52ccdd6351087 (diff) | |
download | terraform-provider-statuscake-863486a6b71ed0e562a3965bed56465d007b1418.tar.gz terraform-provider-statuscake-863486a6b71ed0e562a3965bed56465d007b1418.tar.zst terraform-provider-statuscake-863486a6b71ed0e562a3965bed56465d007b1418.zip |
update vendor and go.modadd_contact_groups
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go')
-rw-r--r-- | vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go new file mode 100644 index 0000000..864fb67 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go | |||
@@ -0,0 +1,296 @@ | |||
1 | // Package jsonutil provides JSON serialization of AWS requests and responses. | ||
2 | package jsonutil | ||
3 | |||
4 | import ( | ||
5 | "bytes" | ||
6 | "encoding/base64" | ||
7 | "encoding/json" | ||
8 | "fmt" | ||
9 | "math" | ||
10 | "reflect" | ||
11 | "sort" | ||
12 | "strconv" | ||
13 | "time" | ||
14 | |||
15 | "github.com/aws/aws-sdk-go/aws" | ||
16 | "github.com/aws/aws-sdk-go/private/protocol" | ||
17 | ) | ||
18 | |||
19 | var timeType = reflect.ValueOf(time.Time{}).Type() | ||
20 | var byteSliceType = reflect.ValueOf([]byte{}).Type() | ||
21 | |||
22 | // BuildJSON builds a JSON string for a given object v. | ||
23 | func BuildJSON(v interface{}) ([]byte, error) { | ||
24 | var buf bytes.Buffer | ||
25 | |||
26 | err := buildAny(reflect.ValueOf(v), &buf, "") | ||
27 | return buf.Bytes(), err | ||
28 | } | ||
29 | |||
30 | func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { | ||
31 | origVal := value | ||
32 | value = reflect.Indirect(value) | ||
33 | if !value.IsValid() { | ||
34 | return nil | ||
35 | } | ||
36 | |||
37 | vtype := value.Type() | ||
38 | |||
39 | t := tag.Get("type") | ||
40 | if t == "" { | ||
41 | switch vtype.Kind() { | ||
42 | case reflect.Struct: | ||
43 | // also it can't be a time object | ||
44 | if value.Type() != timeType { | ||
45 | t = "structure" | ||
46 | } | ||
47 | case reflect.Slice: | ||
48 | // also it can't be a byte slice | ||
49 | if _, ok := value.Interface().([]byte); !ok { | ||
50 | t = "list" | ||
51 | } | ||
52 | case reflect.Map: | ||
53 | // cannot be a JSONValue map | ||
54 | if _, ok := value.Interface().(aws.JSONValue); !ok { | ||
55 | t = "map" | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
60 | switch t { | ||
61 | case "structure": | ||
62 | if field, ok := vtype.FieldByName("_"); ok { | ||
63 | tag = field.Tag | ||
64 | } | ||
65 | return buildStruct(value, buf, tag) | ||
66 | case "list": | ||
67 | return buildList(value, buf, tag) | ||
68 | case "map": | ||
69 | return buildMap(value, buf, tag) | ||
70 | default: | ||
71 | return buildScalar(origVal, buf, tag) | ||
72 | } | ||
73 | } | ||
74 | |||
75 | func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { | ||
76 | if !value.IsValid() { | ||
77 | return nil | ||
78 | } | ||
79 | |||
80 | // unwrap payloads | ||
81 | if payload := tag.Get("payload"); payload != "" { | ||
82 | field, _ := value.Type().FieldByName(payload) | ||
83 | tag = field.Tag | ||
84 | value = elemOf(value.FieldByName(payload)) | ||
85 | |||
86 | if !value.IsValid() { | ||
87 | return nil | ||
88 | } | ||
89 | } | ||
90 | |||
91 | buf.WriteByte('{') | ||
92 | |||
93 | t := value.Type() | ||
94 | first := true | ||
95 | for i := 0; i < t.NumField(); i++ { | ||
96 | member := value.Field(i) | ||
97 | |||
98 | // This allocates the most memory. | ||
99 | // Additionally, we cannot skip nil fields due to | ||
100 | // idempotency auto filling. | ||
101 | field := t.Field(i) | ||
102 | |||
103 | if field.PkgPath != "" { | ||
104 | continue // ignore unexported fields | ||
105 | } | ||
106 | if field.Tag.Get("json") == "-" { | ||
107 | continue | ||
108 | } | ||
109 | if field.Tag.Get("location") != "" { | ||
110 | continue // ignore non-body elements | ||
111 | } | ||
112 | if field.Tag.Get("ignore") != "" { | ||
113 | continue | ||
114 | } | ||
115 | |||
116 | if protocol.CanSetIdempotencyToken(member, field) { | ||
117 | token := protocol.GetIdempotencyToken() | ||
118 | member = reflect.ValueOf(&token) | ||
119 | } | ||
120 | |||
121 | if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { | ||
122 | continue // ignore unset fields | ||
123 | } | ||
124 | |||
125 | if first { | ||
126 | first = false | ||
127 | } else { | ||
128 | buf.WriteByte(',') | ||
129 | } | ||
130 | |||
131 | // figure out what this field is called | ||
132 | name := field.Name | ||
133 | if locName := field.Tag.Get("locationName"); locName != "" { | ||
134 | name = locName | ||
135 | } | ||
136 | |||
137 | writeString(name, buf) | ||
138 | buf.WriteString(`:`) | ||
139 | |||
140 | err := buildAny(member, buf, field.Tag) | ||
141 | if err != nil { | ||
142 | return err | ||
143 | } | ||
144 | |||
145 | } | ||
146 | |||
147 | buf.WriteString("}") | ||
148 | |||
149 | return nil | ||
150 | } | ||
151 | |||
152 | func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { | ||
153 | buf.WriteString("[") | ||
154 | |||
155 | for i := 0; i < value.Len(); i++ { | ||
156 | buildAny(value.Index(i), buf, "") | ||
157 | |||
158 | if i < value.Len()-1 { | ||
159 | buf.WriteString(",") | ||
160 | } | ||
161 | } | ||
162 | |||
163 | buf.WriteString("]") | ||
164 | |||
165 | return nil | ||
166 | } | ||
167 | |||
168 | type sortedValues []reflect.Value | ||
169 | |||
170 | func (sv sortedValues) Len() int { return len(sv) } | ||
171 | func (sv sortedValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } | ||
172 | func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() } | ||
173 | |||
174 | func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { | ||
175 | buf.WriteString("{") | ||
176 | |||
177 | sv := sortedValues(value.MapKeys()) | ||
178 | sort.Sort(sv) | ||
179 | |||
180 | for i, k := range sv { | ||
181 | if i > 0 { | ||
182 | buf.WriteByte(',') | ||
183 | } | ||
184 | |||
185 | writeString(k.String(), buf) | ||
186 | buf.WriteString(`:`) | ||
187 | |||
188 | buildAny(value.MapIndex(k), buf, "") | ||
189 | } | ||
190 | |||
191 | buf.WriteString("}") | ||
192 | |||
193 | return nil | ||
194 | } | ||
195 | |||
196 | func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { | ||
197 | // prevents allocation on the heap. | ||
198 | scratch := [64]byte{} | ||
199 | switch value := reflect.Indirect(v); value.Kind() { | ||
200 | case reflect.String: | ||
201 | writeString(value.String(), buf) | ||
202 | case reflect.Bool: | ||
203 | if value.Bool() { | ||
204 | buf.WriteString("true") | ||
205 | } else { | ||
206 | buf.WriteString("false") | ||
207 | } | ||
208 | case reflect.Int64: | ||
209 | buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10)) | ||
210 | case reflect.Float64: | ||
211 | f := value.Float() | ||
212 | if math.IsInf(f, 0) || math.IsNaN(f) { | ||
213 | return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)} | ||
214 | } | ||
215 | buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) | ||
216 | default: | ||
217 | switch converted := value.Interface().(type) { | ||
218 | case time.Time: | ||
219 | format := tag.Get("timestampFormat") | ||
220 | if len(format) == 0 { | ||
221 | format = protocol.UnixTimeFormatName | ||
222 | } | ||
223 | |||
224 | ts := protocol.FormatTime(format, converted) | ||
225 | if format != protocol.UnixTimeFormatName { | ||
226 | ts = `"` + ts + `"` | ||
227 | } | ||
228 | |||
229 | buf.WriteString(ts) | ||
230 | case []byte: | ||
231 | if !value.IsNil() { | ||
232 | buf.WriteByte('"') | ||
233 | if len(converted) < 1024 { | ||
234 | // for small buffers, using Encode directly is much faster. | ||
235 | dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted))) | ||
236 | base64.StdEncoding.Encode(dst, converted) | ||
237 | buf.Write(dst) | ||
238 | } else { | ||
239 | // for large buffers, avoid unnecessary extra temporary | ||
240 | // buffer space. | ||
241 | enc := base64.NewEncoder(base64.StdEncoding, buf) | ||
242 | enc.Write(converted) | ||
243 | enc.Close() | ||
244 | } | ||
245 | buf.WriteByte('"') | ||
246 | } | ||
247 | case aws.JSONValue: | ||
248 | str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) | ||
249 | if err != nil { | ||
250 | return fmt.Errorf("unable to encode JSONValue, %v", err) | ||
251 | } | ||
252 | buf.WriteString(str) | ||
253 | default: | ||
254 | return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) | ||
255 | } | ||
256 | } | ||
257 | return nil | ||
258 | } | ||
259 | |||
260 | var hex = "0123456789abcdef" | ||
261 | |||
262 | func writeString(s string, buf *bytes.Buffer) { | ||
263 | buf.WriteByte('"') | ||
264 | for i := 0; i < len(s); i++ { | ||
265 | if s[i] == '"' { | ||
266 | buf.WriteString(`\"`) | ||
267 | } else if s[i] == '\\' { | ||
268 | buf.WriteString(`\\`) | ||
269 | } else if s[i] == '\b' { | ||
270 | buf.WriteString(`\b`) | ||
271 | } else if s[i] == '\f' { | ||
272 | buf.WriteString(`\f`) | ||
273 | } else if s[i] == '\r' { | ||
274 | buf.WriteString(`\r`) | ||
275 | } else if s[i] == '\t' { | ||
276 | buf.WriteString(`\t`) | ||
277 | } else if s[i] == '\n' { | ||
278 | buf.WriteString(`\n`) | ||
279 | } else if s[i] < 32 { | ||
280 | buf.WriteString("\\u00") | ||
281 | buf.WriteByte(hex[s[i]>>4]) | ||
282 | buf.WriteByte(hex[s[i]&0xF]) | ||
283 | } else { | ||
284 | buf.WriteByte(s[i]) | ||
285 | } | ||
286 | } | ||
287 | buf.WriteByte('"') | ||
288 | } | ||
289 | |||
290 | // Returns the reflection element of a value, if it is a pointer. | ||
291 | func elemOf(value reflect.Value) reflect.Value { | ||
292 | for value.Kind() == reflect.Ptr { | ||
293 | value = value.Elem() | ||
294 | } | ||
295 | return value | ||
296 | } | ||