redefiniendo el builder

packs2
DEV 3 years ago
parent 20c9b63cea
commit 51b175307a

@ -41,5 +41,9 @@ func main() {
st.Reset()
a := map[int]string {1:"344343",3:"4343434",5:"frtrtrtr"}
js.RPacker(st,a,0)
fmt.Printf("JSON \n%s\n",st.Bytes())
st.Reset()
}

@ -147,3 +147,22 @@ func BenchmarkListJSON (b *testing.B) {
j.Marshal(cas)
}
}
var ma = map[int]string {1:"344343",3:"4343434",5:"frtrtrtr"}
func BenchmarkMapPack (b *testing.B) {
s := packs.NewState()
for i:=0; i< b.N; i++ {
js.RPacker(s,ma,0)
s.Reset()
}
}
func BenchmarkMapJSON (b *testing.B) {
for i:=0; i< b.N; i++ {
j.Marshal(ma)
}
}

@ -32,12 +32,16 @@ type (
cachePackers struct {
sync.RWMutex
packers map[reflect.Type]packerFn
packers map[reflect.Type]packerFn
keyers map[reflect.Type]StringerFn
}
)
func NewCachePackers () *cachePackers {
return &cachePackers{
keyers : make(map[reflect.Type]StringerFn),
packers: make(map[reflect.Type]packerFn),
}
}

@ -0,0 +1,41 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name type_map_entry.go
// Created by DEV
// Modified 30/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 js
import "reflect"
type (
typeMapEntry struct {
val reflect.Value
key string
}
)
func newTypeMapEntry (v reflect.Value, k string) *typeMapEntry {
return &typeMapEntry{
val : v,
key : k,
}
}

@ -0,0 +1,180 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name type_map_packer.go
// Created by DEV
// Modified 30/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 js
import (
"activething.com/go/gogo/packs"
"encoding"
"reflect"
"strconv"
)
type (
typeMapPacker struct {
keyStringer StringerFn
valPacker packerFn
}
StringerFn func(value reflect.Value, entry *typeMapEntry) error
)
func newTypeMapPacker (rtype reflect.Type) *typeMapPacker {
var kp StringerFn
switch rtype.Key().Kind() {
case reflect.String :
kp = func(v reflect.Value, e *typeMapEntry) error {
e.key = v.String()
return nil
}
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
kp = func(v reflect.Value, e *typeMapEntry) error {
e.key = strconv.FormatInt(v.Int(),10)
return nil
}
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
kp = func(v reflect.Value, e *typeMapEntry) error {
e.key = strconv.FormatUint(v.Uint(),10)
return nil
}
default:
kp = func(v reflect.Value, e *typeMapEntry) error {
if tm,hs := v.Interface().(encoding.TextMarshaler); hs {
bf,er := tm.MarshalText()
if er != nil {
return er
}
e.key = string(bf)
return nil
}
return packs.G.ErrInvalidKey
}
}
return &typeMapPacker{
valPacker : typePacker(rtype.Elem()),
keyStringer: kp,
}
}
func (m typeMapPacker) pack (s *packs.State, v reflect.Value, f Flags) {
if v.IsNil() {
_,_ = s.Write(G.nullValue)
return
}
var er error
mi := v.MapRange()
ls := make([]typeMapEntry,v.Len())
s.Open ('{')
for i:=0; mi.Next(); i++ {
ls[i] = typeMapEntry {
val: mi.Value(),
}
if er = m.keyStringer(mi.Key(),&ls[i]); er != nil {
s.SetError(er)
return
}
if i>0 {
s.WriteByte(',')
}
s.WriteString(ls[i].key)
s.WriteByte(':')
m.valPacker(s,mi.Value(),f)
}
s.Close('}')
}
func buildKeyPacker (rt reflect.Type) func(me *typeMapEntry, key reflect.Value) error {
if rt.Key().Kind() == reflect.String {
return func(e *typeMapEntry, k reflect.Value ) error {
e.key = k.String()
return nil
}
}
if rt.Implements(reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()) {
return func(e *typeMapEntry, 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)
}
return er
}
}
switch rt.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
return func(e *typeMapEntry, 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 *typeMapEntry, k reflect.Value) error {
e.key = strconv.FormatUint(k.Uint(),10)
return nil
}
}
return func(e *typeMapEntry, k reflect.Value) error {
if rt.Key().Kind() == reflect.String {
e.key = k.String()
}
return packs.G.ErrInvalidKey
}
}

@ -87,7 +87,13 @@ func buildTypePacker(t reflect.Type) packerFn {
case reflect.Slice :
return (typeSlicePacker{ packer: typePacker(t.Elem()) }).pack
case reflect.Map :
return newTypeMapPacker(t).pack
}
return func (s *packs.State, v reflect.Value, _ Flags) { unsupportedTypePacker(s,v,0)}
}

Loading…
Cancel
Save

Powered by TurnKey Linux.