1
0
mirror of https://github.com/json-iterator/go.git synced 2025-06-06 22:36:25 +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 DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) 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) { func (decoder *funcDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.fun(ptr, iter) decoder.fun(ptr, iter)
} }
@ -78,11 +72,6 @@ func (encoder *funcEncoder) isEmpty(ptr unsafe.Pointer) bool {
return encoder.isEmptyFunc(ptr) 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 jsonNumberType reflect.Type
var jsonRawMessageType reflect.Type var jsonRawMessageType reflect.Type
var jsoniterRawMessageType reflect.Type var jsoniterRawMessageType reflect.Type
@ -92,11 +81,6 @@ var unmarshalerType reflect.Type
var textUnmarshalerType reflect.Type var textUnmarshalerType reflect.Type
func init() { 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() jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem() jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
@ -106,42 +90,6 @@ func init() {
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 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 { type optionalDecoder struct {
valueType reflect.Type valueType reflect.Type
valueDecoder ValDecoder valueDecoder ValDecoder
@ -260,18 +208,13 @@ type nonEmptyInterface struct {
func (iter *Iterator) ReadVal(obj interface{}) { func (iter *Iterator) ReadVal(obj interface{}) {
typ := reflect.TypeOf(obj) typ := reflect.TypeOf(obj)
cacheKey := typ.Elem() cacheKey := typ.Elem()
cachedDecoder := iter.cfg.getDecoderFromCache(cacheKey) decoder, err := decoderOfType(iter.cfg, cacheKey)
if cachedDecoder == nil { if err != nil {
decoder, err := decoderOfType(iter.cfg, cacheKey) iter.Error = err
if err != nil { return
iter.Error = err
return
}
cachedDecoder = decoder
iter.cfg.addDecoderToCache(cacheKey, decoder)
} }
e := (*emptyInterface)(unsafe.Pointer(&obj)) e := (*emptyInterface)(unsafe.Pointer(&obj))
cachedDecoder.decode(e.word, iter) decoder.decode(e.word, iter)
} }
func (stream *Stream) WriteVal(val interface{}) { func (stream *Stream) WriteVal(val interface{}) {
@ -281,17 +224,12 @@ func (stream *Stream) WriteVal(val interface{}) {
} }
typ := reflect.TypeOf(val) typ := reflect.TypeOf(val)
cacheKey := typ cacheKey := typ
cachedEncoder := stream.cfg.getEncoderFromCache(cacheKey) encoder, err := encoderOfType(stream.cfg, cacheKey)
if cachedEncoder == nil { if err != nil {
encoder, err := encoderOfType(stream.cfg, cacheKey) stream.Error = err
if err != nil { return
stream.Error = err
return
}
cachedEncoder = encoder
stream.cfg.addEncoderToCache(cacheKey, encoder)
} }
cachedEncoder.encodeInterface(val, stream) encoder.encodeInterface(val, stream)
} }
type prefix string 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) { 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 cacheKey := typ
cachedDecoder := cfg.getDecoderFromCache(cacheKey) decoder := cfg.getDecoderFromCache(cacheKey)
if cachedDecoder != nil { if decoder != nil {
return cachedDecoder, nil return decoder, nil
} }
placeholder := &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} decoder = getTypeDecoderFromExtension(typ)
cfg.addDecoderToCache(cacheKey, placeholder) if decoder != nil {
newDecoder, err := createDecoderOfType(cfg, typ) cfg.addDecoderToCache(cacheKey, decoder)
cfg.addDecoderToCache(cacheKey, newDecoder) return decoder, nil
return newDecoder, err }
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) { 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) { 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 cacheKey := typ
cachedEncoder := cfg.getEncoderFromCache(cacheKey) encoder := cfg.getEncoderFromCache(cacheKey)
if cachedEncoder != nil { if encoder != nil {
return cachedEncoder, nil return encoder, nil
} }
placeholder := &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} encoder = getTypeEncoderFromExtension(typ)
cfg.addEncoderToCache(cacheKey, placeholder) if encoder != nil {
newEncoder, err := createEncoderOfType(cfg, typ) cfg.addEncoderToCache(cacheKey, encoder)
cfg.addEncoderToCache(cacheKey, newEncoder) return encoder, nil
return newEncoder, err }
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) { func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {