github.com/3JoB/go-json@v0.10.4/internal/decoder/func.go (about)

     1  package decoder
     2  
     3  import (
     4  	"bytes"
     5  	"unsafe"
     6  
     7  	"github.com/3JoB/go-json/internal/errors"
     8  	"github.com/3JoB/go-json/internal/runtime"
     9  	"github.com/3JoB/go-reflect"
    10  )
    11  
    12  type funcDecoder struct {
    13  	typ        *runtime.Type
    14  	structName string
    15  	fieldName  string
    16  }
    17  
    18  func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder {
    19  	fnDecoder := &funcDecoder{typ: typ, structName: structName, fieldName: fieldName}
    20  	return fnDecoder
    21  }
    22  
    23  func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
    24  	s.skipWhiteSpace()
    25  	start := s.cursor
    26  	if err := s.skipValue(depth); err != nil {
    27  		return err
    28  	}
    29  	src := s.buf[start:s.cursor]
    30  	if len(src) > 0 {
    31  		switch src[0] {
    32  		case '"':
    33  			return &errors.UnmarshalTypeError{
    34  				Value:  "string",
    35  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    36  				Offset: s.totalOffset(),
    37  			}
    38  		case '[':
    39  			return &errors.UnmarshalTypeError{
    40  				Value:  "array",
    41  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    42  				Offset: s.totalOffset(),
    43  			}
    44  		case '{':
    45  			return &errors.UnmarshalTypeError{
    46  				Value:  "object",
    47  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    48  				Offset: s.totalOffset(),
    49  			}
    50  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
    51  			return &errors.UnmarshalTypeError{
    52  				Value:  "number",
    53  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    54  				Offset: s.totalOffset(),
    55  			}
    56  		case 'n':
    57  			if err := nullBytes(s); err != nil {
    58  				return err
    59  			}
    60  			*(*unsafe.Pointer)(p) = nil
    61  			return nil
    62  		case 't':
    63  			if err := trueBytes(s); err == nil {
    64  				return &errors.UnmarshalTypeError{
    65  					Value:  "boolean",
    66  					Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    67  					Offset: s.totalOffset(),
    68  				}
    69  			}
    70  		case 'f':
    71  			if err := falseBytes(s); err == nil {
    72  				return &errors.UnmarshalTypeError{
    73  					Value:  "boolean",
    74  					Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    75  					Offset: s.totalOffset(),
    76  				}
    77  			}
    78  		}
    79  	}
    80  	return errors.ErrInvalidBeginningOfValue(s.buf[s.cursor], s.totalOffset())
    81  }
    82  
    83  func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
    84  	buf := ctx.Buf
    85  	cursor = skipWhiteSpace(buf, cursor)
    86  	start := cursor
    87  	end, err := skipValue(buf, cursor, depth)
    88  	if err != nil {
    89  		return 0, err
    90  	}
    91  	src := buf[start:end]
    92  	if len(src) > 0 {
    93  		switch src[0] {
    94  		case '"':
    95  			return 0, &errors.UnmarshalTypeError{
    96  				Value:  "string",
    97  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
    98  				Offset: start,
    99  			}
   100  		case '[':
   101  			return 0, &errors.UnmarshalTypeError{
   102  				Value:  "array",
   103  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
   104  				Offset: start,
   105  			}
   106  		case '{':
   107  			return 0, &errors.UnmarshalTypeError{
   108  				Value:  "object",
   109  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
   110  				Offset: start,
   111  			}
   112  		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
   113  			return 0, &errors.UnmarshalTypeError{
   114  				Value:  "number",
   115  				Type:   reflect.ToT(runtime.RType2Type(d.typ)),
   116  				Offset: start,
   117  			}
   118  		case 'n':
   119  			if bytes.Equal(src, nullbytes) {
   120  				*(*unsafe.Pointer)(p) = nil
   121  				return end, nil
   122  			}
   123  		case 't':
   124  			if err := validateTrue(buf, start); err == nil {
   125  				return 0, &errors.UnmarshalTypeError{
   126  					Value:  "boolean",
   127  					Type:   reflect.ToT(runtime.RType2Type(d.typ)),
   128  					Offset: start,
   129  				}
   130  			}
   131  		case 'f':
   132  			if err := validateFalse(buf, start); err == nil {
   133  				return 0, &errors.UnmarshalTypeError{
   134  					Value:  "boolean",
   135  					Type:   reflect.ToT(runtime.RType2Type(d.typ)),
   136  					Offset: start,
   137  				}
   138  			}
   139  		}
   140  	}
   141  	return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
   142  }
   143  
   144  func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
   145  	return nil, 0, errors.New("json: func decoder does not support decode path")
   146  }