| 212 | /// This is the versatile slow path that handles all edge cases |
| 213 | template <typename K, typename V, typename MapType> |
| 214 | inline void write_map_data_slow(const MapType &map, WriteContext &ctx, |
| 215 | bool has_generics) { |
| 216 | // write total length |
| 217 | ctx.write_var_uint32(static_cast<uint32_t>(map.size())); |
| 218 | |
| 219 | if (map.empty()) { |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | // Type characteristics |
| 224 | constexpr bool key_is_polymorphic = is_polymorphic_v<K>; |
| 225 | constexpr bool val_is_polymorphic = is_polymorphic_v<V>; |
| 226 | constexpr bool key_is_shared_ref = is_shared_ref_v<K>; |
| 227 | constexpr bool val_is_shared_ref = is_shared_ref_v<V>; |
| 228 | |
| 229 | const bool is_key_declared = |
| 230 | has_generics && !need_to_write_type_for_field<K>(); |
| 231 | const bool is_val_declared = |
| 232 | has_generics && !need_to_write_type_for_field<V>(); |
| 233 | |
| 234 | // State for chunked writing |
| 235 | size_t header_offset = 0; |
| 236 | uint8_t pair_counter = 0; |
| 237 | bool need_write_header = true; |
| 238 | |
| 239 | // Track current chunk's types for polymorphic handling |
| 240 | const TypeInfo *current_key_type_info = nullptr; |
| 241 | const TypeInfo *current_val_type_info = nullptr; |
| 242 | |
| 243 | for (const auto &[key, value] : map) { |
| 244 | // Check if key or value is null (for nullable types: optional, shared_ptr, |
| 245 | // unique_ptr, weak_ptr) |
| 246 | bool key_is_none = false; |
| 247 | bool value_is_none = false; |
| 248 | if constexpr (is_nullable_v<K>) { |
| 249 | key_is_none = is_null_value(key); |
| 250 | } |
| 251 | if constexpr (is_nullable_v<V>) { |
| 252 | value_is_none = is_null_value(value); |
| 253 | } |
| 254 | |
| 255 | // Handle null entries - write as separate single-entry chunks |
| 256 | if (key_is_none || value_is_none) { |
| 257 | // Finish current chunk if any |
| 258 | if (pair_counter > 0) { |
| 259 | write_chunk_size(ctx, header_offset, pair_counter); |
| 260 | ctx.exit_flush_barrier(); |
| 261 | pair_counter = 0; |
| 262 | need_write_header = true; |
| 263 | } |
| 264 | |
| 265 | if (key_is_none && value_is_none) { |
| 266 | ctx.write_uint8(KEY_NULL | VALUE_NULL); |
| 267 | continue; |
| 268 | } else if (value_is_none) { |
| 269 | // Non-null key, null value |
| 270 | // Java writes: chunk_header, then ref_flag, then type_info, then data |
| 271 | uint8_t chunk_header = VALUE_NULL; |
nothing calls this directly
no test coverage detected