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