1 package ini
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "strconv"
8 "strings"
9 "time"
10 )
11
12
13 type Key struct {
14 s *Section
15 Comment string
16 name string
17 value string
18 isAutoIncrement bool
19 isBooleanType bool
20
21 isShadow bool
22 shadows []*Key
23
24 nestedValues []string
25 }
26
27
28 func newKey(s *Section, name, val string) *Key {
29 return &Key{
30 s: s,
31 name: name,
32 value: val,
33 }
34 }
35
36 func (k *Key) addShadow(val string) error {
37 if k.isShadow {
38 return errors.New("cannot add shadow to another shadow key")
39 } else if k.isAutoIncrement || k.isBooleanType {
40 return errors.New("cannot add shadow to auto-increment or boolean key")
41 }
42
43 if !k.s.f.options.AllowDuplicateShadowValues {
44
45 if k.value == val {
46 return nil
47 }
48 for i := range k.shadows {
49 if k.shadows[i].value == val {
50 return nil
51 }
52 }
53 }
54
55 shadow := newKey(k.s, k.name, val)
56 shadow.isShadow = true
57 k.shadows = append(k.shadows, shadow)
58 return nil
59 }
60
61
62 func (k *Key) AddShadow(val string) error {
63 if !k.s.f.options.AllowShadows {
64 return errors.New("shadow key is not allowed")
65 }
66 return k.addShadow(val)
67 }
68
69 func (k *Key) addNestedValue(val string) error {
70 if k.isAutoIncrement || k.isBooleanType {
71 return errors.New("cannot add nested value to auto-increment or boolean key")
72 }
73
74 k.nestedValues = append(k.nestedValues, val)
75 return nil
76 }
77
78
79 func (k *Key) AddNestedValue(val string) error {
80 if !k.s.f.options.AllowNestedValues {
81 return errors.New("nested value is not allowed")
82 }
83 return k.addNestedValue(val)
84 }
85
86
87 type ValueMapper func(string) string
88
89
90 func (k *Key) Name() string {
91 return k.name
92 }
93
94
95 func (k *Key) Value() string {
96 return k.value
97 }
98
99
100
101 func (k *Key) ValueWithShadows() []string {
102 if len(k.shadows) == 0 {
103 if k.value == "" {
104 return []string{}
105 }
106 return []string{k.value}
107 }
108
109 vals := make([]string, 0, len(k.shadows)+1)
110 if k.value != "" {
111 vals = append(vals, k.value)
112 }
113 for _, s := range k.shadows {
114 if s.value != "" {
115 vals = append(vals, s.value)
116 }
117 }
118 return vals
119 }
120
121
122
123 func (k *Key) NestedValues() []string {
124 return k.nestedValues
125 }
126
127
128 func (k *Key) transformValue(val string) string {
129 if k.s.f.ValueMapper != nil {
130 val = k.s.f.ValueMapper(val)
131 }
132
133
134 if !strings.Contains(val, "%") {
135 return val
136 }
137 for i := 0; i < depthValues; i++ {
138 vr := varPattern.FindString(val)
139 if len(vr) == 0 {
140 break
141 }
142
143
144 noption := vr[2 : len(vr)-2]
145
146
147
148 nk, err := k.s.GetKey(noption)
149 if err != nil || k == nk {
150 nk, _ = k.s.f.Section("").GetKey(noption)
151 if nk == nil {
152
153
154 break
155 }
156 }
157
158
159 val = strings.Replace(val, vr, nk.value, -1)
160 }
161 return val
162 }
163
164
165 func (k *Key) String() string {
166 return k.transformValue(k.value)
167 }
168
169
170
171 func (k *Key) Validate(fn func(string) string) string {
172 return fn(k.String())
173 }
174
175
176
177
178
179
180 func parseBool(str string) (value bool, err error) {
181 switch str {
182 case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On":
183 return true, nil
184 case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off":
185 return false, nil
186 }
187 return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
188 }
189
190
191 func (k *Key) Bool() (bool, error) {
192 return parseBool(k.String())
193 }
194
195
196 func (k *Key) Float64() (float64, error) {
197 return strconv.ParseFloat(k.String(), 64)
198 }
199
200
201 func (k *Key) Int() (int, error) {
202 v, err := strconv.ParseInt(k.String(), 0, 64)
203 return int(v), err
204 }
205
206
207 func (k *Key) Int64() (int64, error) {
208 return strconv.ParseInt(k.String(), 0, 64)
209 }
210
211
212 func (k *Key) Uint() (uint, error) {
213 u, e := strconv.ParseUint(k.String(), 0, 64)
214 return uint(u), e
215 }
216
217
218 func (k *Key) Uint64() (uint64, error) {
219 return strconv.ParseUint(k.String(), 0, 64)
220 }
221
222
223 func (k *Key) Duration() (time.Duration, error) {
224 return time.ParseDuration(k.String())
225 }
226
227
228 func (k *Key) TimeFormat(format string) (time.Time, error) {
229 return time.Parse(format, k.String())
230 }
231
232
233 func (k *Key) Time() (time.Time, error) {
234 return k.TimeFormat(time.RFC3339)
235 }
236
237
238 func (k *Key) MustString(defaultVal string) string {
239 val := k.String()
240 if len(val) == 0 {
241 k.value = defaultVal
242 return defaultVal
243 }
244 return val
245 }
246
247
248
249 func (k *Key) MustBool(defaultVal ...bool) bool {
250 val, err := k.Bool()
251 if len(defaultVal) > 0 && err != nil {
252 k.value = strconv.FormatBool(defaultVal[0])
253 return defaultVal[0]
254 }
255 return val
256 }
257
258
259
260 func (k *Key) MustFloat64(defaultVal ...float64) float64 {
261 val, err := k.Float64()
262 if len(defaultVal) > 0 && err != nil {
263 k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64)
264 return defaultVal[0]
265 }
266 return val
267 }
268
269
270
271 func (k *Key) MustInt(defaultVal ...int) int {
272 val, err := k.Int()
273 if len(defaultVal) > 0 && err != nil {
274 k.value = strconv.FormatInt(int64(defaultVal[0]), 10)
275 return defaultVal[0]
276 }
277 return val
278 }
279
280
281
282 func (k *Key) MustInt64(defaultVal ...int64) int64 {
283 val, err := k.Int64()
284 if len(defaultVal) > 0 && err != nil {
285 k.value = strconv.FormatInt(defaultVal[0], 10)
286 return defaultVal[0]
287 }
288 return val
289 }
290
291
292
293 func (k *Key) MustUint(defaultVal ...uint) uint {
294 val, err := k.Uint()
295 if len(defaultVal) > 0 && err != nil {
296 k.value = strconv.FormatUint(uint64(defaultVal[0]), 10)
297 return defaultVal[0]
298 }
299 return val
300 }
301
302
303
304 func (k *Key) MustUint64(defaultVal ...uint64) uint64 {
305 val, err := k.Uint64()
306 if len(defaultVal) > 0 && err != nil {
307 k.value = strconv.FormatUint(defaultVal[0], 10)
308 return defaultVal[0]
309 }
310 return val
311 }
312
313
314
315 func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration {
316 val, err := k.Duration()
317 if len(defaultVal) > 0 && err != nil {
318 k.value = defaultVal[0].String()
319 return defaultVal[0]
320 }
321 return val
322 }
323
324
325
326 func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
327 val, err := k.TimeFormat(format)
328 if len(defaultVal) > 0 && err != nil {
329 k.value = defaultVal[0].Format(format)
330 return defaultVal[0]
331 }
332 return val
333 }
334
335
336
337 func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
338 return k.MustTimeFormat(time.RFC3339, defaultVal...)
339 }
340
341
342
343 func (k *Key) In(defaultVal string, candidates []string) string {
344 val := k.String()
345 for _, cand := range candidates {
346 if val == cand {
347 return val
348 }
349 }
350 return defaultVal
351 }
352
353
354
355 func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
356 val := k.MustFloat64()
357 for _, cand := range candidates {
358 if val == cand {
359 return val
360 }
361 }
362 return defaultVal
363 }
364
365
366
367 func (k *Key) InInt(defaultVal int, candidates []int) int {
368 val := k.MustInt()
369 for _, cand := range candidates {
370 if val == cand {
371 return val
372 }
373 }
374 return defaultVal
375 }
376
377
378
379 func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
380 val := k.MustInt64()
381 for _, cand := range candidates {
382 if val == cand {
383 return val
384 }
385 }
386 return defaultVal
387 }
388
389
390
391 func (k *Key) InUint(defaultVal uint, candidates []uint) uint {
392 val := k.MustUint()
393 for _, cand := range candidates {
394 if val == cand {
395 return val
396 }
397 }
398 return defaultVal
399 }
400
401
402
403 func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
404 val := k.MustUint64()
405 for _, cand := range candidates {
406 if val == cand {
407 return val
408 }
409 }
410 return defaultVal
411 }
412
413
414
415 func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
416 val := k.MustTimeFormat(format)
417 for _, cand := range candidates {
418 if val == cand {
419 return val
420 }
421 }
422 return defaultVal
423 }
424
425
426
427 func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
428 return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
429 }
430
431
432
433 func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 {
434 val := k.MustFloat64()
435 if val < min || val > max {
436 return defaultVal
437 }
438 return val
439 }
440
441
442
443 func (k *Key) RangeInt(defaultVal, min, max int) int {
444 val := k.MustInt()
445 if val < min || val > max {
446 return defaultVal
447 }
448 return val
449 }
450
451
452
453 func (k *Key) RangeInt64(defaultVal, min, max int64) int64 {
454 val := k.MustInt64()
455 if val < min || val > max {
456 return defaultVal
457 }
458 return val
459 }
460
461
462
463 func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time {
464 val := k.MustTimeFormat(format)
465 if val.Unix() < min.Unix() || val.Unix() > max.Unix() {
466 return defaultVal
467 }
468 return val
469 }
470
471
472
473 func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time {
474 return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max)
475 }
476
477
478 func (k *Key) Strings(delim string) []string {
479 str := k.String()
480 if len(str) == 0 {
481 return []string{}
482 }
483
484 runes := []rune(str)
485 vals := make([]string, 0, 2)
486 var buf bytes.Buffer
487 escape := false
488 idx := 0
489 for {
490 if escape {
491 escape = false
492 if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) {
493 buf.WriteRune('\\')
494 }
495 buf.WriteRune(runes[idx])
496 } else {
497 if runes[idx] == '\\' {
498 escape = true
499 } else if strings.HasPrefix(string(runes[idx:]), delim) {
500 idx += len(delim) - 1
501 vals = append(vals, strings.TrimSpace(buf.String()))
502 buf.Reset()
503 } else {
504 buf.WriteRune(runes[idx])
505 }
506 }
507 idx++
508 if idx == len(runes) {
509 break
510 }
511 }
512
513 if buf.Len() > 0 {
514 vals = append(vals, strings.TrimSpace(buf.String()))
515 }
516
517 return vals
518 }
519
520
521
522 func (k *Key) StringsWithShadows(delim string) []string {
523 vals := k.ValueWithShadows()
524 results := make([]string, 0, len(vals)*2)
525 for i := range vals {
526 if len(vals) == 0 {
527 continue
528 }
529
530 results = append(results, strings.Split(vals[i], delim)...)
531 }
532
533 for i := range results {
534 results[i] = k.transformValue(strings.TrimSpace(results[i]))
535 }
536 return results
537 }
538
539
540 func (k *Key) Float64s(delim string) []float64 {
541 vals, _ := k.parseFloat64s(k.Strings(delim), true, false)
542 return vals
543 }
544
545
546 func (k *Key) Ints(delim string) []int {
547 vals, _ := k.parseInts(k.Strings(delim), true, false)
548 return vals
549 }
550
551
552 func (k *Key) Int64s(delim string) []int64 {
553 vals, _ := k.parseInt64s(k.Strings(delim), true, false)
554 return vals
555 }
556
557
558 func (k *Key) Uints(delim string) []uint {
559 vals, _ := k.parseUints(k.Strings(delim), true, false)
560 return vals
561 }
562
563
564 func (k *Key) Uint64s(delim string) []uint64 {
565 vals, _ := k.parseUint64s(k.Strings(delim), true, false)
566 return vals
567 }
568
569
570 func (k *Key) Bools(delim string) []bool {
571 vals, _ := k.parseBools(k.Strings(delim), true, false)
572 return vals
573 }
574
575
576
577 func (k *Key) TimesFormat(format, delim string) []time.Time {
578 vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false)
579 return vals
580 }
581
582
583
584 func (k *Key) Times(delim string) []time.Time {
585 return k.TimesFormat(time.RFC3339, delim)
586 }
587
588
589
590 func (k *Key) ValidFloat64s(delim string) []float64 {
591 vals, _ := k.parseFloat64s(k.Strings(delim), false, false)
592 return vals
593 }
594
595
596
597 func (k *Key) ValidInts(delim string) []int {
598 vals, _ := k.parseInts(k.Strings(delim), false, false)
599 return vals
600 }
601
602
603
604 func (k *Key) ValidInt64s(delim string) []int64 {
605 vals, _ := k.parseInt64s(k.Strings(delim), false, false)
606 return vals
607 }
608
609
610
611 func (k *Key) ValidUints(delim string) []uint {
612 vals, _ := k.parseUints(k.Strings(delim), false, false)
613 return vals
614 }
615
616
617
618 func (k *Key) ValidUint64s(delim string) []uint64 {
619 vals, _ := k.parseUint64s(k.Strings(delim), false, false)
620 return vals
621 }
622
623
624
625 func (k *Key) ValidBools(delim string) []bool {
626 vals, _ := k.parseBools(k.Strings(delim), false, false)
627 return vals
628 }
629
630
631 func (k *Key) ValidTimesFormat(format, delim string) []time.Time {
632 vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false)
633 return vals
634 }
635
636
637 func (k *Key) ValidTimes(delim string) []time.Time {
638 return k.ValidTimesFormat(time.RFC3339, delim)
639 }
640
641
642 func (k *Key) StrictFloat64s(delim string) ([]float64, error) {
643 return k.parseFloat64s(k.Strings(delim), false, true)
644 }
645
646
647 func (k *Key) StrictInts(delim string) ([]int, error) {
648 return k.parseInts(k.Strings(delim), false, true)
649 }
650
651
652 func (k *Key) StrictInt64s(delim string) ([]int64, error) {
653 return k.parseInt64s(k.Strings(delim), false, true)
654 }
655
656
657 func (k *Key) StrictUints(delim string) ([]uint, error) {
658 return k.parseUints(k.Strings(delim), false, true)
659 }
660
661
662 func (k *Key) StrictUint64s(delim string) ([]uint64, error) {
663 return k.parseUint64s(k.Strings(delim), false, true)
664 }
665
666
667 func (k *Key) StrictBools(delim string) ([]bool, error) {
668 return k.parseBools(k.Strings(delim), false, true)
669 }
670
671
672
673 func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) {
674 return k.parseTimesFormat(format, k.Strings(delim), false, true)
675 }
676
677
678
679 func (k *Key) StrictTimes(delim string) ([]time.Time, error) {
680 return k.StrictTimesFormat(time.RFC3339, delim)
681 }
682
683
684 func (k *Key) parseBools(strs []string, addInvalid, returnOnInvalid bool) ([]bool, error) {
685 vals := make([]bool, 0, len(strs))
686 parser := func(str string) (interface{}, error) {
687 val, err := parseBool(str)
688 return val, err
689 }
690 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
691 if err == nil {
692 for _, val := range rawVals {
693 vals = append(vals, val.(bool))
694 }
695 }
696 return vals, err
697 }
698
699
700 func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) {
701 vals := make([]float64, 0, len(strs))
702 parser := func(str string) (interface{}, error) {
703 val, err := strconv.ParseFloat(str, 64)
704 return val, err
705 }
706 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
707 if err == nil {
708 for _, val := range rawVals {
709 vals = append(vals, val.(float64))
710 }
711 }
712 return vals, err
713 }
714
715
716 func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) {
717 vals := make([]int, 0, len(strs))
718 parser := func(str string) (interface{}, error) {
719 val, err := strconv.ParseInt(str, 0, 64)
720 return val, err
721 }
722 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
723 if err == nil {
724 for _, val := range rawVals {
725 vals = append(vals, int(val.(int64)))
726 }
727 }
728 return vals, err
729 }
730
731
732 func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) {
733 vals := make([]int64, 0, len(strs))
734 parser := func(str string) (interface{}, error) {
735 val, err := strconv.ParseInt(str, 0, 64)
736 return val, err
737 }
738
739 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
740 if err == nil {
741 for _, val := range rawVals {
742 vals = append(vals, val.(int64))
743 }
744 }
745 return vals, err
746 }
747
748
749 func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) {
750 vals := make([]uint, 0, len(strs))
751 parser := func(str string) (interface{}, error) {
752 val, err := strconv.ParseUint(str, 0, 64)
753 return val, err
754 }
755
756 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
757 if err == nil {
758 for _, val := range rawVals {
759 vals = append(vals, uint(val.(uint64)))
760 }
761 }
762 return vals, err
763 }
764
765
766 func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) {
767 vals := make([]uint64, 0, len(strs))
768 parser := func(str string) (interface{}, error) {
769 val, err := strconv.ParseUint(str, 0, 64)
770 return val, err
771 }
772 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
773 if err == nil {
774 for _, val := range rawVals {
775 vals = append(vals, val.(uint64))
776 }
777 }
778 return vals, err
779 }
780
781 type Parser func(str string) (interface{}, error)
782
783
784 func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) {
785 vals := make([]time.Time, 0, len(strs))
786 parser := func(str string) (interface{}, error) {
787 val, err := time.Parse(format, str)
788 return val, err
789 }
790 rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser)
791 if err == nil {
792 for _, val := range rawVals {
793 vals = append(vals, val.(time.Time))
794 }
795 }
796 return vals, err
797 }
798
799
800 func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) {
801 vals := make([]interface{}, 0, len(strs))
802 for _, str := range strs {
803 val, err := parser(str)
804 if err != nil && returnOnInvalid {
805 return nil, err
806 }
807 if err == nil || addInvalid {
808 vals = append(vals, val)
809 }
810 }
811 return vals, nil
812 }
813
814
815 func (k *Key) SetValue(v string) {
816 if k.s.f.BlockMode {
817 k.s.f.lock.Lock()
818 defer k.s.f.lock.Unlock()
819 }
820
821 k.value = v
822 k.s.keysHash[k.name] = v
823 }
824
View as plain text