redefiniendo el builder

packs2
DEV 3 years ago
parent 7e8cfee304
commit 36e6cf3998

@ -1 +1,3 @@
module app module app
go 1.20

@ -25,6 +25,6 @@ package main
func main() { func main() {
reflects_main() packs_main()
} }

@ -27,6 +27,7 @@ import (
"activething.com/go/gogo/core/errs" "activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packs/pjson" "activething.com/go/gogo/packs/pjson"
"fmt" "fmt"
"time"
) )
func packs_main () { func packs_main () {
@ -73,7 +74,7 @@ func packs_main () {
*/ */
/*
var s = struct { var s = struct {
F1Int int F1Int int
F2Uint uint F2Uint uint
@ -86,11 +87,26 @@ func packs_main () {
F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"), F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"),
} }
pk.Pack(s) pk.Pack(s)
errs.Test(pk.Error(),true) errs.Test(pk.Error(),true)
fmt.Printf("JSON \n%s",pk.Bytes()) fmt.Printf("JSON \n%s",pk.Bytes())
*/
mp := map[int]any {
3:"23434434",
1:time.Now(),
4:233,
7:[]uint16{2323,2323,2323},
}
pk.Pack(mp)
errs.Test(pk.Error(),true)
fmt.Printf("JSON \n%s",pk.Bytes())
} }

@ -24,7 +24,7 @@
package main package main
import ( import (
"activething.com/go/gogo/core/reflects" "activething.com/go/gogo/packs/reflects"
"fmt" "fmt"
"reflect" "reflect"
) )
@ -67,6 +67,11 @@ func reflects_main () {
} }
} }

@ -28,6 +28,7 @@ import (
j "encoding/json" j "encoding/json"
"fmt" "fmt"
"testing" "testing"
"time"
) )
var s = struct { var s = struct {
@ -42,6 +43,15 @@ var s = struct {
F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"), F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"),
} }
var packer = pjson.NewPacker()
var mp = map[int]any {
3:"23434434",
1:time.Now(),
4:233,
7:[]uint16{2323,2323,2323},
}
func BenchmarkHtmlPacker(b *testing.B) { func BenchmarkHtmlPacker(b *testing.B) {
packer := pjson.NewPacker() packer := pjson.NewPacker()
@ -74,4 +84,30 @@ func BenchmarkJsonMarshal(b *testing.B) {
} }
} }
} }
func BenchmarkMapPacker(b *testing.B) {
for i := 0; i < b.N; i++ {
packer.Pack(mp)
if packer.Error() != nil {
panic(packer.Error())
}
packer.Reset()
}
}
var bf []byte
func BenchmarkMapJSON(b *testing.B) {
var e error
var d []byte
for i := 0; i < b.N; i++ {
d, e = j.Marshal(s)
if e != nil {
panic(e)
}
}
bf = d
}

@ -1,3 +0,0 @@
module activething.com/go/gogo/core/reflects
go 1.20

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

@ -31,6 +31,15 @@ type (
Build (packer Packer) ([]byte,error) Build (packer Packer) ([]byte,error)
} }
PackableFnc func (packer Packer)([]byte,error)
) )
func (f PackableFnc) Build (packer Packer)([]byte,error) {
return f(packer)
}

