~hduran-8/+junk/caddylegacy

« back to all changes in this revision

Viewing changes to debian/gocode/src/github.com/naoina/toml/decode.go

  • Committer: Horacio Durán
  • Date: 2016-10-14 14:33:43 UTC
  • Revision ID: horacio.duran@canonical.com-20161014143343-ytyhz5sx7d1cje4q
Added new upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package toml
 
2
 
 
3
import (
 
4
        "fmt"
 
5
        "io"
 
6
        "io/ioutil"
 
7
        "reflect"
 
8
        "strconv"
 
9
        "strings"
 
10
 
 
11
        "github.com/naoina/toml/ast"
 
12
)
 
13
 
 
14
const (
 
15
        tableSeparator = '.'
 
16
)
 
17
 
 
18
var (
 
19
        escapeReplacer = strings.NewReplacer(
 
20
                "\b", "\\n",
 
21
                "\f", "\\f",
 
22
                "\n", "\\n",
 
23
                "\r", "\\r",
 
24
                "\t", "\\t",
 
25
        )
 
26
        underscoreReplacer = strings.NewReplacer(
 
27
                "_", "",
 
28
        )
 
29
)
 
30
 
 
31
// Unmarshal parses the TOML data and stores the result in the value pointed to by v.
 
32
//
 
33
// Unmarshal will mapped to v that according to following rules:
 
34
//
 
35
//      TOML strings to string
 
36
//      TOML integers to any int type
 
37
//      TOML floats to float32 or float64
 
38
//      TOML booleans to bool
 
39
//      TOML datetimes to time.Time
 
40
//      TOML arrays to any type of slice or []interface{}
 
41
//      TOML tables to struct
 
42
//      TOML array of tables to slice of struct
 
43
func Unmarshal(data []byte, v interface{}) error {
 
44
        table, err := Parse(data)
 
45
        if err != nil {
 
46
                return err
 
47
        }
 
48
        if err := UnmarshalTable(table, v); err != nil {
 
49
                return fmt.Errorf("toml: unmarshal: %v", err)
 
50
        }
 
51
        return nil
 
52
}
 
53
 
 
54
// A Decoder reads and decodes TOML from an input stream.
 
55
type Decoder struct {
 
56
        r io.Reader
 
57
}
 
58
 
 
59
// NewDecoder returns a new Decoder that reads from r.
 
60
// Note that it reads all from r before parsing it.
 
61
func NewDecoder(r io.Reader) *Decoder {
 
62
        return &Decoder{
 
63
                r: r,
 
64
        }
 
65
}
 
66
 
 
67
// Decode parses the TOML data from its input and stores it in the value pointed to by v.
 
68
// See the documentation for Unmarshal for details about the conversion of TOML into a Go value.
 
69
func (d *Decoder) Decode(v interface{}) error {
 
70
        b, err := ioutil.ReadAll(d.r)
 
71
        if err != nil {
 
72
                return err
 
73
        }
 
74
        return Unmarshal(b, v)
 
75
}
 
76
 
 
77
// Unmarshaler is the interface implemented by objects that can unmarshal a
 
78
// TOML description of themselves.
 
79
// The input can be assumed to be a valid encoding of a TOML value.
 
80
// UnmarshalJSON must copy the TOML data if it wishes to retain the data after
 
81
// returning.
 
82
type Unmarshaler interface {
 
83
        UnmarshalTOML([]byte) error
 
84
}
 
85
 
 
86
// UnmarshalTable applies the contents of an ast.Table to the value pointed at by v.
 
87
//
 
88
// UnmarshalTable will mapped to v that according to following rules:
 
89
//
 
90
//      TOML strings to string
 
91
//      TOML integers to any int type
 
92
//      TOML floats to float32 or float64
 
93
//      TOML booleans to bool
 
94
//      TOML datetimes to time.Time
 
95
//      TOML arrays to any type of slice or []interface{}
 
96
//      TOML tables to struct
 
