Added support for int and uint
diff --git a/properties.go b/properties.go index 7382520..1c59e70 100644 --- a/properties.go +++ b/properties.go
@@ -131,6 +131,29 @@ // ---------------------------------------------------------------------------- +// GetInt parses the expanded value as an int if the key exists. +// If key does not exist or the value cannot be parsed the default +// value is returned. +func (p *Properties) GetInt(key string, def int) int { + v, err := p.getInt64(key) + if err != nil { + return def + } + return intRangeCheck(key, v) +} + +// MustGetInt parses the expanded value as an int if the key exists. +// If key does not exist or the value cannot be parsed the function panics. +func (p *Properties) MustGetInt(key string) int { + v, err := p.getInt64(key) + if err != nil { + panic(err) + } + return intRangeCheck(key, v) +} + +// ---------------------------------------------------------------------------- + // GetInt64 parses the expanded value as an int64 if the key exists. // If key does not exist or the value cannot be parsed the default // value is returned. @@ -165,6 +188,29 @@ // ---------------------------------------------------------------------------- +// GetUint parses the expanded value as an uint if the key exists. +// If key does not exist or the value cannot be parsed the default +// value is returned. +func (p *Properties) GetUint(key string, def uint) uint { + v, err := p.getUint64(key) + if err != nil { + return def + } + return uintRangeCheck(key, v) +} + +// MustGetUint parses the expanded value as an int if the key exists. +// If key does not exist or the value cannot be parsed the function panics. +func (p *Properties) MustGetUint(key string) uint { + v, err := p.getUint64(key) + if err != nil { + panic(err) + } + return uintRangeCheck(key, v) +} + +// ---------------------------------------------------------------------------- + // GetUint64 parses the expanded value as an uint64 if the key exists. // If key does not exist or the value cannot be parsed the default // value is returned.
diff --git a/properties_test.go b/properties_test.go index 3d2a413..1dbbc1b 100644 --- a/properties_test.go +++ b/properties_test.go
@@ -8,6 +8,7 @@ "bytes" "flag" "fmt" + "math" "os" "strings" "testing" @@ -184,48 +185,48 @@ // ---------------------------------------------------------------------------- -type intTest struct { +type int64Test struct { input, key string def, value int64 } -var intTests = []*intTest{ +var int64Tests = []*int64Test{ // valid values - &intTest{"key = 1", "key", 999, 1}, - &intTest{"key = 0", "key", 999, 0}, - &intTest{"key = -1", "key", 999, -1}, - &intTest{"key = 0123", "key", 999, 123}, + &int64Test{"key = 1", "key", 999, 1}, + &int64Test{"key = 0", "key", 999, 0}, + &int64Test{"key = -1", "key", 999, -1}, + &int64Test{"key = 0123", "key", 999, 123}, // invalid values - &intTest{"key = 0xff", "key", 999, 999}, - &intTest{"key = 1.0", "key", 999, 999}, - &intTest{"key = a", "key", 999, 999}, + &int64Test{"key = 0xff", "key", 999, 999}, + &int64Test{"key = 1.0", "key", 999, 999}, + &int64Test{"key = a", "key", 999, 999}, // non existent key - &intTest{"key = 1", "key2", 999, 999}, + &int64Test{"key = 1", "key2", 999, 999}, } // ---------------------------------------------------------------------------- -type uintTest struct { +type uint64Test struct { input, key string def, value uint64 } -var uintTests = []*uintTest{ +var uint64Tests = []*uint64Test{ // valid values - &uintTest{"key = 1", "key", 999, 1}, - &uintTest{"key = 0", "key", 999, 0}, - &uintTest{"key = 0123", "key", 999, 123}, + &uint64Test{"key = 1", "key", 999, 1}, + &uint64Test{"key = 0", "key", 999, 0}, + &uint64Test{"key = 0123", "key", 999, 123}, // invalid values - &uintTest{"key = -1", "key", 999, 999}, - &uintTest{"key = 0xff", "key", 999, 999}, - &uintTest{"key = 1.0", "key", 999, 999}, - &uintTest{"key = a", "key", 999, 999}, + &uint64Test{"key = -1", "key", 999, 999}, + &uint64Test{"key = 0xff", "key", 999, 999}, + &uint64Test{"key = 1.0", "key", 999, 999}, + &uint64Test{"key = a", "key", 999, 999}, // non existent key - &uintTest{"key = 1", "key2", 999, 999}, + &uint64Test{"key = 1", "key2", 999, 999}, } // ---------------------------------------------------------------------------- @@ -309,8 +310,26 @@ c.Assert(func() { p.MustGetFloat64("invalid") }, PanicMatches, "invalid key: invalid") } +func (l *TestSuite) TestGetInt(c *C) { + for _, test := range int64Tests { + p, err := parse(test.input) + c.Assert(err, IsNil) + c.Assert(p.Len(), Equals, 1) + c.Assert(p.GetInt(test.key, int(test.def)), Equals, int(test.value)) + } +} + +func (l *TestSuite) TestMustGetInt(c *C) { + input := "key = 123\nkey2 = ghi" + p, err := parse(input) + c.Assert(err, IsNil) + c.Assert(p.MustGetInt("key"), Equals, int(123)) + c.Assert(func() { p.MustGetInt("key2") }, PanicMatches, "strconv.ParseInt: parsing.*") + c.Assert(func() { p.MustGetInt("invalid") }, PanicMatches, "invalid key: invalid") +} + func (l *TestSuite) TestGetInt64(c *C) { - for _, test := range intTests { + for _, test := range int64Tests { p, err := parse(test.input) c.Assert(err, IsNil) c.Assert(p.Len(), Equals, 1) @@ -327,8 +346,26 @@ c.Assert(func() { p.MustGetInt64("invalid") }, PanicMatches, "invalid key: invalid") } +func (l *TestSuite) TestGetUint(c *C) { + for _, test := range uint64Tests { + p, err := parse(test.input) + c.Assert(err, IsNil) + c.Assert(p.Len(), Equals, 1) + c.Assert(p.GetUint(test.key, uint(test.def)), Equals, uint(test.value)) + } +} + +func (l *TestSuite) TestMustGetUint(c *C) { + input := "key = 123\nkey2 = ghi" + p, err := parse(input) + c.Assert(err, IsNil) + c.Assert(p.MustGetUint("key"), Equals, uint(123)) + c.Assert(func() { p.MustGetUint64("key2") }, PanicMatches, "strconv.ParseUint: parsing.*") + c.Assert(func() { p.MustGetUint64("invalid") }, PanicMatches, "invalid key: invalid") +} + func (l *TestSuite) TestGetUint64(c *C) { - for _, test := range uintTests { + for _, test := range uint64Tests { p, err := parse(test.input) c.Assert(err, IsNil) c.Assert(p.Len(), Equals, 1) @@ -386,6 +423,28 @@ testKeyValuePrePostfix(c, "*[", "]*", "key=value\nkey2=*[key]*", "key", "value", "key2", "value") } +func (l *TestSuite) TestPanicOn32BitIntOverflow(c *C) { + is32Bit = true + var min, max int64 = math.MinInt32-1, math.MaxInt32+1 + input := fmt.Sprintf("min=%d\nmax=%d", min, max) + p, err := parse(input) + c.Assert(err, IsNil) + c.Assert(p.MustGetInt64("min"), Equals, min) + c.Assert(p.MustGetInt64("max"), Equals, max) + c.Assert(func() { p.MustGetInt("min") }, PanicMatches, ".* out of range") + c.Assert(func() { p.MustGetInt("max") }, PanicMatches, ".* out of range") +} + +func (l *TestSuite) TestPanicOn32BitUintOverflow(c *C) { + is32Bit = true + var max uint64 = math.MaxUint32+1 + input := fmt.Sprintf("max=%d", max) + p, err := parse(input) + c.Assert(err, IsNil) + c.Assert(p.MustGetUint64("max"), Equals, max) + c.Assert(func() { p.MustGetUint("max") }, PanicMatches, ".* out of range") +} + // ---------------------------------------------------------------------------- // tests all combinations of delimiters, leading and/or trailing whitespace and newlines.
diff --git a/rangecheck.go b/rangecheck.go new file mode 100644 index 0000000..21cf6f6 --- /dev/null +++ b/rangecheck.go
@@ -0,0 +1,31 @@ +// Copyright 2013 Frank Schroeder. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package properties + +import ( + "fmt" + "math" +) + +// make this a var to overwrite it in a test +var is32Bit = ^uint(0) == math.MaxUint32 + +// intRangeCheck checks if the value fits into the int type and +// panics if it does not. +func intRangeCheck(key string, v int64) int { + if is32Bit && (v < math.MinInt32 || v > math.MaxInt32) { + panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) + } + return int(v) +} + +// uintRangeCheck checks if the value fits into the uint type and +// panics if it does not. +func uintRangeCheck(key string, v uint64) uint { + if is32Bit && v > math.MaxUint32 { + panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) + } + return uint(v) +}