Xargin пре 8 година
родитељ
комит
f245011c7d
3 измењених фајлова са 87 додато и 5 уклоњено
  1. 42 4
      feature_any_string.go
  2. 42 1
      jsoniter_any_float_test.go
  3. 3 0
      jsoniter_any_int_test.go

+ 42 - 4
feature_any_string.go

@@ -119,13 +119,51 @@ func (any *stringAny) ToUint64() uint64 {
 }
 
 func (any *stringAny) ToFloat32() float32 {
-	parsed, _ := strconv.ParseFloat(any.val, 32)
-	return float32(parsed)
+	return float32(any.ToFloat64())
 }
 
 func (any *stringAny) ToFloat64() float64 {
-	parsed, _ := strconv.ParseFloat(any.val, 64)
-	return parsed
+	if any.val == "" {
+		return 0
+	}
+
+	startPos := 0
+	endPos := 0
+	flag := 1
+
+	if any.val[0] == '+' || any.val[0] == '-' {
+		startPos = 1
+	}
+
+	if any.val[0] == '-' {
+		flag = -1
+	}
+
+	pointOccurCnt := 0
+	pointPos := -1
+
+	for i := startPos; i < len(any.val); i++ {
+		if any.val[i] >= '0' && any.val[i] <= '9' {
+			endPos = i + 1
+		} else if any.val[i] == '.' && pointOccurCnt == 0 {
+			endPos = i + 1
+			pointOccurCnt++
+			pointPos = i
+		} else {
+			break
+		}
+	}
+
+	if pointPos == endPos-1 {
+		endPos--
+	}
+
+	if endPos <= startPos {
+		return 0
+	}
+
+	parsed, _ := strconv.ParseFloat(any.val[startPos:endPos], 64)
+	return float64(flag) * parsed
 }
 
 func (any *stringAny) ToString() string {

+ 42 - 1
jsoniter_any_float_test.go

@@ -1,10 +1,51 @@
 package jsoniter
 
 import (
-	"github.com/json-iterator/go/require"
 	"testing"
+
+	"github.com/json-iterator/go/require"
 )
 
+var floatConvertMap = map[string]float64{
+	"null":  0,
+	"true":  1,
+	"false": 0,
+
+	`"true"`:  0,
+	`"false"`: 0,
+
+	"123":       123,
+	`"123true"`: 123,
+
+	`"-123true"`: -123,
+	"0":          0,
+	`"0"`:        0,
+	"-1":         -1,
+
+	"1.1":       1.1,
+	"0.0":       0,
+	"-1.1":      -1.1,
+	`"+1.1"`:    1.1,
+	`""`:        0,
+	"[1,2]":     1,
+	"[]":        0,
+	"{}":        0,
+	`{"abc":1}`: 0,
+}
+
+func Test_read_any_to_float(t *testing.T) {
+	should := require.New(t)
+	for k, v := range floatConvertMap {
+		any := Get([]byte(k))
+		should.Equal(float64(v), any.ToFloat64(), "the original val is "+k)
+	}
+
+	for k, v := range floatConvertMap {
+		any := Get([]byte(k))
+		should.Equal(float32(v), any.ToFloat32(), "the original val is "+k)
+	}
+}
+
 func Test_read_float_as_any(t *testing.T) {
 	should := require.New(t)
 	any := Get([]byte("12.3"))

+ 3 - 0
jsoniter_any_int_test.go

@@ -25,12 +25,14 @@ var intConvertMap = map[string]int{
 	`"false"`:    0,
 	`"true123"`:  0,
 	`"123true"`:  123,
+	`"-123true"`: -123,
 	`"1.2332e6"`: 1,
 	`""`:         0,
 	"+":          0,
 	"-":          0,
 	"[]":         0,
 	"[1,2]":      1,
+	`["1","2"]`:  1,
 	// object in php cannot convert to int
 	"{}": 0,
 }
@@ -73,6 +75,7 @@ var uintConvertMap = map[string]int{
 	`"true"`:     0,
 	`"false"`:    0,
 	`"true123"`:  0,
+	`"+1"`:       1,
 	`"123true"`:  123,
 	`"-123true"`: 0,
 	`"1.2332e6"`: 1,