1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-01 21:24:21 +02:00

#66 extract out feacture_reflect_extension

This commit is contained in:
Tao Wen 2017-06-20 08:42:25 +08:00
parent 14588726a1
commit c36a7ed7cd

View File

@ -48,12 +48,6 @@ func writeToStream(val interface{}, stream *Stream, encoder ValEncoder) {
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
type EncoderFunc func(ptr unsafe.Pointer, stream *Stream)
type ExtensionFunc func(typ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc)
type funcDecoder struct {
fun DecoderFunc
}
func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.fun(ptr, iter)
}
@ -78,11 +72,6 @@ func (encoder *funcEncoder) isEmpty(ptr unsafe.Pointer) bool {
return encoder.isEmptyFunc(ptr)
}
var typeDecoders map[string]ValDecoder
var fieldDecoders map[string]ValDecoder
var typeEncoders map[string]ValEncoder
var fieldEncoders map[string]ValEncoder
var extensions []ExtensionFunc
var jsonNumberType reflect.Type
var jsonRawMessageType reflect.Type
var jsoniterRawMessageType reflect.Type
@ -92,11 +81,6 @@ var unmarshalerType reflect.Type
var textUnmarshalerType reflect.Type
func init() {
typeDecoders = map[string]ValDecoder{}
fieldDecoders = map[string]ValDecoder{}
typeEncoders = map[string]ValEncoder{}
fieldEncoders = map[string]ValEncoder{}
extensions = []ExtensionFunc{}
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
@ -106,42 +90,6 @@ func init() {
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
}
func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
typeDecoders[typ] = &funcDecoder{fun}
}
func RegisterTypeDecoder(typ string, decoder ValDecoder) {
typeDecoders[typ] = decoder
}
func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) {
RegisterFieldDecoder(typ, field, &funcDecoder{fun})
}
func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) {
fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder
}
func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc}
}
func RegisterTypeEncoder(typ string, encoder ValEncoder) {
typeEncoders[typ] = encoder
}
func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) {
RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc})
}
func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
}
func RegisterExtension(extension ExtensionFunc) {
extensions = append(extensions, extension)
}
type optionalDecoder struct {
valueType reflect.Type
valueDecoder ValDecoder
@ -260,18 +208,13 @@ type nonEmptyInterface struct {
func (iter *Iterator) ReadVal(obj interface{}) {
typ := reflect.TypeOf(obj)
cacheKey := typ.Elem()
cachedDecoder := iter.cfg.getDecoderFromCache(cacheKey)
if cachedDecoder == nil {
decoder, err := decoderOfType(iter.cfg, cacheKey)
if err != nil {
iter.Error = err
return
}
cachedDecoder = decoder
iter.cfg.addDecoderToCache(cacheKey, decoder)
decoder, err := decoderOfType(iter.cfg, cacheKey)
if err != nil {
iter.Error = err
return
}
e := (*emptyInterface)(unsafe.Pointer(&obj))
cachedDecoder.decode(e.word, iter)
decoder.decode(e.word, iter)
}
func (stream *Stream) WriteVal(val interface{}) {
@ -281,17 +224,12 @@ func (stream *Stream) WriteVal(val interface{}) {
}
typ := reflect.TypeOf(val)
cacheKey := typ
cachedEncoder := stream.cfg.getEncoderFromCache(cacheKey)
if cachedEncoder == nil {
encoder, err := encoderOfType(stream.cfg, cacheKey)
if err != nil {
stream.Error = err
return
}
cachedEncoder = encoder
stream.cfg.addEncoderToCache(cacheKey, encoder)
encoder, err := encoderOfType(stream.cfg, cacheKey)
if err != nil {
stream.Error = err
return
}
cachedEncoder.encodeInterface(val, stream)
encoder.encodeInterface(val, stream)
}
type prefix string
@ -311,27 +249,21 @@ func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error)
}
func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
typeName := typ.String()
typeDecoder := typeDecoders[typeName]
if typeDecoder != nil {
return typeDecoder, nil
}
if typ.Kind() == reflect.Ptr {
typeDecoder := typeDecoders[typ.Elem().String()]
if typeDecoder != nil {
return &optionalDecoder{typ.Elem(), typeDecoder}, nil
}
}
cacheKey := typ
cachedDecoder := cfg.getDecoderFromCache(cacheKey)
if cachedDecoder != nil {
return cachedDecoder, nil
decoder := cfg.getDecoderFromCache(cacheKey)
if decoder != nil {
return decoder, nil
}
placeholder := &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
cfg.addDecoderToCache(cacheKey, placeholder)
newDecoder, err := createDecoderOfType(cfg, typ)
cfg.addDecoderToCache(cacheKey, newDecoder)
return newDecoder, err
decoder = getTypeDecoderFromExtension(typ)
if decoder != nil {
cfg.addDecoderToCache(cacheKey, decoder)
return decoder, nil
}
decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
cfg.addDecoderToCache(cacheKey, decoder)
decoder, err := createDecoderOfType(cfg, typ)
cfg.addDecoderToCache(cacheKey, decoder)
return decoder, err
}
func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
@ -409,27 +341,21 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
}
func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
typeName := typ.String()
typeEncoder := typeEncoders[typeName]
if typeEncoder != nil {
return typeEncoder, nil
}
if typ.Kind() == reflect.Ptr {
typeEncoder := typeEncoders[typ.Elem().String()]
if typeEncoder != nil {
return &optionalEncoder{typeEncoder}, nil
}
}
cacheKey := typ
cachedEncoder := cfg.getEncoderFromCache(cacheKey)
if cachedEncoder != nil {
return cachedEncoder, nil
encoder := cfg.getEncoderFromCache(cacheKey)
if encoder != nil {
return encoder, nil
}
placeholder := &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
cfg.addEncoderToCache(cacheKey, placeholder)
newEncoder, err := createEncoderOfType(cfg, typ)
cfg.addEncoderToCache(cacheKey, newEncoder)
return newEncoder, err
encoder = getTypeEncoderFromExtension(typ)
if encoder != nil {
cfg.addEncoderToCache(cacheKey, encoder)
return encoder, nil
}
encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
cfg.addEncoderToCache(cacheKey, encoder)
encoder, err := createEncoderOfType(cfg, typ)
cfg.addEncoderToCache(cacheKey, encoder)
return encoder, err
}
func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {