status-go/vendor/github.com/segmentio/encoding/json/decode.go

1463 lines
31 KiB
Go
Raw Normal View History

2024-10-19 19:31:59 +00:00
package json
import (
"bytes"
"encoding"
"encoding/json"
"fmt"
"math"
"reflect"
"strconv"
"time"
"unsafe"
"github.com/segmentio/asm/base64"
"github.com/segmentio/asm/keyset"
"github.com/segmentio/encoding/iso8601"
)
func (d decoder) decodeNull(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
return d.inputError(b, nullType)
}
func (d decoder) decodeBool(b []byte, p unsafe.Pointer) ([]byte, error) {
switch {
case hasTruePrefix(b):
*(*bool)(p) = true
return b[4:], nil
case hasFalsePrefix(b):
*(*bool)(p) = false
return b[5:], nil
case hasNullPrefix(b):
return b[4:], nil
default:
return d.inputError(b, boolType)
}
}
func (d decoder) decodeInt(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseInt(b, intType)
if err != nil {
return r, err
}
*(*int)(p) = int(v)
return r, nil
}
func (d decoder) decodeInt8(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseInt(b, int8Type)
if err != nil {
return r, err
}
if v < math.MinInt8 || v > math.MaxInt8 {
return r, unmarshalOverflow(b[:len(b)-len(r)], int8Type)
}
*(*int8)(p) = int8(v)
return r, nil
}
func (d decoder) decodeInt16(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseInt(b, int16Type)
if err != nil {
return r, err
}
if v < math.MinInt16 || v > math.MaxInt16 {
return r, unmarshalOverflow(b[:len(b)-len(r)], int16Type)
}
*(*int16)(p) = int16(v)
return r, nil
}
func (d decoder) decodeInt32(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseInt(b, int32Type)
if err != nil {
return r, err
}
if v < math.MinInt32 || v > math.MaxInt32 {
return r, unmarshalOverflow(b[:len(b)-len(r)], int32Type)
}
*(*int32)(p) = int32(v)
return r, nil
}
func (d decoder) decodeInt64(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseInt(b, int64Type)
if err != nil {
return r, err
}
*(*int64)(p) = v
return r, nil
}
func (d decoder) decodeUint(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uintType)
if err != nil {
return r, err
}
*(*uint)(p) = uint(v)
return r, nil
}
func (d decoder) decodeUintptr(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uintptrType)
if err != nil {
return r, err
}
*(*uintptr)(p) = uintptr(v)
return r, nil
}
func (d decoder) decodeUint8(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uint8Type)
if err != nil {
return r, err
}
if v > math.MaxUint8 {
return r, unmarshalOverflow(b[:len(b)-len(r)], uint8Type)
}
*(*uint8)(p) = uint8(v)
return r, nil
}
func (d decoder) decodeUint16(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uint16Type)
if err != nil {
return r, err
}
if v > math.MaxUint16 {
return r, unmarshalOverflow(b[:len(b)-len(r)], uint16Type)
}
*(*uint16)(p) = uint16(v)
return r, nil
}
func (d decoder) decodeUint32(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uint32Type)
if err != nil {
return r, err
}
if v > math.MaxUint32 {
return r, unmarshalOverflow(b[:len(b)-len(r)], uint32Type)
}
*(*uint32)(p) = uint32(v)
return r, nil
}
func (d decoder) decodeUint64(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, err := d.parseUint(b, uint64Type)
if err != nil {
return r, err
}
*(*uint64)(p) = v
return r, nil
}
func (d decoder) decodeFloat32(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, _, err := d.parseNumber(b)
if err != nil {
return d.inputError(b, float32Type)
}
f, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&v)), 32)
if err != nil {
return d.inputError(b, float32Type)
}
*(*float32)(p) = float32(f)
return r, nil
}
func (d decoder) decodeFloat64(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, _, err := d.parseNumber(b)
if err != nil {
return d.inputError(b, float64Type)
}
f, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&v)), 64)
if err != nil {
return d.inputError(b, float64Type)
}
*(*float64)(p) = f
return r, nil
}
func (d decoder) decodeNumber(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
v, r, _, err := d.parseNumber(b)
if err != nil {
return d.inputError(b, numberType)
}
if (d.flags & DontCopyNumber) != 0 {
*(*Number)(p) = *(*Number)(unsafe.Pointer(&v))
} else {
*(*Number)(p) = Number(v)
}
return r, nil
}
func (d decoder) decodeString(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
s, r, new, err := d.parseStringUnquote(b, nil)
if err != nil {
if len(b) == 0 || b[0] != '"' {
return d.inputError(b, stringType)
}
return r, err
}
if new || (d.flags&DontCopyString) != 0 {
*(*string)(p) = *(*string)(unsafe.Pointer(&s))
} else {
*(*string)(p) = string(s)
}
return r, nil
}
func (d decoder) decodeFromString(b []byte, p unsafe.Pointer, decode decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
return decode(d, b, p)
}
v, b, _, err := d.parseStringUnquote(b, nil)
if err != nil {
return d.inputError(v, stringType)
}
if v, err = decode(d, v, p); err != nil {
return b, err
}
if v = skipSpaces(v); len(v) != 0 {
return b, syntaxError(v, "unexpected trailing tokens after string value")
}
return b, nil
}
func (d decoder) decodeFromStringToInt(b []byte, p unsafe.Pointer, t reflect.Type, decode decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
return decode(d, b, p)
}
if len(b) > 0 && b[0] != '"' {
v, r, k, err := d.parseNumber(b)
if err == nil {
// The encoding/json package will return a *json.UnmarshalTypeError if
// the input was a floating point number representation, even tho a
// string is expected here.
if k == Float {
_, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&v)), 64)
if err != nil {
return r, unmarshalTypeError(v, t)
}
}
}
return r, fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into int")
}
if len(b) > 1 && b[0] == '"' && b[1] == '"' {
return b, fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal \"\" into int")
}
v, b, _, err := d.parseStringUnquote(b, nil)
if err != nil {
return d.inputError(v, t)
}
if hasLeadingZeroes(v) {
// In this context the encoding/json package accepts leading zeroes because
// it is not constrained by the JSON syntax, remove them so the parsing
// functions don't return syntax errors.
u := make([]byte, 0, len(v))
i := 0
if i < len(v) && v[i] == '-' || v[i] == '+' {
u = append(u, v[i])
i++
}
for (i+1) < len(v) && v[i] == '0' && '0' <= v[i+1] && v[i+1] <= '9' {
i++
}
v = append(u, v[i:]...)
}
if r, err := decode(d, v, p); err != nil {
if _, isSyntaxError := err.(*SyntaxError); isSyntaxError {
if hasPrefix(v, "-") {
// The standard library interprets sequences of '-' characters
// as numbers but still returns type errors in this case...
return b, unmarshalTypeError(v, t)
}
return b, fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into int", prefix(v))
}
// When the input value was a valid number representation we retain the
// error returned by the decoder.
if _, _, _, err := d.parseNumber(v); err != nil {
// When the input value valid JSON we mirror the behavior of the
// encoding/json package and return a generic error.
if _, _, _, err := d.parseValue(v); err == nil {
return b, fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into int", prefix(v))
}
}
return b, err
} else if len(r) != 0 {
return r, unmarshalTypeError(v, t)
}
return b, nil
}
func (d decoder) decodeBytes(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*[]byte)(p) = nil
return b[4:], nil
}
if len(b) < 2 {
return d.inputError(b, bytesType)
}
if b[0] != '"' {
// Go 1.7- behavior: bytes slices may be decoded from array of integers.
if len(b) > 0 && b[0] == '[' {
return d.decodeSlice(b, p, 1, bytesType, decoder.decodeUint8)
}
return d.inputError(b, bytesType)
}
// The input string contains escaped sequences, we need to parse it before
// decoding it to match the encoding/json package behvaior.
src, r, _, err := d.parseStringUnquote(b, nil)
if err != nil {
return d.inputError(b, bytesType)
}
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
n, err := base64.StdEncoding.Decode(dst, src)
if err != nil {
return r, err
}
*(*[]byte)(p) = dst[:n]
return r, nil
}
func (d decoder) decodeDuration(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
// in order to inter-operate with the stdlib, we must be able to interpret
// durations passed as integer values. there's some discussion about being
// flexible on how durations are formatted, but for the time being, it's
// been punted to go2 at the earliest: https://github.com/golang/go/issues/4712
if len(b) > 0 && b[0] != '"' {
v, r, err := d.parseInt(b, durationType)
if err != nil {
return d.inputError(b, int32Type)
}
if v < math.MinInt64 || v > math.MaxInt64 {
return r, unmarshalOverflow(b[:len(b)-len(r)], int32Type)
}
*(*time.Duration)(p) = time.Duration(v)
return r, nil
}
if len(b) < 2 || b[0] != '"' {
return d.inputError(b, durationType)
}
i := bytes.IndexByte(b[1:], '"') + 1
if i <= 0 {
return d.inputError(b, durationType)
}
s := b[1:i] // trim quotes
v, err := time.ParseDuration(*(*string)(unsafe.Pointer(&s)))
if err != nil {
return d.inputError(b, durationType)
}
*(*time.Duration)(p) = v
return b[i+1:], nil
}
func (d decoder) decodeTime(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
if len(b) < 2 || b[0] != '"' {
return d.inputError(b, timeType)
}
i := bytes.IndexByte(b[1:], '"') + 1
if i <= 0 {
return d.inputError(b, timeType)
}
s := b[1:i] // trim quotes
v, err := iso8601.Parse(*(*string)(unsafe.Pointer(&s)))
if err != nil {
return d.inputError(b, timeType)
}
*(*time.Time)(p) = v
return b[i+1:], nil
}
func (d decoder) decodeArray(b []byte, p unsafe.Pointer, n int, size uintptr, t reflect.Type, decode decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
if len(b) < 2 || b[0] != '[' {
return d.inputError(b, t)
}
b = b[1:]
var err error
for i := 0; i < n; i++ {
b = skipSpaces(b)
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected EOF after array element")
}
switch b[0] {
case ',':
b = skipSpaces(b[1:])
case ']':
return b[1:], nil
default:
return b, syntaxError(b, "expected ',' after array element but found '%c'", b[0])
}
}
b, err = decode(d, b, unsafe.Pointer(uintptr(p)+(uintptr(i)*size)))
if err != nil {
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = t.String() + e.Struct
e.Field = d.prependField(strconv.Itoa(i), e.Field)
}
return b, err
}
}
// The encoding/json package ignores extra elements found when decoding into
// array types (which have a fixed size).
for {
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "missing closing ']' in array value")
}
switch b[0] {
case ',':
b = skipSpaces(b[1:])
case ']':
return b[1:], nil
}
_, b, _, err = d.parseValue(b)
if err != nil {
return b, err
}
}
}
var (
// This is a placeholder used to consturct non-nil empty slices.
empty struct{}
)
func (d decoder) decodeSlice(b []byte, p unsafe.Pointer, size uintptr, t reflect.Type, decode decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
*(*slice)(p) = slice{}
return b[4:], nil
}
if len(b) < 2 {
return d.inputError(b, t)
}
if b[0] != '[' {
// Go 1.7- behavior: fallback to decoding as a []byte if the element
// type is byte; allow conversions from JSON strings even tho the
// underlying type implemented unmarshaler interfaces.
if t.Elem().Kind() == reflect.Uint8 {
return d.decodeBytes(b, p)
}
return d.inputError(b, t)
}
input := b
b = b[1:]
s := (*slice)(p)
s.len = 0
var err error
for {
b = skipSpaces(b)
if len(b) != 0 && b[0] == ']' {
if s.data == nil {
s.data = unsafe.Pointer(&empty)
}
return b[1:], nil
}
if s.len != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected EOF after array element")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after array element but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if s.len == s.cap {
c := s.cap
if c == 0 {
c = 10
} else {
c *= 2
}
*s = extendSlice(t, s, c)
}
b, err = decode(d, b, unsafe.Pointer(uintptr(s.data)+(uintptr(s.len)*size)))
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = t.String() + e.Struct
e.Field = d.prependField(strconv.Itoa(s.len), e.Field)
}
return b, err
}
s.len++
}
}
func (d decoder) decodeMap(b []byte, p unsafe.Pointer, t, kt, vt reflect.Type, kz, vz reflect.Value, decodeKey, decodeValue decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, t)
}
i := 0
m := reflect.NewAt(t, p).Elem()
k := reflect.New(kt).Elem()
v := reflect.New(vt).Elem()
kptr := (*iface)(unsafe.Pointer(&k)).ptr
vptr := (*iface)(unsafe.Pointer(&v)).ptr
input := b
if m.IsNil() {
m = reflect.MakeMap(t)
}
var err error
b = b[1:]
for {
k.Set(kz)
v.Set(vz)
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = unsafe.Pointer(m.Pointer())
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
if b, err = decodeKey(d, b, kptr); err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
if b, err = decodeValue(d, b, vptr); err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = "map[" + kt.String() + "]" + vt.String() + "{" + e.Struct + "}"
e.Field = d.prependField(fmt.Sprint(k.Interface()), e.Field)
}
return b, err
}
m.SetMapIndex(k, v)
i++
}
}
func (d decoder) decodeMapStringInterface(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, mapStringInterfaceType)
}
i := 0
m := *(*map[string]interface{})(p)
if m == nil {
m = make(map[string]interface{}, 64)
}
var err error
var key string
var val interface{}
var input = b
b = b[1:]
for {
key = ""
val = nil
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(unsafe.Pointer(&m))
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
b, err = d.decodeString(b, unsafe.Pointer(&key))
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
b, err = d.decodeInterface(b, unsafe.Pointer(&val))
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = mapStringInterfaceType.String() + e.Struct
e.Field = d.prependField(key, e.Field)
}
return b, err
}
m[key] = val
i++
}
}
func (d decoder) decodeMapStringRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, mapStringRawMessageType)
}
i := 0
m := *(*map[string]RawMessage)(p)
if m == nil {
m = make(map[string]RawMessage, 64)
}
var err error
var key string
var val RawMessage
var input = b
b = b[1:]
for {
key = ""
val = nil
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(unsafe.Pointer(&m))
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
b, err = d.decodeString(b, unsafe.Pointer(&key))
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
b, err = d.decodeRawMessage(b, unsafe.Pointer(&val))
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = mapStringRawMessageType.String() + e.Struct
e.Field = d.prependField(key, e.Field)
}
return b, err
}
m[key] = val
i++
}
}
func (d decoder) decodeMapStringString(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, mapStringStringType)
}
i := 0
m := *(*map[string]string)(p)
if m == nil {
m = make(map[string]string, 64)
}
var err error
var key string
var val string
var input = b
b = b[1:]
for {
key = ""
val = ""
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(unsafe.Pointer(&m))
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
b, err = d.decodeString(b, unsafe.Pointer(&key))
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
b, err = d.decodeString(b, unsafe.Pointer(&val))
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = mapStringStringType.String() + e.Struct
e.Field = d.prependField(key, e.Field)
}
return b, err
}
m[key] = val
i++
}
}
func (d decoder) decodeMapStringStringSlice(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, mapStringStringSliceType)
}
i := 0
m := *(*map[string][]string)(p)
if m == nil {
m = make(map[string][]string, 64)
}
var err error
var key string
var buf []string
var input = b
var stringSize = unsafe.Sizeof("")
b = b[1:]
for {
key = ""
buf = buf[:0]
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(unsafe.Pointer(&m))
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
b, err = d.decodeString(b, unsafe.Pointer(&key))
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
b, err = d.decodeSlice(b, unsafe.Pointer(&buf), stringSize, sliceStringType, decoder.decodeString)
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = mapStringStringType.String() + e.Struct
e.Field = d.prependField(key, e.Field)
}
return b, err
}
val := make([]string, len(buf))
copy(val, buf)
m[key] = val
i++
}
}
func (d decoder) decodeMapStringBool(b []byte, p unsafe.Pointer) ([]byte, error) {
if hasNullPrefix(b) {
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, mapStringBoolType)
}
i := 0
m := *(*map[string]bool)(p)
if m == nil {
m = make(map[string]bool, 64)
}
var err error
var key string
var val bool
var input = b
b = b[1:]
for {
key = ""
val = false
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(unsafe.Pointer(&m))
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
b, err = d.decodeString(b, unsafe.Pointer(&key))
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
b, err = d.decodeBool(b, unsafe.Pointer(&val))
if err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = mapStringStringType.String() + e.Struct
e.Field = d.prependField(key, e.Field)
}
return b, err
}
m[key] = val
i++
}
}
func (d decoder) decodeStruct(b []byte, p unsafe.Pointer, st *structType) ([]byte, error) {
if hasNullPrefix(b) {
return b[4:], nil
}
if len(b) < 2 || b[0] != '{' {
return d.inputError(b, st.typ)
}
var err error
var k []byte
var i int
// memory buffer used to convert short field names to lowercase
var buf [64]byte
var key []byte
var input = b
b = b[1:]
for {
b = skipSpaces(b)
if len(b) != 0 && b[0] == '}' {
return b[1:], nil
}
if i != 0 {
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field value")
}
if b[0] != ',' {
return b, syntaxError(b, "expected ',' after object field value but found '%c'", b[0])
}
b = skipSpaces(b[1:])
}
i++
if hasNullPrefix(b) {
return b, syntaxError(b, "cannot decode object key string from 'null' value")
}
k, b, _, err = d.parseStringUnquote(b, nil)
if err != nil {
return objectKeyError(b, err)
}
b = skipSpaces(b)
if len(b) == 0 {
return b, syntaxError(b, "unexpected end of JSON input after object field key")
}
if b[0] != ':' {
return b, syntaxError(b, "expected ':' after object field key but found '%c'", b[0])
}
b = skipSpaces(b[1:])
var f *structField
if len(st.keyset) != 0 {
if n := keyset.Lookup(st.keyset, k); n < len(st.fields) {
f = &st.fields[n]
}
} else {
f = st.fieldsIndex[string(k)]
}
if f == nil && (d.flags&DontMatchCaseInsensitiveStructFields) == 0 {
key = appendToLower(buf[:0], k)
f = st.ficaseIndex[string(key)]
}
if f == nil {
if (d.flags & DisallowUnknownFields) != 0 {
return b, fmt.Errorf("json: unknown field %q", k)
}
if _, b, _, err = d.parseValue(b); err != nil {
return b, err
}
continue
}
if b, err = f.codec.decode(d, b, unsafe.Pointer(uintptr(p)+f.offset)); err != nil {
if _, r, _, err := d.parseValue(input); err != nil {
return r, err
} else {
b = r
}
if e, ok := err.(*UnmarshalTypeError); ok {
e.Struct = st.typ.String() + e.Struct
e.Field = d.prependField(string(k), e.Field)
}
return b, err
}
}
}
func (d decoder) decodeEmbeddedStructPointer(b []byte, p unsafe.Pointer, t reflect.Type, unexported bool, offset uintptr, decode decodeFunc) ([]byte, error) {
v := *(*unsafe.Pointer)(p)
if v == nil {
if unexported {
return nil, fmt.Errorf("json: cannot set embedded pointer to unexported struct: %s", t)
}
v = unsafe.Pointer(reflect.New(t).Pointer())
*(*unsafe.Pointer)(p) = v
}
return decode(d, b, unsafe.Pointer(uintptr(v)+offset))
}
func (d decoder) decodePointer(b []byte, p unsafe.Pointer, t reflect.Type, decode decodeFunc) ([]byte, error) {
if hasNullPrefix(b) {
pp := *(*unsafe.Pointer)(p)
if pp != nil && t.Kind() == reflect.Ptr {
return decode(d, b, pp)
}
*(*unsafe.Pointer)(p) = nil
return b[4:], nil
}
v := *(*unsafe.Pointer)(p)
if v == nil {
v = unsafe.Pointer(reflect.New(t).Pointer())
*(*unsafe.Pointer)(p) = v
}
return decode(d, b, v)
}
func (d decoder) decodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) {
val := *(*interface{})(p)
*(*interface{})(p) = nil
if t := reflect.TypeOf(val); t != nil && t.Kind() == reflect.Ptr {
if v := reflect.ValueOf(val); v.IsNil() || t.Elem().Kind() != reflect.Ptr {
// If the destination is nil the only value that is OK to decode is
// `null`, and the encoding/json package always nils the destination
// interface value in this case.
if hasNullPrefix(b) {
*(*interface{})(p) = nil
return b[4:], nil
}
}
b, err := Parse(b, val, d.flags)
if err == nil {
*(*interface{})(p) = val
}
return b, err
}
v, b, k, err := d.parseValue(b)
if err != nil {
return b, err
}
switch k.Class() {
case Object:
m := make(map[string]interface{})
v, err = d.decodeMapStringInterface(v, unsafe.Pointer(&m))
val = m
case Array:
a := make([]interface{}, 0, 10)
v, err = d.decodeSlice(v, unsafe.Pointer(&a), unsafe.Sizeof(a[0]), sliceInterfaceType, decoder.decodeInterface)
val = a
case String:
s := ""
v, err = d.decodeString(v, unsafe.Pointer(&s))
val = s
case Null:
v, val = nil, nil
case Bool:
v, val = nil, k == True
case Num:
if (d.flags & UseNumber) != 0 {
n := Number("")
v, err = d.decodeNumber(v, unsafe.Pointer(&n))
val = n
} else {
f := 0.0
v, err = d.decodeFloat64(v, unsafe.Pointer(&f))
val = f
}
default:
return b, syntaxError(v, "expected token but found '%c'", v[0])
}
if err != nil {
return b, err
}
if v = skipSpaces(v); len(v) != 0 {
return b, syntaxError(v, "unexpected trailing trailing tokens after json value")
}
*(*interface{})(p) = val
return b, nil
}
func (d decoder) decodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) {
if hasNullPrefix(b) {
*(*interface{})(p) = nil
return b[4:], nil
}
if x := reflect.NewAt(t, p).Elem(); !x.IsNil() {
if e := x.Elem(); e.Kind() == reflect.Ptr {
return Parse(b, e.Interface(), d.flags)
}
} else if t.NumMethod() == 0 { // empty interface
return Parse(b, (*interface{})(p), d.flags)
}
return d.decodeUnmarshalTypeError(b, p, t)
}
func (d decoder) decodeUnmarshalTypeError(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) {
v, b, _, err := d.parseValue(b)
if err != nil {
return b, err
}
return b, &UnmarshalTypeError{
Value: string(v),
Type: t,
}
}
func (d decoder) decodeRawMessage(b []byte, p unsafe.Pointer) ([]byte, error) {
v, r, _, err := d.parseValue(b)
if err != nil {
return d.inputError(b, rawMessageType)
}
if (d.flags & DontCopyRawMessage) == 0 {
v = append(make([]byte, 0, len(v)), v...)
}
*(*RawMessage)(p) = json.RawMessage(v)
return r, err
}
func (d decoder) decodeJSONUnmarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) {
v, b, _, err := d.parseValue(b)
if err != nil {
return b, err
}
u := reflect.NewAt(t, p)
if !pointer {
u = u.Elem()
t = t.Elem()
}
if u.IsNil() {
u.Set(reflect.New(t))
}
return b, u.Interface().(Unmarshaler).UnmarshalJSON(v)
}
func (d decoder) decodeTextUnmarshaler(b []byte, p unsafe.Pointer, t reflect.Type, pointer bool) ([]byte, error) {
var value string
v, b, k, err := d.parseValue(b)
if err != nil {
return b, err
}
if len(v) == 0 {
return d.inputError(v, t)
}
switch k.Class() {
case Null:
return b, err
case String:
s, _, _, err := d.parseStringUnquote(v, nil)
if err != nil {
return b, err
}
u := reflect.NewAt(t, p)
if !pointer {
u = u.Elem()
t = t.Elem()
}
if u.IsNil() {
u.Set(reflect.New(t))
}
return b, u.Interface().(encoding.TextUnmarshaler).UnmarshalText(s)
case Bool:
if k == True {
value = "true"
} else {
value = "false"
}
case Num:
value = "number"
case Object:
value = "object"
case Array:
value = "array"
}
return b, &UnmarshalTypeError{Value: value, Type: reflect.PtrTo(t)}
}
func (d decoder) prependField(key, field string) string {
if field != "" {
return key + "." + field
}
return key
}
func (d decoder) inputError(b []byte, t reflect.Type) ([]byte, error) {
if len(b) == 0 {
return nil, unexpectedEOF(b)
}
_, r, _, err := d.parseValue(b)
if err != nil {
return r, err
}
return skipSpaces(r), unmarshalTypeError(b, t)
}