387 lines
9.9 KiB
Go
387 lines
9.9 KiB
Go
package gojay
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// UnmarshalJSONArray parses the JSON-encoded data and stores the result in the value pointed to by v.
|
|
//
|
|
// v must implement UnmarshalerJSONArray.
|
|
//
|
|
// If a JSON value is not appropriate for a given target type, or if a JSON number
|
|
// overflows the target type, UnmarshalJSONArray skips that field and completes the unmarshaling as best it can.
|
|
func UnmarshalJSONArray(data []byte, v UnmarshalerJSONArray) error {
|
|
dec := borrowDecoder(nil, 0)
|
|
defer dec.Release()
|
|
dec.data = make([]byte, len(data))
|
|
copy(dec.data, data)
|
|
dec.length = len(data)
|
|
_, err := dec.decodeArray(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if dec.err != nil {
|
|
return dec.err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UnmarshalJSONObject parses the JSON-encoded data and stores the result in the value pointed to by v.
|
|
//
|
|
// v must implement UnmarshalerJSONObject.
|
|
//
|
|
// If a JSON value is not appropriate for a given target type, or if a JSON number
|
|
// overflows the target type, UnmarshalJSONObject skips that field and completes the unmarshaling as best it can.
|
|
func UnmarshalJSONObject(data []byte, v UnmarshalerJSONObject) error {
|
|
dec := borrowDecoder(nil, 0)
|
|
defer dec.Release()
|
|
dec.data = make([]byte, len(data))
|
|
copy(dec.data, data)
|
|
dec.length = len(data)
|
|
_, err := dec.decodeObject(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if dec.err != nil {
|
|
return dec.err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
|
|
// If v is nil, not an implementation of UnmarshalerJSONObject or UnmarshalerJSONArray or not one of the following types:
|
|
// *string, **string, *int, **int, *int8, **int8, *int16, **int16, *int32, **int32, *int64, **int64, *uint8, **uint8, *uint16, **uint16,
|
|
// *uint32, **uint32, *uint64, **uint64, *float64, **float64, *float32, **float32, *bool, **bool
|
|
// Unmarshal returns an InvalidUnmarshalError.
|
|
//
|
|
//
|
|
// If a JSON value is not appropriate for a given target type, or if a JSON number
|
|
// overflows the target type, Unmarshal skips that field and completes the unmarshaling as best it can.
|
|
// If no more serious errors are encountered, Unmarshal returns an UnmarshalTypeError describing the earliest such error.
|
|
// In any case, it's not guaranteed that all the remaining fields following the problematic one will be unmarshaled into the target object.
|
|
func Unmarshal(data []byte, v interface{}) error {
|
|
var err error
|
|
var dec *Decoder
|
|
switch vt := v.(type) {
|
|
case *string:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeString(vt)
|
|
case **string:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeStringNull(vt)
|
|
case *int:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt(vt)
|
|
case **int:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeIntNull(vt)
|
|
case *int8:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt8(vt)
|
|
case **int8:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt8Null(vt)
|
|
case *int16:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt16(vt)
|
|
case **int16:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt16Null(vt)
|
|
case *int32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt32(vt)
|
|
case **int32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt32Null(vt)
|
|
case *int64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt64(vt)
|
|
case **int64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeInt64Null(vt)
|
|
case *uint8:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint8(vt)
|
|
case **uint8:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint8Null(vt)
|
|
case *uint16:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint16(vt)
|
|
case **uint16:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint16Null(vt)
|
|
case *uint32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint32(vt)
|
|
case **uint32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint32Null(vt)
|
|
case *uint64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint64(vt)
|
|
case **uint64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeUint64Null(vt)
|
|
case *float64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeFloat64(vt)
|
|
case **float64:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeFloat64Null(vt)
|
|
case *float32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeFloat32(vt)
|
|
case **float32:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeFloat32Null(vt)
|
|
case *bool:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeBool(vt)
|
|
case **bool:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = data
|
|
err = dec.decodeBoolNull(vt)
|
|
case UnmarshalerJSONObject:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = make([]byte, len(data))
|
|
copy(dec.data, data)
|
|
_, err = dec.decodeObject(vt)
|
|
case UnmarshalerJSONArray:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = make([]byte, len(data))
|
|
copy(dec.data, data)
|
|
_, err = dec.decodeArray(vt)
|
|
case *interface{}:
|
|
dec = borrowDecoder(nil, 0)
|
|
dec.length = len(data)
|
|
dec.data = make([]byte, len(data))
|
|
copy(dec.data, data)
|
|
err = dec.decodeInterface(vt)
|
|
default:
|
|
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt))
|
|
}
|
|
defer dec.Release()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return dec.err
|
|
}
|
|
|
|
// UnmarshalerJSONObject is the interface to implement to decode a JSON Object.
|
|
type UnmarshalerJSONObject interface {
|
|
UnmarshalJSONObject(*Decoder, string) error
|
|
NKeys() int
|
|
}
|
|
|
|
// UnmarshalerJSONArray is the interface to implement to decode a JSON Array.
|
|
type UnmarshalerJSONArray interface {
|
|
UnmarshalJSONArray(*Decoder) error
|
|
}
|
|
|
|
// A Decoder reads and decodes JSON values from an input stream.
|
|
type Decoder struct {
|
|
r io.Reader
|
|
data []byte
|
|
err error
|
|
isPooled byte
|
|
called byte
|
|
child byte
|
|
cursor int
|
|
length int
|
|
keysDone int
|
|
arrayIndex int
|
|
}
|
|
|
|
// Decode reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v.
|
|
//
|
|
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
|
|
// The differences between Decode and Unmarshal are:
|
|
// - Decode reads from an io.Reader in the Decoder, whereas Unmarshal reads from a []byte
|
|
// - Decode leaves to the user the option of borrowing and releasing a Decoder, whereas Unmarshal internally always borrows a Decoder and releases it when the unmarshaling is completed
|
|
func (dec *Decoder) Decode(v interface{}) error {
|
|
if dec.isPooled == 1 {
|
|
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
|
|
}
|
|
var err error
|
|
switch vt := v.(type) {
|
|
case *string:
|
|
err = dec.decodeString(vt)
|
|
case **string:
|
|
err = dec.decodeStringNull(vt)
|
|
case *int:
|
|
err = dec.decodeInt(vt)
|
|
case **int:
|
|
err = dec.decodeIntNull(vt)
|
|
case *int8:
|
|
err = dec.decodeInt8(vt)
|
|
case **int8:
|
|
err = dec.decodeInt8Null(vt)
|
|
case *int16:
|
|
err = dec.decodeInt16(vt)
|
|
case **int16:
|
|
err = dec.decodeInt16Null(vt)
|
|
case *int32:
|
|
err = dec.decodeInt32(vt)
|
|
case **int32:
|
|
err = dec.decodeInt32Null(vt)
|
|
case *int64:
|
|
err = dec.decodeInt64(vt)
|
|
case **int64:
|
|
err = dec.decodeInt64Null(vt)
|
|
case *uint8:
|
|
err = dec.decodeUint8(vt)
|
|
case **uint8:
|
|
err = dec.decodeUint8Null(vt)
|
|
case *uint16:
|
|
err = dec.decodeUint16(vt)
|
|
case **uint16:
|
|
err = dec.decodeUint16Null(vt)
|
|
case *uint32:
|
|
err = dec.decodeUint32(vt)
|
|
case **uint32:
|
|
err = dec.decodeUint32Null(vt)
|
|
case *uint64:
|
|
err = dec.decodeUint64(vt)
|
|
case **uint64:
|
|
err = dec.decodeUint64Null(vt)
|
|
case *float64:
|
|
err = dec.decodeFloat64(vt)
|
|
case **float64:
|
|
err = dec.decodeFloat64Null(vt)
|
|
case *float32:
|
|
err = dec.decodeFloat32(vt)
|
|
case **float32:
|
|
err = dec.decodeFloat32Null(vt)
|
|
case *bool:
|
|
err = dec.decodeBool(vt)
|
|
case **bool:
|
|
err = dec.decodeBoolNull(vt)
|
|
case UnmarshalerJSONObject:
|
|
_, err = dec.decodeObject(vt)
|
|
case UnmarshalerJSONArray:
|
|
_, err = dec.decodeArray(vt)
|
|
case *EmbeddedJSON:
|
|
err = dec.decodeEmbeddedJSON(vt)
|
|
case *interface{}:
|
|
err = dec.decodeInterface(vt)
|
|
default:
|
|
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt))
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return dec.err
|
|
}
|
|
|
|
// Non exported
|
|
|
|
func isDigit(b byte) bool {
|
|
switch b {
|
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (dec *Decoder) read() bool {
|
|
if dec.r != nil {
|
|
// if we reach the end, double the buffer to ensure there's always more space
|
|
if len(dec.data) == dec.length {
|
|
nLen := dec.length * 2
|
|
if nLen == 0 {
|
|
nLen = 512
|
|
}
|
|
Buf := make([]byte, nLen, nLen)
|
|
copy(Buf, dec.data)
|
|
dec.data = Buf
|
|
}
|
|
var n int
|
|
var err error
|
|
for n == 0 {
|
|
n, err = dec.r.Read(dec.data[dec.length:])
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
dec.err = err
|
|
return false
|
|
}
|
|
if n == 0 {
|
|
return false
|
|
}
|
|
dec.length = dec.length + n
|
|
return true
|
|
}
|
|
}
|
|
dec.length = dec.length + n
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (dec *Decoder) nextChar() byte {
|
|
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
|
|
switch dec.data[dec.cursor] {
|
|
case ' ', '\n', '\t', '\r', ',':
|
|
continue
|
|
}
|
|
d := dec.data[dec.cursor]
|
|
return d
|
|
}
|
|
return 0
|
|
}
|