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