redefiniendo el builder

packs2
DEV 3 years ago
parent 8c2c4c1a67
commit 9dfaa3659d

@ -28,7 +28,6 @@ import (
"activething.com/go/gogo/packs"
"activething.com/go/gogo/packs/pjson"
"fmt"
"time"
)
func main() {
@ -36,17 +35,23 @@ func main() {
pk := pjson.NewPacker()
slc := [][]int16 {[]int16{1,2,3,4},[]int16{16,26,36,46}}
pk.PackMap(func(mp packs.MapPacker) {
mp.KeyValueBool("boolean",true)
mp.KeyValueBinary("binary",[]byte{22,121,21,23,23,54,67})
//mp.KeyValueBool("boolean",true)
//mp.KeyValueBinary("binary",[]byte{22,121,21,23,23,54,67})
//mp.KeyValueDate("date",time.Now())
//mp.KeyValueInt16("<unakey>",34)
mp.KeyValueDate("date",time.Now())
mp.KeyValueInt16("<unakey>",34)
mp.KeyValueObject("MiObjeto",func(op packs.ObjectPacker){
op.FieldFloat64("23",43433.3)
op.FieldString("3","dfsdfsd<fdf}{43433.3")
op.FieldFloat64("fb1",43433.3)
op.FieldString ("fb2","aaaaa")
op.Field("fb3",slc)
})
})

@ -118,9 +118,9 @@ func getStackTrace(err error) StackTrace {
func Test(err error, halt bool) {
if err != nil {
fmt.Printf("err %v\n", err.Error())
ei := NewErrInfo(err,ErrInfoWithStack())
if halt {
panic(err)
panic(ei)
}
}
}

@ -83,6 +83,9 @@ func (f StackTraceFrame) getFunc(cls bool) string {
return unknown
}
/*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@ -27,6 +27,7 @@ import (
"activething.com/go/gogo/core/bins"
"activething.com/go/gogo/core/slices"
"activething.com/go/gogo/core/syncs"
"fmt"
"sync/atomic"
)
@ -82,8 +83,6 @@ func ReleaseState (state *State) {
}
func (s *State) SetError(err error) bool {
if s.Error != nil {
return true
@ -117,7 +116,7 @@ func (s *State) Open(kind NodeKind) bool {
}
if s.Node.Kind == NodeKindValue {
if s.Node.Count > 0 {
if s.Node.Start > s.Len() {
return !s.SetError(G.ErrInvalidNode)
}
s.Node.Init(s.Node.Parent, kind, s.Len())
@ -141,6 +140,8 @@ func (s *State) Close() bool {
G.nodePool.Put(p.Reset())
}
s.Node.Count++
fmt.Printf("Level %d Count %d\n",s.Node.Level,s.Node.Count)
return true
}

@ -24,36 +24,45 @@
package pjson
import (
"activething.com/go/gogo/packets"
"activething.com/go/gogo/packs"
"fmt"
"time"
)
func (p *Packer) Item (value any) { p.addSep().Pack(value) }
func (p *Packer) Item (value any) { p.addItem().Pack(value) }
func (p *Packer) ItemRaw (value []byte) { p.addSep().PackRaw(value) }
func (p *Packer) ItemRaw (value []byte) { p.addItem().PackRaw(value) }
func (p *Packer) ItemBinary (value []byte) { p.addSep().PackBinary(value) }
func (p *Packer) ItemString (value string) { p.addSep().PackString(value) }
func (p *Packer) ItemBinary (value []byte) { p.addItem().PackBinary(value) }
func (p *Packer) ItemString (value string) { p.addItem().PackString(value) }
func (p *Packer) ItemBool (value bool) { p.addSep().PackBool(value) }
func (p *Packer) ItemBool (value bool) { p.addItem().PackBool(value) }
func (p *Packer) ItemInt8 (value int8) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt16 (value int16) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt32 (value int32) { p.addSep().PackInt64(int64(value)) }
func (p *Packer) ItemInt64 (value int64) { p.addSep().PackInt64(value) }
func (p *Packer) ItemInt8 (value int8) { p.addItem().PackInt64(int64(value)) }
func (p *Packer) ItemInt16 (value int16) { p.addItem().PackInt64(int64(value)) }
func (p *Packer) ItemInt32 (value int32) { p.addItem().PackInt64(int64(value)) }
func (p *Packer) ItemInt64 (value int64) { p.addItem().PackInt64(value) }
func (p *Packer) ItemUInt8 (value uint8) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt16 (value uint16) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt32 (value uint32) { p.addSep().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt64 (value uint64) { p.addSep().PackUInt64(value) }
func (p *Packer) ItemUInt8 (value uint8) { p.addItem().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt16 (value uint16) { p.addItem().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt32 (value uint32) { p.addItem().PackUInt64(uint64(value)) }
func (p *Packer) ItemUInt64 (value uint64) { p.addItem().PackUInt64(value) }
func (p *Packer) ItemFloat32 (value float32) { p.addSep().PackFloat64(float64(value))}
func (p *Packer) ItemFloat64 (value float64) { p.addSep().PackFloat64(value) }
func (p *Packer) ItemFloat32 (value float32) { p.addItem().PackFloat64(float64(value))}
func (p *Packer) ItemFloat64 (value float64) { p.addItem().PackFloat64(value) }
func (p *Packer) ItemDate (value time.Time) { p.addSep().PackDate(value) }
func (p *Packer) ItemDate (value time.Time) { p.addItem().PackDate(value) }
func (p *Packer) ItemList (builder func(packer packs.ListPacker)) { p.addSep().ItemList (builder) }
func (p *Packer) ItemMap (builder func(packer packs.MapPacker )) { p.addSep().ItemMap (builder) }
func (p *Packer) ItemObject(builder func(packer packs.ObjectPacker)) { p.addSep().ItemObject(builder) }
func (p *Packer) ItemList (builder func(packer packs.ListPacker)) { p.addItem().ItemList (builder) }
func (p *Packer) ItemMap (builder func(packer packs.MapPacker )) { p.addItem().ItemMap (builder) }
func (p *Packer) ItemObject(builder func(packer packs.ObjectPacker)) { p.addItem().ItemObject(builder) }
func (p *Packer) addItem () *Packer {
if p.state.Node.Count > 0 {
_ = p.state.WriteByte(',')
}
p.state.Node.Count++
fmt.Printf("Set %d.%d\n",p.state.Node.Level,p.state.Node.Count)
return p
}

@ -24,7 +24,7 @@
package pjson
import (
"activething.com/go/gogo/packets"
"activething.com/go/gogo/packs"
"time"
)

@ -24,7 +24,7 @@
package pjson
import (
"activething.com/go/gogo/packets"
"activething.com/go/gogo/packs"
"time"
)

@ -36,7 +36,7 @@ type (
func (o *Options) reset () {
o.Flags = JSONFlagEscapeHTML | JSONFlagQuote
o.Flags = JSONFlagEscapeHTML | JSONFlagQuote | JSONFlagResetOnRead | JSONByteSliceAsBinary
o.dateLayout = time.RFC822Z
}

@ -31,10 +31,13 @@ const (
JSONFlagIgnoreKeys
JSONFlagQuoteNumbers
JSONFlagIgnoreDefaults
JSONByteSliceAsBinary
JSONFlagResetOnRead
)
type Flags uint8
type Flags uint16
@ -59,3 +62,11 @@ func (o Flags) IgnoreDefaults() bool {
return o&JSONFlagIgnoreDefaults != 0
}
func (o Flags) ByteSliceAsBinary() bool {
return o&JSONByteSliceAsBinary != 0
}
func (o Flags) ResetOnRead() bool {
return o&JSONFlagResetOnRead != 0
}

@ -30,17 +30,21 @@ import (
"activething.com/go/gogo/packs"
"encoding/base64"
"encoding/json"
"fmt"
"reflect"
"time"
"unicode/utf8"
)
const notDetectingCycles = 100
type (
Packer struct {
options Options
state *packs.State
checks map[any]struct{}
}
@ -49,7 +53,7 @@ type (
func NewPacker (options ...opts.OptionFnc[Packer]) *Packer {
return opts.Apply(&Packer{
options: Options{
Flags: JSONFlagQuote | JSONFlagEscapeHTML,
Flags: JSONFlagQuote | JSONFlagEscapeHTML | JSONByteSliceAsBinary,
dateLayout: time.RFC822Z,
},
state : packs.NewState(),
@ -59,7 +63,9 @@ func NewPacker (options ...opts.OptionFnc[Packer]) *Packer {
func (p *Packer) Bytes () []byte {
defer p.Reset()
if p.options.ResetOnRead() {
defer p.Reset()
}
return append([]byte(nil),p.state.Bytes()...)
}
@ -83,13 +89,12 @@ func (p *Packer) Pack (value any) {
if value == nil {
if p.options.Quote() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Write(G.nullValue)
_,_ = p.state.Write(G.nullValue)
if p.options.Quote() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
return
}
@ -113,16 +118,17 @@ func (p *Packer) Pack (value any) {
case float32: p.packFloat(float64(v),32)
case float64: p.packFloat(v,64)
case time.Time : p.PackDate(v)
case reflect.Value : p.Pack(v.Elem())
default:
if pb,is := value.(packs.Packabler); is {
d,e := pb.Build(p)
d, e := pb.Build(p)
if p.state.SetError(e) {
return
}
_,_ = p.state.Write(d)
p.state.Node.Count++
_, _ = p.state.Write(d)
return
}
if ms,is := value.(json.Marshaler); is {
@ -131,26 +137,21 @@ func (p *Packer) Pack (value any) {
return
}
_,_ = p.state.Write(d)
p.state.Node.Count++
return
}
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Slice,reflect.Array :
case reflect.Slice, reflect.Array:
p.packListReflected(rv)
return
case reflect.Map :
case reflect.Map:
p.packMapReflected(rv)
return
case reflect.Struct:
p.packObjectReflected(rv)
return
default:
p.state.SetError(packs.G.ErrUnsupportedType)
}
p.state.SetError(packs.G.ErrUnsupportedType)
}
}
@ -173,7 +174,7 @@ func (p *Packer) PackRaw (value []byte) {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
//p.state.Node.Count++
}
@ -208,36 +209,34 @@ func (p *Packer) PackBinary (value []byte) {
}
_ = p.state.WriteByte('"')
p.state.Node.Count++
//p.state.Node.Count++
}
func (p *Packer) PackString (value string) {
func (p *Packer) PackString(value string) {
if p.state.Error != nil {
panic(p.state.Error)
}
if len(value) == 0 {
p.state.Write2Byte('"','"')
} else {
p.packString(value,p.options.EscapeHTML())
//p.state.Node.Count++
return
}
p.state.Node.Count++
}
func (p *Packer) packString(s string, scapeHTML bool) {
_ = p.state.WriteByte('"')
start := 0
for i := 0; i < len(s); {
if b := s[i]; b < utf8.RuneSelf {
if !G.jsonChars[b].isHtmlUnsafe() || (!scapeHTML && !G.jsonChars[b].isUnsafe()) {
for i := 0; i < len(value); {
if b := value[i]; b < utf8.RuneSelf {
if !G.jsonChars[b].isHtmlUnsafe() || (!p.options.EscapeHTML() && !G.jsonChars[b].isUnsafe()) {
i++
continue
}
if start < i {
_,_ = p.state.WriteString(s[start:i])
_,_ = p.state.WriteString(value[start:i])
}
_ = p.state.WriteByte('\\')
switch b {
@ -253,10 +252,10 @@ func (p *Packer) packString(s string, scapeHTML bool) {
start = i
continue
}
c, size := utf8.DecodeRuneInString(s[i:])
c, size := utf8.DecodeRuneInString(value[i:])
if c == utf8.RuneError && size == 1 {
if start < i {
_,_ = p.state.WriteString(s[start:i])
_,_ = p.state.WriteString(value[start:i])
}
_,_ = p.state.WriteString(`\ufffd`)
i += size
@ -266,7 +265,7 @@ func (p *Packer) packString(s string, scapeHTML bool) {
if c == '\u2028' || c == '\u2029' {
if start < i {
_,_ = p.state.WriteString(s[start:i])
_,_ = p.state.WriteString(value[start:i])
}
_,_ = p.state.WriteString(`\u202`)
_ = p.state.WriteByte(G.hex[c&0xF])
@ -276,10 +275,13 @@ func (p *Packer) packString(s string, scapeHTML bool) {
}
i += size
}
if start < len(s) {
_,_ = p.state.WriteString(s[start:])
if start < len(value) {
_,_ = p.state.WriteString(value[start:])
}
_ = p.state.WriteByte('"')
//p.state.Node.Count++
}
@ -303,7 +305,7 @@ func (p *Packer) PackBool (value bool) {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
//p.state.Node.Count++
}
func (p *Packer) PackInt8 (value int8) { p.PackInt64(int64(value)) }
@ -326,7 +328,7 @@ func (p *Packer) PackInt64 (value int64) {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
//p.state.Node.Count++
}
func (p *Packer) PackUInt8 (value uint8 ) { p.PackUInt64(uint64(value)) }
@ -349,7 +351,7 @@ func (p *Packer) PackUInt64 (value uint64) {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
//p.state.Node.Count++
}
func (p *Packer) PackFloat32 (value float32) { p.packFloat(float64(value),32) }
@ -372,7 +374,7 @@ func (p *Packer) packFloat (value float64, bits int) {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
//p.state.Node.Count++
}
@ -387,7 +389,7 @@ func (p *Packer) PackDate (value time.Time) {
}))
_ = p.state.WriteByte('"')
p.state.Node.Count++
//p.state.Node.Count++
}
@ -414,19 +416,12 @@ func (p *Packer) packCompound(kind packs.NodeKind, opening, closing byte, buildF
}
}(&dn)
//p.addSep()
if p.state.Open(kind) {
fmt.Printf("Node Count %d\n",p.state.Node.Count)
_ = p.state.WriteByte(opening)
/*
if !p.state.SetValue() {
panic(p.state.Error)
}
*/
buildFnc(p)
if p.state.Error == nil {
if p.state.Close() {
_ = p.state.WriteByte(closing)
@ -470,10 +465,10 @@ func (p *Packer) addKey (key any, call func(*Packer)) {
return
}
p.packString(ks,p.options.EscapeHTML())
p.PackString(ks)
_ = p.state.WriteByte(':')
call(p)
p.state.Node.Count++
}
@ -487,17 +482,87 @@ func (p *Packer) addField (name string, call func(*Packer)) {
return
}
p.packString(name,p.options.EscapeHTML())
p.PackString(name)
_ = p.state.WriteByte(':')
call(p)
p.state.Node.Count++
}
func (p *Packer) packListReflected (value reflect.Value) {
//todo
if value.IsNil() {
_,_ = p.state.Write(G.nullValue)
return
}
if value.Len() == 0 {
p.state.Write2Byte('[',']')
return
}
tp := value.Type()
if tp.Elem().Kind() == reflect.Uint8 && p.options.ByteSliceAsBinary() {
p.PackBinary(value.Bytes())
return
}
// Comprobamos las llamadas recursivas
/*
if p.state.Node.Level > notDetectingCycles {
rf := value.Interface()
if _,is := p.checks[rf]; is {
p.state.SetError(packs.G.ErrRedundantPack)
return
}
p.checks[rf]=struct{}{}
defer delete(p.checks,rf)
}
*/
switch tp.Elem().Kind() {
case reflect.String :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemString(rv.String()) })
case reflect.Bool :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemBool (rv.Bool()) })
case reflect.Uint8 ,
reflect.Uint16 ,
reflect.Uint32 ,
reflect.Uint64 :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemUInt64(rv.Uint()) })
case reflect.Int8 ,
reflect.Int16 ,
reflect.Int32 ,
reflect.Int64 :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemInt64(rv.Int()) })
case reflect.Float32,
reflect.Float64:
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemFloat64(rv.Float()) })
case reflect.Slice :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){
p.packListReflected(rv) // Llamamos recursivamente a packListReflected para cada elemento del slice
if p.state.Error != nil {
return
}
})
case reflect.Map :
case reflect.Struct :
}
}
func (p *Packer) buildList (value reflect.Value, call func(lp packs.ListPacker, rv reflect.Value)) {
p.PackList(func (lp packs.ListPacker){
for i:=0; i<value.Len(); i++ {
call(lp,value.Index(i))
if p.state.Error != nil {
return
}
}
})
}
func (p *Packer) packMapReflected (value reflect.Value) {
//todo
}

Loading…
Cancel
Save

Powered by TurnKey Linux.