redefiniendo el builder

packs2
DEV 3 years ago
parent 7e8cfee304
commit 36e6cf3998

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

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

@ -27,6 +27,7 @@ import (
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packs/pjson"
"fmt"
"time"
)
func packs_main () {
@ -73,7 +74,7 @@ func packs_main () {
*/
/*
var s = struct {
F1Int int
F2Uint uint
@ -86,11 +87,26 @@ func packs_main () {
F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"),
}
pk.Pack(s)
errs.Test(pk.Error(),true)
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
import (
"activething.com/go/gogo/core/reflects"
"activething.com/go/gogo/packs/reflects"
"fmt"
"reflect"
)
@ -67,6 +67,11 @@ func reflects_main () {
}
}

@ -28,6 +28,7 @@ import (
j "encoding/json"
"fmt"
"testing"
"time"
)
var s = struct {
@ -42,6 +43,15 @@ var s = struct {
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) {
packer := pjson.NewPacker()
@ -75,3 +85,29 @@ 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/opts
./core/syncs
./core/reflects
./packs
./packs/reflects
)

@ -31,6 +31,15 @@ type (
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 (
@ -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) {
if s.Node.Kind == NodeKindValue {

@ -28,6 +28,7 @@ import (
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/core/opts"
"activething.com/go/gogo/packs"
"activething.com/go/gogo/packs/reflects"
"encoding/base64"
"encoding/json"
"reflect"
@ -526,28 +527,28 @@ func (p *Packer) packListReflected (value reflect.Value) {
switch tp.Elem().Kind() {
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 :
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 ,
reflect.Uint16 ,
reflect.Uint32 ,
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 ,
reflect.Int16 ,
reflect.Int32 ,
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,
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 :
p.buildList(value, func(bl packs.ListPacker, rv reflect.Value){
p.buildListReflected(value, func(bl packs.ListPacker, rv reflect.Value){
p.packListReflected(rv)
})
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())
})
@ -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){
for i:=0; i<value.Len(); i++ {
call(lp,value.Index(i))
@ -577,6 +578,30 @@ func (p *Packer) packMapReflected (value reflect.Value) {
p.state.Write2Byte('{','}')
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
// Active Thing (activething.com) git.activething.com/go
//
// File name struct_field.go
// File name gogo.go
// Created by DEV
// Modified 26/01/2024
// Modified 28/01/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
@ -21,7 +21,36 @@
// 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
Tags map[string]slices.String
Flags uint16
EqualFoldFn func(s, t []byte) bool
}

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

Powered by TurnKey Linux.