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 } 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) } //编码对象到json 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 } //解码json到对象 func (this *Codec) UnmarshalJson(data []byte, v interface{}) error { extra := this.BorrowExtractor(data) defer this.ReturnExtractor(extra) extra.ReadVal(v) return extra.Error() } //编码对象到mapjson func (this *Codec) MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) { return } //解码mapjson到对象 func (this *Codec) UnmarshalMapString(data []byte, v interface{}) error { return nil } ///日志*********************************************************************** 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 Codec] "+format, a...) } } func (this *Codec) Infof(format string, a ...interface{}) { if this.options.Debug { this.options.Log.Infof("[SYS Codec] "+format, a...) } } func (this *Codec) Warnf(format string, a ...interface{}) { if this.options.Debug { this.options.Log.Warnf("[SYS Codec] "+format, a...) } } func (this *Codec) Errorf(format string, a ...interface{}) { if this.options.Debug { this.options.Log.Errorf("[SYS Codec] "+format, a...) } } func (this *Codec) Panicf(format string, a ...interface{}) { if this.options.Debug { this.options.Log.Panicf("[SYS Codec] "+format, a...) } } func (this *Codec) Fatalf(format string, a ...interface{}) { if this.options.Debug { this.options.Log.Fatalf("[SYS Codec] "+format, a...) } }