97
//      TOML array of tables to slice of struct
 
98
func UnmarshalTable(t *ast.Table, v interface{}) (err error) {
 
99
        if v == nil {
 
100
                return fmt.Errorf("v must not be nil")
 
101
        }
 
102
        rv := reflect.ValueOf(v)
 
103
        if kind := rv.Kind(); kind != reflect.Ptr && kind != reflect.Map {
 
104
                return fmt.Errorf("v must be a pointer or map")
 
105
        }
 
106
        for rv.Kind() == reflect.Ptr {
 
107
                rv = rv.Elem()
 
108
        }
 
109
        if err, ok := setUnmarshaler(rv, string(t.Data)); ok {
 
110
                return err
 
111
        }
 
112
        for key, val := range t.Fields {
 
113
                switch av := val.(type) {
 
114
                case *ast.KeyValue:
 
115
                        fv, fieldName, found := findField(rv, key)
 
116
                        if !found {
 
117
                                return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
 
118
                        }
 
119
                        switch fv.Kind() {
 
120
                        case reflect.Map:
 
121
                                mv := reflect.New(fv.Type().Elem()).Elem()
 
122
                                if err := UnmarshalTable(t, mv.Addr().Interface()); err != nil {
 
123
                                        return err
 
124
                                }
 
125
                                fv.SetMapIndex(reflect.ValueOf(fieldName), mv)
 
126
                        default:
 
127
                                if err := setValue(fv, av.Value); err != nil {
 
128
                                        return fmt.Errorf("line %d: %v.%s: %v", av.Line, rv.Type(), fieldName, err)
 
129
                                }
 
130
                                if rv.Kind() == reflect.Map {
 
131
                                        rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
 
132
                                }
 
133
                        }
 
134
                case *ast.Table:
 
135
                        fv, fieldName, found := findField(rv, key)
 
136
                        if !found {
 
137
                                return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v)
 
138
                        }
 
139
                        if err, ok := setUnmarshaler(fv, string(av.Data)); ok {
 
140
                                if err != nil {
 
141
                                        return err
 
142
                                }
 
143
                                continue
 
144
                        }
 
145
                        for fv.Kind() == reflect.Ptr {
 
146
                                fv.Set(reflect.New(fv.Type().Elem()))
 
147
                                fv = fv.Elem()
 
148
                        }
 
149
                        switch fv.Kind() {
 
150
                        case reflect.Struct:
 
151
                                vv := reflect.New(fv.Type()).Elem()
 
152
                                if err := UnmarshalTable(av, vv.Addr().Interface()); err != nil {
 
153
                                        return err
 
154
                                }
 
155
                                fv.Set(vv)
 
156
                                if rv.Kind() == reflect.Map {
 
157
                                        rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
 
158
                                }
 
159
                        case reflect.Map:
 
160
                                mv := reflect.MakeMap(fv.Type())
 
161
                                if err := UnmarshalTable(av, mv.Interface()); err != nil {
 
162
                                        return err
 
163
                                }
 
164
                                fv.Set(mv)
 
165
                        default:
 
166
                                return fmt.Errorf("line %d: `%v.%s' must be struct or map, but %v given", av.Line, rv.Type(), fieldName, fv.Kind())
 
167
                        }
 
168
                case []*ast.Table:
 
169
                        fv, fieldName, found := findField(rv, key)
 
170
                        if !found {
 
171
                                return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av[0].Line, key, v)
 
172
                        }
 
173
                        data := make([]string, 0, len(av))
 
174
                        for _, tbl := range av {
 
175
                                data = append(data, string(tbl.Data))
 
176
                        }
 
177
                        if err, ok := setUnmarshaler(fv, strings.Join(data, "\n")); ok {
 
178
                                if err != nil {
 
179
                                        return err
 
180
                                }
 
181
                                continue
 
182
                        }
 
183
                        t := fv.Type().Elem()
 
184
                        pc := 0
 
185
                        for ; t.Kind() == reflect.Ptr; pc++ {
 
186
                                t = t.Elem()
 
187
                        }
 
188
                        if fv.Kind() != reflect.Slice {
 
189
                                return fmt.Errorf("line %d: `%v.%s' must be slice type, but %v given", av[0].Line, rv.Type(), fieldName, fv.Kind())
 
190
                        }
 
191
                        for _, tbl := range av {
 
192
                                var vv reflect.Value
 
193
                                switch t.Kind() {
 
194
                                case reflect.Map:
 
195
                                        vv = reflect.MakeMap(t)
 
196
                                        if err := UnmarshalTable(tbl, vv.Interface()); err != nil {
 
197
                                                return err
 
198
                                        }
 
199
                                default:
 
200
                                        vv = reflect.New(t).Elem()
 
201
                                        if err := UnmarshalTable(tbl, vv.Addr().Interface()); err != nil {
 
202
                                                return err
 
203
                                        }
 
204
                                }
 
205
                                for i := 0; i < pc; i++ {
 
206
                                        vv = vv.Addr()
 
207
                                        pv := reflect.New(vv.Type()).Elem()
 
208
                                        pv.Set(vv)
 
209
                                        vv = pv
 
210
                                }
 
211
                                fv.Set(reflect.Append(fv, vv))
 
212
                        }
 
213
                        if rv.Kind() == reflect.Map {
 
214
                                rv.SetMapIndex(reflect.ValueOf(fieldName), fv)
 
215
                        }
 
216
                default:
 
217
                        return fmt.Errorf("BUG: unknown type `%T'", t)
 
218
                }
 
