180 lines
4.3 KiB
Go
180 lines
4.3 KiB
Go
package codec
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"go_dreamfactory/lego/sys/codec/core"
|
|
"go_dreamfactory/lego/sys/codec/factory"
|
|
"go_dreamfactory/lego/sys/codec/render"
|
|
|
|
"github.com/modern-go/reflect2"
|
|
)
|
|
|
|
func newSys(options core.Options) (sys *codec, err error) {
|
|
sys = &codec{
|
|
options: &options,
|
|
decoderCache: new(sync.Map),
|
|
encoderCache: new(sync.Map),
|
|
streamPool: &sync.Pool{
|
|
New: func() interface{} {
|
|
return render.NewStream(sys, 512)
|
|
},
|
|
},
|
|
extraPool: &sync.Pool{
|
|
New: func() interface{} {
|
|
return render.NewExtractor(sys)
|
|
},
|
|
},
|
|
}
|
|
return
|
|
}
|
|
|
|
type codec struct {
|
|
options *core.Options
|
|
decoderCache *sync.Map
|
|
encoderCache *sync.Map
|
|
streamPool *sync.Pool
|
|
extraPool *sync.Pool
|
|
}
|
|
|
|
func (this *codec) Options() *core.Options {
|
|
return this.options
|
|
}
|
|
|
|
//序列化Josn
|
|
func (this *codec) MarshalJson(val interface{}, option ...core.ExecuteOption) (buf []byte, err error) {
|
|
stream := this.BorrowStream()
|
|
defer this.ReturnStream(stream)
|
|
stream.WriteVal(val)
|
|
if stream.Error() != nil {
|
|
return nil, stream.Error()
|
|
}
|
|
result := stream.Buffer()
|
|
copied := make([]byte, len(result))
|
|
copy(copied, result)
|
|
return copied, nil
|
|
}
|
|
|
|
func (this *codec) UnmarshalJson(data []byte, v interface{}) error {
|
|
extra := this.BorrowExtractor(data)
|
|
defer this.ReturnExtractor(extra)
|
|
extra.ReadVal(v)
|
|
return extra.Error()
|
|
}
|
|
|
|
func (this *codec) addDecoderToCache(cacheKey uintptr, decoder core.IDecoder) {
|
|
this.decoderCache.Store(cacheKey, decoder)
|
|
}
|
|
func (this *codec) addEncoderToCache(cacheKey uintptr, encoder core.IEncoder) {
|
|
this.encoderCache.Store(cacheKey, encoder)
|
|
}
|
|
|
|
func (this *codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder {
|
|
encoder, found := this.encoderCache.Load(cacheKey)
|
|
if found {
|
|
return encoder.(core.IEncoder)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder {
|
|
decoder, found := this.decoderCache.Load(cacheKey)
|
|
if found {
|
|
return decoder.(core.IDecoder)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *codec) EncoderOf(typ reflect2.Type) core.IEncoder {
|
|
cacheKey := typ.RType()
|
|
encoder := this.GetEncoderFromCache(cacheKey)
|
|
if encoder != nil {
|
|
return encoder
|
|
}
|
|
ctx := &core.Ctx{
|
|
ICodec: this,
|
|
Prefix: "",
|
|
Decoders: map[reflect2.Type]core.IDecoder{},
|
|
Encoders: map[reflect2.Type]core.IEncoder{},
|
|
}
|
|
encoder = factory.EncoderOfType(ctx, typ)
|
|
if typ.LikePtr() {
|
|
encoder = factory.NewonePtrEncoder(encoder)
|
|
}
|
|
this.addEncoderToCache(cacheKey, encoder)
|
|
return encoder
|
|
}
|
|
|
|
func (this *codec) DecoderOf(typ reflect2.Type) core.IDecoder {
|
|
cacheKey := typ.RType()
|
|
decoder := this.GetDecoderFromCache(cacheKey)
|
|
if decoder != nil {
|
|
return decoder
|
|
}
|
|
ctx := &core.Ctx{
|
|
ICodec: this,
|
|
Prefix: "",
|
|
Decoders: map[reflect2.Type]core.IDecoder{},
|
|
Encoders: map[reflect2.Type]core.IEncoder{},
|
|
}
|
|
ptrType := typ.(*reflect2.UnsafePtrType)
|
|
decoder = factory.DecoderOfType(ctx, ptrType.Elem())
|
|
this.addDecoderToCache(cacheKey, decoder)
|
|
return decoder
|
|
}
|
|
|
|
func (this *codec) BorrowStream() core.IStream {
|
|
stream := this.streamPool.Get().(core.IStream)
|
|
return stream
|
|
}
|
|
|
|
func (this *codec) ReturnStream(stream core.IStream) {
|
|
this.streamPool.Put(stream)
|
|
}
|
|
|
|
func (this *codec) BorrowExtractor(buf []byte) core.IExtractor {
|
|
extra := this.extraPool.Get().(core.IExtractor)
|
|
extra.ResetBytes(buf)
|
|
return extra
|
|
}
|
|
|
|
func (this *codec) ReturnExtractor(extra core.IExtractor) {
|
|
this.extraPool.Put(extra)
|
|
}
|
|
|
|
///日志***********************************************************************
|
|
func (this *codec) Debug() bool {
|
|
return this.options.Debug
|
|
}
|
|
|
|
func (this *codec) Debugf(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Debugf("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|
|
func (this *codec) Infof(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Infof("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|
|
func (this *codec) Warnf(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Warnf("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|
|
func (this *codec) Errorf(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Errorf("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|
|
func (this *codec) Panicf(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Panicf("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|
|
func (this *codec) Fatalf(format string, a ...interface{}) {
|
|
if this.options.Debug {
|
|
this.options.Log.Fatalf("[SYS Gin] "+format, a...)
|
|
}
|
|
}
|