mirror of https://github.com/goccy/go-json.git
Merge 96b9d74fc6
into 3e9769d637
This commit is contained in:
commit
b18db1095d
|
@ -208,10 +208,18 @@ func Test_Decoder(t *testing.T) {
|
|||
t.Run("interface", func(t *testing.T) {
|
||||
t.Run("number", func(t *testing.T) {
|
||||
var v interface{}
|
||||
assertErr(t, json.Unmarshal([]byte(`10`), &v))
|
||||
assertErr(t, json.Unmarshal([]byte(`10.0`), &v))
|
||||
assertEq(t, "interface.kind", "float64", reflect.TypeOf(v).Kind().String())
|
||||
assertEq(t, "interface", `10`, fmt.Sprint(v))
|
||||
})
|
||||
t.Run("int64", func(t *testing.T) {
|
||||
type StructValueLayout struct {
|
||||
Values []interface{} `json:"values"`
|
||||
}
|
||||
var structLayout StructValueLayout
|
||||
assertErr(t, json.Unmarshal([]byte(`{"values":[2074546971352916989, "test"]}`), &structLayout))
|
||||
assertEq(t, "int64", int64(2074546971352916989), structLayout.Values[0].(int64))
|
||||
})
|
||||
t.Run("string", func(t *testing.T) {
|
||||
var v interface{}
|
||||
assertErr(t, json.Unmarshal([]byte(`"hello"`), &v))
|
||||
|
|
|
@ -18,12 +18,20 @@ type intDecoder struct {
|
|||
}
|
||||
|
||||
func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder {
|
||||
return &intDecoder{
|
||||
typ: typ,
|
||||
kind: typ.Kind(),
|
||||
op: op,
|
||||
structName: structName,
|
||||
fieldName: fieldName,
|
||||
if typ != nil {
|
||||
return &intDecoder{
|
||||
typ: typ,
|
||||
kind: typ.Kind(),
|
||||
op: op,
|
||||
structName: structName,
|
||||
fieldName: fieldName,
|
||||
}
|
||||
} else {
|
||||
return &intDecoder{
|
||||
op: op,
|
||||
structName: structName,
|
||||
fieldName: fieldName,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,18 +198,20 @@ func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
|||
if err != nil {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
switch d.kind {
|
||||
case reflect.Int8:
|
||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
case reflect.Int16:
|
||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
case reflect.Int32:
|
||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
if d.typ != nil {
|
||||
switch d.kind {
|
||||
case reflect.Int8:
|
||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
case reflect.Int16:
|
||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
case reflect.Int32:
|
||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
||||
return d.typeError(bytes, s.totalOffset())
|
||||
}
|
||||
}
|
||||
}
|
||||
d.op(p, i64)
|
||||
|
@ -223,18 +233,20 @@ func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.P
|
|||
if err != nil {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
switch d.kind {
|
||||
case reflect.Int8:
|
||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
case reflect.Int16:
|
||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
case reflect.Int32:
|
||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
if d.typ != nil {
|
||||
switch d.kind {
|
||||
case reflect.Int8:
|
||||
if i64 < -1*(1<<7) || (1<<7) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
case reflect.Int16:
|
||||
if i64 < -1*(1<<15) || (1<<15) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
case reflect.Int32:
|
||||
if i64 < -1*(1<<31) || (1<<31) <= i64 {
|
||||
return 0, d.typeError(bytes, cursor)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.op(p, i64)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goccy/go-json/internal/errors"
|
||||
|
@ -18,6 +19,7 @@ type interfaceDecoder struct {
|
|||
sliceDecoder *sliceDecoder
|
||||
mapDecoder *mapDecoder
|
||||
floatDecoder *floatDecoder
|
||||
intDecoder *intDecoder
|
||||
numberDecoder *numberDecoder
|
||||
stringDecoder *stringDecoder
|
||||
}
|
||||
|
@ -30,6 +32,9 @@ func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
|
|||
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
intDecoder: newIntDecoder(nil, structName, fieldName, func(p unsafe.Pointer, v int64) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
|
@ -78,6 +83,9 @@ func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *inter
|
|||
floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
intDecoder: newIntDecoder(nil, structName, fieldName, func(p unsafe.Pointer, v int64) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
|
||||
*(*interface{})(p) = v
|
||||
}),
|
||||
|
@ -423,7 +431,13 @@ func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, dep
|
|||
**(**interface{})(unsafe.Pointer(&p)) = v
|
||||
return cursor, nil
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
return d.floatDecoder.Decode(ctx, cursor, depth, p)
|
||||
bytes, _, _ := d.numberDecoder.decodeByte(ctx.Buf, cursor)
|
||||
numberStr := *(*string)(unsafe.Pointer(&bytes))
|
||||
if strings.Contains(numberStr, ".") {
|
||||
return d.floatDecoder.Decode(ctx, cursor, depth, p)
|
||||
} else {
|
||||
return d.intDecoder.Decode(ctx, cursor, depth, p)
|
||||
}
|
||||
case '"':
|
||||
var v string
|
||||
ptr := unsafe.Pointer(&v)
|
||||
|
|
Loading…
Reference in New Issue