219
        }
 
220
        return nil
 
221
}
 
222
 
 
223
func setUnmarshaler(lhs reflect.Value, data string) (error, bool) {
 
224
        for lhs.Kind() == reflect.Ptr {
 
225
                lhs.Set(reflect.New(lhs.Type().Elem()))
 
226
                lhs = lhs.Elem()
 
227
        }
 
228
        if lhs.CanAddr() {
 
229
                if u, ok := lhs.Addr().Interface().(Unmarshaler); ok {
 
230
                        return u.UnmarshalTOML([]byte(data)), true
 
231
                }
 
232
        }
 
233
        return nil, false
 
234
}
 
235
 
 
236
func setValue(lhs reflect.Value, val ast.Value) error {
 
237
        for lhs.Kind() == reflect.Ptr {
 
238
                lhs.Set(reflect.New(lhs.Type().Elem()))
 
239
                lhs = lhs.Elem()
 
240
        }
 
241
        if err, ok := setUnmarshaler(lhs, val.Source()); ok {
 
242
                return err
 
243
        }
 
244
        switch v := val.(type) {
 
245
        case *ast.Integer:
 
246
                if err := setInt(lhs, v); err != nil {
 
247
                        return err
 
248
                }
 
249
        case *ast.Float:
 
250
                if err := setFloat(lhs, v); err != nil {
 
251
                        return err
 
252
                }
 
253
        case *ast.String:
 
254
                if err := setString(lhs, v); err != nil {
 
255
                        return err
 
256
                }
 
257
        case *ast.Boolean:
 
258
                if err := setBoolean(lhs, v); err != nil {
 
259
                        return err
 
260
                }
 
261
        case *ast.Datetime:
 
262
                if err := setDatetime(lhs, v); err != nil {
 
263
                        return err
 
264
                }
 
265
        case *ast.Array:
 
266
                if err := setArray(lhs, v); err != nil {
 
267
                        return err
 
268
                }
 
269
        }
 
270
        return nil
 
271
}
 
