diff options
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go')
-rw-r--r-- | vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go new file mode 100644 index 0000000..24df543 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go | |||
@@ -0,0 +1,324 @@ | |||
1 | package ini | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "strconv" | ||
6 | "strings" | ||
7 | ) | ||
8 | |||
9 | var ( | ||
10 | runesTrue = []rune("true") | ||
11 | runesFalse = []rune("false") | ||
12 | ) | ||
13 | |||
14 | var literalValues = [][]rune{ | ||
15 | runesTrue, | ||
16 | runesFalse, | ||
17 | } | ||
18 | |||
19 | func isBoolValue(b []rune) bool { | ||
20 | for _, lv := range literalValues { | ||
21 | if isLitValue(lv, b) { | ||
22 | return true | ||
23 | } | ||
24 | } | ||
25 | return false | ||
26 | } | ||
27 | |||
28 | func isLitValue(want, have []rune) bool { | ||
29 | if len(have) < len(want) { | ||
30 | return false | ||
31 | } | ||
32 | |||
33 | for i := 0; i < len(want); i++ { | ||
34 | if want[i] != have[i] { | ||
35 | return false | ||
36 | } | ||
37 | } | ||
38 | |||
39 | return true | ||
40 | } | ||
41 | |||
42 | // isNumberValue will return whether not the leading characters in | ||
43 | // a byte slice is a number. A number is delimited by whitespace or | ||
44 | // the newline token. | ||
45 | // | ||
46 | // A number is defined to be in a binary, octal, decimal (int | float), hex format, | ||
47 | // or in scientific notation. | ||
48 | func isNumberValue(b []rune) bool { | ||
49 | negativeIndex := 0 | ||
50 | helper := numberHelper{} | ||
51 | needDigit := false | ||
52 | |||
53 | for i := 0; i < len(b); i++ { | ||
54 | negativeIndex++ | ||
55 | |||
56 | switch b[i] { | ||
57 | case '-': | ||
58 | if helper.IsNegative() || negativeIndex != 1 { | ||
59 | return false | ||
60 | } | ||
61 | helper.Determine(b[i]) | ||
62 | needDigit = true | ||
63 | continue | ||
64 | case 'e', 'E': | ||
65 | if err := helper.Determine(b[i]); err != nil { | ||
66 | return false | ||
67 | } | ||
68 | negativeIndex = 0 | ||
69 | needDigit = true | ||
70 | continue | ||
71 | case 'b': | ||
72 | if helper.numberFormat == hex { | ||
73 | break | ||
74 | } | ||
75 | fallthrough | ||
76 | case 'o', 'x': | ||
77 | needDigit = true | ||
78 | if i == 0 { | ||
79 | return false | ||
80 | } | ||
81 | |||
82 | fallthrough | ||
83 | case '.': | ||
84 | if err := helper.Determine(b[i]); err != nil { | ||
85 | return false | ||
86 | } | ||
87 | needDigit = true | ||
88 | continue | ||
89 | } | ||
90 | |||
91 | if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) { | ||
92 | return !needDigit | ||
93 | } | ||
94 | |||
95 | if !helper.CorrectByte(b[i]) { | ||
96 | return false | ||
97 | } | ||
98 | needDigit = false | ||
99 | } | ||
100 | |||
101 | return !needDigit | ||
102 | } | ||
103 | |||
104 | func isValid(b []rune) (bool, int, error) { | ||
105 | if len(b) == 0 { | ||
106 | // TODO: should probably return an error | ||
107 | return false, 0, nil | ||
108 | } | ||
109 | |||
110 | return isValidRune(b[0]), 1, nil | ||
111 | } | ||
112 | |||
113 | func isValidRune(r rune) bool { | ||
114 | return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n' | ||
115 | } | ||
116 | |||
117 | // ValueType is an enum that will signify what type | ||
118 | // the Value is | ||
119 | type ValueType int | ||
120 | |||
121 | func (v ValueType) String() string { | ||
122 | switch v { | ||
123 | case NoneType: | ||
124 | return "NONE" | ||
125 | case DecimalType: | ||
126 | return "FLOAT" | ||
127 | case IntegerType: | ||
128 | return "INT" | ||
129 | case StringType: | ||
130 | return "STRING" | ||
131 | case BoolType: | ||
132 | return "BOOL" | ||
133 | } | ||
134 | |||
135 | return "" | ||
136 | } | ||
137 | |||
138 | // ValueType enums | ||
139 | const ( | ||
140 | NoneType = ValueType(iota) | ||
141 | DecimalType | ||
142 | IntegerType | ||
143 | StringType | ||
144 | QuotedStringType | ||
145 | BoolType | ||
146 | ) | ||
147 | |||
148 | // Value is a union container | ||
149 | type Value struct { | ||
150 | Type ValueType | ||
151 | raw []rune | ||
152 | |||
153 | integer int64 | ||
154 | decimal float64 | ||
155 | boolean bool | ||
156 | str string | ||
157 | } | ||
158 | |||
159 | func newValue(t ValueType, base int, raw []rune) (Value, error) { | ||
160 | v := Value{ | ||
161 | Type: t, | ||
162 | raw: raw, | ||
163 | } | ||
164 | var err error | ||
165 | |||
166 | switch t { | ||
167 | case DecimalType: | ||
168 | v.decimal, err = strconv.ParseFloat(string(raw), 64) | ||
169 | case IntegerType: | ||
170 | if base != 10 { | ||
171 | raw = raw[2:] | ||
172 | } | ||
173 | |||
174 | v.integer, err = strconv.ParseInt(string(raw), base, 64) | ||
175 | case StringType: | ||
176 | v.str = string(raw) | ||
177 | case QuotedStringType: | ||
178 | v.str = string(raw[1 : len(raw)-1]) | ||
179 | case BoolType: | ||
180 | v.boolean = runeCompare(v.raw, runesTrue) | ||
181 | } | ||
182 | |||
183 | // issue 2253 | ||
184 | // | ||
185 | // if the value trying to be parsed is too large, then we will use | ||
186 | // the 'StringType' and raw value instead. | ||
187 | if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange { | ||
188 | v.Type = StringType | ||
189 | v.str = string(raw) | ||
190 | err = nil | ||
191 | } | ||
192 | |||
193 | return v, err | ||
194 | } | ||
195 | |||
196 | // Append will append values and change the type to a string | ||
197 | // type. | ||
198 | func (v *Value) Append(tok Token) { | ||
199 | r := tok.Raw() | ||
200 | if v.Type != QuotedStringType { | ||
201 | v.Type = StringType | ||
202 | r = tok.raw[1 : len(tok.raw)-1] | ||
203 | } | ||
204 | if tok.Type() != TokenLit { | ||
205 | v.raw = append(v.raw, tok.Raw()...) | ||
206 | } else { | ||
207 | v.raw = append(v.raw, r...) | ||
208 | } | ||
209 | } | ||
210 | |||
211 | func (v Value) String() string { | ||
212 | switch v.Type { | ||
213 | case DecimalType: | ||
214 | return fmt.Sprintf("decimal: %f", v.decimal) | ||
215 | case IntegerType: | ||
216 | return fmt.Sprintf("integer: %d", v.integer) | ||
217 | case StringType: | ||
218 | return fmt.Sprintf("string: %s", string(v.raw)) | ||
219 | case QuotedStringType: | ||
220 | return fmt.Sprintf("quoted string: %s", string(v.raw)) | ||
221 | case BoolType: | ||
222 | return fmt.Sprintf("bool: %t", v.boolean) | ||
223 | default: | ||
224 | return "union not set" | ||
225 | } | ||
226 | } | ||
227 | |||
228 | func newLitToken(b []rune) (Token, int, error) { | ||
229 | n := 0 | ||
230 | var err error | ||
231 | |||
232 | token := Token{} | ||
233 | if b[0] == '"' { | ||
234 | n, err = getStringValue(b) | ||
235 | if err != nil { | ||
236 | return token, n, err | ||
237 | } | ||
238 | |||
239 | token = newToken(TokenLit, b[:n], QuotedStringType) | ||
240 | } else if isNumberValue(b) { | ||
241 | var base int | ||
242 | base, n, err = getNumericalValue(b) | ||
243 | if err != nil { | ||
244 | return token, 0, err | ||
245 | } | ||
246 | |||
247 | value := b[:n] | ||
248 | vType := IntegerType | ||
249 | if contains(value, '.') || hasExponent(value) { | ||
250 | vType = DecimalType | ||
251 | } | ||
252 | token = newToken(TokenLit, value, vType) | ||
253 | token.base = base | ||
254 | } else if isBoolValue(b) { | ||
255 | n, err = getBoolValue(b) | ||
256 | |||
257 | token = newToken(TokenLit, b[:n], BoolType) | ||
258 | } else { | ||
259 | n, err = getValue(b) | ||
260 | token = newToken(TokenLit, b[:n], StringType) | ||
261 | } | ||
262 | |||
263 | return token, n, err | ||
264 | } | ||
265 | |||
266 | // IntValue returns an integer value | ||
267 | func (v Value) IntValue() int64 { | ||
268 | return v.integer | ||
269 | } | ||
270 | |||
271 | // FloatValue returns a float value | ||
272 | func (v Value) FloatValue() float64 { | ||
273 | return v.decimal | ||
274 | } | ||
275 | |||
276 | // BoolValue returns a bool value | ||
277 | func (v Value) BoolValue() bool { | ||
278 | return v.boolean | ||
279 | } | ||
280 | |||
281 | func isTrimmable(r rune) bool { | ||
282 | switch r { | ||
283 | case '\n', ' ': | ||
284 | return true | ||
285 | } | ||
286 | return false | ||
287 | } | ||
288 | |||
289 | // StringValue returns the string value | ||
290 | func (v Value) StringValue() string { | ||
291 | switch v.Type { | ||
292 | case StringType: | ||
293 | return strings.TrimFunc(string(v.raw), isTrimmable) | ||
294 | case QuotedStringType: | ||
295 | // preserve all characters in the quotes | ||
296 | return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1])) | ||
297 | default: | ||
298 | return strings.TrimFunc(string(v.raw), isTrimmable) | ||
299 | } | ||
300 | } | ||
301 | |||
302 | func contains(runes []rune, c rune) bool { | ||
303 | for i := 0; i < len(runes); i++ { | ||
304 | if runes[i] == c { | ||
305 | return true | ||
306 | } | ||
307 | } | ||
308 | |||
309 | return false | ||
310 | } | ||
311 | |||
312 | func runeCompare(v1 []rune, v2 []rune) bool { | ||
313 | if len(v1) != len(v2) { | ||
314 | return false | ||
315 | } | ||
316 | |||
317 | for i := 0; i < len(v1); i++ { | ||
318 | if v1[i] != v2[i] { | ||
319 | return false | ||
320 | } | ||
321 | } | ||
322 | |||
323 | return true | ||
324 | } | ||