1
0
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:
Tao Wen 2016-12-04 21:19:54 +08:00
parent 7bb029bca5
commit 38e256e526
3 changed files with 68 additions and 21 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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])
}
}