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
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)
|
|
}
|
|
|
|
|
|
|