gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

bytes.go (3242B)


      1 package decoder
      2 
      3 import (
      4 	"encoding/base64"
      5 	"fmt"
      6 	"unsafe"
      7 
      8 	"github.com/goccy/go-json/internal/errors"
      9 	"github.com/goccy/go-json/internal/runtime"
     10 )
     11 
     12 type bytesDecoder struct {
     13 	typ           *runtime.Type
     14 	sliceDecoder  Decoder
     15 	stringDecoder *stringDecoder
     16 	structName    string
     17 	fieldName     string
     18 }
     19 
     20 func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName string) Decoder {
     21 	var unmarshalDecoder Decoder
     22 	switch {
     23 	case runtime.PtrTo(typ).Implements(unmarshalJSONType):
     24 		unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName)
     25 	case runtime.PtrTo(typ).Implements(unmarshalTextType):
     26 		unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName)
     27 	default:
     28 		unmarshalDecoder, _ = compileUint8(typ, structName, fieldName)
     29 	}
     30 	return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName)
     31 }
     32 
     33 func newBytesDecoder(typ *runtime.Type, structName string, fieldName string) *bytesDecoder {
     34 	return &bytesDecoder{
     35 		typ:           typ,
     36 		sliceDecoder:  byteUnmarshalerSliceDecoder(typ, structName, fieldName),
     37 		stringDecoder: newStringDecoder(structName, fieldName),
     38 		structName:    structName,
     39 		fieldName:     fieldName,
     40 	}
     41 }
     42 
     43 func (d *bytesDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
     44 	bytes, err := d.decodeStreamBinary(s, depth, p)
     45 	if err != nil {
     46 		return err
     47 	}
     48 	if bytes == nil {
     49 		s.reset()
     50 		return nil
     51 	}
     52 	decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
     53 	buf := make([]byte, decodedLen)
     54 	n, err := base64.StdEncoding.Decode(buf, bytes)
     55 	if err != nil {
     56 		return err
     57 	}
     58 	*(*[]byte)(p) = buf[:n]
     59 	s.reset()
     60 	return nil
     61 }
     62 
     63 func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
     64 	bytes, c, err := d.decodeBinary(ctx, cursor, depth, p)
     65 	if err != nil {
     66 		return 0, err
     67 	}
     68 	if bytes == nil {
     69 		return c, nil
     70 	}
     71 	cursor = c
     72 	decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
     73 	b := make([]byte, decodedLen)
     74 	n, err := base64.StdEncoding.Decode(b, bytes)
     75 	if err != nil {
     76 		return 0, err
     77 	}
     78 	*(*[]byte)(p) = b[:n]
     79 	return cursor, nil
     80 }
     81 
     82 func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
     83 	return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path")
     84 }
     85 
     86 func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {
     87 	c := s.skipWhiteSpace()
     88 	if c == '[' {
     89 		if d.sliceDecoder == nil {
     90 			return nil, &errors.UnmarshalTypeError{
     91 				Type:   runtime.RType2Type(d.typ),
     92 				Offset: s.totalOffset(),
     93 			}
     94 		}
     95 		err := d.sliceDecoder.DecodeStream(s, depth, p)
     96 		return nil, err
     97 	}
     98 	return d.stringDecoder.decodeStreamByte(s)
     99 }
    100 
    101 func (d *bytesDecoder) decodeBinary(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) ([]byte, int64, error) {
    102 	buf := ctx.Buf
    103 	cursor = skipWhiteSpace(buf, cursor)
    104 	if buf[cursor] == '[' {
    105 		if d.sliceDecoder == nil {
    106 			return nil, 0, &errors.UnmarshalTypeError{
    107 				Type:   runtime.RType2Type(d.typ),
    108 				Offset: cursor,
    109 			}
    110 		}
    111 		c, err := d.sliceDecoder.Decode(ctx, cursor, depth, p)
    112 		if err != nil {
    113 			return nil, 0, err
    114 		}
    115 		return nil, c, nil
    116 	}
    117 	return d.stringDecoder.decodeByte(buf, cursor)
    118 }