github.com/3JoB/go-json@v0.10.4/decode.go (about) 1 package json 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "unsafe" 8 9 "github.com/3JoB/go-reflect" 10 11 "github.com/3JoB/go-json/internal/decoder" 12 "github.com/3JoB/go-json/internal/errors" 13 "github.com/3JoB/go-json/internal/runtime" 14 ) 15 16 type Decoder struct { 17 s *decoder.Stream 18 } 19 20 const ( 21 nul = '\000' 22 ) 23 24 type emptyInterface struct { 25 typ *runtime.Type 26 ptr unsafe.Pointer 27 } 28 29 func unmarshal(data []byte, v any, optFuncs ...DecodeOptionFunc) error { 30 src := make([]byte, len(data)+1) // append nul byte to the end 31 copy(src, data) 32 33 header := (*emptyInterface)(unsafe.Pointer(&v)) 34 35 if err := validateType(header.typ, uintptr(header.ptr)); err != nil { 36 return err 37 } 38 dec, err := decoder.CompileToGetDecoder(header.typ) 39 if err != nil { 40 return err 41 } 42 ctx := decoder.TakeRuntimeContext() 43 ctx.Buf = src 44 ctx.Option.Flags = 0 45 for _, optFunc := range optFuncs { 46 optFunc(ctx.Option) 47 } 48 cursor, err := dec.Decode(ctx, 0, 0, header.ptr) 49 if err != nil { 50 decoder.ReleaseRuntimeContext(ctx) 51 return err 52 } 53 decoder.ReleaseRuntimeContext(ctx) 54 return validateEndBuf(src, cursor) 55 } 56 57 func unmarshalContext(ctx context.Context, data []byte, v any, optFuncs ...DecodeOptionFunc) error { 58 src := make([]byte, len(data)+1) // append nul byte to the end 59 copy(src, data) 60 61 header := (*emptyInterface)(unsafe.Pointer(&v)) 62 63 if err := validateType(header.typ, uintptr(header.ptr)); err != nil { 64 return err 65 } 66 dec, err := decoder.CompileToGetDecoder(header.typ) 67 if err != nil { 68 return err 69 } 70 rctx := decoder.TakeRuntimeContext() 71 rctx.Buf = src 72 rctx.Option.Flags = 0 73 rctx.Option.Flags |= decoder.ContextOption 74 rctx.Option.Context = ctx 75 for _, optFunc := range optFuncs { 76 optFunc(rctx.Option) 77 } 78 cursor, err := dec.Decode(rctx, 0, 0, header.ptr) 79 if err != nil { 80 decoder.ReleaseRuntimeContext(rctx) 81 return err 82 } 83 decoder.ReleaseRuntimeContext(rctx) 84 return validateEndBuf(src, cursor) 85 } 86 87 var ( 88 pathDecoder = decoder.NewPathDecoder() 89 ) 90 91 func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) { 92 if path.path.RootSelectorOnly { 93 return [][]byte{data}, nil 94 } 95 src := make([]byte, len(data)+1) // append nul byte to the end 96 copy(src, data) 97 98 ctx := decoder.TakeRuntimeContext() 99 ctx.Buf = src 100 ctx.Option.Flags = 0 101 ctx.Option.Flags |= decoder.PathOption 102 ctx.Option.Path = path.path 103 for _, optFunc := range optFuncs { 104 optFunc(ctx.Option) 105 } 106 paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0) 107 if err != nil { 108 decoder.ReleaseRuntimeContext(ctx) 109 return nil, err 110 } 111 decoder.ReleaseRuntimeContext(ctx) 112 if err := validateEndBuf(src, cursor); err != nil { 113 return nil, err 114 } 115 return paths, nil 116 } 117 118 func unmarshalNoEscape(data []byte, v any, optFuncs ...DecodeOptionFunc) error { 119 src := make([]byte, len(data)+1) // append nul byte to the end 120 copy(src, data) 121 122 header := (*emptyInterface)(unsafe.Pointer(&v)) 123 124 if err := validateType(header.typ, uintptr(header.ptr)); err != nil { 125 return err 126 } 127 dec, err := decoder.CompileToGetDecoder(header.typ) 128 if err != nil { 129 return err 130 } 131 132 ctx := decoder.TakeRuntimeContext() 133 ctx.Buf = src 134 ctx.Option.Flags = 0 135 for _, optFunc := range optFuncs { 136 optFunc(ctx.Option) 137 } 138 cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr)) 139 if err != nil { 140 decoder.ReleaseRuntimeContext(ctx) 141 return err 142 } 143 decoder.ReleaseRuntimeContext(ctx) 144 return validateEndBuf(src, cursor) 145 } 146 147 func validateEndBuf(src []byte, cursor int64) error { 148 for { 149 switch src[cursor] { 150 case ' ', '\t', '\n', '\r': 151 cursor++ 152 continue 153 case nul: 154 return nil 155 } 156 return errors.ErrSyntax( 157 fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), 158 cursor+1, 159 ) 160 } 161 } 162 163 //nolint:staticcheck 164 //go:nosplit 165 func noescape(p unsafe.Pointer) unsafe.Pointer { 166 x := uintptr(p) 167 return unsafe.Pointer(x ^ 0) 168 } 169 170 func validateType(typ *runtime.Type, p uintptr) error { 171 if typ == nil || typ.Kind() != reflect.Ptr || p == 0 { 172 return &InvalidUnmarshalError{Type: reflect.ToT(runtime.RType2Type(typ))} 173 } 174 return nil 175 } 176 177 // NewDecoder returns a new decoder that reads from r. 178 // 179 // The decoder introduces its own buffering and may 180 // read data from r beyond the JSON values requested. 181 func NewDecoder(r io.Reader) *Decoder { 182 s := decoder.NewStream(r) 183 return &Decoder{ 184 s: s, 185 } 186 } 187 188 // Buffered returns a reader of the data remaining in the Decoder's 189 // buffer. The reader is valid until the next call to Decode. 190 func (d *Decoder) Buffered() io.Reader { 191 return d.s.Buffered() 192 } 193 194 // Decode reads the next JSON-encoded value from its 195 // input and stores it in the value pointed to by v. 196 // 197 // See the documentation for Unmarshal for details about 198 // the conversion of JSON into a Go value. 199 func (d *Decoder) Decode(v any) error { 200 return d.DecodeWithOption(v) 201 } 202 203 // DecodeContext reads the next JSON-encoded value from its 204 // input and stores it in the value pointed to by v with context.Context. 205 func (d *Decoder) DecodeContext(ctx context.Context, v any) error { 206 d.s.Option.Flags |= decoder.ContextOption 207 d.s.Option.Context = ctx 208 return d.DecodeWithOption(v) 209 } 210 211 func (d *Decoder) DecodeWithOption(v any, optFuncs ...DecodeOptionFunc) error { 212 header := (*emptyInterface)(unsafe.Pointer(&v)) 213 typ := header.typ 214 ptr := uintptr(header.ptr) 215 typeptr := uintptr(unsafe.Pointer(typ)) 216 // noescape trick for header.typ ( reflect.*rtype ) 217 copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) 218 219 if err := validateType(copiedType, ptr); err != nil { 220 return err 221 } 222 223 dec, err := decoder.CompileToGetDecoder(typ) 224 if err != nil { 225 return err 226 } 227 if err := d.s.PrepareForDecode(); err != nil { 228 return err 229 } 230 s := d.s 231 for _, optFunc := range optFuncs { 232 optFunc(s.Option) 233 } 234 if err := dec.DecodeStream(s, 0, header.ptr); err != nil { 235 d.s.SkipErrorValue() 236 return err 237 } 238 s.Reset() 239 return nil 240 } 241 242 func (d *Decoder) More() bool { 243 return d.s.More() 244 } 245 246 func (d *Decoder) Token() (Token, error) { 247 return d.s.Token() 248 } 249 250 // DisallowUnknownFields causes the Decoder to return an error when the destination 251 // is a struct and the input contains object keys which do not match any 252 // non-ignored, exported fields in the destination. 253 func (d *Decoder) DisallowUnknownFields() { 254 d.s.DisallowUnknownFields = true 255 } 256 257 func (d *Decoder) InputOffset() int64 { 258 return d.s.TotalOffset() 259 } 260 261 // UseNumber causes the Decoder to unmarshal a number into an interface{} as a 262 // Number instead of as a float64. 263 func (d *Decoder) UseNumber() { 264 d.s.UseNumber = true 265 }