restructurando el codigo para actualizar los packs con la nueva arquitectura del builder

master
DEV 2 years ago
parent 11a264d42b
commit 867a3cbd9b

@ -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

@ -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)

@ -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())
}
})
}

@ -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,7 +84,6 @@ func (s *keyStringer) packStringifyKey (b *Builder, key any) {
}
b.packString(v.Error(),apack.FlagScapeHTML)
default:
me := &rMapEntry{ v: reflect.ValueOf(key) }
@ -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
}
}
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
}
}
return func(e *rMapEntry, k reflect.Value) error {
func (s *keyStringer) defaultStringer(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())
fn := s.stringers[k.Type()]
if fn != nil {
return fn(e,k)
}
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
}

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

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

@ -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; i<len(ls); i++ {
b.writeSepIf(i>0)
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)

@ -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', '"'},

@ -27,8 +27,6 @@ import (
"bfrs"
"cdcs/base32"
"cdcs/base64"
"math"
"strconv"
"time"
"unicode/utf8"
)
@ -102,87 +100,45 @@ 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.WriteDateStr(value,layout)
if quote {
b.WriteByte('"')
}
}
func WriteBase64(b *bfrs.ABuffer, value []byte) (er error) {
@ -191,3 +147,5 @@ 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,'"') }

@ -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:

Loading…
Cancel
Save

Powered by TurnKey Linux.