272
 
 
273
func setInt(fv reflect.Value, v *ast.Integer) error {
 
274
        i, err := v.Int()
 
275
        if err != nil {
 
276
                return err
 
277
        }
 
278
        switch fv.Kind() {
 
279
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 
280
                if fv.OverflowInt(i) {
 
281
                        return &errorOutOfRange{fv.Kind(), i}
 
282
                }
 
283
                fv.SetInt(i)
 
284
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 
285
                fv.SetUint(uint64(i))
 
286
        case reflect.Interface:
 
287
                fv.Set(reflect.ValueOf(i))
 
288
        default:
 
289
                return fmt.Errorf("`%v' is not any types of int", fv.Type())
 
290
        }
 
291
        return nil
 
292
}
 
293
 
 
294
func setFloat(fv reflect.Value, v *ast.Float) error {
 
295
        f, err := v.Float()
 
296
        if err != nil {
 
297
                return err
 
298
        }
 
299
        switch fv.Kind() {
 
300
        case reflect.Float32, reflect.Float64:
 
301
                if fv.OverflowFloat(f) {
 
302
                        return &errorOutOfRange{fv.Kind(), f}
 
303
                }
 
304
                fv.SetFloat(f)
 
305
        case reflect.Interface:
 
306
                fv.Set(reflect.ValueOf(f))
 
307
        default:
 
308
                return fmt.Errorf("`%v' is not float32 or float64", fv.Type())
 
309
        }
 
310
        return nil
 
311
}
 
312
 
 
313
func setString(fv reflect.Value, v *ast.String) error {
 
314
        return set(fv, v.Value)
 
315
}
 
316
 
 
317
func setBoolean(fv reflect.Value, v *ast.Boolean) error {
 
318
        b, err := v.Boolean()
 
319
        if err != nil {
 
320
                return err
 
321
        }
 
322
        return set(fv, b)
 
323
}
 
324
 
 
325
func setDatetime(fv reflect.Value, v *ast.Datetime) error {
 
326
        tm, err := v.Time()
 
327
        if err != nil {
 
328
                return err
 
329
        }
 
330
        return set(fv, tm)
 
331
}
 
332
 
 
333
func setArray(fv reflect.Value, v *ast.Array) error {
 
334
        if len(v.Value) == 0 {
 
335
                return nil
 
336
        }
 
337
        typ := reflect.TypeOf(v.Value[0])
 
338
        for _, vv := range v.Value[1:] {
 
339
                if typ != reflect.TypeOf(vv) {
 
340
                        return fmt.Errorf("array cannot contain multiple types")
 
341
                }
 
342
        }
 
343
        sliceType := fv.Type()
 
344
        if fv.Kind() == reflect.Interface {
 
345
                sliceType = reflect.SliceOf(sliceType)
 
346
        }
 
347
        slice := reflect.MakeSlice(sliceType, 0, len(v.Value))
 
348
        t := sliceType.Elem()
 
349
        for _, vv := range v.Value {
 
350
                tmp := reflect.New(t).Elem()
 
351
                if err := setValue(tmp, vv); err != nil {
 
352
                        return err
 
353
                }
 
354
                slice = reflect.Append(slice, tmp)
 
355
        }
 
356
        fv.Set(slice)
 
357
        return nil
 
358
}
 
359
 
 
360
func set(fv reflect.Value, v interface{}) error {
 
361
        rhs := reflect.ValueOf(v)
 
362
        if !rhs.Type().AssignableTo(fv.Type()) {
 
363
                return fmt.Errorf("`%v' type is not assignable to `%v' type", rhs.Type(), fv.Type())
 
364
        }
 
365
        fv.Set(rhs)
 
366
        return nil
 
367
}
 
368
 
 
369
type stack struct {
 
370
        key   string
 
371
        table *ast.Table
 
372
}
 
373
 
 
374
type toml struct {
 
375
        table        *ast.Table
 
376
        line         int
 
377
        currentTable *ast.Table
 
378
        s            string
 
379
        key          string
 
380
        val          ast.Value
 
381
        arr          *array
 
382
        tableMap     map[string]*ast.Table
 
383
        stack        []*stack
 
384
        skip         bool
 
385
}
 
