aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
diff options
context:
space:
mode:
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.go324
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 @@
1package ini
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7)
8
9var (
10 runesTrue = []rune("true")
11 runesFalse = []rune("false")
12)
13
14var literalValues = [][]rune{
15 runesTrue,
16 runesFalse,
17}
18
19func isBoolValue(b []rune) bool {
20 for _, lv := range literalValues {
21 if isLitValue(lv, b) {
22 return true
23 }
24 }
25 return false
26}
27
28func 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.
48func 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
104func 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
113func 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
119type ValueType int
120
121func (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
139const (
140 NoneType = ValueType(iota)
141 DecimalType
142 IntegerType
143 StringType
144 QuotedStringType
145 BoolType
146)
147
148// Value is a union container
149type Value struct {
150 Type ValueType
151 raw []rune
152
153 integer int64
154 decimal float64
155 boolean bool
156 str string
157}
158
159func 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.
198func (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
211func (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
228func 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
267func (v Value) IntValue() int64 {
268 return v.integer
269}
270
271// FloatValue returns a float value
272func (v Value) FloatValue() float64 {
273 return v.decimal
274}
275
276// BoolValue returns a bool value
277func (v Value) BoolValue() bool {
278 return v.boolean
279}
280
281func 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
290func (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
302func 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
312func 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}