mirror of
https://github.com/json-iterator/go.git
synced 2025-01-23 18:54:21 +02:00
support int
This commit is contained in:
parent
7bb029bca5
commit
38e256e526
12
jsoniter.go
12
jsoniter.go
@ -132,6 +132,16 @@ func (iter *Iterator) ReadUint64() (ret uint64) {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (iter *Iterator) ReadInt() (ret int) {
|
||||
val := iter.ReadInt64()
|
||||
converted := int(val)
|
||||
if int64(converted) != val {
|
||||
iter.ReportError("ReadInt", "int overflow")
|
||||
return
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func (iter *Iterator) ReadInt64() (ret int64) {
|
||||
c := iter.readByte()
|
||||
if iter.Error != nil {
|
||||
@ -163,7 +173,7 @@ func (iter *Iterator) ReadString() (ret string) {
|
||||
}
|
||||
return ""
|
||||
case '"':
|
||||
// nothing
|
||||
// nothing
|
||||
default:
|
||||
iter.ReportError("ReadString", `expects " or n`)
|
||||
return
|
||||
|
@ -19,6 +19,13 @@ func (decoder *stringDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
*((*string)(ptr)) = iter.ReadString()
|
||||
}
|
||||
|
||||
type intDecoder struct {
|
||||
}
|
||||
|
||||
func (decoder *intDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||
*((*int)(ptr)) = iter.ReadInt()
|
||||
}
|
||||
|
||||
type optionalDecoder struct {
|
||||
valueType reflect.Type
|
||||
valueDecoder Decoder
|
||||
@ -115,7 +122,6 @@ func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Typ
|
||||
slice.Data = dst
|
||||
}
|
||||
|
||||
var DECODER_STRING *stringDecoder
|
||||
var DECODERS unsafe.Pointer
|
||||
|
||||
func addDecoderToCache(cacheKey string, decoder Decoder) {
|
||||
@ -139,7 +145,6 @@ func getDecoderFromCache(cacheKey string) Decoder {
|
||||
}
|
||||
|
||||
func init() {
|
||||
DECODER_STRING = &stringDecoder{}
|
||||
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
|
||||
}
|
||||
|
||||
@ -187,25 +192,26 @@ func decoderOfType(type_ reflect.Type) (Decoder, error) {
|
||||
func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
|
||||
switch type_.Kind() {
|
||||
case reflect.String:
|
||||
return DECODER_STRING, nil
|
||||
return &stringDecoder{}, nil
|
||||
case reflect.Int:
|
||||
return &intDecoder{}, nil
|
||||
case reflect.Struct:
|
||||
return decoderOfStruct(type_)
|
||||
case reflect.Slice:
|
||||
return decoderOfSlice(type_)
|
||||
return prefix("[slice]").addTo(decoderOfSlice(type_))
|
||||
case reflect.Ptr:
|
||||
return prefix("optional").addTo(decoderOfOptional(type_.Elem()))
|
||||
return prefix("[optional]").addTo(decoderOfOptional(type_.Elem()))
|
||||
default:
|
||||
return nil, errors.New("expect string, struct, slice")
|
||||
return nil, fmt.Errorf("unsupported type: %v", type_)
|
||||
}
|
||||
}
|
||||
|
||||
func decoderOfOptional(type_ reflect.Type) (Decoder, error) {
|
||||
switch type_.Kind() {
|
||||
case reflect.String:
|
||||
return &optionalDecoder{type_, DECODER_STRING}, nil
|
||||
default:
|
||||
return nil, errors.New("expect string")
|
||||
decoder, err := decoderOfPtr(type_)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &optionalDecoder{type_, decoder}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -225,7 +231,7 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
|
||||
func decoderOfSlice(type_ reflect.Type) (Decoder, error) {
|
||||
decoder, err := decoderOfPtr(type_.Elem())
|
||||
if err != nil {
|
||||
return prefix("[elem]").addTo(decoder, err)
|
||||
return nil, err
|
||||
}
|
||||
return &sliceDecoder{type_, type_.Elem(), decoder}, nil
|
||||
}
|
||||
|
@ -25,6 +25,15 @@ func Test_reflect_ptr_str(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_reflect_int(t *testing.T) {
|
||||
iter := ParseString(`123`)
|
||||
val := int(0)
|
||||
iter.Read(&val)
|
||||
if val != 123 {
|
||||
t.Fatal(val)
|
||||
}
|
||||
}
|
||||
|
||||
type StructOfString struct {
|
||||
field1 string
|
||||
field2 string
|
||||
@ -65,19 +74,41 @@ func Test_reflect_struct_string_ptr(t *testing.T) {
|
||||
|
||||
func Test_reflect_slice(t *testing.T) {
|
||||
iter := ParseString(`["hello", "world"]`)
|
||||
array := make([]string, 0, 1)
|
||||
iter.Read(&array)
|
||||
if len(array) != 2 {
|
||||
slice := make([]string, 0, 1)
|
||||
iter.Read(&slice)
|
||||
if len(slice) != 2 {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(len(array))
|
||||
t.Fatal(len(slice))
|
||||
}
|
||||
if array[0] != "hello" {
|
||||
if slice[0] != "hello" {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(array[0])
|
||||
t.Fatal(slice[0])
|
||||
}
|
||||
if array[1] != "world" {
|
||||
if slice[1] != "world" {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(array[1])
|
||||
t.Fatal(slice[1])
|
||||
}
|
||||
}
|
||||
|
||||
func Test_reflect_nested(t *testing.T) {
|
||||
iter := ParseString(`[{"field1": "hello"}, null, {"field2": "world"}]`)
|
||||
slice := []*StructOfString{}
|
||||
iter.Read(&slice)
|
||||
if len(slice) != 3 {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(len(slice))
|
||||
}
|
||||
if slice[0].field1 != "hello" {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(slice[0])
|
||||
}
|
||||
if slice[1] != nil {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(slice[1])
|
||||
}
|
||||
if slice[2].field2 != "world" {
|
||||
fmt.Println(iter.Error)
|
||||
t.Fatal(slice[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user