package gojay
import "reflect"
func (dec *Decoder ) DecodeArray (v UnmarshalerJSONArray ) error {
if dec .isPooled == 1 {
panic (InvalidUsagePooledDecoderError ("Invalid usage of pooled decoder" ))
}
_ , err := dec .decodeArray (v )
return err
}
func (dec *Decoder ) decodeArray (arr UnmarshalerJSONArray ) (int , error ) {
lastArrayIndex := dec .arrayIndex
dec .arrayIndex = 0
defer func () {
dec .arrayIndex = lastArrayIndex
}()
for ; dec .cursor < dec .length || dec .read (); dec .cursor ++ {
switch dec .data [dec .cursor ] {
case ' ' , '\n' , '\t' , '\r' , ',' :
continue
case '[' :
dec .cursor = dec .cursor + 1
for dec .nextChar () != 0 {
if dec .data [dec .cursor ] == ']' {
dec .cursor = dec .cursor + 1
return dec .cursor , nil
}
err := arr .UnmarshalJSONArray (dec )
if err != nil {
return 0 , err
}
dec .arrayIndex ++
}
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
case 'n' :
dec .cursor ++
err := dec .assertNull ()
if err != nil {
return 0 , err
}
return dec .cursor , nil
case '{' , '"' , 'f' , 't' , '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' :
dec .err = dec .makeInvalidUnmarshalErr (arr )
err := dec .skipData ()
if err != nil {
return 0 , err
}
return dec .cursor , nil
default :
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
}
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
func (dec *Decoder ) decodeArrayNull (v interface {}) (int , error ) {
lastArrayIndex := dec .arrayIndex
dec .arrayIndex = 0
defer func () {
dec .arrayIndex = lastArrayIndex
}()
vv := reflect .ValueOf (v )
vvt := vv .Type ()
if vvt .Kind () != reflect .Ptr || vvt .Elem ().Kind () != reflect .Ptr {
dec .err = ErrUnmarshalPtrExpected
return 0 , dec .err
}
for ; dec .cursor < dec .length || dec .read (); dec .cursor ++ {
switch dec .data [dec .cursor ] {
case ' ' , '\n' , '\t' , '\r' , ',' :
continue
case '[' :
dec .cursor = dec .cursor + 1
elt := vv .Elem ()
n := reflect .New (elt .Type ().Elem ())
var arr UnmarshalerJSONArray
var ok bool
if arr , ok = n .Interface ().(UnmarshalerJSONArray ); !ok {
dec .err = dec .makeInvalidUnmarshalErr ((UnmarshalerJSONArray )(nil ))
return 0 , dec .err
}
for dec .nextChar () != 0 {
if dec .data [dec .cursor ] == ']' {
elt .Set (n )
dec .cursor = dec .cursor + 1
return dec .cursor , nil
}
err := arr .UnmarshalJSONArray (dec )
if err != nil {
return 0 , err
}
dec .arrayIndex ++
}
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
case 'n' :
dec .cursor ++
err := dec .assertNull ()
if err != nil {
return 0 , err
}
return dec .cursor , nil
case '{' , '"' , 'f' , 't' , '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' :
dec .err = dec .makeInvalidUnmarshalErr ((UnmarshalerJSONArray )(nil ))
err := dec .skipData ()
if err != nil {
return 0 , err
}
return dec .cursor , nil
default :
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
}
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
func (dec *Decoder ) skipArray () (int , error ) {
var arraysOpen = 1
var arraysClosed = 0
for j := dec .cursor ; j < dec .length || dec .read (); j ++ {
switch dec .data [j ] {
case ']' :
arraysClosed ++
if arraysOpen == arraysClosed {
return j + 1 , nil
}
case '[' :
arraysOpen ++
case '"' :
j ++
var isInEscapeSeq bool
var isFirstQuote = true
for ; j < dec .length || dec .read (); j ++ {
if dec .data [j ] != '"' {
continue
}
if dec .data [j -1 ] != '\\' || (!isInEscapeSeq && !isFirstQuote ) {
break
} else {
isInEscapeSeq = false
}
if isFirstQuote {
isFirstQuote = false
}
ct := 0
for i := j - 1 ; i > 0 ; i -- {
if dec .data [i ] != '\\' {
break
}
ct ++
}
if ct &1 == 0 {
break
}
isInEscapeSeq = true
}
default :
continue
}
}
return 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
type DecodeArrayFunc func (*Decoder ) error
func (f DecodeArrayFunc ) UnmarshalJSONArray (dec *Decoder ) error {
return f (dec )
}
func (f DecodeArrayFunc ) IsNil () bool {
return f == nil
}
func (dec *Decoder ) AddArray (v UnmarshalerJSONArray ) error {
return dec .Array (v )
}
func (dec *Decoder ) AddArrayNull (v interface {}) error {
return dec .ArrayNull (v )
}
func (dec *Decoder ) Array (v UnmarshalerJSONArray ) error {
newCursor , err := dec .decodeArray (v )
if err != nil {
return err
}
dec .cursor = newCursor
dec .called |= 1
return nil
}
func (dec *Decoder ) ArrayNull (v interface {}) error {
newCursor , err := dec .decodeArrayNull (v )
if err != nil {
return err
}
dec .cursor = newCursor
dec .called |= 1
return nil
}
func (dec *Decoder ) Index () int {
return dec .arrayIndex
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .