github.com/grbit/go-json@v0.11.0/internal/decoder/interface.go (about) 1 package decoder 2 3 import ( 4 "bytes" 5 "encoding" 6 "encoding/json" 7 "reflect" 8 "unsafe" 9 10 "github.com/grbit/go-json/internal/errors" 11 "github.com/grbit/go-json/internal/runtime" 12 ) 13 14 type interfaceDecoder struct { 15 typ *runtime.Type 16 structName string 17 fieldName string 18 sliceDecoder *sliceDecoder 19 mapDecoder *mapDecoder 20 floatDecoder *floatDecoder 21 numberDecoder *numberDecoder 22 stringDecoder *stringDecoder 23 } 24 25 func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder { 26 ifaceDecoder := &interfaceDecoder{ 27 typ: emptyInterfaceType, 28 structName: structName, 29 fieldName: fieldName, 30 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 31 *(*interface{})(p) = v 32 }), 33 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { 34 *(*interface{})(p) = v 35 }), 36 stringDecoder: newStringDecoder(structName, fieldName), 37 } 38 ifaceDecoder.sliceDecoder = newSliceDecoder( 39 ifaceDecoder, 40 emptyInterfaceType, 41 emptyInterfaceType.Size(), 42 structName, fieldName, 43 ) 44 ifaceDecoder.mapDecoder = newMapDecoder( 45 interfaceMapType, 46 stringType, 47 ifaceDecoder.stringDecoder, 48 interfaceMapType.Elem(), 49 ifaceDecoder, 50 structName, 51 fieldName, 52 ) 53 return ifaceDecoder 54 } 55 56 func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder { 57 emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName) 58 stringDecoder := newStringDecoder(structName, fieldName) 59 return &interfaceDecoder{ 60 typ: typ, 61 structName: structName, 62 fieldName: fieldName, 63 sliceDecoder: newSliceDecoder( 64 emptyIfaceDecoder, 65 emptyInterfaceType, 66 emptyInterfaceType.Size(), 67 structName, fieldName, 68 ), 69 mapDecoder: newMapDecoder( 70 interfaceMapType, 71 stringType, 72 stringDecoder, 73 interfaceMapType.Elem(), 74 emptyIfaceDecoder, 75 structName, 76 fieldName, 77 ), 78 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 79 *(*interface{})(p) = v 80 }), 81 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { 82 *(*interface{})(p) = v 83 }), 84 stringDecoder: stringDecoder, 85 } 86 } 87 88 func (d *interfaceDecoder) numDecoder(s *Stream) Decoder { 89 if s.UseNumber { 90 return d.numberDecoder 91 } 92 return d.floatDecoder 93 } 94 95 var ( 96 emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem()) 97 EmptyInterfaceType = emptyInterfaceType 98 interfaceMapType = runtime.Type2RType( 99 reflect.TypeOf((*map[string]interface{})(nil)).Elem(), 100 ) 101 errorType = reflect.TypeOf((*error)(nil)).Elem() 102 stringType = runtime.Type2RType( 103 reflect.TypeOf(""), 104 ) 105 ) 106 107 func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error { 108 start := s.cursor 109 if err := s.skipValue(depth); err != nil { 110 return err 111 } 112 src := s.buf[start:s.cursor] 113 dst := make([]byte, len(src)) 114 copy(dst, src) 115 116 if err := unmarshaler.UnmarshalJSON(dst); err != nil { 117 return err 118 } 119 return nil 120 } 121 122 func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error { 123 start := s.cursor 124 if err := s.skipValue(depth); err != nil { 125 return err 126 } 127 src := s.buf[start:s.cursor] 128 dst := make([]byte, len(src)) 129 copy(dst, src) 130 131 if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil { 132 return err 133 } 134 return nil 135 } 136 137 func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) { 138 cursor = skipWhiteSpace(buf, cursor) 139 start := cursor 140 end, err := skipValue(buf, cursor, depth) 141 if err != nil { 142 return 0, err 143 } 144 src := buf[start:end] 145 dst := make([]byte, len(src)) 146 copy(dst, src) 147 148 if err := unmarshaler.UnmarshalJSON(dst); err != nil { 149 return 0, err 150 } 151 return end, nil 152 } 153 154 func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) { 155 cursor = skipWhiteSpace(buf, cursor) 156 start := cursor 157 end, err := skipValue(buf, cursor, depth) 158 if err != nil { 159 return 0, err 160 } 161 src := buf[start:end] 162 dst := make([]byte, len(src)) 163 copy(dst, src) 164 165 if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil { 166 return 0, err 167 } 168 return end, nil 169 } 170 171 func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error { 172 start := s.cursor 173 if err := s.skipValue(depth); err != nil { 174 return err 175 } 176 src := s.buf[start:s.cursor] 177 if bytes.Equal(src, nullbytes) { 178 *(*unsafe.Pointer)(p) = nil 179 return nil 180 } 181 182 dst := make([]byte, len(src)) 183 copy(dst, src) 184 185 if err := unmarshaler.UnmarshalText(dst); err != nil { 186 return err 187 } 188 return nil 189 } 190 191 func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) { 192 cursor = skipWhiteSpace(buf, cursor) 193 start := cursor 194 end, err := skipValue(buf, cursor, depth) 195 if err != nil { 196 return 0, err 197 } 198 src := buf[start:end] 199 if bytes.Equal(src, nullbytes) { 200 *(*unsafe.Pointer)(p) = nil 201 return end, nil 202 } 203 if s, ok := unquoteBytes(src); ok { 204 src = s 205 } 206 if err := unmarshaler.UnmarshalText(src); err != nil { 207 return 0, err 208 } 209 return end, nil 210 } 211 212 func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error { 213 c := s.skipWhiteSpace() 214 for { 215 switch c { 216 case '{': 217 var v map[string]interface{} 218 ptr := unsafe.Pointer(&v) 219 if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil { 220 return err 221 } 222 *(*interface{})(p) = v 223 return nil 224 case '[': 225 var v []interface{} 226 ptr := unsafe.Pointer(&v) 227 if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil { 228 return err 229 } 230 *(*interface{})(p) = v 231 return nil 232 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 233 return d.numDecoder(s).DecodeStream(s, depth, p) 234 case '"': 235 s.cursor++ 236 start := s.cursor 237 for { 238 switch s.char() { 239 case '\\': 240 if _, err := decodeEscapeString(s, nil); err != nil { 241 return err 242 } 243 case '"': 244 literal := s.buf[start:s.cursor] 245 s.cursor++ 246 *(*interface{})(p) = string(literal) 247 return nil 248 case nul: 249 if s.read() { 250 continue 251 } 252 return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) 253 } 254 s.cursor++ 255 } 256 case 't': 257 if err := trueBytes(s); err != nil { 258 return err 259 } 260 **(**interface{})(unsafe.Pointer(&p)) = true 261 return nil 262 case 'f': 263 if err := falseBytes(s); err != nil { 264 return err 265 } 266 **(**interface{})(unsafe.Pointer(&p)) = false 267 return nil 268 case 'n': 269 if err := nullBytes(s); err != nil { 270 return err 271 } 272 *(*interface{})(p) = nil 273 return nil 274 case nul: 275 if s.read() { 276 c = s.char() 277 continue 278 } 279 } 280 break 281 } 282 return errors.ErrInvalidBeginningOfValue(c, s.totalOffset()) 283 } 284 285 type emptyInterface struct { 286 typ *runtime.Type 287 ptr unsafe.Pointer 288 } 289 290 func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { 291 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ 292 typ: d.typ, 293 ptr: p, 294 })) 295 rv := reflect.ValueOf(runtimeInterfaceValue) 296 if rv.NumMethod() > 0 && rv.CanInterface() { 297 if u, ok := rv.Interface().(unmarshalerContext); ok { 298 return decodeStreamUnmarshalerContext(s, depth, u) 299 } 300 if u, ok := rv.Interface().(json.Unmarshaler); ok { 301 return decodeStreamUnmarshaler(s, depth, u) 302 } 303 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { 304 return decodeStreamTextUnmarshaler(s, depth, u, p) 305 } 306 if s.skipWhiteSpace() == 'n' { 307 if err := nullBytes(s); err != nil { 308 return err 309 } 310 *(*interface{})(p) = nil 311 return nil 312 } 313 t := rv.Type() 314 if t == errorType { 315 return d.errUnmarshalType(rv.Type(), s.totalOffset()) 316 } 317 } 318 iface := rv.Interface() 319 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) 320 typ := ifaceHeader.typ 321 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { 322 // concrete type is empty interface 323 return d.decodeStreamEmptyInterface(s, depth, p) 324 } 325 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { 326 return d.decodeStreamEmptyInterface(s, depth, p) 327 } 328 if s.skipWhiteSpace() == 'n' { 329 if err := nullBytes(s); err != nil { 330 return err 331 } 332 *(*interface{})(p) = nil 333 return nil 334 } 335 decoder, err := CompileToGetDecoder(typ) 336 if err != nil { 337 return err 338 } 339 return decoder.DecodeStream(s, depth, ifaceHeader.ptr) 340 } 341 342 func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError { 343 return &errors.UnmarshalTypeError{ 344 Value: typ.String(), 345 Type: typ, 346 Offset: offset, 347 Struct: d.structName, 348 Field: d.fieldName, 349 } 350 } 351 352 func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 353 buf := ctx.Buf 354 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ 355 typ: d.typ, 356 ptr: p, 357 })) 358 rv := reflect.ValueOf(runtimeInterfaceValue) 359 if rv.NumMethod() > 0 && rv.CanInterface() { 360 if u, ok := rv.Interface().(unmarshalerContext); ok { 361 return decodeUnmarshalerContext(ctx, buf, cursor, depth, u) 362 } 363 if u, ok := rv.Interface().(json.Unmarshaler); ok { 364 return decodeUnmarshaler(buf, cursor, depth, u) 365 } 366 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { 367 return decodeTextUnmarshaler(buf, cursor, depth, u, p) 368 } 369 cursor = skipWhiteSpace(buf, cursor) 370 if buf[cursor] == 'n' { 371 if err := validateNull(buf, cursor); err != nil { 372 return 0, err 373 } 374 cursor += 4 375 **(**interface{})(unsafe.Pointer(&p)) = nil 376 return cursor, nil 377 } 378 t := rv.Type() 379 if t == errorType { 380 return 0, d.errUnmarshalType(t, cursor) 381 } 382 } 383 384 iface := rv.Interface() 385 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) 386 typ := ifaceHeader.typ 387 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { 388 // concrete type is empty interface 389 return d.decodeEmptyInterface(ctx, cursor, depth, p) 390 } 391 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { 392 return d.decodeEmptyInterface(ctx, cursor, depth, p) 393 } 394 cursor = skipWhiteSpace(buf, cursor) 395 if buf[cursor] == 'n' { 396 if err := validateNull(buf, cursor); err != nil { 397 return 0, err 398 } 399 cursor += 4 400 **(**interface{})(unsafe.Pointer(&p)) = nil 401 return cursor, nil 402 } 403 decoder, err := CompileToGetDecoder(typ) 404 if err != nil { 405 return 0, err 406 } 407 return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr) 408 } 409 410 func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 411 buf := ctx.Buf 412 cursor = skipWhiteSpace(buf, cursor) 413 switch buf[cursor] { 414 case '{': 415 var v map[string]interface{} 416 ptr := unsafe.Pointer(&v) 417 cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr) 418 if err != nil { 419 return 0, err 420 } 421 **(**interface{})(unsafe.Pointer(&p)) = v 422 return cursor, nil 423 case '[': 424 var v []interface{} 425 ptr := unsafe.Pointer(&v) 426 cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr) 427 if err != nil { 428 return 0, err 429 } 430 **(**interface{})(unsafe.Pointer(&p)) = v 431 return cursor, nil 432 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 433 return d.floatDecoder.Decode(ctx, cursor, depth, p) 434 case '"': 435 var v string 436 ptr := unsafe.Pointer(&v) 437 cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr) 438 if err != nil { 439 return 0, err 440 } 441 **(**interface{})(unsafe.Pointer(&p)) = v 442 return cursor, nil 443 case 't': 444 if err := validateTrue(buf, cursor); err != nil { 445 return 0, err 446 } 447 cursor += 4 448 **(**interface{})(unsafe.Pointer(&p)) = true 449 return cursor, nil 450 case 'f': 451 if err := validateFalse(buf, cursor); err != nil { 452 return 0, err 453 } 454 cursor += 5 455 **(**interface{})(unsafe.Pointer(&p)) = false 456 return cursor, nil 457 case 'n': 458 if err := validateNull(buf, cursor); err != nil { 459 return 0, err 460 } 461 cursor += 4 462 **(**interface{})(unsafe.Pointer(&p)) = nil 463 return cursor, nil 464 } 465 return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) 466 } 467 468 func NewPathDecoder() Decoder { 469 ifaceDecoder := &interfaceDecoder{ 470 typ: emptyInterfaceType, 471 structName: "", 472 fieldName: "", 473 floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) { 474 *(*interface{})(p) = v 475 }), 476 numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) { 477 *(*interface{})(p) = v 478 }), 479 stringDecoder: newStringDecoder("", ""), 480 } 481 ifaceDecoder.sliceDecoder = newSliceDecoder( 482 ifaceDecoder, 483 emptyInterfaceType, 484 emptyInterfaceType.Size(), 485 "", "", 486 ) 487 ifaceDecoder.mapDecoder = newMapDecoder( 488 interfaceMapType, 489 stringType, 490 ifaceDecoder.stringDecoder, 491 interfaceMapType.Elem(), 492 ifaceDecoder, 493 "", "", 494 ) 495 return ifaceDecoder 496 } 497 498 var ( 499 truebytes = []byte("true") 500 falsebytes = []byte("false") 501 ) 502 503 func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { 504 buf := ctx.Buf 505 cursor = skipWhiteSpace(buf, cursor) 506 switch buf[cursor] { 507 case '{': 508 return d.mapDecoder.DecodePath(ctx, cursor, depth) 509 case '[': 510 return d.sliceDecoder.DecodePath(ctx, cursor, depth) 511 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 512 return d.floatDecoder.DecodePath(ctx, cursor, depth) 513 case '"': 514 return d.stringDecoder.DecodePath(ctx, cursor, depth) 515 case 't': 516 if err := validateTrue(buf, cursor); err != nil { 517 return nil, 0, err 518 } 519 cursor += 4 520 return [][]byte{truebytes}, cursor, nil 521 case 'f': 522 if err := validateFalse(buf, cursor); err != nil { 523 return nil, 0, err 524 } 525 cursor += 5 526 return [][]byte{falsebytes}, cursor, nil 527 case 'n': 528 if err := validateNull(buf, cursor); err != nil { 529 return nil, 0, err 530 } 531 cursor += 4 532 return [][]byte{nullbytes}, cursor, nil 533 } 534 return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) 535 }