386
 
 
387
func (p *toml) init(data []rune) {
 
388
        p.line = 1
 
389
        p.table = &ast.Table{
 
390
                Line: p.line,
 
391
                Type: ast.TableTypeNormal,
 
392
                Data: data[:len(data)-1], // truncate the end_symbol added by PEG parse generator.
 
393
        }
 
394
        p.tableMap = map[string]*ast.Table{
 
395
                "": p.table,
 
396
        }
 
397
        p.currentTable = p.table
 
398
}
 
399
 
 
400
func (p *toml) Error(err error) {
 
401
        panic(convertError{fmt.Errorf("toml: line %d: %v", p.line, err)})
 
402
}
 
403
 
 
404
func (p *tomlParser) SetTime(begin, end int) {
 
405
        p.val = &ast.Datetime{
 
406
                Position: ast.Position{Begin: begin, End: end},
 
407
                Data:     p.buffer[begin:end],
 
408
                Value:    string(p.buffer[begin:end]),
 
409
        }
 
410
}
 
411
 
 
412
func (p *tomlParser) SetFloat64(begin, end int) {
 
413
        p.val = &ast.Float{
 
414
                Position: ast.Position{Begin: begin, End: end},
 
415
                Data:     p.buffer[begin:end],
 
416
                Value:    underscoreReplacer.Replace(string(p.buffer[begin:end])),
 
417
        }
 
418
}
 
419
 
 
420
func (p *tomlParser) SetInt64(begin, end int) {
 
421
        p.val = &ast.Integer{
 
422
                Position: ast.Position{Begin: begin, End: end},
 
423
                Data:     p.buffer[begin:end],
 
424
                Value:    underscoreReplacer.Replace(string(p.buffer[begin:end])),
 
425
        }
 
426
}
 
427
 
 
428
func (p *tomlParser) SetString(begin, end int) {
 
429
        p.val = &ast.String{
 
430
                Position: ast.Position{Begin: begin, End: end},
 
431
                Data:     p.buffer[begin:end],
 
432
                Value:    p.s,
 
433
        }
 
434
        p.s = ""
 
435
}
 
436
 
 
437
func (p *tomlParser) SetBool(begin, end int) {
 
438
        p.val = &ast.Boolean{
 
439
                Position: ast.Position{Begin: begin, End: end},
 
440
                Data:     p.buffer[begin:end],
 
441
                Value:    string(p.buffer[begin:end]),
 
442
        }
 
443
}
 
444
 
 
445
func (p *tomlParser) StartArray() {
 
446
        if p.arr == nil {
 
447
                p.arr = &array{line: p.line, current: &ast.Array{}}
 
448
                return
 
449
        }
 
450
        p.arr.child = &array{parent: p.arr, line: p.line, current: &ast.Array{}}
 
451
        p.arr = p.arr.child
 
452
}
 
453
 
 
454
func (p *tomlParser) AddArrayVal() {
 
455
        if p.arr.current == nil {
 
456
                p.arr.current = &ast.Array{}
 
457
        }
 
458
        p.arr.current.Value = append(p.arr.current.Value, p.val)
 
459
}
 
460
 
 
461
func (p *tomlParser) SetArray(begin, end int) {
 
462
        p.arr.current.Position = ast.Position{Begin: begin, End: end}
 
463
        p.arr.current.Data = p.buffer[begin:end]
 
464
        p.val = p.arr.current
 
465
        p.arr = p.arr.parent
 
466
}
 
467
 
 
468
func (p *toml) SetTable(buf []rune, begin, end int) {
 
469
        p.setTable(p.table, buf, begin, end)
 
470
}
 
471
 
 
472
func (p *toml) setTable(t *ast.Table, buf []rune, begin, end int) {
 
473
        name := string(buf[begin:end])
 
474
        names := splitTableKey(name)
 
475
        if t, exists := p.tableMap[name]; exists {
 
476
                if lt := p.tableMap[names[len(names)-1]]; t.Type == ast.TableTypeArray || lt != nil && lt.Type == ast.TableTypeNormal {
 
477
                        p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
 
478
                }
 
479
        }
 
480
        t, err := p.lookupTable(t, names)
 
481
        if err != nil {
 
482
                p.Error(err)
 
483
        }
 
484
        p.currentTable = t
 
485
        p.tableMap[name] = p.currentTable
 
486
}
 
