redefiniendo el builder

packs2
DEV 3 years ago
parent 51dc2ab480
commit 9851697694

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import "time" import "time"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import "time" import "time"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import "time" import "time"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import "time" import "time"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import ( import (
"activething.com/go/gogo/core/bins" "activething.com/go/gogo/core/bins"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import ( import (
"activething.com/go/gogo/core/slices" "activething.com/go/gogo/core/slices"

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
const ( const (

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
import ( import (
"activething.com/go/gogo/core/errs" "activething.com/go/gogo/core/errs"

@ -45,7 +45,7 @@ type (
encoder *json.Encoder encoder *json.Encoder
dateLayout string dateLayout string
scratch [64]byte scratch [64]byte
state *packs.State state *__packs.State
} }
) )
@ -57,9 +57,9 @@ func NewBuilder(options ...opts.OptionFnc[Builder]) *Builder {
G.builderPool = syncs.NewPool[Builder]( G.builderPool = syncs.NewPool[Builder](
syncs.PoolWithNew[Builder](func() *Builder { syncs.PoolWithNew[Builder](func() *Builder {
return &Builder{ return &Builder{
options : jsonOptionsDefaults, options : jsonOptionsDefaults,
state : packs.NewState(), state : __packs.NewState(),
dateLayout: time.RFC822Z, dateLayout: time.RFC822Z,
} }
}), }),
) )
@ -95,13 +95,13 @@ func (b *Builder) Any (value any) {
func (b *Builder) BuildMap (builder func(packer packs.BuilderMap)) {} func (b *Builder) BuildMap (builder func(packer __packs.BuilderMap)) {}
func (b *Builder) BuildList(builder func(packer packs.BuilderList)) {} func (b *Builder) BuildList(builder func(packer __packs.BuilderList)) {}
func (b *Builder) BuildObject(builder func(packer packs.BuilderList)) {} func (b *Builder) BuildObject(builder func(packer __packs.BuilderList)) {}

@ -49,7 +49,7 @@ func (b *Builder) listPacker(rv reflect.Value) {
len: rv.Len(), len: rv.Len(),
} }
if _,ok := b.state.Seen[p]; ok { if _,ok := b.state.Seen[p]; ok {
b.state.SetError(packs.G.ErrRedundantPack) b.state.SetError(__packs.G.ErrRedundantPack)
return return
} }
b.state.Seen[p] = struct{}{} b.state.Seen[p] = struct{}{}
@ -57,48 +57,48 @@ func (b *Builder) listPacker(rv reflect.Value) {
} }
switch rv.Type().Elem().Kind() { switch rv.Type().Elem().Kind() {
case reflect.String: b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemString(ev.String()) }) case reflect.String: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemString(ev.String()) })
case reflect.Bool : b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemBool(ev.Bool()) }) case reflect.Bool : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemBool(ev.Bool()) })
case reflect.Int8, case reflect.Int8,
reflect.Int16, reflect.Int16,
reflect.Int32, reflect.Int32,
reflect.Int64, reflect.Int64,
reflect.Int : b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemInt64(ev.Int()) }) reflect.Int : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemInt64(ev.Int()) })
case reflect.Uint8, case reflect.Uint8,
reflect.Uint16, reflect.Uint16,
reflect.Uint32, reflect.Uint32,
reflect.Uint64, reflect.Uint64,
reflect.Uint : b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemUInt64(ev.Uint()) }) reflect.Uint : b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemUInt64(ev.Uint()) })
case reflect.Float32, case reflect.Float32,
reflect.Float64: b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemFloat64(ev.Float()) }) reflect.Float64: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemFloat64(ev.Float()) })
case reflect.Complex64, case reflect.Complex64,
reflect.Complex128: b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemComplex128(ev.Complex()) }) reflect.Complex128: b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemComplex128(ev.Complex()) })
case reflect.Map: case reflect.Map:
b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) }) b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
case reflect.Struct: case reflect.Struct:
if rv.Type() == reflect.TypeOf(time.Time{}) { if rv.Type() == reflect.TypeOf(time.Time{}) {
b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemDate(rv.Interface().(time.Time)) }) b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemDate(rv.Interface().(time.Time)) })
return return
} }
b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) }) b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
case reflect.Array, case reflect.Array,
reflect.Slice : reflect.Slice :
b._listPacker (rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) }) b._listPacker (rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
default: default:
b._listPacker(rv, func(lb packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) }) b._listPacker(rv, func(lb __packs.BuilderList, ev reflect.Value) { lb.ItemAny(rv.Interface()) })
} }
} }
func (b *Builder) _listPacker (list reflect.Value, pack func(lb packs.BuilderList, ev reflect.Value)) { func (b *Builder) _listPacker (list reflect.Value, pack func(lb __packs.BuilderList, ev reflect.Value)) {
b.BuildList(func(l packs.BuilderList) { b.BuildList(func(l __packs.BuilderList) {
for i := 0; i < list.Len(); i++ { for i := 0; i < list.Len(); i++ {
pack(l, list.Index(i)) pack(l, list.Index(i))
if b.state.Error != nil { if b.state.Error != nil {

@ -41,7 +41,7 @@ func (b *Builder) mapPacker (rv reflect.Value) {
if b.state.Node.Level > maxDeepUncheck { if b.state.Node.Level > maxDeepUncheck {
p := rv.UnsafePointer() p := rv.UnsafePointer()
if _,ok := b.state.Seen[p]; ok { if _,ok := b.state.Seen[p]; ok {
b.state.SetError(packs.G.ErrRedundantPack) b.state.SetError(__packs.G.ErrRedundantPack)
return return
} }
b.state.Seen[p] = struct{}{} b.state.Seen[p] = struct{}{}
@ -56,7 +56,7 @@ func (b *Builder) mapPacker (rv reflect.Value) {
ls[i].k = mi.Key() ls[i].k = mi.Key()
ls[i].v = mi.Value() ls[i].v = mi.Value()
if !ls[i].stringifyKey(b.options) { if !ls[i].stringifyKey(b.options) {
b.state.SetError(packs.G.ErrInvalidKey) b.state.SetError(__packs.G.ErrInvalidKey)
return return
} }
} }
@ -64,7 +64,7 @@ func (b *Builder) mapPacker (rv reflect.Value) {
sort.Slice(ls, func(i, j int) bool { return ls[i].s < ls[j].s }) sort.Slice(ls, func(i, j int) bool { return ls[i].s < ls[j].s })
} }
b.Map(func(bm packs.BuilderMap) { b.Map(func(bm __packs.BuilderMap) {
for _, e := range ls { for _, e := range ls {
bm.ElemAny(e.s, e.v) bm.ElemAny(e.s, e.v)
if b.state.Error != nil { if b.state.Error != nil {
@ -75,7 +75,7 @@ func (b *Builder) mapPacker (rv reflect.Value) {
return return
} }
b.Map(func(bm packs.BuilderMap) { b.Map(func(bm __packs.BuilderMap) {
for i:=0; mi.Next(); i++ { for i:=0; mi.Next(); i++ {
bm.ElemAny(mi.Key(),mi.Value()) bm.ElemAny(mi.Key(),mi.Value())
if b.state.Error != nil { if b.state.Error != nil {

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
type ( type (

@ -21,7 +21,7 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package packs package __packs
type ( type (

@ -25,17 +25,34 @@ package main
import ( import (
"activething.com/go/gogo/core/errs" "activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packs/jjson" "activething.com/go/gogo/packets"
"activething.com/go/gogo/packets/pjson"
"fmt" "fmt"
"time"
) )
func main() { func main() {
p := jjson.JSONPacker{} pk := pjson.NewPacker()
d,e := p.Pack(22)
errs.Test(e,false)
fmt.Printf("Data = %s\n",d) pk.PackMap(func(mp packets.MapPacker) {
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.KeyValueObject("MiObjeto",func(op packets.ObjectPacker){
op.FieldFloat64("23",43433.3)
op.FieldString("3","dfsdfsd<fdf}{43433.3")
})
})
errs.Test(pk.Error(),true)
fmt.Printf("JSON \n%s",pk.Bytes())
} }

@ -9,7 +9,6 @@ use (
./core/errs ./core/errs
./core/opts ./core/opts
./core/syncs ./core/syncs
./packs
./packets ./packets
) )

@ -46,7 +46,7 @@ var (
ErrRedundantPack errs.ErrCode ErrRedundantPack errs.ErrCode
ErrInvalidValue errs.ErrCode ErrInvalidValue errs.ErrCode
}{ }{
ErrInvalidNode : errs.ErrCode("packs.invalid-StateNode"), ErrInvalidNode : errs.ErrCode("packs.invalid-node"),
ErrInvalidElement: errs.ErrCode("packs.invalid-element"), ErrInvalidElement: errs.ErrCode("packs.invalid-element"),
ErrInvalidKey : errs.ErrCode("packs.invalid-key"), ErrInvalidKey : errs.ErrCode("packs.invalid-key"),
ErrDuplicatedKey : errs.ErrCode("packs:duplicated-key"), ErrDuplicatedKey : errs.ErrCode("packs:duplicated-key"),

@ -51,7 +51,7 @@ type (
ItemFloat32 (value float32) ItemFloat32 (value float32)
ItemFloat64 (value float64) ItemFloat64 (value float64)
ItemDate (value time.Time) ItemDate (value time.Time)
ItemList (builder func(packer ListPacker)) ItemList (builder func(packer ListPacker))
ItemMap (builder func(packer MapPacker )) ItemMap (builder func(packer MapPacker ))

@ -31,10 +31,10 @@ type (
KeyValue (key any, value any) KeyValue (key any, value any)
KeyValueRaw (value []byte) KeyValueRaw (key any,value []byte)
KeyValueBinary (key any, value []byte) KeyValueBinary(key any, value []byte)
KeyValueString (key any, value string) KeyValueString(key any, value string)
KeyValueBool (key any, value bool) KeyValueBool (key any, value bool)
@ -48,14 +48,14 @@ type (
KeyValueUInt32 (key any, value uint32) KeyValueUInt32 (key any, value uint32)
KeyValueUInt64 (key any, value uint64) KeyValueUInt64 (key any, value uint64)
KeyValueFloat32 (key any, value float32) KeyValueFloat32(key any, value float32)
KeyValueFloat64 (key any, value float64) KeyValueFloat64(key any, value float64)
KeyValueDate (key any, value time.Time) KeyValueDate (key any, value time.Time)
KeyValueList (builder func(packer ListPacker)) KeyValueList (key any, builder func(packer ListPacker))
KeyValueMap (builder func(packer MapPacker )) KeyValueMap (key any, builder func(packer MapPacker ))
KeyValueObject(builder func(packer ObjectPacker)) KeyValueObject(key any, builder func(packer ObjectPacker))
} }

@ -44,7 +44,6 @@ func (n *Node) Init(parent *Node, kind NodeKind, start int) *Node {
} else { } else {
n.Level = 0 n.Level = 0
} }
n.Level = 0
n.Count = 0 n.Count = 0
n.Start = start n.Start = start
n.Kind = kind n.Kind = kind

@ -29,33 +29,33 @@ type (
ObjectPacker interface { ObjectPacker interface {
Field (key any, value any) Field (name string, value any)
FieldRaw (value []byte) FieldRaw (name string, value []byte)
FieldBinary (key any, value []byte) FieldBinary (name string, value []byte)
FieldString (key any, value string) FieldString (name string, value string)
FieldBool (key any, value bool) FieldBool (name string, value bool)
FieldInt8 (key any, value int8) FieldInt8 (name string, value int8)
FieldInt16 (key any, value int16) FieldInt16 (name string, value int16)
FieldInt32 (key any, value int32) FieldInt32 (name string, value int32)
FieldInt64 (key any, value int64) FieldInt64 (name string, value int64)
FieldUInt8 (key any, value uint8) FieldUInt8 (name string, value uint8)
FieldUInt16 (key any, value uint16) FieldUInt16 (name string, value uint16)
FieldUInt32 (key any, value uint32) FieldUInt32 (name string, value uint32)
FieldUInt64 (key any, value uint64) FieldUInt64 (name string, value uint64)
FieldFloat32 (key any, value float32) FieldFloat32 (name string, value float32)
FieldFloat64 (key any, value float64) FieldFloat64 (name string, value float64)
FieldDate (key any, value time.Time) FieldDate (name string, value time.Time)
FieldList (builder func(packer ListPacker)) FieldList (name string, builder func(packer ListPacker))
FieldMap (builder func(packer MapPacker )) FieldMap (name string, builder func(packer MapPacker ))
FieldObject(builder func(packer ObjectPacker)) FieldObject(name string, builder func(packer ObjectPacker))
} }

@ -109,18 +109,13 @@ func (s *State) SetKey(key string) bool {
return true return true
} }
func (s *State) SetValue() bool {
if s.Error != nil {
return false
}
s.Node.Count++
return true
}
func (s *State) Open(kind NodeKind) bool { func (s *State) Open(kind NodeKind) bool {
if s.Error != nil { if s.Error != nil {
return false return false
} }
if s.Node.Kind == NodeKindValue { if s.Node.Kind == NodeKindValue {
if s.Node.Count > 0 { if s.Node.Count > 0 {
return !s.SetError(G.ErrInvalidNode) return !s.SetError(G.ErrInvalidNode)

@ -23,7 +23,12 @@
package pjson package pjson
import "unicode/utf8" import (
"encoding"
"math"
"strconv"
"unicode/utf8"
)
var ( var (
G = struct { G = struct {
@ -76,3 +81,70 @@ func initJSONChars() [utf8.RuneSelf]jsonCharAtt {
func stringifyKey(buffer []byte, value any) []byte {
if value == nil {
return G.nullValue
}
if st,is := value.(string); is {
return append(buffer[:0],st...)
}
if tm,is := value.(encoding.TextMarshaler); is {
if bf,er := tm.MarshalText(); er == nil {
return append(buffer[:0],bf...)
}
return nil
}
switch tp := value.(type) {
case bool:
if tp {
return G.trueValue
}
return G.falseValue
case int : return strconv.AppendInt (buffer[:0],int64(tp), 10)
case int8 : return strconv.AppendInt (buffer[:0],int64(tp), 10)
case int16 : return strconv.AppendInt (buffer[:0],int64(tp), 10)
case int32 : return strconv.AppendInt (buffer[:0],int64(tp), 10)
case int64 : return strconv.AppendInt (buffer[:0],tp, 10)
case uint : return strconv.AppendUint(buffer[:0],uint64(tp), 10)
case uint8 : return strconv.AppendUint(buffer[:0],uint64(tp), 10)
case uint16 : return strconv.AppendUint(buffer[:0],uint64(tp), 10)
case uint32 : return strconv.AppendUint(buffer[:0],uint64(tp), 10)
case uint64 : return strconv.AppendUint(buffer[:0],tp, 10)
case float32: return stringifyFloat(buffer[:0],float64(tp),32)
case float64: return stringifyFloat(buffer[:0],tp,64)
}
return nil
}
func stringifyFloat (buffer []byte, f float64, bits int) []byte {
if math.IsInf(f, 0) || math.IsNaN(f) {
return nil
}
abs := math.Abs(f)
fmt := byte('f')
if abs != 0 {
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
fmt = 'e'
}
}
buffer = strconv.AppendFloat(buffer[:0], f, fmt, -1, int(bits))
if fmt == 'e' {
// clean up e-09 to e-9
n := len(buffer)
if n >= 4 && buffer[n-4] == 'e' && buffer[n-3] == '-' && buffer[n-2] == '0' {
buffer[n-2] = buffer[n-1]
buffer = buffer[:n-1]
}
}
return buffer
}

@ -28,36 +28,36 @@ import (
"time" "time"
) )
func (p *Packer) KeyValue ( key any, value any) {} func (p *Packer) KeyValue ( key any, value any) { p.addKey(key,func (pk *Packer) { pk.Pack(value) }) }
func (p *Packer) KeyValueRaw (value []byte) {} func (p *Packer) KeyValueRaw (key any, value []byte) { p.addKey(key,func (pk *Packer) { pk.PackRaw(value) }) }
func (p *Packer) KeyValueBinary ( key any, value []byte) {} func (p *Packer) KeyValueBinary ( key any, value []byte) { p.addKey(key,func (pk *Packer) { pk.PackBinary(value) }) }
func (p *Packer) KeyValueString ( key any, value string) {} func (p *Packer) KeyValueString ( key any, value string) { p.addKey(key,func (pk *Packer) { pk.PackString(value) }) }
func (p *Packer) KeyValueBool ( key any, value bool) {} func (p *Packer) KeyValueBool ( key any, value bool) { p.addKey(key,func (pk *Packer) { pk.PackBool(value) }) }
func (p *Packer) KeyValueRune ( key any, value rune) {}
func (p *Packer) KeyValueInt8 ( key any, value int8) {} func (p *Packer) KeyValueInt8 ( key any, value int8) { p.addKey(key,func (pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) KeyValueInt16 ( key any, value int16) {} func (p *Packer) KeyValueInt16 ( key any, value int16) { p.addKey(key,func (pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) KeyValueInt32 ( key any, value int32) {} func (p *Packer) KeyValueInt32 ( key any, value int32) { p.addKey(key,func (pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) KeyValueInt64 ( key any, value int64) {} func (p *Packer) KeyValueInt64 ( key any, value int64) { p.addKey(key,func (pk *Packer) { pk.PackInt64(value) }) }
func (p *Packer) KeyValueUInt8 ( key any, value uint8) {} func (p *Packer) KeyValueUInt8 ( key any, value uint8) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) KeyValueUInt16 ( key any, value uint16) {} func (p *Packer) KeyValueUInt16 ( key any, value uint16) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) KeyValueUInt32 ( key any, value uint32) {} func (p *Packer) KeyValueUInt32 ( key any, value uint32) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) KeyValueUInt64 ( key any, value uint64) {} func (p *Packer) KeyValueUInt64 ( key any, value uint64) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(value) }) }
func (p *Packer) KeyValueFloat32 ( key any, value float32) {} func (p *Packer) KeyValueFloat32 ( key any, value float32) { p.addKey(key,func (pk *Packer) { pk.PackFloat64(float64(value)) }) }
func (p *Packer) KeyValueFloat64 ( key any, value float64) {} func (p *Packer) KeyValueFloat64 ( key any, value float64) { p.addKey(key,func (pk *Packer) { pk.PackFloat64(value) }) }
func (p *Packer) KeyValueDate ( key any, value time.Time) {} func (p *Packer) KeyValueDate ( key any, value time.Time) { p.addKey(key,func (pk *Packer) { pk.PackDate(value) }) }
func (p *Packer) KeyValueList (builder func(packer packets.ListPacker)) {} func (p *Packer) KeyValueList (key any, builder func(packer packets.ListPacker)) { p.addKey(key,func (pk *Packer) { pk.PackList(builder) }) }
func (p *Packer) KeyValueMap (builder func(packer packets.MapPacker )) {} func (p *Packer) KeyValueMap (key any, builder func(packer packets.MapPacker )) { p.addKey(key,func (pk *Packer) { pk.PackMap (builder) }) }
func (p *Packer) KeyValueObject(builder func(packer packets.ObjectPacker)) {} func (p *Packer) KeyValueObject(key any, builder func(packer packets.ObjectPacker)) { p.addKey(key,func (pk *Packer){ pk.PackObject (builder) }) }

@ -28,34 +28,33 @@ import (
"time" "time"
) )
func (p *Packer) Field ( key any, value any) {} func (p *Packer) Field (name string, value any) { p.addField(name,func(pk *Packer) { pk.Pack(value) }) }
func (p *Packer) FieldRaw (value []byte) {} func (p *Packer) FieldRaw (name string, value []byte) { p.addField(name,func(pk *Packer) { pk.PackRaw(value) }) }
func (p *Packer) FieldBinary ( key any, value []byte) {} func (p *Packer) FieldBinary( name string, value []byte) { p.addField(name,func(pk *Packer) { pk.PackBinary(value) }) }
func (p *Packer) FieldString ( key any, value string) {} func (p *Packer) FieldString( name string, value string) { p.addField(name,func(pk *Packer) { pk.PackString(value) }) }
func (p *Packer) FieldBool ( key any, value bool) {} func (p *Packer) FieldBool ( name string, value bool) { p.addField(name,func(pk *Packer) { pk.PackBool(value) }) }
func (p *Packer) FieldRune ( key any, value rune) {}
func (p *Packer) FieldInt8 ( key any, value int8) {} func (p *Packer) FieldInt8 ( name string, value int8) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) FieldInt16 ( key any, value int16) {} func (p *Packer) FieldInt16 ( name string, value int16) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) FieldInt32 ( key any, value int32) {} func (p *Packer) FieldInt32 ( name string, value int32) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) FieldInt64 ( key any, value int64) {} func (p *Packer) FieldInt64 ( name string, value int64) { p.addField(name,func(pk *Packer) { pk.PackInt64(value) }) }
func (p *Packer) FieldUInt8 ( key any, value uint8) {} func (p *Packer) FieldUInt8 ( name string, value uint8) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) FieldUInt16 ( key any, value uint16) {} func (p *Packer) FieldUInt16 ( name string, value uint16) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) FieldUInt32 ( key any, value uint32) {} func (p *Packer) FieldUInt32 ( name string, value uint32) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) FieldUInt64 ( key any, value uint64) {} func (p *Packer) FieldUInt64 ( name string, value uint64) { p.addField(name,func(pk *Packer) { pk.PackUInt64(value) }) }
func (p *Packer) FieldFloat32 ( key any, value float32) {} func (p *Packer) FieldFloat32( name string, value float32) { p.addField(name,func(pk *Packer) { pk.PackFloat64(float64(value)) }) }
func (p *Packer) FieldFloat64 ( key any, value float64) {} func (p *Packer) FieldFloat64( name string, value float64) { p.addField(name,func(pk *Packer) { pk.PackFloat64(value) }) }
func (p *Packer) FieldDate ( key any, value time.Time) {} func (p *Packer) FieldDate ( name string, value time.Time) { p.addField(name,func(pk *Packer) { pk.PackDate(value) }) }
func (p *Packer) FieldList (builder func(packer packets.ListPacker)) {} func (p *Packer) FieldList (name string, builder func(packer packets.ListPacker)) { p.addField(name,func(pk *Packer) { pk.PackList(builder) }) }
func (p *Packer) FieldMap (builder func(packer packets.MapPacker )) {} func (p *Packer) FieldMap (name string, builder func(packer packets.MapPacker )) { p.addField(name,func(pk *Packer) { pk.PackMap(builder) }) }
func (p *Packer) FieldObject(builder func(packer packets.ObjectPacker)) {} func (p *Packer) FieldObject(name string, builder func(packer packets.ObjectPacker)) { p.addField(name,func(pk *Packer) { pk.PackObject(builder) }) }

@ -23,6 +23,7 @@
package pjson package pjson
import "time"
type ( type (
@ -30,4 +31,12 @@ type (
Flags /*embedded*/ Flags /*embedded*/
dateLayout string dateLayout string
} }
) )
func (o *Options) reset () {
o.Flags = JSONFlagEscapeHTML | JSONFlagQuote
o.dateLayout = time.RFC822Z
}

@ -26,10 +26,10 @@ package pjson
import ( import (
"activething.com/go/gogo/core/bins" "activething.com/go/gogo/core/bins"
"activething.com/go/gogo/core/errs" "activething.com/go/gogo/core/errs"
"activething.com/go/gogo/core/opts"
"activething.com/go/gogo/packets" "activething.com/go/gogo/packets"
"encoding/base64" "encoding/base64"
"math" "fmt"
"strconv"
"time" "time"
"unicode/utf8" "unicode/utf8"
) )
@ -45,178 +45,273 @@ type (
) )
func NewPacker (options ...opts.OptionFnc[Packer]) *Packer {
return opts.Apply(&Packer{
options: Options{
Flags: JSONFlagQuote | JSONFlagEscapeHTML,
dateLayout: time.RFC822Z,
},
state : packets.NewState(),
})
}
func (p *Packer) Bytes () []byte {
defer p.reset()
return append([]byte(nil),p.state.Bytes()...)
}
func (p *Packer) Error () error {
return p.state.Error
}
func (p *Packer) Pack (value any) { func (p *Packer) Pack (value any) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
p.state.Node.Count++
} }
func (p *Packer) PackRaw (value []byte) { func (p *Packer) PackRaw (value []byte) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if value == nil { if value == nil {
p.state.Write(G.nullValue) _,_ = p.state.Write(G.nullValue)
return return
} }
p.state.Write(value)
if p.options.Quote() {
_ = p.state.WriteByte('"')
}
_,_ = p.state.Write(value)
if p.options.Quote() {
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
} }
func (p *Packer) PackBinary (value []byte) { func (p *Packer) PackBinary (value []byte) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if value == nil { if value == nil {
p.state.Write(G.nullValue) _,_ = p.state.Write(G.nullValue)
return return
} }
if len(value) == 0 { if len(value) == 0 {
p.state.Write2Byte('"','"') p.state.Write2Byte('"','"')
return return
} }
p.state.WriteByte('"') _ = p.state.WriteByte('"')
ln := base64.StdEncoding.EncodedLen(len(value)) ln := base64.StdEncoding.EncodedLen(len(value))
if ln <= len(p.state.Temp) { if ln <= len(p.state.Temp) {
dst := p.state.Temp[:ln] dst := p.state.Temp[:ln]
base64.StdEncoding.Encode(dst, value) base64.StdEncoding.Encode(dst, value)
p.state.Write(dst) _,_= p.state.Write(dst)
} else if ln <= 1024 { } else if ln <= 1024 {
dst := make([]byte, ln) dst := make([]byte, ln)
base64.StdEncoding.Encode(dst, value) base64.StdEncoding.Encode(dst, value)
p.state.Write(dst) _,_ = p.state.Write(dst)
} else { } else {
enc := base64.NewEncoder(base64.StdEncoding, p.state) enc := base64.NewEncoder(base64.StdEncoding, p.state)
enc.Write(value) _,_ = enc.Write(value)
enc.Close() p.state.SetError(enc.Close())
return
} }
p.state.WriteByte('"') _ = p.state.WriteByte('"')
p.state.Node.Count++
} }
func (p *Packer) PackString (value string) { func (p *Packer) PackString (value string) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if len(value) == 0 { if len(value) == 0 {
p.state.Write2Byte('"','"') p.state.Write2Byte('"','"')
} else { } else {
p.string(value,p.options.EscapeHTML()) p.packString(value,p.options.EscapeHTML())
} }
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()) {
i++
continue
}
if start < i {
_,_ = p.state.WriteString(s[start:i])
}
_ = p.state.WriteByte('\\')
switch b {
case '\\', '"': p.state.WriteByte(b)
case '\n': p.state.WriteByte('n')
case '\r': p.state.WriteByte('r')
case '\t': p.state.WriteByte('t')
default:
_,_ = p.state.WriteString(`u00`)
p.state.Write2Byte(G.hex[b>>4], G.hex[b&0xF])
}
i++
start = i
continue
}
c, size := utf8.DecodeRuneInString(s[i:])
if c == utf8.RuneError && size == 1 {
if start < i {
_,_ = p.state.WriteString(s[start:i])
}
_,_ = p.state.WriteString(`\ufffd`)
i += size
start = i
continue
}
if c == '\u2028' || c == '\u2029' {
if start < i {
_,_ = p.state.WriteString(s[start:i])
}
_,_ = p.state.WriteString(`\u202`)
_ = p.state.WriteByte(G.hex[c&0xF])
i += size
start = i
continue
}
i += size
}
if start < len(s) {
_,_ = p.state.WriteString(s[start:])
}
_ = p.state.WriteByte('"')
}
func (p *Packer) PackBool (value bool) { func (p *Packer) PackBool (value bool) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
if value { if value {
p.state.Write(G.trueValue) _,_ = p.state.Write(G.trueValue)
} else { } else {
p.state.Write(G.falseValue) _,_ = p.state.Write(G.falseValue)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
p.state.Node.Count++
} }
func (p *Packer) PackInt8 (value int8) {} func (p *Packer) PackInt8 (value int8) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt16 (value int16) {} func (p *Packer) PackInt16 (value int16) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt32 (value int32) {} func (p *Packer) PackInt32 (value int32) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt64 (value int64) { func (p *Packer) PackInt64 (value int64) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
if value == 0 { if value == 0 {
p.state.WriteByte('0') _ = p.state.WriteByte('0')
} else { } else {
p.state.WriteIntStr(value, 10) p.state.WriteIntStr(value, 10)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
p.state.Node.Count++
} }
func (p *Packer) PackUInt8 (value uint8) {} func (p *Packer) PackUInt8 (value uint8 ) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt16 (value uint16) {} func (p *Packer) PackUInt16 (value uint16) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt32 (value uint32) {} func (p *Packer) PackUInt32 (value uint32) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt64 (value uint64) { func (p *Packer) PackUInt64 (value uint64) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
if value == 0 { if value == 0 {
p.state.WriteByte('0') _ = p.state.WriteByte('0')
} else { } else {
p.state.WriteUIntStr(value, 10) p.state.WriteUIntStr(value, 10)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
p.state.Node.Count++
} }
func (p *Packer) PackFloat32 (value float32) {} func (p *Packer) PackFloat32 (value float32) { p.packFloat(float64(value),32) }
func (p *Packer) PackFloat64 (value float64) { func (p *Packer) PackFloat64 (value float64) { p.packFloat(value,64) }
if !p.state.SetValue() {
func (p *Packer) packFloat (value float64, bits int) {
if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
if math.IsInf(value,0) || math.IsNaN(value) {
p.state.SetError(packets.G.ErrInvalidValue)
return
}
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
switch { b := stringifyFloat(p.state.Temp[:0], value,bits)
case value == 0 : p.state.Write(G.zeroValue) if b == nil {
case math.IsNaN(value) : p.state.Write(G.floatNaN) p.state.SetError(packets.G.ErrInvalidValue)
case math.IsInf(value, 1) : p.state.Write(G.floatInfPos) return
case math.IsInf(value, -1) : p.state.Write(G.floatInfNeg)
default:
fm := byte('f')
if ab := math.Abs(value); ab != 0 {
if ab < 1e-6 || ab >= 1e21 {
fm = 'e'
}
}
b := p.state.Temp[:0]
b = strconv.AppendFloat(b, value, fm, -1, 64)
if fm == 'e' {
// clean up e-09 to e-9
n := len(b)
if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
b[n-2] = b[n-1]
b = b[:n-1]
}
}
p.state.Write(b)
} }
if p.options.QuoteNumbers() { if p.options.QuoteNumbers() {
p.state.WriteByte('"') _ = p.state.WriteByte('"')
} }
p.state.Node.Count++
} }
func (p *Packer) PackDate (value time.Time) { func (p *Packer) PackDate (value time.Time) {
if !p.state.SetValue() { if p.state.Error != nil {
panic(p.state.Error) panic(p.state.Error)
} }
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
p.state.AppendWith(bins.AppendFnc(func(d []byte) []byte { p.state.AppendWith(bins.AppendFnc(func(d []byte) []byte {
return value.AppendFormat(d,p.options.dateLayout) return value.AppendFormat(d,p.options.dateLayout)
})) }))
p.state.WriteByte('"') _ = p.state.WriteByte('"')
p.state.Node.Count++
} }
@ -236,10 +331,6 @@ func (p *Packer) PackObject(builder func(packer packets.ObjectPacker)) {
func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buildFnc func(*Packer)) { func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buildFnc func(*Packer)) {
if !p.state.SetValue() {
panic(p.state.Error)
}
dn := false dn := false
defer func(d *bool) { defer func(d *bool) {
if !(*d) { if !(*d) {
@ -247,15 +338,22 @@ func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buil
} }
}(&dn) }(&dn)
if p.state.Open(kind) { if p.state.Open(kind) {
p.addSep() fmt.Printf("Node Count %d\n",p.state.Node.Count)
p.state.WriteByte(opening) _ = p.state.WriteByte(opening)
/*
if !p.state.SetValue() {
panic(p.state.Error)
}
*/
buildFnc(p) buildFnc(p)
if p.state.Error == nil { if p.state.Error == nil {
if p.state.Close() { if p.state.Close() {
p.state.WriteByte(closing) _ = p.state.WriteByte(closing)
} }
} }
} }
@ -267,66 +365,62 @@ func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buil
func (p *Packer) string(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()) {
i++
continue
}
if start < i {
p.state.WriteString(s[start:i])
}
p.state.WriteByte('\\')
switch b {
case '\\', '"': p.state.WriteByte(b)
case '\n': p.state.WriteByte('n')
case '\r': p.state.WriteByte('r')
case '\t': p.state.WriteByte('t')
default:
p.state.WriteString(`u00`)
p.state.Write2Byte(G.hex[b>>4], G.hex[b&0xF])
}
i++
start = i
continue
}
c, size := utf8.DecodeRuneInString(s[i:])
if c == utf8.RuneError && size == 1 {
if start < i {
p.state.WriteString(s[start:i])
}
p.state.WriteString(`\ufffd`)
i += size
start = i
continue
}
if c == '\u2028' || c == '\u2029' {
if start < i {
p.state.WriteString(s[start:i])
}
p.state.WriteString(`\u202`)
p.state.WriteByte(G.hex[c&0xF])
i += size
start = i
continue
}
i += size
}
if start < len(s) {
p.state.WriteString(s[start:])
}
p.state.WriteByte('"')
}
func (p *Packer) addSep () *Packer { func (p *Packer) addSep () *Packer {
if p.state.Node.Count > 0 { if p.state.Node.Count > 0 {
p.state.WriteByte(',') _ = p.state.WriteByte(',')
} }
return p return p
}
func (p *Packer) addKey (key any, call func(*Packer)) {
if p.state.Error != nil {
panic(p.state.Error)
}
p.addSep()
k := stringifyKey(p.state.Temp[0:],key)
if k == nil {
p.state.SetError(packets.G.ErrInvalidKey)
return
}
ks := string(k)
if !p.options.IgnoreKeys() && !p.state.SetKey(ks) {
return
}
p.packString(ks,p.options.EscapeHTML())
_ = p.state.WriteByte(':')
call(p)
p.state.Node.Count++
}
func (p *Packer) addField (name string, call func(*Packer)) {
if p.state.Error != nil {
panic(p.state.Error)
}
p.addSep()
ks := string(name)
if !p.options.IgnoreKeys() && !p.state.SetKey(ks) {
return
}
p.packString(name,p.options.EscapeHTML())
_ = p.state.WriteByte(':')
call(p)
p.state.Node.Count++
}
func (p *Packer) reset () {
p.state.Reset()
p.options.reset()
} }
Loading…
Cancel
Save

Powered by TurnKey Linux.