package decoder
import (
"encoding/base64"
"fmt"
"unsafe"
"github.com/goccy/go-json/internal/errors"
"github.com/goccy/go-json/internal/runtime"
)
type bytesDecoder struct {
typ *runtime .Type
sliceDecoder Decoder
stringDecoder *stringDecoder
structName string
fieldName string
}
func byteUnmarshalerSliceDecoder(typ *runtime .Type , structName string , fieldName string ) Decoder {
var unmarshalDecoder Decoder
switch {
case runtime .PtrTo (typ ).Implements (unmarshalJSONType ):
unmarshalDecoder = newUnmarshalJSONDecoder (runtime .PtrTo (typ ), structName , fieldName )
case runtime .PtrTo (typ ).Implements (unmarshalTextType ):
unmarshalDecoder = newUnmarshalTextDecoder (runtime .PtrTo (typ ), structName , fieldName )
default :
unmarshalDecoder , _ = compileUint8 (typ , structName , fieldName )
}
return newSliceDecoder (unmarshalDecoder , typ , 1 , structName , fieldName )
}
func newBytesDecoder(typ *runtime .Type , structName string , fieldName string ) *bytesDecoder {
return &bytesDecoder {
typ : typ ,
sliceDecoder : byteUnmarshalerSliceDecoder (typ , structName , fieldName ),
stringDecoder : newStringDecoder (structName , fieldName ),
structName : structName ,
fieldName : fieldName ,
}
}
func (d *bytesDecoder ) DecodeStream (s *Stream , depth int64 , p unsafe .Pointer ) error {
bytes , err := d .decodeStreamBinary (s , depth , p )
if err != nil {
return err
}
if bytes == nil {
s .reset ()
return nil
}
decodedLen := base64 .StdEncoding .DecodedLen (len (bytes ))
buf := make ([]byte , decodedLen )
n , err := base64 .StdEncoding .Decode (buf , bytes )
if err != nil {
return err
}
*(*[]byte )(p ) = buf [:n ]
s .reset ()
return nil
}
func (d *bytesDecoder ) Decode (ctx *RuntimeContext , cursor , depth int64 , p unsafe .Pointer ) (int64 , error ) {
bytes , c , err := d .decodeBinary (ctx , cursor , depth , p )
if err != nil {
return 0 , err
}
if bytes == nil {
return c , nil
}
cursor = c
decodedLen := base64 .StdEncoding .DecodedLen (len (bytes ))
b := make ([]byte , decodedLen )
n , err := base64 .StdEncoding .Decode (b , bytes )
if err != nil {
return 0 , err
}
*(*[]byte )(p ) = b [:n ]
return cursor , nil
}
func (d *bytesDecoder ) DecodePath (ctx *RuntimeContext , cursor , depth int64 ) ([][]byte , int64 , error ) {
return nil , 0 , fmt .Errorf ("json: []byte decoder does not support decode path" )
}
func (d *bytesDecoder ) decodeStreamBinary (s *Stream , depth int64 , p unsafe .Pointer ) ([]byte , error ) {
c := s .skipWhiteSpace ()
if c == '[' {
if d .sliceDecoder == nil {
return nil , &errors .UnmarshalTypeError {
Type : runtime .RType2Type (d .typ ),
Offset : s .totalOffset (),
}
}
err := d .sliceDecoder .DecodeStream (s , depth , p )
return nil , err
}
return d .stringDecoder .decodeStreamByte (s )
}
func (d *bytesDecoder ) decodeBinary (ctx *RuntimeContext , cursor , depth int64 , p unsafe .Pointer ) ([]byte , int64 , error ) {
buf := ctx .Buf
cursor = skipWhiteSpace (buf , cursor )
if buf [cursor ] == '[' {
if d .sliceDecoder == nil {
return nil , 0 , &errors .UnmarshalTypeError {
Type : runtime .RType2Type (d .typ ),
Offset : cursor ,
}
}
c , err := d .sliceDecoder .Decode (ctx , cursor , depth , p )
if err != nil {
return nil , 0 , err
}
return nil , c , nil
}
return d .stringDecoder .decodeByte (buf , cursor )
}
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 .