From 867a3cbd9b5c33af42e336f4c992116184fcf31c Mon Sep 17 00:00:00 2001 From: DEV Date: Tue, 28 May 2024 01:05:06 +0200 Subject: [PATCH] restructurando el codigo para actualizar los packs con la nueva arquitectura del builder --- a/main.go | 52 +----- base/apack/flags.go | 2 +- base/apack/pkjson/active.go | 19 ++- base/apack/pkjson/builder.go | 160 +++++++++++++++++- base/apack/pkjson/key_stringer.go | 123 ++++---------- base/apack/pkjson/packer.go | 252 +---------------------------- base/apack/pkjson/reflected.go | 144 +++++++++++++++++ base/apack/pkjson/reflected_map.go | 3 +- core/cdcs/cjson/active.go | 4 +- core/cdcs/cjson/writer.go | 74 ++------- core/errs/efjson/json_builder.go | 10 +- 11 files changed, 369 insertions(+), 474 deletions(-) create mode 100644 base/apack/pkjson/reflected.go diff --git a/a/main.go b/a/main.go index a6cddc3..f6af466 100644 --- a/a/main.go +++ b/a/main.go @@ -4,7 +4,6 @@ import ( "apack/pkjson" "errs" "errs/eftext" - "errs/wrap" "fmt" "math/rand" "time" @@ -31,50 +30,11 @@ func randomInt(min, max int) int { func main() { - a := wrap.ErrCode("UnError") - //a = nil - //var e error - - m := errs.NewErrMulti( - errs.ErrCode("Un Err"), - errs.ErrCode("Dos"), - a, - ) - - e := wrap.WithTrace(*wrap.WithMessage(m,"mensage"),1) - - - l := wrap.WithInfo(e,func(i *wrap.Info){ - i.Link = "http://nodes.com" - }) - - - - //e = wrap.WithFieldNew(e,"MiCampo",334.33) - - - /* - erstfy.WithTransformers( - false,"unlabel","upper", - )(&erstfy.g.stringify) - */ - - - //fmt.Printf("%s \n",string(erstfy.DefaultStringer().Stringify(e))) - //fmt.Printf("%s \n",string(errs.Encode(e, efjson.Formatter()))) - //fmt.Printf("%s \n",string(errs.Encode(l, eftext.Formatter()))) p := pkjson.NewPacker() - r := p.Pack(l) - if !r.Ok() { - fmt.Printf("%s \n",string(errs.Encode(r.Fail(), eftext.Formatter()))) - return - } - - fmt.Printf("Data\n\n%s",string(r.Value())) myMap := map[interface{}]interface{}{ @@ -88,20 +48,14 @@ func main() { 10.11: "doce", false: 13, "catorce": 15.16, + "dfate": time.Now(), + time.Now(): "ff", } - r = p.Pack(map[string]string{"g":"dsd","aa":"myMap"}) - if !r.Ok() { - fmt.Printf("%s \n",string(errs.Encode(r.Fail(), eftext.Formatter()))) - return - } - - fmt.Printf("Data\n\n%s",string(r.Value())) - - r = p.Pack(myMap) + r := p.Pack(myMap) if !r.Ok() { fmt.Printf("%s \n",string(errs.Encode(r.Fail(), eftext.Formatter()))) return diff --git a/base/apack/flags.go b/base/apack/flags.go index e623bd3..f8c9e17 100644 --- a/base/apack/flags.go +++ b/base/apack/flags.go @@ -45,7 +45,7 @@ const ( flagMaskBin Flags = 0b0000110000000000 FlagDateRFC822 Flags = 0b0001000000000000 - FlagDateUnix Flags = 0b0010000000000000 + FlagDateUnix Flags = 0b0010000000000000 FlagDateANSIC Flags = 0b0100000000000000 FlagDateRFC850 Flags = 0b1000000000000000 flagMaskDate Flags = 0b1111000000000000 diff --git a/base/apack/pkjson/active.go b/base/apack/pkjson/active.go index 940f9fb..4ee7d78 100644 --- a/base/apack/pkjson/active.go +++ b/base/apack/pkjson/active.go @@ -80,16 +80,27 @@ var ( +func defaultPackers () *sync.Map { + mp := &sync.Map{} + return mp +} + func defaultKeyStringer () *keyStringer { return newKeyStringer(func(s *keyStringer){ // Registramos los tipos conocidos + s.stringers[reflect.TypeOf("")] = func(e *rMapEntry, k reflect.Value) error { + e.k = k.String() + return nil + } + fnI := func(e *rMapEntry, k reflect.Value) error { e.k = strconv.FormatInt(k.Int(), 10) - return nil } + return nil + } s.stringers[reflect.TypeOf(int (0))]=fnI s.stringers[reflect.TypeOf(int8 (0))]=fnI @@ -99,7 +110,8 @@ func defaultKeyStringer () *keyStringer { fnU := func(e *rMapEntry, k reflect.Value) error { e.k = strconv.FormatUint(k.Uint(), 10) - return nil } + return nil + } s.stringers[reflect.TypeOf(uint (0))]=fnU s.stringers[reflect.TypeOf(uint8 (0))]=fnU @@ -110,7 +122,8 @@ func defaultKeyStringer () *keyStringer { s.stringers[reflect.TypeOf(false)]= func(e *rMapEntry, k reflect.Value) error { e.k = strconv.FormatBool(k.Bool()) - return nil } + return nil + } s.stringers[reflect.TypeOf(float64(0))]=func(e *rMapEntry, k reflect.Value) error { e.k = cjson.JSONFloat(k.Float(),64) diff --git a/base/apack/pkjson/builder.go b/base/apack/pkjson/builder.go index 796f9f2..c7a4e42 100644 --- a/base/apack/pkjson/builder.go +++ b/base/apack/pkjson/builder.go @@ -139,6 +139,7 @@ func (b *Builder) Any (value any) { case []string : packListString(b,v,b.f) case []time.Time: packListDate (b,v,b.f) case []time.Duration: packListInt[time.Duration](b,v,b.f) + case []error : packListError(b,v,b.f) default: rv := reflect.ValueOf (value) @@ -156,6 +157,7 @@ func (b *Builder) Raw (value []byte){ _,_ = b.B.Write(value) b.checkValue() } + func (b *Builder) Binary (value []byte){ b.checkValue() b.packBinary(value,b.f) @@ -170,7 +172,7 @@ func (b *Builder) String (value string){ func (b *Builder) Bool (value bool){ b.checkValue() - cjson.WriteBool(b.B,value,true) + cjson.WriteBool(b.B,value) b.postValue() } @@ -180,7 +182,7 @@ func (b *Builder) Int16 (value int16 ){ b.Int64(int64(value)) } func (b *Builder) Int32 (value int32 ){ b.Int64(int64(value)) } func (b *Builder) Int64 (value int64 ){ b.checkValue() - cjson.WriteInt(b.B,value,true) + cjson.WriteInt(b.B,value) b.postValue() } @@ -191,7 +193,7 @@ func (b *Builder) Uint32 (value uint32 ){ b.Uint64(uint64(value)) } func (b *Builder) Uintptr (value uintptr){ b.Uint64(uint64(value)) } func (b *Builder) Uint64 (value uint64 ){ b.checkValue() - cjson.WriteUint(b.B,value,true) + cjson.WriteUint(b.B,value) b.postValue() } @@ -203,7 +205,7 @@ func (b *Builder) Float64 (value float64){ func (b *Builder) float (value float64, bits int) { b.checkValue() - cjson.WriteFloat(b.B,value,bits,b.f.Quote()) + cjson.WriteFloat(b.B,value,bits) b.postValue() } @@ -220,7 +222,7 @@ func (b *Builder) Error (value error){ func (b *Builder) Time (value time.Time){ b.checkValue() - cjson.WriteTime(b.B,value,b.f.DateFormat(),true) + cjson.WriteTime(b.B,value,b.f.DateFormat()) b.postValue() } @@ -254,15 +256,13 @@ func (b *Builder) Object(fnc func (objBuilder blds.ObjectBuilder)){ - - - func (b *Builder) Item() blds.ValueBuilder { b.checkState() b.writeSepIf(b.Current.Count > 0) return b } + func (b *Builder) Key(key any) blds.ValueBuilder { b.checkState() b.writeSepIf(b.Current.Count > 0) @@ -274,6 +274,7 @@ func (b *Builder) Key(key any) blds.ValueBuilder { return b } + func (b *Builder) Field(name string) blds.ValueBuilder { b.checkState() b.writeSepIf(b.Current.Count > 0) @@ -287,6 +288,56 @@ func (b *Builder) Field(name string) blds.ValueBuilder { + +func (b *Builder) packString (value string, flags apack.Flags) { + if len(value) == 0 { + b.B.Write2Byte('"','"') + return + } + if flags.Encrypted() { + b.packEncrypted([]byte(value),flags) + return + } + if flags.Binary() { + b.packBinary([]byte(value),flags) + return + } + cjson.WriteString(b.B,value,flags.EscapeHTML()) +} + +func (b *Builder) packEncrypted (value []byte, flags apack.Flags) { + if b.Encrypter == nil { + b.SetError(apack.G.ErrInvalidEncrypter) + return + } + rs := b.Encrypter.Encrypt(value) + if !rs.Ok() { + b.SetError(rs.Fail()) + return + } + if !flags.Binary() { + flags|=apack.FlagBinary64 + } + b.packBinary (rs.Value(),flags) +} + +func (b *Builder) packBinary (value []byte, flags apack.Flags) { + if flags.Bin64() { + b.SetError(cjson.WriteBase64(b.B,value)) + return + } + if flags.Bin32() { + b.SetError(cjson.WriteBase64(b.B,value)) + return + } +} + + + + + + + func (b *Builder) makeLevel (mode pstate.Mode, isNil, isEmpty bool, maker func(builder *Builder)) { b.checkValue() if isNil { @@ -332,6 +383,7 @@ func (b *Builder) checkState () { } } + func (b *Builder) checkValue () { if b.Err != nil { panic(apack.G.ErrInvalidState.WithCause(b.Err)) @@ -341,6 +393,7 @@ func (b *Builder) checkValue () { } } + func (b *Builder) postValue() { if b.Err == nil { b.Current.IsValue = false @@ -351,6 +404,7 @@ func (b *Builder) postValue() { } } + func (b *Builder) writeSepIf(cond bool) { if cond { b.B.WriteByte(sep) } } @@ -362,3 +416,93 @@ func (b *Builder) writeSepIf(cond bool) { + +func packListString (p *Builder, list []string, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + p.packString(v, flags) + if p.Err != nil { + return + } + } + }) +} + + +func packListError (p *Builder, list []error, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + if v == nil { + b.B.WOQ(true,'"',cjson.G.NullValue) + continue + } + p.packString(v.Error(), apack.FlagScapeHTML) + } + }) +} + + +func packListBool (p *Builder, list []bool, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + cjson.WriteBool(p.B,v) + } + }) +} + + +func packListInt [T int | int8 | int16 | int32 | int64 | time.Duration](p *Builder, list []T, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + cjson.WriteInt(p.B,int64(v)) + } + }) +} + + +func packListUInt [T uint | uint8 | uint16 | uint32 | uint64|uintptr](p *Builder, list []T, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + cjson.WriteUint(p.B,uint64(v)) + } + }) +} + + +func packListFloat[T float32 | float64](p *Builder, list []T, flags apack.Flags, bits int) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + cjson.WriteFloat(p.B,float64(v),bits) + } + }) +} + + +func packListDate (p *Builder, list []time.Time, flags apack.Flags) { + p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ + for i,v := range list { + if i > 0 { + p.B.WriteByte(sep) + } + cjson.WriteTime(p.B,v,flags.DateFormat()) + } + }) +} diff --git a/base/apack/pkjson/key_stringer.go b/base/apack/pkjson/key_stringer.go index edba427..ab24b7f 100644 --- a/base/apack/pkjson/key_stringer.go +++ b/base/apack/pkjson/key_stringer.go @@ -27,10 +27,8 @@ package pkjson import ( "apack" "cdcs/cjson" - "encoding" "errs" "reflect" - "strconv" "sync" "time" ) @@ -63,22 +61,22 @@ func newKeyStringer (options...keyStringerFnc) *keyStringer { func (s *keyStringer) packStringifyKey (b *Builder, key any) { switch v := key.(type) { case string : b.packString(v,apack.FlagScapeHTML) - case bool : cjson.WriteBool (b.B,v,true) - case uint : cjson.WriteUint (b.B,uint64(v),true) - case uint8 : cjson.WriteUint (b.B,uint64(v),true) - case uint16 : cjson.WriteUint (b.B,uint64(v),true) - case uint32 : cjson.WriteUint (b.B,uint64(v),true) - case uintptr : cjson.WriteUint (b.B,uint64(v),true) - case uint64 : cjson.WriteUint (b.B,v,true) - case int : cjson.WriteInt (b.B,int64(v),true) - case int8 : cjson.WriteInt (b.B,int64(v),true) - case int16 : cjson.WriteInt (b.B,int64(v),true) - case int32 : cjson.WriteInt (b.B,int64(v),true) - case int64 : cjson.WriteInt (b.B,v,true) - case float64 : cjson.WriteFloat (b.B,v,64,true) - case float32 : cjson.WriteFloat (b.B,float64(v),32,true) - case time.Time : cjson.WriteTime (b.B,v,b.f.DateFormat(),true) - case time.Duration : cjson.WriteInt (b.B,int64(v),true) + case bool : cjson.WriteBool (b.B,v) + case uint : cjson.WriteUint (b.B,uint64(v)) + case uint8 : cjson.WriteUint (b.B,uint64(v)) + case uint16 : cjson.WriteUint (b.B,uint64(v)) + case uint32 : cjson.WriteUint (b.B,uint64(v)) + case uintptr : cjson.WriteUint (b.B,uint64(v)) + case uint64 : cjson.WriteUint (b.B,v) + case int : cjson.WriteInt (b.B,int64(v)) + case int8 : cjson.WriteInt (b.B,int64(v)) + case int16 : cjson.WriteInt (b.B,int64(v)) + case int32 : cjson.WriteInt (b.B,int64(v)) + case int64 : cjson.WriteInt (b.B,v) + case float64 : cjson.WriteFloat (b.B,v,64) + case float32 : cjson.WriteFloat (b.B,float64(v),32) + case time.Time : cjson.WriteTime (b.B,v,b.f.DateFormat()) + case time.Duration : cjson.WriteInt (b.B,int64(v)) case error : if ec,is := v.(errs.ErrCoder); is { b.packString(ec.Code(),apack.FlagScapeHTML) @@ -86,8 +84,7 @@ func (s *keyStringer) packStringifyKey (b *Builder, key any) { } b.packString(v.Error(),apack.FlagScapeHTML) - - default: + default: me := &rMapEntry{ v: reflect.ValueOf(key) } fn := g.keyStringer.getOrBuildStringer(me.v.Type()) @@ -113,7 +110,7 @@ func (s *keyStringer) getOrBuildStringer(rtype reflect.Type) rMapEntryFnc { fn := s.checkInterfaces(rtype) if fn == nil { - fn = s.interfaceStringer(rtype) + fn = s.defaultStringer } s.RUnlock() @@ -128,84 +125,18 @@ func (s *keyStringer) getOrBuildStringer(rtype reflect.Type) rMapEntryFnc { -func (s *keyStringer) interfaceStringer(rtype reflect.Type) rMapEntryFnc { - - if rtype.Kind() == reflect.String { - return func(e *rMapEntry, v reflect.Value) error { - e.k = v.String() - e.f = apack.FlagScapeHTML - return nil - } - } - - - if rtype.Implements(g.stringifyType) { - return func(e *rMapEntry, v reflect.Value) error { - if v.Elem().Type().Kind() == reflect.Pointer && v.Elem().IsNil() { - return nil - } - e.k = (v.Interface().(stringify)).String() - e.f = apack.FlagScapeHTML - return nil - } - } +func (s *keyStringer) defaultStringer(e *rMapEntry, k reflect.Value) error { + k = k.Elem() - if rtype.Implements(g.textMarshalerType) { - return func(e *rMapEntry, v reflect.Value) error { - if v.Elem().Type().Kind() == reflect.Pointer && v.Elem().IsNil() { - return nil - } - bf, er := (v.Interface().(encoding.TextMarshaler)).MarshalText() - if er == nil { - e.k = string(bf) - e.f = apack.FlagScapeHTML - } - return er - } + fn := s.stringers[k.Type()] + if fn != nil { + return fn(e,k) } - - return func(e *rMapEntry, k reflect.Value) error { - k = k.Elem() - - switch k.Kind() { - - case reflect.String: - e.k = k.String() - return nil - - case reflect.Bool: - e.k = strconv.FormatBool(k.Bool()) - return nil - - case reflect.Int, - reflect.Int8, - reflect.Int16, - reflect.Int32, - reflect.Int64: - e.k = strconv.FormatInt(k.Int(), 10) - return nil - - case reflect.Uint, - reflect.Uint8, - reflect.Uint16, - reflect.Uint32, - reflect.Uint64, - reflect.Uintptr: - e.k = strconv.FormatUint(k.Uint(), 10) - return nil - - case reflect.Float32: - e.k = cjson.JSONFloat(k.Float(),32) - return nil - case reflect.Float64: - e.k = cjson.JSONFloat(k.Float(),64) - return nil - - default: - return apack.G.ErrInvalidKey.WithMessageF("%s", k.String()) - } + if fn = s.checkInterfaces(k.Type()); fn != nil { + return fn(e,k) } + return apack.G.ErrInvalidKey.WithMessageF("%s", k.String()) } @@ -222,6 +153,7 @@ func (s *keyStringer) RegKeyStringer (rtype reflect.Type, stringerFn rMapEntryFn func (s *keyStringer) RegInterfaceChecker (checkfn ... func(p reflect.Type) rMapEntryFnc) { s.ifaceCheckers = append(s.ifaceCheckers,checkfn ...) } + func (s *keyStringer) checkInterfaces (rtype reflect.Type) rMapEntryFnc { for _,cf := range s.ifaceCheckers { if fn := cf(rtype); fn != nil { @@ -230,4 +162,3 @@ func (s *keyStringer) checkInterfaces (rtype reflect.Type) rMapEntryFnc { } return nil } - diff --git a/base/apack/pkjson/packer.go b/base/apack/pkjson/packer.go index 922b85d..1f92991 100644 --- a/base/apack/pkjson/packer.go +++ b/base/apack/pkjson/packer.go @@ -26,12 +26,7 @@ package pkjson import ( "apack" - "apack/pstate" - "cdcs/cjson" - "reflect" "rsls" - "sync" - "time" ) @@ -47,9 +42,7 @@ type ( func NewPacker (options ...PackerFnc) *Packer { - p := &Packer { - - } + p := &Packer {} for _,o:=range options { o(p) } @@ -73,246 +66,3 @@ func (p Packer) Pack (value any) rsls.Bytes { - -func (b *Builder) packString (value string, flags apack.Flags) { - if len(value) == 0 { - b.B.Write2Byte('"','"') - return - } - if flags.Encrypted() { - b.packEncrypted([]byte(value),flags) - return - } - if flags.Binary() { - b.packBinary([]byte(value),flags) - return - } - cjson.WriteString(b.B,value,flags.EscapeHTML()) -} - -func (b *Builder) packEncrypted (value []byte, flags apack.Flags) { - if b.Encrypter == nil { - b.SetError(apack.G.ErrInvalidEncrypter) - return - } - rs := b.Encrypter.Encrypt(value) - if !rs.Ok() { - b.SetError(rs.Fail()) - return - } - if !flags.Binary() { - flags|=apack.FlagBinary64 - } - b.packBinary (rs.Value(),flags) -} - -func (b *Builder) packBinary (value []byte, flags apack.Flags) { - if flags.Bin64() { - b.SetError(cjson.WriteBase64(b.B,value)) - return - } - if flags.Bin32() { - b.SetError(cjson.WriteBase64(b.B,value)) - return - } -} - - - -func packListString (p *Builder, list []string, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - p.packString(v, flags) - if p.Err != nil { - return - } - } - }) -} - - -func packListError (p *Builder, list []error, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - if v == nil { - b.B.WOQ(true,'"',cjson.G.NullValue) - continue - } - p.packString(v.Error(), apack.FlagScapeHTML) - } - }) -} - - -func packListBool (p *Builder, list []bool, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - cjson.WriteBool(p.B,v,flags.Quote()) - } - }) -} - - -func packListInt [T int | int8 | int16 | int32 | int64 | time.Duration](p *Builder, list []T, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - cjson.WriteInt(p.B,int64(v),flags.Quote()) - } - }) -} - - -func packListUInt [T uint | uint8 | uint16 | uint32 | uint64|uintptr](p *Builder, list []T, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - cjson.WriteUint(p.B,uint64(v),flags.Quote()) - } - }) -} - - -func packListFloat[T float32 | float64](p *Builder, list []T, flags apack.Flags, bits int) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - cjson.WriteFloat(p.B,float64(v),bits,flags.Quote()) - } - }) -} - - -func packListDate (p *Builder, list []time.Time, flags apack.Flags) { - p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){ - for i,v := range list { - if i > 0 { - p.B.WriteByte(sep) - } - cjson.WriteTime(p.B,v,flags.DateFormat(),flags.Quote()) - } - }) -} - - -func packReflected(rtype reflect.Type) func (b *Builder, v reflect.Value) { - if fn,hs := g.packersCache.Load(rtype); hs { - return fn.(func (builder *Builder,value reflect.Value)) - } - var wg sync.WaitGroup - var fn func(*Builder, reflect.Value) - - wg.Add(1) - - fi,ld := g.packersCache.LoadOrStore(rtype,func(builder *Builder, value reflect.Value){ - wg.Wait() - fn(builder,value) - }) - if ld { - return fi.(func(builder *Builder, value reflect.Value)) - } - - fn = makePackReflectedFn(rtype) - wg.Done() - - g.packersCache.Store(rtype,fn) - return fn -} - - -func makePackReflectedFn(rtype reflect.Type) func(b *Builder, v reflect.Value) { - switch rtype.Kind() { - - case reflect.Bool : return func(b *Builder, v reflect.Value) { b.Bool(v.Bool()) } - - case reflect.String : return func(b *Builder, v reflect.Value) { b.String(v.String()) } - - case reflect.Int, - reflect.Int8, - reflect.Int16, - reflect.Int32, - reflect.Int64 : return func(b *Builder, v reflect.Value) { b.Int64(v.Int()) } - - case reflect.Uint, - reflect.Uint8, - reflect.Uint16, - reflect.Uint32, - reflect.Uint64, - reflect.Uintptr : return func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) } - - case reflect.Float32: return func(b *Builder, v reflect.Value) { b.float(v.Float(),32) } - case reflect.Float64: return func(b *Builder, v reflect.Value) { b.float(v.Float(),64) } - - case reflect.Pointer: - eleFn := packReflected(rtype.Elem()) - return func(b *Builder, v reflect.Value) { - if v.IsNil() { - b.B.W(cjson.G.NullValue) - return - } - b.Level++ - if b.Level > maxCyclesAfter { - if fn,ok := b.CheckCycle(v.Interface()); ok { - defer fn() - } else { - return - } - } - eleFn(b,v.Elem()) - b.Level-- - } - - case reflect.Interface: - return func(b *Builder, v reflect.Value) { - if v.IsNil() { - b.B.W(cjson.G.NullValue) - return - } - /* - if v.Elem().IsNil() { - packReflectedInvalid(b,v.Elem()) - return - } - - */ - packReflected(v.Elem().Type())(b,v.Elem()) - } - - case reflect.Slice, - reflect.Array: - return (*newRList(rtype)).pack - - case reflect.Map : - return (*newRMap(rtype)).pack - - - case reflect.Struct: - return (*newRObject(rtype)).pack - - default: - return packReflectedInvalid - } -} - - - - - - -func packReflectedInvalid (b *Builder, _ reflect.Value) { - b.SetError(apack.G.ErrInvalidValue) } \ No newline at end of file diff --git a/base/apack/pkjson/reflected.go b/base/apack/pkjson/reflected.go new file mode 100644 index 0000000..ed34041 --- /dev/null +++ b/base/apack/pkjson/reflected.go @@ -0,0 +1,144 @@ +// ------------------------------------------------------------------------ +// 🚀 Project active3 +// 🔗 Active Thing (activething.com) git.activething.com/go +// +// File name reflected.go +// ✍️ Created by DEV +// 📅 Modified 25/05/2024 +// +// 🔒 Copyright 2024 activething.com +// +// 📜 LICENSE -------------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package pkjson + +import ( + "apack" + "cdcs/cjson" + "reflect" + "sync" +) + + +type ( + + PackReflectedFnc func(b *Builder, v reflect.Value) +) + + +func packReflected(rtype reflect.Type) PackReflectedFnc { + if fn,hs := g.packersCache.Load(rtype); hs { + return fn.(func(b *Builder, v reflect.Value)) + } + var wg sync.WaitGroup + var fn func(*Builder, reflect.Value) + + wg.Add(1) + + fs := PackReflectedFnc(func(builder *Builder, value reflect.Value){ + wg.Wait() + fn(builder,value) + }) + + + fi,ld := g.packersCache.LoadOrStore(rtype,fs) + if ld { + return fi.(PackReflectedFnc) + } + + fn = makePackReflectedFn(rtype) + wg.Done() + + g.packersCache.Store(rtype,fn) + return fn +} + + +func makePackReflectedFn(rtype reflect.Type) PackReflectedFnc { + switch rtype.Kind() { + + case reflect.Bool : return func(b *Builder, v reflect.Value) { b.Bool(v.Bool()) } + + case reflect.String : return func(b *Builder, v reflect.Value) { b.String(v.String()) } + + case reflect.Int, + reflect.Int8, + reflect.Int16, + reflect.Int32, + reflect.Int64 : return func(b *Builder, v reflect.Value) { b.Int64(v.Int()) } + + case reflect.Uint, + reflect.Uint8, + reflect.Uint16, + reflect.Uint32, + reflect.Uint64, + reflect.Uintptr : return func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) } + + case reflect.Float32: return func(b *Builder, v reflect.Value) { b.float(v.Float(),32) } + case reflect.Float64: return func(b *Builder, v reflect.Value) { b.float(v.Float(),64) } + + case reflect.Pointer: + eleFn := packReflected(rtype.Elem()) + return func(b *Builder, v reflect.Value) { + if v.IsNil() { + b.B.W(cjson.G.NullValue) + return + } + b.Level++ + if b.Level > maxCyclesAfter { + if fn,ok := b.CheckCycle(v.Interface()); ok { + defer fn() + } else { + return + } + } + eleFn(b,v.Elem()) + b.Level-- + } + + case reflect.Interface: + return func(b *Builder, v reflect.Value) { + if v.IsNil() { + b.B.W(cjson.G.NullValue) + return + } + packReflected(v.Elem().Type())(b,v.Elem()) + } + + case reflect.Slice, + reflect.Array: + return (*newRList(rtype)).pack + + case reflect.Map : + return (*newRMap(rtype)).pack + + + case reflect.Struct: + return (*newRObject(rtype)).pack + + default: + return packReflectedInvalid + } +} + + + + + + +func packReflectedInvalid (b *Builder, _ reflect.Value) { + b.SetError(apack.G.ErrInvalidValue) } + + diff --git a/base/apack/pkjson/reflected_map.go b/base/apack/pkjson/reflected_map.go index 67e5a5e..e68ce3a 100644 --- a/base/apack/pkjson/reflected_map.go +++ b/base/apack/pkjson/reflected_map.go @@ -86,7 +86,8 @@ func (m *rMap) pack (builder *Builder, value reflect.Value) { builder.makeLevel(pstate.ModeMap,false,len(ls)==0,func (b *Builder){ for i:=0; i0) - b.B.WriteString(ls[i].k) + b.packString(ls[i].k,0) + //b.B.WriteString(ls[i].k) b.B.WriteByte(':') b.Current.IsValue = true m.packFn(b,ls[i].v) diff --git a/core/cdcs/cjson/active.go b/core/cdcs/cjson/active.go index 8d04637..e30c3ed 100644 --- a/core/cdcs/cjson/active.go +++ b/core/cdcs/cjson/active.go @@ -52,8 +52,8 @@ var ( NullValue: []byte{'n', 'u', 'l', 'l'}, ZeroValue: []byte{'0'}, EmptyValue: []byte{'"','"'}, - TrueValue: []byte{'"','t', 'r', 'u', 'e','"'}, - FalseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'}, + TrueValue: []byte{'t', 'r', 'u', 'e'}, + FalseValue: []byte{'f', 'a', 'l', 's', 'e'}, FloatNaN: []byte{'"', 'N', 'a', 'N', '"'}, FloatInfPos: []byte{'"', 'I', 'n', 'f', '"'}, diff --git a/core/cdcs/cjson/writer.go b/core/cdcs/cjson/writer.go index 45cd030..88e77d5 100644 --- a/core/cdcs/cjson/writer.go +++ b/core/cdcs/cjson/writer.go @@ -27,8 +27,6 @@ import ( "bfrs" "cdcs/base32" "cdcs/base64" - "math" - "strconv" "time" "unicode/utf8" ) @@ -102,86 +100,44 @@ func WriteString(b *bfrs.ABuffer, value string, escapeHTML bool ) { -func WriteUint (b *bfrs.ABuffer, value uint64 , quoted bool) { - if quoted { - b.WriteByte('"') - } +func WriteUint (b *bfrs.ABuffer, value uint64) { if value == 0 { b.WriteByte('0') - } else { - b.WriteUIntStr(value, 10) - } - if quoted { - b.WriteByte('"') + return } + b.WriteUIntStr(value, 10) } -func WriteBool (b *bfrs.ABuffer, value bool , quoted bool) { +func WriteBool (b *bfrs.ABuffer, value bool) { if value { - b.WOQ(quoted,'"', G.TrueValue) - } else { - b.WOQ(quoted,'"', G.FalseValue) + b.W(G.TrueValue) + return } + b.W(G.FalseValue) } -func WriteInt (b *bfrs.ABuffer, value int64 , quoted bool) { - if quoted { - b.WriteByte('"') - } +func WriteInt (b *bfrs.ABuffer, value int64) { if value == 0 { b.WriteByte('0') } else { b.WriteIntStr(value, 10) } - if quoted { - b.WriteByte('"') - } } -func WriteFloat (b *bfrs.ABuffer, f float64, bits int, quoted bool) { - var t [64]byte - if math.IsInf(f, 0) || math.IsNaN(f) { - _,_ = b.Write(G.FloatNaN) - return - } - - abs := math.Abs(f) - fm := byte('f') - - if abs != 0 { - if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { - fm = 'e' - } - } - bf := t[:0] - bf = strconv.AppendFloat(bf, f, fm, -1, int(bits)) - if fm == 'e' { - // clean up e-09 to e-9 - n := len(bf) - if n >= 4 && bf[n-4] == 'e' && bf[n-3] == '-' && bf[n-2] == '0' { - bf[n-2] = bf[n-1] - bf = bf[:n-1] - } - } - - b.WOQ(quoted,'"',bf) -} +func WriteFloat (b *bfrs.ABuffer, f float64, bits int) { + b.WriteString(JSONFloat(f,bits)) } -func WriteTime(b *bfrs.ABuffer, value time.Time, layout string, quote bool) { +func WriteTime(b *bfrs.ABuffer, value time.Time, layout string) { if layout == "" { layout = time.RFC3339 } - if quote { - b.WriteByte('"') - } + b.WriteByte('"') b.WriteDateStr(value,layout) - if quote { - b.WriteByte('"') - } + b.WriteByte('"') } @@ -190,4 +146,6 @@ func WriteBase64(b *bfrs.ABuffer, value []byte) (er error) { func WriteBase32(b *bfrs.ABuffer, value []byte) (er error) { - return base32.Write(b,value,G.NullValue,G.EmptyValue,true,'"') } \ No newline at end of file + return base32.Write(b,value,G.NullValue,G.EmptyValue,true,'"') } + + diff --git a/core/errs/efjson/json_builder.go b/core/errs/efjson/json_builder.go index 73a1197..76efd88 100644 --- a/core/errs/efjson/json_builder.go +++ b/core/errs/efjson/json_builder.go @@ -306,7 +306,7 @@ func (b *jsonBuilder) writeFieldValue (field flds.Field, level int) bool { if v == 0 && b.f.HasIgnoreDefaults() { return false } - cjson.WriteFloat(b.b,v,64,b.f.HasUseQuote()) + cjson.WriteFloat(b.b,v,64) return true case flds.KindInt: @@ -314,7 +314,7 @@ func (b *jsonBuilder) writeFieldValue (field flds.Field, level int) bool { if v == 0 && b.f.HasIgnoreDefaults() { return false } - cjson.WriteInt(b.b,int64(v),b.f.HasUseQuote()) + cjson.WriteInt(b.b,int64(v)) return true case flds.KindString: @@ -330,7 +330,7 @@ func (b *jsonBuilder) writeFieldValue (field flds.Field, level int) bool { if v.IsZero() && b.f.HasIgnoreDefaults(){ return false } - cjson.WriteTime(b.b,v,b.f.TimeLayout,true) + cjson.WriteTime(b.b,v,b.f.TimeLayout) return true case flds.KindDuration: @@ -338,7 +338,7 @@ func (b *jsonBuilder) writeFieldValue (field flds.Field, level int) bool { if v == 0 && b.f.HasIgnoreDefaults(){ return false } - cjson.WriteInt(b.b,int64(v),b.f.HasUseQuote()) + cjson.WriteInt(b.b,int64(v)) return true case flds.KindBool: @@ -346,7 +346,7 @@ func (b *jsonBuilder) writeFieldValue (field flds.Field, level int) bool { if !v && b.f.HasIgnoreDefaults() { return false } - cjson.WriteBool(b.b,v,b.f.HasUseQuote()) + cjson.WriteBool(b.b,v) return true case flds.KindBinary: