You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.8 KiB

// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name type_packer.go
// Created by DEV
// Modified 29/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"
"sync"
)
type (
packer interface {
}
packerFn func (state *packs.State, value reflect.Value, flags Flags)
)
func RPacker(state *packs.State, value any, flags Flags ) {
v := reflect.ValueOf(value)
t := v.Type()
rTypePacker(t)(state,v,flags)
}
func rTypePacker(rtype reflect.Type) packerFn {
if fn,ok := G.packers.Load(rtype); ok {
return fn.(packerFn)
}
var wg sync.WaitGroup
var fn packerFn
wg.Add(1)
fi,ld := G.packers.LoadOrStore(rtype, packerFn(func (e *packs.State, v reflect.Value, f Flags) {
wg.Wait()
fn(e,v,f)
}))
if ld {
return fi.(packerFn)
}
fn = _rTypePacker(rtype)
wg.Done()
G.packers.Store(rtype,fn)
return fn
}
func _rTypePacker(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 )}
case reflect.String : return func(s *packs.State, v reflect.Value, f Flags) { packString(s,v.String(),f )}
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64 : return 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 func(s *packs.State, v reflect.Value, f Flags) { packUInt (s,v.Uint (),f )}
case reflect.Float32: return func(s *packs.State, v reflect.Value, f Flags) { packFloatString(s,v.Float(),32, f.Quote()) }
case reflect.Float64: return func(s *packs.State, v reflect.Value, f Flags) { packFloatString(s,v.Float(),64, f.Quote()) }
case reflect.Slice,
reflect.Array :
return (rList{ valFn: rTypePacker(t.Elem()) }).pack
case reflect.Map :
return newRMap(t).pack
}
return unsupportedTypePacker
}
func unsupportedTypePacker(state *packs.State, _ reflect.Value, _ Flags) {
state.SetError(packs.G.ErrUnsupportedType)
}

Powered by TurnKey Linux.