diff --git a/.idea/atila.iml b/.idea/atila.iml index 5e764c4..3c65d37 100644 --- a/.idea/atila.iml +++ b/.idea/atila.iml @@ -2,7 +2,9 @@ - + + + diff --git a/packs/pjson/gogo.go b/_pjson/gogo.go similarity index 99% rename from packs/pjson/gogo.go rename to _pjson/gogo.go index ff7ccca..c6761c1 100644 --- a/packs/pjson/gogo.go +++ b/_pjson/gogo.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "encoding" diff --git a/packs/pjson/json_char_atts.go b/_pjson/json_char_atts.go similarity index 98% rename from packs/pjson/json_char_atts.go rename to _pjson/json_char_atts.go index b034c41..38bc70e 100644 --- a/packs/pjson/json_char_atts.go +++ b/_pjson/json_char_atts.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson const ( jsonCharAttUnsafe jsonCharAtt = 1 << iota diff --git a/packs/pjson/json_encoder.go b/_pjson/json_encoder.go similarity index 98% rename from packs/pjson/json_encoder.go rename to _pjson/json_encoder.go index f1e5a9d..22986d1 100644 --- a/packs/pjson/json_encoder.go +++ b/_pjson/json_encoder.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson diff --git a/packs/pjson/list_packer.go b/_pjson/list_packer.go similarity index 99% rename from packs/pjson/list_packer.go rename to _pjson/list_packer.go index cfe74a7..f84be1f 100644 --- a/packs/pjson/list_packer.go +++ b/_pjson/list_packer.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "activething.com/go/gogo/packs" diff --git a/packs/pjson/map_packer.go b/_pjson/map_packer.go similarity index 99% rename from packs/pjson/map_packer.go rename to _pjson/map_packer.go index 991ea9c..3ef95a2 100644 --- a/packs/pjson/map_packer.go +++ b/_pjson/map_packer.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "activething.com/go/gogo/packs" diff --git a/packs/pjson/object_packer.go b/_pjson/object_packer.go similarity index 99% rename from packs/pjson/object_packer.go rename to _pjson/object_packer.go index 848f97d..ada0188 100644 --- a/packs/pjson/object_packer.go +++ b/_pjson/object_packer.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "activething.com/go/gogo/packs" diff --git a/packs/pjson/options.go b/_pjson/options.go similarity index 93% rename from packs/pjson/options.go rename to _pjson/options.go index 9ac82b6..72b58d8 100644 --- a/packs/pjson/options.go +++ b/_pjson/options.go @@ -21,16 +21,16 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import "time" type ( Options struct { - Flags /*embedded*/ - encoder JSONEncoder - dateLayout string + Flags /*embedded*/ + encoder JSONEncoder + dateLayout string } ) diff --git a/packs/pjson/options_flags.go b/_pjson/options_flags.go similarity index 99% rename from packs/pjson/options_flags.go rename to _pjson/options_flags.go index 4545ed4..f13f859 100644 --- a/packs/pjson/options_flags.go +++ b/_pjson/options_flags.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson const ( diff --git a/packs/pjson/packer.go b/_pjson/packer.go similarity index 99% rename from packs/pjson/packer.go rename to _pjson/packer.go index 3cb797c..1df9968 100644 --- a/packs/pjson/packer.go +++ b/_pjson/packer.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "activething.com/go/gogo/core/bins" @@ -45,7 +45,7 @@ type ( Packer struct { options Options - state *packs.State + state *packs.State } @@ -54,7 +54,7 @@ type ( func NewPacker (options ...opts.OptionFnc[Packer]) *Packer { p := opts.Apply(&Packer{ options: Options{ - Flags: JSONFlagQuote | JSONFlagEscapeHTML | JSONByteSliceAsBinary, + Flags: JSONFlagQuote | JSONFlagEscapeHTML | JSONByteSliceAsBinary, dateLayout: time.RFC822Z, }, state : packs.NewState(), diff --git a/packs/pjson/packer_types.go b/_pjson/packer_types.go similarity index 98% rename from packs/pjson/packer_types.go rename to _pjson/packer_types.go index 7e9efa7..f7e20fe 100644 --- a/packs/pjson/packer_types.go +++ b/_pjson/packer_types.go @@ -21,7 +21,7 @@ // limitations under the License. // ------------------------------------------------------------------------ -package pjson +package _pjson import ( "activething.com/go/gogo/packs" @@ -104,7 +104,7 @@ func reflectTypePacker(packer *Packer, value reflect.Value, flags Flags) { -func reflectTypePacker(value reflect.Value) PackerTypeFn { +func reflectTypePacker(value reflect.Value) PackerTypeFn { tp := value.Type() switch tp.Kind() { diff --git a/app/main.go b/app/main.go index 5d5e2dd..4b42efd 100644 --- a/app/main.go +++ b/app/main.go @@ -27,7 +27,6 @@ import ( "activething.com/go/gogo/packs" "activething.com/go/gogo/packs/js" "fmt" - "reflect" ) func main() { @@ -37,12 +36,10 @@ func main() { cas := []string {"a1111","b2222","c3333"} - js.TypePacker(reflect.TypeOf(cas))(st,reflect.ValueOf(cas),0) + js.RPacker(st,cas,0) fmt.Printf("JSON \n%s\n",st.Bytes()) st.Reset() - js.RPack(st,cas) - fmt.Printf("JSON \n%s\n",st.Bytes()) } diff --git a/app/packs.go b/app/packs.go index b6684c7..a167202 100644 --- a/app/packs.go +++ b/app/packs.go @@ -23,92 +23,8 @@ package main -import ( - "activething.com/go/gogo/core/errs" - "activething.com/go/gogo/packs/pjson" - "fmt" - "time" -) - func packs_main () { - pk := pjson.NewPacker() - - /* - slc2 := [][]int16 {{1,2,3,4},{16,26,36,46}} - - //slc2:= [][]int16 {{}} - slc2 = append(slc2,slc2 ...) - - pk.PackMap(func(mp packs.MapPacker) { - mp.KeyValue("fb0",slc2) - mp.KeyValueList("l01",func(l packs.ListPacker){ - l.ItemList(func(l1 packs.ListPacker){ - l1.ItemUInt64(11) - l1.ItemUInt64(22) - }) - l.ItemList(func(l1 packs.ListPacker){ - l1.ItemUInt64(33) - l1.ItemUInt64(44) - }) - }) - - - - mp.KeyValueBool("boolean",true) - mp.KeyValueFloat32("bf",12223234.34234) - mp.KeyValueBinary("binary",[]byte{22,121,21,23,23,54,67}) - - mp.KeyValueDate("date",time.Now()) - mp.KeyValueInt16("una",34) - - - - mp.KeyValueObject("MiObjeto",func(op packs.ObjectPacker){ - op.FieldInt32("fb1",43433) - op.FieldString ("fb2","aaaaa") - op.Field("fb3",slc) - }) - }) - - - */ -/* - var s = struct { - F1Int int - F2Uint uint - F3String string - F4Binary []byte - }{ - F1Int :-111, - F2Uint: 333, - F3String: "Esto es un string ", - F4Binary: []byte("dklsdjflsdjflsdkfjlsdkfjlsdkfjlsdfjdlsfjsdlf"), - } - - - - - pk.Pack(s) - - errs.Test(pk.Error(),true) - fmt.Printf("JSON \n%s",pk.Bytes()) - -*/ - as := 44 - mp := map[int]any { - 3:"23434434", - 1:time.Now(), - 4:233, - 9:as, - 7:[]uint16{2323,2323,2323}, - } - - pk.Pack(mp) - - errs.Test(pk.Error(),true) - fmt.Printf("JSON \n%s",pk.Bytes()) - } \ No newline at end of file diff --git a/app/tests/benchmarks_test.go b/app/tests/benchmarks_test.go index 57e2c92..a2d6377 100644 --- a/app/tests/benchmarks_test.go +++ b/app/tests/benchmarks_test.go @@ -27,7 +27,6 @@ import ( "activething.com/go/gogo/packs" "activething.com/go/gogo/packs/js" j "encoding/json" - "reflect" "testing" ) @@ -131,21 +130,12 @@ func BenchmarkFlagsParams (b *testing.B) { //var cas = []int32 {1111,2222,3333} var cas = []float64 {1111,2222,3333} -func BenchmarkListPack (b *testing.B) { - s := packs.NewState() - //t := reflect.TypeOf(cas) - //v := reflect.ValueOf(cas) - for i:=0; i< b.N; i++ { - v := reflect.ValueOf(cas) - js.TypePacker(v.Type())(s,v,0) - s.Reset() - } -} -func BenchmarkListMapPack (b *testing.B) { + +func BenchmarkListPack (b *testing.B) { s := packs.NewState() for i:=0; i< b.N; i++ { - js.RPack(s,cas) + js.RPacker(s,cas,0) s.Reset() } } diff --git a/packs/js/cache.go b/packs/js/cache.go new file mode 100644 index 0000000..6fded79 --- /dev/null +++ b/packs/js/cache.go @@ -0,0 +1,45 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name cache.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" + "sync" +) + +type ( + + cachePackers struct { + sync.RWMutex + packers map[reflect.Type]packerFn + } +) + +func NewCachePackers () *cachePackers { + return &cachePackers{ + packers: make(map[reflect.Type]packerFn), + } +} + + diff --git a/packs/js/gogo.go b/packs/js/gogo.go index 60718f3..7bfb526 100644 --- a/packs/js/gogo.go +++ b/packs/js/gogo.go @@ -49,7 +49,7 @@ var ( floatInfNeg []byte */ - + packers *cachePackers }{ @@ -70,6 +70,7 @@ var ( floatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'}, */ + packers: NewCachePackers(), } ) diff --git a/packs/js/type_packer.go b/packs/js/type_packer.go index 65bc145..0f65eb2 100644 --- a/packs/js/type_packer.go +++ b/packs/js/type_packer.go @@ -39,25 +39,35 @@ type ( ) -var cache = make(map[reflect.Type]packerFn) -func RPack (state *packs.State, value any) { +func RPacker(state *packs.State, value any, flags Flags ) { v := reflect.ValueOf(value) t := v.Type() - if f,h := cache[t]; h { - f(state,v,0) - return - } - f := TypePacker(t) - cache[t]=f - f(state,v,0) + typePacker(t)(state,v,flags) } +func typePacker (rtype reflect.Type) packerFn { + G.packers.RLock() + if f,h := G.packers.packers[rtype]; h { + G.packers.RUnlock() + return f + } + G.packers.RUnlock() + + f := buildTypePacker(rtype) -func TypePacker(t reflect.Type) packerFn { + G.packers.Lock() + G.packers.packers[rtype]=f + G.packers.Unlock() + + return f +} + + +func buildTypePacker(t reflect.Type) packerFn { switch t.Kind() { case reflect.Bool : return func(s *packs.State, v reflect.Value, f Flags) { packBool (s,v.Bool (),f )} @@ -76,56 +86,16 @@ func TypePacker(t reflect.Type) packerFn { case reflect.Float64: return func(s *packs.State, v reflect.Value, f Flags) { packFloatString(s,v.Float(),64, f.Quote()) } case reflect.Slice : - return listPacker(TypePacker(t.Elem())) + return (typeSlicePacker{ packer: typePacker(t.Elem()) }).pack } - return func (s *packs.State, v reflect.Value, _ Flags) { unsupportedPacker(s,v,0)} + return func (s *packs.State, v reflect.Value, _ Flags) { unsupportedTypePacker(s,v,0)} } -func typeListPacker (t reflect.Type) packerFn { - switch t.Kind() { - case reflect.Bool : return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packBool (s,v.Bool (),f )}) - case reflect.String : return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packString (s,v.Interface().(string),f )}) - case reflect.Int, - reflect.Int8, - reflect.Int16, - reflect.Int32, - reflect.Int64 : return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packInt (s,v.Int (),f )}) - case reflect.Uint, - reflect.Uint8, - reflect.Uint16, - reflect.Uint32, - reflect.Uint64 : return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packUInt (s,v.Uint (),f )}) - case reflect.Float32: return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packFloatString(s,v.Float(),32, f.Quote()) }) - case reflect.Float64: return listPacker(func(s *packs.State, v reflect.Value, f Flags) { packFloatString(s,v.Float(),64, f.Quote()) }) - - default: - return listPacker(func(s *packs.State, v reflect.Value, f Flags) { TypePacker(v.Type())(s, v ,f) }) - } -} - - -func listPacker(elementPacker packerFn) packerFn { - return func(s *packs.State, v reflect.Value, f Flags) { - fn := elementPacker - s.Open('[') - for i:=0; i 0 { - _ = s.WriteByte(',') - } - fn(s,v.Index(i),f) - if s.Error != nil { - return - } - } - s.Close(']') - } -} - -func unsupportedPacker(state *packs.State, _ reflect.Value, _ Flags) { +func unsupportedTypePacker(state *packs.State, _ reflect.Value, _ Flags) { state.SetError(packs.G.ErrUnsupportedType) } diff --git a/packs/js/type_slice_packer.go b/packs/js/type_slice_packer.go new file mode 100644 index 0000000..7450d8c --- /dev/null +++ b/packs/js/type_slice_packer.go @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name type_slice_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" + "reflect" +) + +type ( + + typeSlicePacker struct { + packer packerFn + } +) + + +func (p typeSlicePacker) pack (s *packs.State, v reflect.Value, f Flags) { + if v.IsNil() { + _,_ = s.Write(G.nullValue) + return + } + if v.Len() == 0 { + s.Write2Byte('[',']') + return + } + s.Open('[') + for i:=0; i 0 { + _ = s.WriteByte(',') + } + p.packer(s,v.Index(i),f) + if s.Error != nil { + return + } + } + s.Close(']') +}