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