mirror of https://github.com/tidwall/gjson.git
parent
35fa0d71c8
commit
0cbc0f402f
104
gjson.go
104
gjson.go
|
@ -1103,6 +1103,7 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
|||
}
|
||||
hit = pmatch && !rp.more
|
||||
for ; i < len(c.json); i++ {
|
||||
var num bool
|
||||
switch c.json[i] {
|
||||
default:
|
||||
continue
|
||||
|
@ -1150,15 +1151,13 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
|||
return i, true
|
||||
}
|
||||
}
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
i, val = parseNumber(c.json, i)
|
||||
if hit {
|
||||
c.value.Raw = val
|
||||
c.value.Type = Number
|
||||
c.value.Num, _ = strconv.ParseFloat(val, 64)
|
||||
return i, true
|
||||
case 'n':
|
||||
if i+1 < len(c.json) && c.json[i+1] != 'u' {
|
||||
num = true
|
||||
break
|
||||
}
|
||||
case 't', 'f', 'n':
|
||||
fallthrough
|
||||
case 't', 'f':
|
||||
vc := c.json[i]
|
||||
i, val = parseLiteral(c.json, i)
|
||||
if hit {
|
||||
|
@ -1171,6 +1170,18 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
|||
}
|
||||
return i, true
|
||||
}
|
||||
case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'i', 'I', 'N':
|
||||
num = true
|
||||
}
|
||||
if num {
|
||||
i, val = parseNumber(c.json, i)
|
||||
if hit {
|
||||
c.value.Raw = val
|
||||
c.value.Type = Number
|
||||
c.value.Num, _ = strconv.ParseFloat(val, 64)
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -1358,6 +1369,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
|
|||
} else {
|
||||
ch = c.json[i]
|
||||
}
|
||||
var num bool
|
||||
switch ch {
|
||||
default:
|
||||
continue
|
||||
|
@ -1440,26 +1452,13 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
|
|||
return i, true
|
||||
}
|
||||
}
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
i, val = parseNumber(c.json, i)
|
||||
if rp.query.on {
|
||||
var qval Result
|
||||
qval.Raw = val
|
||||
qval.Type = Number
|
||||
qval.Num, _ = strconv.ParseFloat(val, 64)
|
||||
if procQuery(qval) {
|
||||
return i, true
|
||||
}
|
||||
} else if hit {
|
||||
if rp.alogok {
|
||||
break
|
||||
}
|
||||
c.value.Raw = val
|
||||
c.value.Type = Number
|
||||
c.value.Num, _ = strconv.ParseFloat(val, 64)
|
||||
return i, true
|
||||
case 'n':
|
||||
if i+1 < len(c.json) && c.json[i+1] != 'u' {
|
||||
num = true
|
||||
break
|
||||
}
|
||||
case 't', 'f', 'n':
|
||||
fallthrough
|
||||
case 't', 'f':
|
||||
vc := c.json[i]
|
||||
i, val = parseLiteral(c.json, i)
|
||||
if rp.query.on {
|
||||
|
@ -1487,6 +1486,9 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
|
|||
}
|
||||
return i, true
|
||||
}
|
||||
case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'i', 'I', 'N':
|
||||
num = true
|
||||
case ']':
|
||||
if rp.arrch && rp.part == "#" {
|
||||
if rp.alogok {
|
||||
|
@ -1562,6 +1564,26 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
|
|||
}
|
||||
return i + 1, false
|
||||
}
|
||||
if num {
|
||||
i, val = parseNumber(c.json, i)
|
||||
if rp.query.on {
|
||||
var qval Result
|
||||
qval.Raw = val
|
||||
qval.Type = Number
|
||||
qval.Num, _ = strconv.ParseFloat(val, 64)
|
||||
if procQuery(qval) {
|
||||
return i, true
|
||||
}
|
||||
} else if hit {
|
||||
if rp.alogok {
|
||||
break
|
||||
}
|
||||
c.value.Raw = val
|
||||
c.value.Type = Number
|
||||
c.value.Num, _ = strconv.ParseFloat(val, 64)
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -2081,6 +2103,7 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) {
|
|||
if json[i] <= ' ' {
|
||||
continue
|
||||
}
|
||||
var num bool
|
||||
switch json[i] {
|
||||
case '"':
|
||||
i++
|
||||
|
@ -2100,15 +2123,13 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) {
|
|||
}
|
||||
}
|
||||
return i, res, true
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
i, val = parseNumber(json, i)
|
||||
if hit {
|
||||
res.Raw = val
|
||||
res.Type = Number
|
||||
res.Num, _ = strconv.ParseFloat(val, 64)
|
||||
case 'n':
|
||||
if i+1 < len(json) && json[i+1] != 'u' {
|
||||
num = true
|
||||
break
|
||||
}
|
||||
return i, res, true
|
||||
case 't', 'f', 'n':
|
||||
fallthrough
|
||||
case 't', 'f':
|
||||
vc := json[i]
|
||||
i, val = parseLiteral(json, i)
|
||||
if hit {
|
||||
|
@ -2121,7 +2142,20 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) {
|
|||
}
|
||||
return i, res, true
|
||||
}
|
||||
case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'i', 'I', 'N':
|
||||
num = true
|
||||
}
|
||||
if num {
|
||||
i, val = parseNumber(json, i)
|
||||
if hit {
|
||||
res.Raw = val
|
||||
res.Type = Number
|
||||
res.Num, _ = strconv.ParseFloat(val, 64)
|
||||
}
|
||||
return i, res, true
|
||||
}
|
||||
|
||||
}
|
||||
return i, res, false
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -2235,3 +2236,32 @@ func TestKeysValuesModifier(t *testing.T) {
|
|||
assert(t, Get(`[]`, `@values`).String() == `[]`)
|
||||
assert(t, Get(`[1,2,3]`, `@values`).String() == `[1,2,3]`)
|
||||
}
|
||||
|
||||
func TestNaNInf(t *testing.T) {
|
||||
json := `[+Inf,-Inf,Inf,iNF,-iNF,+iNF,NaN,nan,nAn,-0,+0]`
|
||||
raws := []string{"+Inf", "-Inf", "Inf", "iNF", "-iNF", "+iNF", "NaN", "nan",
|
||||
"nAn", "-0", "+0"}
|
||||
nums := []float64{math.Inf(+1), math.Inf(-1), math.Inf(0), math.Inf(0),
|
||||
math.Inf(-1), math.Inf(+1), math.NaN(), math.NaN(), math.NaN(),
|
||||
math.Copysign(0, -1), 0}
|
||||
|
||||
// assert(t, int(Get(json, `#`).Int()) == len(raws))
|
||||
for i := 0; i < len(raws); i++ {
|
||||
r := Get(json, fmt.Sprintf("%d", i))
|
||||
// fmt.Printf("%s %s\n", r.Raw, raws[i])
|
||||
assert(t, r.Raw == raws[i])
|
||||
// fmt.Printf("%f %f\n", r.Num, nums[i])
|
||||
assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i])))
|
||||
}
|
||||
// println("------------")
|
||||
var i int
|
||||
Parse(json).ForEach(func(_, r Result) bool {
|
||||
// fmt.Printf("%s %s\n", r.Raw, raws[i])
|
||||
assert(t, r.Raw == raws[i])
|
||||
// fmt.Printf("%f %f\n", r.Num, nums[i])
|
||||
assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i])))
|
||||
i++
|
||||
return true
|
||||
})
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue