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...) } }