github.com/grbit/go-json@v0.11.0/internal/decoder/func.go (about) 1 package decoder 2 3 import ( 4 "bytes" 5 "fmt" 6 "unsafe" 7 8 "github.com/grbit/go-json/internal/errors" 9 "github.com/grbit/go-json/internal/runtime" 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, structName, 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: runtime.RType2Type(d.typ), 36 Offset: s.totalOffset(), 37 } 38 case '[': 39 return &errors.UnmarshalTypeError{ 40 Value: "array", 41 Type: runtime.RType2Type(d.typ), 42 Offset: s.totalOffset(), 43 } 44 case '{': 45 return &errors.UnmarshalTypeError{ 46 Value: "object", 47 Type: 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: 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: 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: 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: runtime.RType2Type(d.typ), 98 Offset: start, 99 } 100 case '[': 101 return 0, &errors.UnmarshalTypeError{ 102 Value: "array", 103 Type: runtime.RType2Type(d.typ), 104 Offset: start, 105 } 106 case '{': 107 return 0, &errors.UnmarshalTypeError{ 108 Value: "object", 109 Type: 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: 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: 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: 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, fmt.Errorf("json: func decoder does not support decode path") 146 }