487
 
 
488
func (p *tomlParser) SetTableString(begin, end int) {
 
489
        p.currentTable.Data = p.buffer[begin:end]
 
490
 
 
491
        p.currentTable.Position.Begin = begin
 
492
        p.currentTable.Position.End = end
 
493
}
 
494
 
 
495
func (p *toml) SetArrayTable(buf []rune, begin, end int) {
 
496
        p.setArrayTable(p.table, buf, begin, end)
 
497
}
 
498
 
 
499
func (p *toml) setArrayTable(t *ast.Table, buf []rune, begin, end int) {
 
500
        name := string(buf[begin:end])
 
501
        if t, exists := p.tableMap[name]; exists && t.Type == ast.TableTypeNormal {
 
502
                p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line))
 
503
        }
 
504
        names := splitTableKey(name)
 
505
        t, err := p.lookupTable(t, names[:len(names)-1])
 
506
        if err != nil {
 
507
                p.Error(err)
 
508
        }
 
509
        last := names[len(names)-1]
 
510
        tbl := &ast.Table{
 
511
                Position: ast.Position{begin, end},
 
512
                Line:     p.line,
 
513
                Name:     last,
 
514
                Type:     ast.TableTypeArray,
 
515
        }
 
516
        switch v := t.Fields[last].(type) {
 
517
        case nil:
 
518
                if t.Fields == nil {
 
519
                        t.Fields = make(map[string]interface{})
 
520
                }
 
521
                t.Fields[last] = []*ast.Table{tbl}
 
522
        case []*ast.Table:
 
523
                t.Fields[last] = append(v, tbl)
 
524
        case *ast.KeyValue:
 
525
                p.Error(fmt.Errorf("key `%s' is in conflict with line %d", last, v.Line))
 
526
        default:
 
527
                p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", last, v))
 
528
        }
 
529
        p.currentTable = tbl
 
530
        p.tableMap[name] = p.currentTable
 
531
}
 
532
 
 
533
func (p *toml) StartInlineTable() {
 
534
        p.skip = false
 
535
        p.stack = append(p.stack, &stack{p.key, p.currentTable})
 
536
        buf := []rune(p.key)
 
537
        if p.arr == nil {
 
538
                p.setTable(p.currentTable, buf, 0, len(buf))
 
539
        } else {
 
540
                p.setArrayTable(p.currentTable, buf, 0, len(buf))
 
541
        }
 
542
}
 
543
 
 
544
func (p *toml) EndInlineTable() {
 
545
        st := p.stack[len(p.stack)-1]
 
546
        p.key, p.currentTable = st.key, st.table
 
547
        p.stack[len(p.stack)-1] = nil
 
548
        p.stack = p.stack[:len(p.stack)-1]
 
549
        p.skip = true
 
550
}
 
551
 
 
552
func (p *toml) AddLineCount(i int) {
 
553
        p.line += i
 
554
}
 
555
 
 
556
func (p *toml) SetKey(buf []rune, begin, end int) {
 
557
        p.key = string(buf[begin:end])
 
558
}
 
559
 
 
560
func (p *toml) AddKeyValue() {
 
561
        if p.skip {
 
562
                p.skip = false
 
563
                return
 
564
        }
 
565
        if val, exists := p.currentTable.Fields[p.key]; exists {
 
566
                switch v := val.(type) {
 
567
                case *ast.Table:
 
568
                        p.Error(fmt.Errorf("key `%s' is in conflict with %v table in line %d", p.key, v.Type, v.Line))
 
569
                case *ast.KeyValue:
 
570
                        p.Error(fmt.Errorf("key `%s' is in conflict with line %d", p.key, v.Line))
 
571
                default:
 
572
                        p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", p.key, v))
 
573
                }
 
574
        }
 
575
        if p.currentTable.Fields == nil {
 
576
                p.currentTable.Fields = make(map[string]interface{})
 
577
        }
 
578
        p.currentTable.Fields[p.key] = &ast.KeyValue{
 
579
                Key:   p.key,
 
580
                Value: p.val,
 
581
                Line:  p.line,
 
582
        }
 
583
}
 
