代码拉取完成,页面将自动刷新
// The MIT License (MIT)
// Copyright (c) 2016 Josh Baker
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package jsonparam
import (
"encoding/base64"
"encoding/json"
"reflect"
"strings"
"sync"
"github.com/henrylee2cn/goutil/tpack"
"github.com/tidwall/gjson"
)
var fieldsmu sync.RWMutex
var fields = make(map[int32]map[string]int)
func init() {
gjson.DisableModifiers = true
}
// Assign unmarshal
func Assign(jsval gjson.Result, goval reflect.Value) {
if jsval.Type == gjson.Null {
return
}
t := goval.Type()
switch goval.Kind() {
default:
case reflect.Ptr:
if !goval.IsNil() {
newval := reflect.New(goval.Elem().Type())
Assign(jsval, newval.Elem())
goval.Elem().Set(newval.Elem())
} else {
newval := reflect.New(t.Elem())
Assign(jsval, newval.Elem())
goval.Set(newval)
}
case reflect.Struct:
runtimeTypeID := tpack.From(goval).RuntimeTypeID()
fieldsmu.RLock()
sf := fields[runtimeTypeID]
fieldsmu.RUnlock()
if sf == nil {
fieldsmu.Lock()
sf = make(map[string]int)
numField := t.NumField()
for i := 0; i < numField; i++ {
f := t.Field(i)
tag := strings.Split(f.Tag.Get("json"), ",")[0]
if tag != "-" {
if tag != "" {
sf[tag] = i
sf[f.Name] = i
} else {
sf[f.Name] = i
}
}
}
fields[runtimeTypeID] = sf
fieldsmu.Unlock()
}
jsval.ForEach(func(key, value gjson.Result) bool {
if idx, ok := sf[key.Str]; ok {
f := goval.Field(idx)
if f.CanSet() {
Assign(value, f)
}
}
return true
})
case reflect.Slice:
if t.Elem().Kind() == reflect.Uint8 && jsval.Type == gjson.String {
data, _ := base64.StdEncoding.DecodeString(jsval.String())
goval.Set(reflect.ValueOf(data))
} else {
jsvals := jsval.Array()
slice := reflect.MakeSlice(t, len(jsvals), len(jsvals))
for i := 0; i < len(jsvals); i++ {
Assign(jsvals[i], slice.Index(i))
}
goval.Set(slice)
}
case reflect.Array:
i, n := 0, goval.Len()
jsval.ForEach(func(_, value gjson.Result) bool {
if i == n {
return false
}
Assign(value, goval.Index(i))
i++
return true
})
case reflect.Map:
if t.Key().Kind() == reflect.String && t.Elem().Kind() == reflect.Interface {
goval.Set(reflect.ValueOf(jsval.Value()))
}
case reflect.Interface:
goval.Set(reflect.ValueOf(jsval.Value()))
case reflect.Bool:
goval.SetBool(jsval.Bool())
case reflect.Float32, reflect.Float64:
goval.SetFloat(jsval.Float())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
goval.SetInt(jsval.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
goval.SetUint(jsval.Uint())
case reflect.String:
goval.SetString(jsval.String())
}
if len(t.PkgPath()) > 0 {
v := goval.Addr()
if v.Type().NumMethod() > 0 {
if u, ok := v.Interface().(json.Unmarshaler); ok {
u.UnmarshalJSON([]byte(jsval.Raw))
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。