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:
parent
14588726a1
commit
c36a7ed7cd
@ -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)
|
|
||||||
if cachedDecoder == nil {
|
|
||||||
decoder, err := decoderOfType(iter.cfg, cacheKey)
|
decoder, err := decoderOfType(iter.cfg, cacheKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
iter.Error = err
|
iter.Error = err
|
||||||
return
|
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)
|
|
||||||
if cachedEncoder == nil {
|
|
||||||
encoder, err := encoderOfType(stream.cfg, cacheKey)
|
encoder, err := encoderOfType(stream.cfg, cacheKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stream.Error = err
|
stream.Error = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cachedEncoder = encoder
|
encoder.encodeInterface(val, stream)
|
||||||
stream.cfg.addEncoderToCache(cacheKey, encoder)
|
|
||||||
}
|
|
||||||
cachedEncoder.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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user