584
 
 
585
func (p *toml) SetBasicString(buf []rune, begin, end int) {
 
586
        p.s = p.unquote(string(buf[begin:end]))
 
587
}
 
588
 
 
589
func (p *toml) SetMultilineString() {
 
590
        p.s = p.unquote(`"` + escapeReplacer.Replace(strings.TrimLeft(p.s, "\r\n")) + `"`)
 
591
}
 
592
 
 
593
func (p *toml) AddMultilineBasicBody(buf []rune, begin, end int) {
 
594
        p.s += string(buf[begin:end])
 
595
}
 
596
 
 
597
func (p *toml) SetLiteralString(buf []rune, begin, end int) {
 
598
        p.s = string(buf[begin:end])
 
599
}
 
600
 
 
601
func (p *toml) SetMultilineLiteralString(buf []rune, begin, end int) {
 
602
        p.s = strings.TrimLeft(string(buf[begin:end]), "\r\n")
 
603
}
 
604
 
 
605
func (p *toml) unquote(s string) string {
 
606
        s, err := strconv.Unquote(s)
 
607
        if err != nil {
 
608
                p.Error(err)
 
609
        }
 
610
        return s
 
611
}
 
612
 
 
613
func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) {
 
614
        for _, s := range keys {
 
615
                val, exists := t.Fields[s]
 
616
                if !exists {
 
617
                        tbl := &ast.Table{
 
618
                                Line: p.line,
 
619
                                Name: s,
 
620
                                Type: ast.TableTypeNormal,
 
621
                        }
 
622
                        if t.Fields == nil {
 
623
                                t.Fields = make(map[string]interface{})
 
624
                        }
 
625
                        t.Fields[s] = tbl
 
626
                        t = tbl
 
627
                        continue
 
628
                }
 
629
                switch v := val.(type) {
 
630
                case *ast.Table:
 
631
                        t = v
 
632
                case []*ast.Table:
 
633
                        t = v[len(v)-1]
 
634
                case *ast.KeyValue:
 
635
                        return nil, fmt.Errorf("key `%s' is in conflict with line %d", s, v.Line)
 
636
                default:
 
637
                        return nil, fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", s, v)
 
638
                }
 
639
        }
 
640
        return t, nil
 
641
}
 
642
 
 
643
func splitTableKey(tk string) []string {
 
644
        key := make([]byte, 0, 1)
 
645
        keys := make([]string, 0, 1)
 
646
        inQuote := false
 
647
        for i := 0; i < len(tk); i++ {
 
648
                k := tk[i]
 
649
                switch {
 
650
                case k == tableSeparator && !inQuote:
 
651
                        keys = append(keys, string(key))
 
652
                        key = key[:0] // reuse buffer.
 
653
                case k == '"':
 
654
                        inQuote = !inQuote
 
655
                case (k == ' ' || k == '\t') && !inQuote:
 
656
                        // skip.
 
657
                default:
 
658
                        key = append(key, k)
 
659
                }
 
660
        }
 
661
        keys = append(keys, string(key))
 
662
        return keys
 
663
}
 
664
 
 
665
type convertError struct {
 
666
        err error
 
667
}
 
668
 
 
669
func (e convertError) Error() string {
 
670
        return e.err.Error()
 
671
}
 
672
 
 
673
type array struct {
 
674
        parent  *array
 
675
        child   *array
 
676
        current *ast.Array
 
677
        line    int
 
678
}