Removed unmarshalling

This commit is contained in:
tidwall 2020-01-20 12:32:37 -07:00
parent 12826915de
commit d10932a0d0
2 changed files with 0 additions and 165 deletions

144
gjson.go
View File

@ -2,14 +2,9 @@
package gjson package gjson
import ( import (
"encoding/base64"
"encoding/json" "encoding/json"
"errors"
"reflect"
"strconv" "strconv"
"strings" "strings"
"sync"
"sync/atomic"
"time" "time"
"unicode/utf16" "unicode/utf16"
"unicode/utf8" "unicode/utf8"
@ -2199,145 +2194,6 @@ func GetManyBytes(json []byte, path ...string) []Result {
return res return res
} }
var fieldsmu sync.RWMutex
var fields = make(map[string]map[string]int)
func assign(jsval Result, goval reflect.Value) {
if jsval.Type == Null {
return
}
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(goval.Type().Elem())
assign(jsval, newval.Elem())
goval.Set(newval)
}
case reflect.Struct:
fieldsmu.RLock()
sf := fields[goval.Type().String()]
fieldsmu.RUnlock()
if sf == nil {
fieldsmu.Lock()
sf = make(map[string]int)
for i := 0; i < goval.Type().NumField(); i++ {
f := goval.Type().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[goval.Type().String()] = sf
fieldsmu.Unlock()
}
jsval.ForEach(func(key, value 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 goval.Type().Elem().Kind() == reflect.Uint8 &&
jsval.Type == String {
data, _ := base64.StdEncoding.DecodeString(jsval.String())
goval.Set(reflect.ValueOf(data))
} else {
jsvals := jsval.Array()
slice := reflect.MakeSlice(goval.Type(), 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 Result) bool {
if i == n {
return false
}
assign(value, goval.Index(i))
i++
return true
})
case reflect.Map:
if goval.Type().Key().Kind() == reflect.String &&
goval.Type().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(goval.Type().PkgPath()) > 0 {
v := goval.Addr()
if v.Type().NumMethod() > 0 {
if u, ok := v.Interface().(json.Unmarshaler); ok {
u.UnmarshalJSON([]byte(jsval.Raw))
}
}
}
}
var validate uintptr = 1
// UnmarshalValidationEnabled provides the option to disable JSON validation
// during the Unmarshal routine. Validation is enabled by default.
//
// Deprecated: Use encoder/json.Unmarshal instead
func UnmarshalValidationEnabled(enabled bool) {
if enabled {
atomic.StoreUintptr(&validate, 1)
} else {
atomic.StoreUintptr(&validate, 0)
}
}
// Unmarshal loads the JSON data into the value pointed to by v.
//
// This function works almost identically to json.Unmarshal except that
// gjson.Unmarshal will automatically attempt to convert JSON values to any Go
// type. For example, the JSON string "100" or the JSON number 100 can be
// equally assigned to Go string, int, byte, uint64, etc. This rule applies to
// all types.
//
// Deprecated: Use encoder/json.Unmarshal instead
func Unmarshal(data []byte, v interface{}) error {
if atomic.LoadUintptr(&validate) == 1 {
_, ok := validpayload(data, 0)
if !ok {
return errors.New("invalid json")
}
}
if v := reflect.ValueOf(v); v.Kind() == reflect.Ptr {
assign(ParseBytes(data), v)
}
return nil
}
func validpayload(data []byte, i int) (outi int, ok bool) { func validpayload(data []byte, i int) (outi int, ok bool) {
for ; i < len(data); i++ { for ; i < len(data); i++ {
switch data[i] { switch data[i] {

View File

@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
"reflect"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -996,26 +995,6 @@ var complicatedJSON = `
} }
` `
func TestUnmarshal(t *testing.T) {
var s1 ComplicatedType
var s2 ComplicatedType
if err := json.Unmarshal([]byte(complicatedJSON), &s1); err != nil {
t.Fatal(err)
}
if err := Unmarshal([]byte(complicatedJSON), &s2); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(&s1, &s2) {
t.Fatal("not equal")
}
var str string
err := json.Unmarshal([]byte(Get(complicatedJSON, "LeftOut").Raw), &str)
if err != nil {
t.Fatal(err)
}
assert(t, str == Get(complicatedJSON, "LeftOut").String())
}
func testvalid(t *testing.T, json string, expect bool) { func testvalid(t *testing.T, json string, expect bool) {
t.Helper() t.Helper()
_, ok := validpayload([]byte(json), 0) _, ok := validpayload([]byte(json), 0)