@ -31,6 +31,8 @@ import (
) )
type ( type (
@ -115,6 +117,19 @@ func (s *State) SetKey(key string) bool {
} }
func (s *State) AddCheck(ptr any) bool {
if _,hs := s.Checks[ptr]; hs {
s.SetError(G.ErrRedundantPack)
return false
}
s.Checks[ptr]=struct{}{}
return true
}
func (s *State) DelCheck(ptr any) {
delete(s.Checks,ptr)
}
func (s *State) Open(kind NodeKind) { func (s *State) Open(kind NodeKind) {
if s.Node.Kind == NodeKindValue { if s.Node.Kind == NodeKindValue {

@ -28,6 +28,7 @@ import (
"activething.com/go/gogo/core/errs" "activething.com/go/gogo/core/errs"
"activething.com/go/gogo/core/opts" "activething.com/go/gogo/core/opts"
"activething.com/go/gogo/packs" "activething.com/go/gogo/packs"
"activething.com/go/gogo/packs/reflects"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"reflect" "reflect"
@ -526,28 +527,28 @@ func (p *Packer) packListReflected (value reflect.Value) {
switch tp.Elem().Kind() { switch tp.Elem().Kind() {
case reflect.String : case reflect.String :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemString(rv.String()) }) p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemString(rv.String()) })
case reflect.Bool : case reflect.Bool :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemBool (rv.Bool()) }) p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemBool (rv.Bool()) })
case reflect.Uint8 , case reflect.Uint8 ,
reflect.Uint16 , reflect.Uint16 ,
reflect.Uint32 , reflect.Uint32 ,
reflect.Uint64 : reflect.Uint64 :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemUInt64(rv.Uint()) }) p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemUInt64(rv.Uint()) })
case reflect.Int8 , case reflect.Int8 ,
reflect.Int16 , reflect.Int16 ,
reflect.Int32 , reflect.Int32 ,
reflect.Int64 : reflect.Int64 :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemInt64(rv.Int()) }) p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemInt64(rv.Int()) })
case reflect.Float32, case reflect.Float32,
reflect.Float64: reflect.Float64:
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemFloat64(rv.Float()) }) p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){ bl.ItemFloat64(rv.Float()) })
case reflect.Slice : case reflect.Slice :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){
p.packListReflected(rv) p.packListReflected(rv)
}) })
default: default:
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){ p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){
bl.Item(rv.Interface()) bl.Item(rv.Interface())
}) })
@ -555,7 +556,7 @@ func (p *Packer) packListReflected (value reflect.Value) {
} }
func (p *Packer) buildList (value reflect.Value, call func(lp packs.ListPacker, rv reflect.Value)) { func (p *Packer) buildListReflected(value reflect.Value, call func(lp packs.ListPacker, rv reflect.Value)) {
p.PackList(func (lp packs.ListPacker){ p.PackList(func (lp packs.ListPacker){
for i:=0; i<value.Len(); i++ { for i:=0; i<value.Len(); i++ {
call(lp,value.Index(i)) call(lp,value.Index(i))
@ -577,6 +578,30 @@ func (p *Packer) packMapReflected (value reflect.Value) {
p.state.Write2Byte('{','}') p.state.Write2Byte('{','}')
return return
} }
if p.state.Level > notDetectingCycles {
pt := value.UnsafePointer()
if !p.state.AddCheck(pt) {
return
}
defer p.state.DelCheck(pt)
}
mp,er := reflects.NewRMap(value,nil,nil)
if er != nil {
p.state.SetError(er)
return
}
p.packLOM(packs.NodeKindMap,'{','}',func(pk *Packer){
for _,kv := range mp.KeyValues {
pk.addField(kv.Key,func(pk *Packer) {
pk.Pack(kv.RVal.Interface())
})
}
})
} }

@ -0,0 +1,3 @@
module activething.com/go/gogo/packs/reflects
go 1.20

@ -2,9 +2,9 @@
// Project atila // Project atila
// Active Thing (activething.com) git.activething.com/go // Active Thing (activething.com) git.activething.com/go
// //
// File name struct_field.go // File name gogo.go
// Created by DEV // Created by DEV
// Modified 26/01/2024 // Modified 28/01/2024
// //
// Copyright 2024 activething.com // Copyright 2024 activething.com
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -21,7 +21,36 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
package pjson package reflects
import (
"activething.com/go/gogo/packs"
"reflect"
"sync"
)
var (
G = struct {
locker sync.Mutex
cache map[reflect.Type]RStruct
}{
}
)
func GetRTypePacker (rtype reflect.Type, packer packs.Packer) *RStruct {
G.locker.Lock()
if G.cache == nil {
G.cache = make(map[reflect.Type]RStruct)
}
G.locker.Unlock()
return nil
}

@ -45,6 +45,7 @@ type (
Index []int Index []int
Tags map[string]slices.String Tags map[string]slices.String
Flags uint16
EqualFoldFn func(s, t []byte) bool EqualFoldFn func(s, t []byte) bool
} }
@ -54,7 +55,7 @@ type (
func NewRField (rfield reflect.StructField, options ...opts.OptionFnc[RField]) *RField { func NewRField (rfield reflect.StructField, options ...opts.OptionFnc[RField]) *RField {
rf := &RField { rf := &RField{
RField: rfield, RField: rfield,
Tags : make(map[string]slices.String), Tags : make(map[string]slices.String),
} }

@ -41,7 +41,7 @@ type (
func NewRFieldTag (rfield reflect.StructField, tag string, onOption func(rf reflect.Type, position int, option string) uint8) *RFieldTag { func NewRFieldTag (rfield reflect.StructField, tag string, onOption func(rf reflect.Type, position int, option string) uint8) *RFieldTag {
f := &RFieldTag { f := &RFieldTag{
Tag : rfield.Tag.Get(tag), Tag : rfield.Tag.Get(tag),
} }
var ops string var ops string

@ -0,0 +1,72 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name rmap.go
// Created by DEV
// Modified 28/01/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// 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 reflects
import (
"reflect"
"sort"
)
type (
RMap struct {
KeyValues []RKeyValue
}
)
func NewRMap (value reflect.Value, stringifyFn func(v reflect.Value) (string,error), scapeFn func(string)string) (*RMap,error) {
ls := make([]RKeyValue,value.Len())
mi := value.MapRange()
sf := scapeFn
if sf == nil {
sf = func(v string) string { return v }
}
for i:=0; mi.Next(); i++ {
k,e := NewRKeyValue(mi.Key(),mi.Value(), stringifyFn,sf)
if e != nil {
return nil,e
}
ls[i]=*k
}
sort.Slice(ls,func(i,j int) bool { return ls[i].Key < ls[j].Key })
return &RMap {
KeyValues: ls,
},nil
}
func ensureScapeFn (sfn func(string)string) func(string)string {
if sfn == nil {
return func(v string) string { return v }
}
return sfn
}

@ -0,0 +1,87 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name rmap.go
// Created by DEV
// Modified 28/01/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// 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 reflects
import (
"activething.com/go/gogo/packs"
"encoding"
"reflect"
"strconv"
)
type (
RKeyValue struct {
RKey reflect.Value
RVal reflect.Value
Key string
}
)
func NewRKeyValue(key reflect.Value, value reflect.Value, stringifyFn func(v reflect.Value) (string,error), scapeFn func(string) string) (*RKeyValue,error) {
kv := &RKeyValue{
RKey : key,
RVal : value,
}
if kv.RKey.Kind() == reflect.String {
kv.Key = scapeFn(kv.RKey.String())
return kv,nil
}
if tm,hs := kv.RKey.Interface().(encoding.TextMarshaler); hs {
if kv.RKey.Kind() == reflect.Pointer && kv.RKey.IsNil() {
return nil,packs.G.ErrInvalidKey
}
b,e := tm.MarshalText()
if e != nil {
return nil,packs.G.ErrInvalidKey
}
kv.Key = string(b)
return kv,nil
}
if stringifyFn != nil {
b,e := stringifyFn(kv.RKey)
if e != nil {
return nil,packs.G.ErrInvalidKey.WithCause(e)
}
kv.Key = scapeFn(b)
return kv,nil
}
switch key.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
kv.Key = strconv.FormatInt(kv.RKey.Int(), 10)
return kv,nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
kv.Key= strconv.FormatUint(kv.RKey.Uint(), 10)
return kv,nil
}
return nil,packs.G.ErrInvalidKey
}

@ -23,25 +23,19 @@
package reflects package reflects
import (
"activething.com/go/gogo/core/slices"
"bytes"
"reflect"
)
type ( type (
RStruct struct { RStruct struct {
Fields RFields Fields RFields
NameIndex map[string]int NameIndex map[string]int
} }
) )
/*
func NewRStruct (rtype reflect.Type) *RStruct { func NewRStruct (rtype reflect.Type) *RStruct {
res := &RStruct{ res := &RStruct{
Fields : make(RFields,0,rtype.NumField()), Fields : make(RFields,0,rtype.NumField()),
NameIndex: make(map[string]int), NameIndex: make(map[string]int),
} }
@ -51,7 +45,6 @@ func NewRStruct (rtype reflect.Type) *RStruct {
var ( var (
cnt,nxc map[reflect.Type]int cnt,nxc map[reflect.Type]int
vis map[reflect.Type]struct{} vis map[reflect.Type]struct{}
fls RFields
nms bytes.Buffer nms bytes.Buffer
) )
@ -95,17 +88,20 @@ func NewRStruct (rtype reflect.Type) *RStruct {
ft=ft.Elem() ft=ft.Elem()
} }
qt := false
if tags.Has("string") { //qt := false
switch ft.Kind() { //if tags.Has("string") {
case reflect.Bool, // switch ft.Kind() {
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, // case reflect.Bool,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, // reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Float32, reflect.Float64, // reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
reflect.String: // reflect.Float32, reflect.Float64,
qt = true // reflect.String:
} // qt = true
} // }
//}
index := make([]int, len(f.Index)+1) index := make([]int, len(f.Index)+1)
copy(index, f.Index) copy(index, f.Index)
@ -121,15 +117,13 @@ func NewRStruct (rtype reflect.Type) *RStruct {
name = sf.Name name = sf.Name
} }
rf := RField{ res.Fields = append(res.Fields, RField{
RField: sf, RField: sf,
RType: ft, RType: ft,
Name: name, Name: name,
BName: []byte(name), BName: []byte(name),
Tags: map[string]slices.String{"json": append(slices.String(nil), tags...)}, Tags: map[string]slices.String{"json": append(slices.String(nil), tags...)},
} })
res.Fields = append(res.Fields, rf)
if cnt[f.RType] > 1 { if cnt[f.RType] > 1 {
res.Fields = append(res.Fields, res.Fields[len(res.Fields)-1]) res.Fields = append(res.Fields, res.Fields[len(res.Fields)-1])
} }
@ -137,7 +131,7 @@ func NewRStruct (rtype reflect.Type) *RStruct {
} }
nxc[ft]++ nxc[ft]++
if nxc[ft] == 1 { if nxc[ft] == 1 {
nxt = append(nxt,RField{ nxt = append(nxt, RField{
RType: ft, RType: ft,
Name: ft.Name(), Name: ft.Name(),
Index: index, Index: index,
@ -148,10 +142,12 @@ func NewRStruct (rtype reflect.Type) *RStruct {
} }
} }
for i,f := range res.Fields {
res.NameIndex[f.Name]=i
}
return res return res
} }
*/
Loading…
Cancel
Save

Powered by TurnKey Linux.