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)
+}