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