redefiniendo el builder

packs2
DEV 3 years ago
parent 51dc2ab480
commit 9851697694

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

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

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

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

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

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

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

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

@ -45,7 +45,7 @@ type (
encoder *json.Encoder
dateLayout string
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](
syncs.PoolWithNew[Builder](func() *Builder {
return &Builder{
options : jsonOptionsDefaults,
state : packs.NewState(),
dateLayout: time.RFC822Z,
options : jsonOptionsDefaults,
state : __packs.NewState(),
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(),
}
if _,ok := b.state.Seen[p]; ok {
b.state.SetError(packs.G.ErrRedundantPack)
b.state.SetError(__packs.G.ErrRedundantPack)
return
}
b.state.Seen[p] = struct{}{}
@ -57,48 +57,48 @@ func (b *Builder) listPacker(rv reflect.Value) {
}
switch rv.Type().Elem().Kind() {
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.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.Int8,
reflect.Int16,
reflect.Int32,
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,
reflect.Uint16,
reflect.Uint32,
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,
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,
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:
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:
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
}
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,
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:
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)) {
b.BuildList(func(l packs.BuilderList) {
func (b *Builder) _listPacker (list reflect.Value, pack func(lb __packs.BuilderList, ev reflect.Value)) {
b.BuildList(func(l __packs.BuilderList) {
for i := 0; i < list.Len(); i++ {
pack(l, list.Index(i))
if b.state.Error != nil {

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

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

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

@ -25,17 +25,34 @@ package main
import (
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packs/jjson"
"activething.com/go/gogo/packets"
"activething.com/go/gogo/packets/pjson"
"fmt"
"time"
)
func main() {
p := jjson.JSONPacker{}
d,e := p.Pack(22)
errs.Test(e,false)
fmt.Printf("Data = %s\n",d)
pk := pjson.NewPacker()
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/opts
./core/syncs
./packs
./packets
)

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

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

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

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

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

@ -109,18 +109,13 @@ func (s *State) SetKey(key string) bool {
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 {
if s.Error != nil {
return false
}
if s.Node.Kind == NodeKindValue {
if s.Node.Count > 0 {
return !s.SetError(G.ErrInvalidNode)

@ -23,7 +23,12 @@
package pjson
import "unicode/utf8"
import (
"encoding"
"math"
"strconv"
"unicode/utf8"
)
var (
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"
)
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) KeyValueString ( key any, value string) {}
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) { p.addKey(key,func (pk *Packer) { pk.PackString(value) }) }
func (p *Packer) KeyValueBool ( key any, value bool) {}
func (p *Packer) KeyValueRune ( key any, value rune) {}
func (p *Packer) KeyValueBool ( key any, value bool) { p.addKey(key,func (pk *Packer) { pk.PackBool(value) }) }
func (p *Packer) KeyValueInt8 ( key any, value int8) {}
func (p *Packer) KeyValueInt16 ( key any, value int16) {}
func (p *Packer) KeyValueInt32 ( key any, value int32) {}
func (p *Packer) KeyValueInt64 ( key any, value int64) {}
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) { p.addKey(key,func (pk *Packer) { pk.PackInt64(int64(value)) }) }
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) { p.addKey(key,func (pk *Packer) { pk.PackInt64(value) }) }
func (p *Packer) KeyValueUInt8 ( key any, value uint8) {}
func (p *Packer) KeyValueUInt16 ( key any, value uint16) {}
func (p *Packer) KeyValueUInt32 ( key any, value uint32) {}
func (p *Packer) KeyValueUInt64 ( key any, value uint64) {}
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) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(uint64(value)) }) }
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) { p.addKey(key,func (pk *Packer) { pk.PackUInt64(value) }) }
func (p *Packer) KeyValueFloat32 ( key any, value float32) {}
func (p *Packer) KeyValueFloat64 ( key any, value float64) {}
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) { 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) KeyValueMap (builder func(packer packets.MapPacker )) {}
func (p *Packer) KeyValueObject(builder func(packer packets.ObjectPacker)) {}
func (p *Packer) KeyValueList (key any, builder func(packer packets.ListPacker)) { p.addKey(key,func (pk *Packer) { pk.PackList(builder) }) }
func (p *Packer) KeyValueMap (key any, builder func(packer packets.MapPacker )) { p.addKey(key,func (pk *Packer) { pk.PackMap (builder) }) }
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"
)
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) FieldString ( key any, value string) {}
func (p *Packer) FieldBinary( name string, value []byte) { p.addField(name,func(pk *Packer) { pk.PackBinary(value) }) }
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) FieldRune ( key any, value rune) {}
func (p *Packer) FieldBool ( name string, value bool) { p.addField(name,func(pk *Packer) { pk.PackBool(value) }) }
func (p *Packer) FieldInt8 ( key any, value int8) {}
func (p *Packer) FieldInt16 ( key any, value int16) {}
func (p *Packer) FieldInt32 ( key any, value int32) {}
func (p *Packer) FieldInt64 ( key any, value int64) {}
func (p *Packer) FieldInt8 ( name string, value int8) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) FieldInt16 ( name string, value int16) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
func (p *Packer) FieldInt32 ( name string, value int32) { p.addField(name,func(pk *Packer) { pk.PackInt64(int64(value)) }) }
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) FieldUInt16 ( key any, value uint16) {}
func (p *Packer) FieldUInt32 ( key any, value uint32) {}
func (p *Packer) FieldUInt64 ( key any, value uint64) {}
func (p *Packer) FieldUInt8 ( name string, value uint8) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) FieldUInt16 ( name string, value uint16) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
func (p *Packer) FieldUInt32 ( name string, value uint32) { p.addField(name,func(pk *Packer) { pk.PackUInt64(uint64(value)) }) }
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) FieldFloat64 ( key any, value float64) {}
func (p *Packer) FieldFloat32( name string, value float32) { p.addField(name,func(pk *Packer) { pk.PackFloat64(float64(value)) }) }
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) FieldMap (builder func(packer packets.MapPacker )) {}
func (p *Packer) FieldObject(builder func(packer packets.ObjectPacker)) {}
func (p *Packer) FieldList (name string, builder func(packer packets.ListPacker)) { p.addField(name,func(pk *Packer) { pk.PackList(builder) }) }
func (p *Packer) FieldMap (name string, builder func(packer packets.MapPacker )) { p.addField(name,func(pk *Packer) { pk.PackMap(builder) }) }
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
import "time"
type (
@ -30,4 +31,12 @@ type (
Flags /*embedded*/
dateLayout string
}
)
)
func (o *Options) reset () {
o.Flags = JSONFlagEscapeHTML | JSONFlagQuote
o.dateLayout = time.RFC822Z
}

