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:
parent
5a696808d6
commit
cbc1786a76
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user