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