1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-27 08:30:57 +02:00

change slice encoder to use reflect2

This commit is contained in:
Tao Wen 2018-02-18 23:27:34 +08:00
parent 5a696808d6
commit cbc1786a76

View File

@ -5,6 +5,7 @@ import (
"io" "io"
"reflect" "reflect"
"unsafe" "unsafe"
"github.com/v2pro/plz/reflect2"
) )
func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder { func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
@ -14,32 +15,31 @@ func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecod
func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder { func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem()) encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem())
return &sliceEncoder{typ, typ.Elem(), encoder} sliceType := reflect2.Type2(typ).(*reflect2.UnsafeSliceType)
return &sliceEncoder{sliceType, encoder}
} }
type sliceEncoder struct { type sliceEncoder struct {
sliceType reflect.Type sliceType *reflect2.UnsafeSliceType
elemType reflect.Type
elemEncoder ValEncoder elemEncoder ValEncoder
} }
func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
slice := (*sliceHeader)(ptr) if encoder.sliceType.UnsafeIsNil(ptr) {
if slice.Data == nil {
stream.WriteNil() stream.WriteNil()
return return
} }
if slice.Len == 0 { length := encoder.sliceType.UnsafeLengthOf(ptr)
if length == 0 {
stream.WriteEmptyArray() stream.WriteEmptyArray()
return return
} }
stream.WriteArrayStart() stream.WriteArrayStart()
elemPtr := unsafe.Pointer(slice.Data) encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGet(ptr, 0), stream)
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) for i := 1; i < length; i++ {
for i := 1; i < slice.Len; i++ {
stream.WriteMore() stream.WriteMore()
elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size()) elemPtr := encoder.sliceType.UnsafeGet(ptr, i)
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream) encoder.elemEncoder.Encode(elemPtr, stream)
} }
stream.WriteArrayEnd() stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF { if stream.Error != nil && stream.Error != io.EOF {