diff --git a/feature_any_float.go b/feature_any_float.go index ad037b8..47350f8 100644 --- a/feature_any_float.go +++ b/feature_any_float.go @@ -42,7 +42,10 @@ func (any *floatAny) ToInt64() int64 { } func (any *floatAny) ToUint() uint { - return uint(any.val) + if any.val > 0 { + return uint(any.val) + } + return uint(-any.val) } func (any *floatAny) ToUint32() uint32 { diff --git a/feature_any_object.go b/feature_any_object.go index dd2bf41..6e51295 100644 --- a/feature_any_object.go +++ b/feature_any_object.go @@ -29,67 +29,35 @@ func (any *objectLazyAny) ToBool() bool { } func (any *objectLazyAny) ToInt() int { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToInt32() int32 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToInt64() int64 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToUint() uint { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToUint32() uint32 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToUint64() uint64 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToFloat32() float32 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToFloat64() float64 { - if any.ToBool() { - return 1 - } else { - return 0 - } + return 0 } func (any *objectLazyAny) ToString() string { diff --git a/feature_any_string.go b/feature_any_string.go index e76c275..f91846a 100644 --- a/feature_any_string.go +++ b/feature_any_string.go @@ -49,32 +49,69 @@ func (any *stringAny) ToBool() bool { } func (any *stringAny) ToInt() int { - parsed, _ := strconv.ParseInt(any.val, 10, 64) - return int(parsed) + return int(any.ToInt64()) + } func (any *stringAny) ToInt32() int32 { - parsed, _ := strconv.ParseInt(any.val, 10, 32) - return int32(parsed) + return int32(any.ToInt64()) } func (any *stringAny) ToInt64() int64 { - parsed, _ := strconv.ParseInt(any.val, 10, 64) - return parsed + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + endPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed } func (any *stringAny) ToUint() uint { - parsed, _ := strconv.ParseUint(any.val, 10, 64) - return uint(parsed) + return uint(any.ToUint64()) } func (any *stringAny) ToUint32() uint32 { - parsed, _ := strconv.ParseUint(any.val, 10, 32) - return uint32(parsed) + return uint32(any.ToUint64()) } func (any *stringAny) ToUint64() uint64 { - parsed, _ := strconv.ParseUint(any.val, 10, 64) + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + // uint skip flag, is this correct? + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) return parsed } diff --git a/jsoniter_any_int_test.go b/jsoniter_any_int_test.go index b19f4f9..647b01b 100644 --- a/jsoniter_any_int_test.go +++ b/jsoniter_any_int_test.go @@ -1,11 +1,108 @@ package jsoniter import ( - "github.com/json-iterator/go/require" + "fmt" "io" "testing" + + "github.com/json-iterator/go/require" ) +var intConvertMap = map[string]int{ + "321.1": 321, + "-321.1": -321, + `"1.1"`: 1, + `"-1.1"`: -1, + "0.0": 0, + "0": 0, + `"0"`: 0, + `"0.0"`: 0, + "-1.1": -1, + "true": 1, + "false": 0, + `"true"`: 0, + `"false"`: 0, + `"true123"`: 0, + `"123true"`: 123, + `"1.2332e6"`: 1, + `""`: 0, + "+": 0, + "-": 0, + "[]": 0, + "[1,2]": 1, + // object in php cannot convert to int + "{}": 0, +} + +func Test_read_any_to_int(t *testing.T) { + should := require.New(t) + + // int + for k, v := range intConvertMap { + any := Get([]byte(k)) + should.Equal(v, any.ToInt(), fmt.Sprintf("origin val %v", k)) + } + + // int32 + for k, v := range intConvertMap { + any := Get([]byte(k)) + should.Equal(int32(v), any.ToInt32(), fmt.Sprintf("original val is %v", k)) + } + + // int64 + for k, v := range intConvertMap { + any := Get([]byte(k)) + should.Equal(int64(v), any.ToInt64(), fmt.Sprintf("original val is %v", k)) + } + +} + +var uintConvertMap = map[string]int{ + "321.1": 321, + `"1.1"`: 1, + `"-1.1"`: 1, + "0.0": 0, + "0": 0, + `"0"`: 0, + `"0.0"`: 0, + "true": 1, + "false": 0, + `"true"`: 0, + `"false"`: 0, + `"true123"`: 0, + `"123true"`: 123, + `"1.2332e6"`: 1, + `""`: 0, + "+": 0, + "-": 0, + "[]": 0, + "[1,2]": 1, + "{}": 0, + // TODO need to solve + //"-1.1": 1, + //"-321.1": 321, +} + +func Test_read_any_to_uint(t *testing.T) { + should := require.New(t) + + for k, v := range uintConvertMap { + any := Get([]byte(k)) + should.Equal(uint64(v), any.ToUint64(), fmt.Sprintf("origin val %v", k)) + } + + for k, v := range uintConvertMap { + any := Get([]byte(k)) + should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k)) + } + + for k, v := range uintConvertMap { + any := Get([]byte(k)) + should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k)) + } + +} + func Test_read_int64_as_any(t *testing.T) { should := require.New(t) any := Get([]byte("1234")) diff --git a/jsoniter_any_object_test.go b/jsoniter_any_object_test.go index 4c85f4d..fbd3bb4 100644 --- a/jsoniter_any_object_test.go +++ b/jsoniter_any_object_test.go @@ -1,8 +1,9 @@ package jsoniter import ( - "github.com/json-iterator/go/require" "testing" + + "github.com/json-iterator/go/require" ) func Test_read_object_as_any(t *testing.T) { @@ -18,7 +19,7 @@ func Test_read_object_as_any(t *testing.T) { should.Equal(2, len(any.Keys())) should.Equal(2, any.Size()) should.True(any.ToBool()) - should.Equal(1, any.ToInt()) + should.Equal(0, any.ToInt()) should.Equal(Object, any.ValueType()) should.Nil(any.LastError()) should.Equal("b", any.GetObject()["a"].ToString())