@ -26,10 +26,10 @@ package pjson
import (
"activething.com/go/gogo/core/bins"
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/core/opts"
"activething.com/go/gogo/packets"
"encoding/base64"
"math"
"strconv"
"fmt"
"time"
"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) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
p.state.Node.Count++
}
func (p *Packer) PackRaw (value []byte) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if value == nil {
p.state.Write(G.nullValue)
_,_ = p.state.Write(G.nullValue)
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) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if value == nil {
p.state.Write(G.nullValue)
_,_ = p.state.Write(G.nullValue)
return
}
if len(value) == 0 {
p.state.Write2Byte('"','"')
return
}
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
ln := base64.StdEncoding.EncodedLen(len(value))
if ln <= len(p.state.Temp) {
dst := p.state.Temp[:ln]
base64.StdEncoding.Encode(dst, value)
p.state.Write(dst)
_,_= p.state.Write(dst)
} else if ln <= 1024 {
dst := make([]byte, ln)
base64.StdEncoding.Encode(dst, value)
p.state.Write(dst)
_,_ = p.state.Write(dst)
} else {
enc := base64.NewEncoder(base64.StdEncoding, p.state)
enc.Write(value)
enc.Close()
_,_ = enc.Write(value)
p.state.SetError(enc.Close())
return
}
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
p.state.Node.Count++
}
func (p *Packer) PackString (value string) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if len(value) == 0 {
p.state.Write2Byte('"','"')
} 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) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
if value {
p.state.Write(G.trueValue)
_,_ = p.state.Write(G.trueValue)
} else {
p.state.Write(G.falseValue)
_,_ = p.state.Write(G.falseValue)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
}
func (p *Packer) PackInt8 (value int8) {}
func (p *Packer) PackInt16 (value int16) {}
func (p *Packer) PackInt32 (value int32) {}
func (p *Packer) PackInt8 (value int8) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt16 (value int16) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt32 (value int32) { p.PackInt64(int64(value)) }
func (p *Packer) PackInt64 (value int64) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
if value == 0 {
p.state.WriteByte('0')
_ = p.state.WriteByte('0')
} else {
p.state.WriteIntStr(value, 10)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
}
func (p *Packer) PackUInt8 (value uint8) {}
func (p *Packer) PackUInt16 (value uint16) {}
func (p *Packer) PackUInt32 (value uint32) {}
func (p *Packer) PackUInt8 (value uint8 ) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt16 (value uint16) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt32 (value uint32) { p.PackUInt64(uint64(value)) }
func (p *Packer) PackUInt64 (value uint64) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
if value == 0 {
p.state.WriteByte('0')
_ = p.state.WriteByte('0')
} else {
p.state.WriteUIntStr(value, 10)
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
}
func (p *Packer) PackFloat32 (value float32) {}
func (p *Packer) PackFloat64 (value float64) {
if !p.state.SetValue() {
func (p *Packer) PackFloat32 (value float32) { p.packFloat(float64(value),32) }
func (p *Packer) PackFloat64 (value float64) { p.packFloat(value,64) }
func (p *Packer) packFloat (value float64, bits int) {
if p.state.Error != nil {
panic(p.state.Error)
}
if math.IsInf(value,0) || math.IsNaN(value) {
p.state.SetError(packets.G.ErrInvalidValue)
return
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
}
switch {
case value == 0 : p.state.Write(G.zeroValue)
case math.IsNaN(value) : p.state.Write(G.floatNaN)
case math.IsInf(value, 1) : p.state.Write(G.floatInfPos)
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)
_ = p.state.WriteByte('"')
}
b := stringifyFloat(p.state.Temp[:0], value,bits)
if b == nil {
p.state.SetError(packets.G.ErrInvalidValue)
return
}
if p.options.QuoteNumbers() {
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
}
p.state.Node.Count++
}
func (p *Packer) PackDate (value time.Time) {
if !p.state.SetValue() {
if p.state.Error != nil {
panic(p.state.Error)
}
p.state.WriteByte('"')
_ = p.state.WriteByte('"')
p.state.AppendWith(bins.AppendFnc(func(d []byte) []byte {
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)) {
if !p.state.SetValue() {
panic(p.state.Error)
}
dn := false
defer func(d *bool) {
if !(*d) {
@ -247,15 +338,22 @@ func (p *Packer) packCompound(kind packets.NodeKind, opening, closing byte, buil
}
}(&dn)
if p.state.Open(kind) {
p.addSep()
p.state.WriteByte(opening)
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)
_ = 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 {
if p.state.Node.Count > 0 {
p.state.WriteByte(',')
_ = p.state.WriteByte(',')
}
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.