redefiniendo el builder

packs2
DEV 3 years ago
parent f1572d9b32
commit 9c824de31a

@ -24,7 +24,10 @@
package main
import (
"activething.com/go/gogo/core/errs"
"activething.com/go/gogo/packs"
"activething.com/go/gogo/packs/js"
"encoding/json"
"fmt"
)
@ -50,9 +53,9 @@ func main() {
execute()
//st := packs.NewState()
st := packs.NewState()
/*
cas := []string {"a1111","b2222","c3333"}
js.RPacker(st,cas,0)
@ -74,12 +77,4 @@ func main() {
fmt.Printf("JSON \n%s\n",d)
*/
keys := []string {"B","G","K","9","Z","L"}
kc := js.NewKeyCollection(10)
for _,v := range keys {
kc.AddKey(v)
}
kc.Iterate()
}

@ -175,58 +175,7 @@ func BenchmarkMapJSON (b *testing.B) {
type s struct {
start int
end int
}
func BenchmarkAppend (b *testing.B) {
for i:=0; i< b.N; i++ {
data := make([]byte,0,3200)
list := make([]s,0,100)
for k,_ := range ma {
list = append(list,s{
start: len(data),
end : len(data)+len(k),
})
data = append(data,[]byte(k)...)
}
for _,v := range list {
if len(string(data[v.start:v.end])) > 100 {
panic("Errror")
}
}
data=data[:0]
}
}
type s1 struct {
cadena string
}
func BenchmarkCrate (b *testing.B) {
for i:=0; i< b.N; i++ {
data := make([]byte,0,3200)
list := make([]s1,0,100)
for k,_ := range ma {
list = append(list,s1{
cadena: k,
})
data = append(data,[]byte(k)...)
}
for _,v := range list {
if len(v.cadena) > 100 {
panic("Errror")
}
}
data=data[:0]
}
}
var ma = map[string]string {

@ -28,26 +28,30 @@ import "reflect"
type (
keyValEntry struct {
flags Flags
value reflect.Value
key string
kvEntry struct {
flags Flags
rval reflect.Value
key string
}
keyValEntries []keyValEntry
kvEntryList []kvEntry
)
func (e keyValEntries) Len() int {
func (e kvEntryList) Len() int {
return len(e)
}
func (e keyValEntries) Less(i, j int) bool {
func (e kvEntryList) Less(i, j int) bool {
return e[i].key < e[j].key
}
func (e keyValEntries) Swap(i, j int) {
func (e kvEntryList) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}

@ -0,0 +1,212 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name key_val_packer.go
// Created by DEV
// Modified 03/02/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 js
import (
"activething.com/go/gogo/packs"
"encoding"
"reflect"
"sort"
"strconv"
)
type (
kvPacker struct {
keyFn keyStringerFnc
valFn packerFn
}
keyStringerFnc func(entry *kvEntry, rkey reflect.Value) error
)
func newKVPacker (rtype reflect.Type) *kvPacker {
return &kvPacker{
valFn : typePacker(rtype.Elem()),
keyFn : _keyStringer(rtype.Key()),
}
}
func (p *kvPacker) pack (s *packs.State, v reflect.Value, f Flags) {
if p.keyFn == nil {
s.SetError(packs.G.ErrInvalidKey)
return
}
if v.IsNil() {
s.W(G.nullValue)
return
}
if v.Len() == 0{
s.Write2Byte('{','}')
return
}
if s.Level > startDetectingCyclesAfter {
if fn,ok := s.CheckCycle(v.UnsafePointer()); ok {
defer fn()
} else {
s.SetError(packs.G.ErrRedundantPack)
return
}
}
mi := v.MapRange()
ls := make(kvEntryList,v.Len())
for i:=0; mi.Next(); i++ {
ls[i] = kvEntry {
rval: mi.Value(),
}
if er := p.keyFn(&ls[i], mi.Key()); er != nil {
s.SetError(er)
return
}
}
sort.Sort(ls)
s.Open ('{')
for i:=0; i<len(ls); i++ {
if i>0 {
s.WriteByte(',')
}
packString(s,ls[i].key,ls[i].flags)
if s.Error != nil {
return
}
s.WriteByte(':')
p.valFn(s,ls[i].rval,0)
if s.Error != nil {
return
}
}
s.Close('}')
}
func _keyStringer(rt reflect.Type) func(me *kvEntry, key reflect.Value) error {
if rt.Kind() == reflect.String {
return func(e *kvEntry, k reflect.Value) error {
e.key = k.String()
e.flags = FlagScapeHTML
return nil
}
}
if rt.Implements(reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()) {
return func(e *kvEntry, k reflect.Value) error {
if k.Kind() == reflect.Pointer && k.IsNil() {
return nil
}
bf, er := (k.Interface().(encoding.TextMarshaler)).MarshalText()
if er == nil {
e.key = string(bf)
e.flags = FlagScapeHTML
}
return er
}
}
switch rt.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
return func(e *kvEntry, k reflect.Value) error {
e.key = strconv.FormatInt(k.Int(), 10)
return nil
}
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
return func(e *kvEntry, k reflect.Value) error {
e.key = strconv.FormatUint(k.Uint(), 10)
return nil
}
case reflect.Interface:
return func(e *kvEntry, k reflect.Value) error {
k = k.Elem()
if k.Type().Kind() == reflect.String {
e.key = k.String()
e.flags = FlagScapeHTML
return nil
}
if t,h := k.Interface().(encoding.TextMarshaler); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
return nil
}
bf, er := t.MarshalText()
if er == nil {
e.key = string(bf)
e.flags = FlagScapeHTML
}
return er
}
switch rt.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
e.key = strconv.FormatInt(k.Int(), 10)
return nil
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
e.key = strconv.FormatUint(k.Uint(), 10)
return nil
default:
return packs.G.ErrInvalidKey
}
}
default:
return nil
}
}

@ -39,7 +39,8 @@ type (
}
StringerFn func(entry *TypeMapEntry, value reflect.Value) error
StringerFn func(me *TypeMapEntry, key reflect.Value) error
TypeMapEntry struct {
@ -71,11 +72,13 @@ func (e Entries) Swap(i, j int) {
func newTypeMapPacker (rtype reflect.Type) *typeMapPacker {
return &typeMapPacker{
valPacker : typePacker (rtype.Elem()),
keyStringer: buildKeyStringer(rtype.Key ()),
keyStringer: keyStringer(rtype.Key ()),
}
}
func (m typeMapPacker) pack (s *packs.State, v reflect.Value, _ Flags) {
if v.IsNil() {
_,_ = s.Write(G.nullValue)
@ -128,7 +131,64 @@ func (m typeMapPacker) pack (s *packs.State, v reflect.Value, _ Flags) {
func buildKeyStringer(rt reflect.Type) func(me *TypeMapEntry, key reflect.Value) error {
/*
func (m typeMapPacker) pack (s *packs.State, v reflect.Value, _ Flags) {
if v.IsNil() {
_,_ = s.Write(G.nullValue)
return
}
mi := v.MapRange()
ls := make(Entries,v.Len())
if s.Level > startDetectingCyclesAfter {
if fn,ok := s.CheckCycle(v.UnsafePointer()); ok {
defer fn()
} else {
s.SetError(packs.G.ErrRedundantPack)
return
}
}
for i:=0; mi.Next(); i++ {
ls[i] = TypeMapEntry{
Val: mi.Value(),
}
if er := m.keyStringer(&ls[i], mi.Key()); er != nil {
s.SetError(er)
return
}
}
sort.Sort(ls)
//sort.Slice(ls, func(i, j int) bool { return ls[i].Key < ls[j].Key })
s.Open ('{')
for i:=0; i<len(ls); i++ {
if i>0 {
s.WriteByte(',')
}
packString(s,ls[i].Key,ls[i].flags)
if s.Error != nil {
return
}
s.WriteByte(':')
m.valPacker(s,ls[i].Val,0)
if s.Error != nil {
return
}
}
s.Close('}')
}
*/
func keyStringer(rt reflect.Type) func(me *TypeMapEntry, key reflect.Value) error {
if rt.Kind() == reflect.String {
return func(e *TypeMapEntry, k reflect.Value) error {
e.Key = k.String()
@ -225,53 +285,5 @@ func buildKeyStringer(rt reflect.Type) func(me *TypeMapEntry, key reflect.Value)
}
}
// caso de map[any]cualquiertypo
/*
return func(e *TypeMapEntry, k reflect.Value) error {
k = k.Elem()
fmt.Printf("Ejecutando packer general\n %v\n",k)
if k.Type().Kind() == reflect.String {
e.Key = k.String()
e.flags = FlagScapeHTML
return nil
}
if t,h := k.Interface().(encoding.TextMarshaler); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
return nil
}
bf, er := t.MarshalText()
if er == nil {
e.Key = string(bf)
e.flags = FlagScapeHTML
}
return er
}
switch rt.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
e.Key = strconv.FormatInt(k.Int(), 10)
return nil
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
e.Key = strconv.FormatUint(k.Uint(), 10)
return nil
default:
return packs.G.ErrInvalidKey
}
}
*/
}

@ -90,7 +90,8 @@ func buildTypePacker(t reflect.Type) packerFn {
return (typeSlicePacker{ packer: typePacker(t.Elem()) }).pack
case reflect.Map :
return newTypeMapPacker(t).pack
return newKVPacker(t).pack
// return newTypeMapPacker(t).pack
}

Loading…
Cancel
Save

Powered by TurnKey Linux.