diff --git a/lego/sys/codec/codec.go b/lego/sys/codec/codec.go index 4761a4807..7878c23e7 100644 --- a/lego/sys/codec/codec.go +++ b/lego/sys/codec/codec.go @@ -10,8 +10,8 @@ import ( "github.com/modern-go/reflect2" ) -func newSys(options core.Options) (sys *codec, err error) { - sys = &codec{ +func newSys(options core.Options) (sys *Codec, err error) { + sys = &Codec{ options: &options, decoderCache: new(sync.Map), encoderCache: new(sync.Map), @@ -29,7 +29,7 @@ func newSys(options core.Options) (sys *codec, err error) { return } -type codec struct { +type Codec struct { options *core.Options decoderCache *sync.Map encoderCache *sync.Map @@ -37,39 +37,18 @@ type codec struct { extraPool *sync.Pool } -func (this *codec) Options() *core.Options { +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) { +func (this *Codec) addDecoderToCache(cacheKey uintptr, decoder core.IDecoder) { this.decoderCache.Store(cacheKey, decoder) } -func (this *codec) addEncoderToCache(cacheKey uintptr, encoder core.IEncoder) { +func (this *Codec) addEncoderToCache(cacheKey uintptr, encoder core.IEncoder) { this.encoderCache.Store(cacheKey, encoder) } -func (this *codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder { +func (this *Codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder { encoder, found := this.encoderCache.Load(cacheKey) if found { return encoder.(core.IEncoder) @@ -77,7 +56,7 @@ func (this *codec) GetEncoderFromCache(cacheKey uintptr) core.IEncoder { return nil } -func (this *codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder { +func (this *Codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder { decoder, found := this.decoderCache.Load(cacheKey) if found { return decoder.(core.IDecoder) @@ -85,7 +64,7 @@ func (this *codec) GetDecoderFromCache(cacheKey uintptr) core.IDecoder { return nil } -func (this *codec) EncoderOf(typ reflect2.Type) core.IEncoder { +func (this *Codec) EncoderOf(typ reflect2.Type) core.IEncoder { cacheKey := typ.RType() encoder := this.GetEncoderFromCache(cacheKey) if encoder != nil { @@ -105,7 +84,7 @@ func (this *codec) EncoderOf(typ reflect2.Type) core.IEncoder { return encoder } -func (this *codec) DecoderOf(typ reflect2.Type) core.IDecoder { +func (this *Codec) DecoderOf(typ reflect2.Type) core.IDecoder { cacheKey := typ.RType() decoder := this.GetDecoderFromCache(cacheKey) if decoder != nil { @@ -123,57 +102,89 @@ func (this *codec) DecoderOf(typ reflect2.Type) core.IDecoder { return decoder } -func (this *codec) BorrowStream() core.IStream { +func (this *Codec) BorrowStream() core.IStream { stream := this.streamPool.Get().(core.IStream) return stream } -func (this *codec) ReturnStream(stream core.IStream) { +func (this *Codec) ReturnStream(stream core.IStream) { this.streamPool.Put(stream) } -func (this *codec) BorrowExtractor(buf []byte) core.IExtractor { +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) { +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 { +func (this *Codec) Debug() bool { return this.options.Debug } -func (this *codec) Debugf(format string, a ...interface{}) { +func (this *Codec) Debugf(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Debugf("[SYS Gin] "+format, a...) + this.options.Log.Debugf("[SYS Codec] "+format, a...) } } -func (this *codec) Infof(format string, a ...interface{}) { +func (this *Codec) Infof(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Infof("[SYS Gin] "+format, a...) + this.options.Log.Infof("[SYS Codec] "+format, a...) } } -func (this *codec) Warnf(format string, a ...interface{}) { +func (this *Codec) Warnf(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Warnf("[SYS Gin] "+format, a...) + this.options.Log.Warnf("[SYS Codec] "+format, a...) } } -func (this *codec) Errorf(format string, a ...interface{}) { +func (this *Codec) Errorf(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Errorf("[SYS Gin] "+format, a...) + this.options.Log.Errorf("[SYS Codec] "+format, a...) } } -func (this *codec) Panicf(format string, a ...interface{}) { +func (this *Codec) Panicf(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Panicf("[SYS Gin] "+format, a...) + this.options.Log.Panicf("[SYS Codec] "+format, a...) } } -func (this *codec) Fatalf(format string, a ...interface{}) { +func (this *Codec) Fatalf(format string, a ...interface{}) { if this.options.Debug { - this.options.Log.Fatalf("[SYS Gin] "+format, a...) + this.options.Log.Fatalf("[SYS Codec] "+format, a...) } } diff --git a/lego/sys/codec/core/core.go b/lego/sys/codec/core/core.go index df31b3cc4..8bed721ad 100644 --- a/lego/sys/codec/core/core.go +++ b/lego/sys/codec/core/core.go @@ -106,6 +106,7 @@ type ( WriteFloat64(val float64) WriteString(val string) WriteBytes(val []byte) + Reset(bufSize int) Buffer() []byte //返回缓存区数据 Error() error SetErr(err error) diff --git a/lego/sys/codec/factory/factory_struct.go b/lego/sys/codec/factory/factory_struct.go index f71befc7e..a3b653bbc 100644 --- a/lego/sys/codec/factory/factory_struct.go +++ b/lego/sys/codec/factory/factory_struct.go @@ -1,6 +1,7 @@ package factory import ( + "errors" "fmt" "io" "reflect" @@ -63,7 +64,7 @@ func encoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { }) } } - return &structEncoder{typ, finalOrderedFields} + return &structEncoder{ctx.ICodec, typ, finalOrderedFields} } func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { @@ -97,7 +98,7 @@ func decoderOfStruct(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { } } } - return createStructDecoder(ctx.Options(), typ, fields) + return createStructDecoder(ctx.ICodec, typ, fields) } //结构第编辑码构建 @@ -205,11 +206,11 @@ func calcFieldNames(originalFieldName string, tagProvidedFieldName string, whole return fieldNames } -func createStructDecoder(opt *core.Options, typ reflect2.Type, fields map[string]*structFieldDecoder) core.IDecoder { - if opt.DisallowUnknownFields { +func createStructDecoder(codec core.ICodec, typ reflect2.Type, fields map[string]*structFieldDecoder) core.IDecoder { + if codec.Options().DisallowUnknownFields { return &structDecoder{typ: typ, fields: fields, disallowUnknownFields: true} } else { - return &structDecoder{opt, typ, fields, false} + return &structDecoder{codec, typ, fields, false} } } @@ -244,6 +245,7 @@ func resolveConflictBinding(opt *core.Options, old, new *Binding) (ignoreOld, ig //结构对象 编解码----------------------------------------------------------------------------------------------------------------------- type structEncoder struct { + codec core.ICodec typ reflect2.Type fields []structFieldTo } @@ -271,12 +273,33 @@ func (this *structEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { } } +func (this *structEncoder) EncodeToMapString(ptr unsafe.Pointer) (ret map[string]string, err error) { + ret = make(map[string]string) + stream := this.codec.BorrowStream() + for _, field := range this.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } + stream.Reset(512) + field.encoder.Encode(ptr, stream) + if stream.Error() != nil && stream.Error() != io.EOF { + err = stream.Error() + return + } + ret[field.toName] = BytesToString(stream.Buffer()) + } + return +} + func (this *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } type structDecoder struct { - opt *core.Options + codec core.ICodec typ reflect2.Type fields map[string]*structFieldDecoder disallowUnknownFields bool @@ -302,7 +325,7 @@ func (this *structDecoder) decodeField(ptr unsafe.Pointer, extra core.IExtractor field = extra.ReadString() fieldDecoder = this.fields[field] - if fieldDecoder == nil && !this.opt.CaseSensitive { + if fieldDecoder == nil && !this.codec.Options().CaseSensitive { fieldDecoder = this.fields[strings.ToLower(field)] } @@ -324,6 +347,32 @@ func (this *structDecoder) decodeField(ptr unsafe.Pointer, extra core.IExtractor fieldDecoder.Decode(ptr, extra) } +//解码对象从MapJson 中 +func (this *structDecoder) DecodeForMapString(ptr unsafe.Pointer, extra map[string]string) (err error) { + var fieldDecoder *structFieldDecoder + ext := this.codec.BorrowExtractor([]byte{}) + for k, v := range extra { + fieldDecoder = this.fields[k] + if fieldDecoder == nil && !this.codec.Options().CaseSensitive { + fieldDecoder = this.fields[strings.ToLower(k)] + } + if fieldDecoder == nil { + if this.disallowUnknownFields { + err = errors.New("found unknown field: " + k) + return + } + continue + } + ext.ResetBytes(StringToBytes(v)) + fieldDecoder.Decode(ptr, ext) + if ext.Error() != nil && ext.Error() != io.EOF { + err = ext.Error() + return + } + } + return +} + //结构对象字段 编解码----------------------------------------------------------------------------------------------------------------------- type structFieldTo struct { encoder *structFieldEncoder diff --git a/lego/sys/codec/render/json_stream.go b/lego/sys/codec/render/json_stream.go index 41ffc6784..4fa115f40 100644 --- a/lego/sys/codec/render/json_stream.go +++ b/lego/sys/codec/render/json_stream.go @@ -146,6 +146,12 @@ func (this *JsonStream) WriteString(val string) { func (this *JsonStream) WriteBytes(val []byte) { this.buf = append(this.buf, val...) } +func (this *JsonStream) Reset(bufSize int) { + this.buf = make([]byte, 0, bufSize) + this.err = nil + this.indention = 0 + return +} func (this *JsonStream) Buffer() []byte { return this.buf }