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