|
@ -5,6 +5,7 @@ import ( |
|
|
"fmt" |
|
|
"fmt" |
|
|
"io" |
|
|
"io" |
|
|
"reflect" |
|
|
"reflect" |
|
|
|
|
|
"sync" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
type TypeInfo struct { |
|
|
type TypeInfo struct { |
|
@ -27,8 +28,23 @@ type HasTypeByte interface { |
|
|
TypeByte() byte |
|
|
TypeByte() byte |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: do not access typeInfos directly, but call GetTypeInfo()
|
|
|
|
|
|
var typeInfosMtx sync.Mutex |
|
|
var typeInfos = map[reflect.Type]*TypeInfo{} |
|
|
var typeInfos = map[reflect.Type]*TypeInfo{} |
|
|
|
|
|
|
|
|
|
|
|
func GetTypeInfo(rt reflect.Type) *TypeInfo { |
|
|
|
|
|
typeInfosMtx.Lock() |
|
|
|
|
|
defer typeInfosMtx.Unlock() |
|
|
|
|
|
info := typeInfos[rt] |
|
|
|
|
|
if info == nil { |
|
|
|
|
|
info = &TypeInfo{Type: rt} |
|
|
|
|
|
RegisterType(info) |
|
|
|
|
|
} |
|
|
|
|
|
return info |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Registers and possibly modifies the TypeInfo.
|
|
|
|
|
|
// NOTE: not goroutine safe, so only call upon program init.
|
|
|
func RegisterType(info *TypeInfo) *TypeInfo { |
|
|
func RegisterType(info *TypeInfo) *TypeInfo { |
|
|
|
|
|
|
|
|
// Register the type info
|
|
|
// Register the type info
|
|
@ -74,10 +90,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err * |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Get typeInfo
|
|
|
// Get typeInfo
|
|
|
typeInfo := typeInfos[rt] |
|
|
|
|
|
if typeInfo == nil { |
|
|
|
|
|
typeInfo = RegisterType(&TypeInfo{Type: rt}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
typeInfo := GetTypeInfo(rt) |
|
|
|
|
|
|
|
|
// Custom decoder
|
|
|
// Custom decoder
|
|
|
if typeInfo.Decoder != nil { |
|
|
if typeInfo.Decoder != nil { |
|
@ -178,10 +191,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err * |
|
|
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) { |
|
|
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) { |
|
|
|
|
|
|
|
|
// Get typeInfo
|
|
|
// Get typeInfo
|
|
|
typeInfo := typeInfos[rt] |
|
|
|
|
|
if typeInfo == nil { |
|
|
|
|
|
typeInfo = RegisterType(&TypeInfo{Type: rt}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
typeInfo := GetTypeInfo(rt) |
|
|
|
|
|
|
|
|
// Custom encoder, say for an interface type rt.
|
|
|
// Custom encoder, say for an interface type rt.
|
|
|
if typeInfo.Encoder != nil { |
|
|
if typeInfo.Encoder != nil { |
|
@ -193,11 +203,8 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err |
|
|
if rt.Kind() == reflect.Interface { |
|
|
if rt.Kind() == reflect.Interface { |
|
|
rv = rv.Elem() |
|
|
rv = rv.Elem() |
|
|
rt = rv.Type() |
|
|
rt = rv.Type() |
|
|
typeInfo = typeInfos[rt] |
|
|
|
|
|
// If interface type, get typeInfo of underlying type.
|
|
|
// If interface type, get typeInfo of underlying type.
|
|
|
if typeInfo == nil { |
|
|
|
|
|
typeInfo = RegisterType(&TypeInfo{Type: rt}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
typeInfo = GetTypeInfo(rt) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Dereference pointer
|
|
|
// Dereference pointer
|
|
|