| 697 | /// Read map data for polymorphic or shared-ref maps |
| 698 | template <typename K, typename V, typename MapType> |
| 699 | inline MapType read_map_data_slow(ReadContext &ctx, uint32_t length) { |
| 700 | MapType result; |
| 701 | if (length == 0) { |
| 702 | return result; |
| 703 | } |
| 704 | if (FORY_PREDICT_FALSE(!reserve_map(result, ctx, length))) { |
| 705 | return result; |
| 706 | } |
| 707 | |
| 708 | constexpr bool key_is_polymorphic = is_polymorphic_v<K>; |
| 709 | constexpr bool val_is_polymorphic = is_polymorphic_v<V>; |
| 710 | constexpr bool key_is_shared_ref = is_shared_ref_v<K>; |
| 711 | constexpr bool val_is_shared_ref = is_shared_ref_v<V>; |
| 712 | |
| 713 | uint32_t len_counter = 0; |
| 714 | |
| 715 | while (len_counter < length) { |
| 716 | uint8_t header = ctx.read_uint8(ctx.error()); |
| 717 | if (FORY_PREDICT_FALSE(ctx.has_error())) { |
| 718 | return MapType{}; |
| 719 | } |
| 720 | |
| 721 | // Handle null entries |
| 722 | if ((header & KEY_NULL) && (header & VALUE_NULL)) { |
| 723 | // Both key and value are null - insert with default-constructed values |
| 724 | result.emplace(K{}, V{}); |
| 725 | len_counter++; |
| 726 | continue; |
| 727 | } |
| 728 | |
| 729 | if (header & KEY_NULL) { |
| 730 | // Null key, non-null value |
| 731 | // Java writes: chunk_header, then ref_flag, then type_info, then data |
| 732 | bool track_value_ref = (header & TRACKING_VALUE_REF) != 0; |
| 733 | bool value_declared = (header & DECL_VALUE_TYPE) != 0; |
| 734 | |
| 735 | // Consume ref flag first if tracking refs |
| 736 | bool has_value = true; |
| 737 | if (track_value_ref || val_is_shared_ref) { |
| 738 | has_value = read_null_only_flag(ctx, RefMode::NullOnly); |
| 739 | if (FORY_PREDICT_FALSE(ctx.has_error())) { |
| 740 | return MapType{}; |
| 741 | } |
| 742 | } |
| 743 | |
| 744 | if (!has_value) { |
| 745 | // Value is null reference |
| 746 | result.emplace(K{}, V{}); |
| 747 | len_counter++; |
| 748 | continue; |
| 749 | } |
| 750 | |
| 751 | // Now read type info if needed |
| 752 | const TypeInfo *value_type_info = nullptr; |
| 753 | if (!value_declared || val_is_polymorphic) { |
| 754 | if constexpr (val_is_polymorphic) { |
| 755 | value_type_info = read_polymorphic_type_info(ctx); |
| 756 | if (FORY_PREDICT_FALSE(ctx.has_error())) { |
nothing calls this directly
no test coverage detected