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.

115 lines
2.9 KiB

// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name rpacker.go
// Created by DEV
// Modified 05/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 pkjson
import (
"apacks"
"reflect"
"sync"
)
type (
rPackerFnc func (state *apacks.State, rvalue reflect.Value, flags apacks.Flags)
)
func rTypePacker (rtype reflect.Type) rPackerFnc {
if fn,ok := g.packersCache.Load(rtype); ok {
return fn.(rPackerFnc)
}
var wg sync.WaitGroup
var fn rPackerFnc
wg.Add(1)
fi,ld := g.packersCache.LoadOrStore(rtype, rPackerFnc(func (e *apacks.State, v reflect.Value, f apacks.Flags) {
wg.Wait()
fn(e,v,f)
}))
if ld {
return fi.(rPackerFnc)
}
fn = _rTypePacker(rtype)
wg.Done()
g.packersCache.Store(rtype,fn)
return fn
}
func _rTypePacker(rtype reflect.Type) rPackerFnc {
switch rtype.Kind() {
case reflect.Bool : return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packBool (s,v.Bool (),f )}
case reflect.String : return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packString(s,v.String(),f )}
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64 : return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packInt (s,v.Int (),f )}
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64 : return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packUInt (s,v.Uint (),f )}
case reflect.Float32: return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packFloatString(s,v.Float(),f,32) }
case reflect.Float64: return func(s *apacks.State, v reflect.Value, f apacks.Flags) { packFloatString(s,v.Float(),f,64) }
case reflect.Pointer:
return rPointerPacker(rtype)
case reflect.Interface:
return rInterfacePacker
case reflect.Slice,
reflect.Array :
return rListPacker(rtype)
case reflect.Map :
return rMapPacker(rtype)
case reflect.Struct:
return rObjectPacker(rtype)
default:
return unsupportedTypePacker
}
}
func unsupportedTypePacker(state *apacks.State, _ reflect.Value, _ apacks.Flags) {
state.SetError(apacks.G.ErrUnsupportedType)
}

Powered by TurnKey Linux.