Skip to main content

fory_core/serializer/
map.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::context::{ReadContext, WriteContext};
19use crate::ensure;
20use crate::error::Error;
21use crate::resolver::RefMode;
22use crate::resolver::{TypeInfo, TypeResolver};
23use crate::serializer::util::read_basic_type_info;
24use crate::serializer::{ForyDefault, Serializer};
25use crate::type_id::{need_to_write_type_for_field, TypeId, SIZE_OF_REF_AND_TYPE};
26use std::collections::{BTreeMap, HashMap};
27use std::rc::Rc;
28
29const MAX_CHUNK_SIZE: u8 = 255;
30
31const TRACKING_KEY_REF: u8 = 0b1;
32pub const KEY_NULL: u8 = 0b10;
33pub const DECL_KEY_TYPE: u8 = 0b100;
34const TRACKING_VALUE_REF: u8 = 0b1000;
35pub const VALUE_NULL: u8 = 0b10000;
36pub const DECL_VALUE_TYPE: u8 = 0b100000;
37
38fn check_map_len(context: &ReadContext, len: u32) -> Result<usize, Error> {
39    let len = len as usize;
40    context.reader.check_bound(len)?;
41    Ok(len)
42}
43
44fn write_chunk_size(context: &mut WriteContext, header_offset: usize, size: u8) {
45    context.writer.set_bytes(header_offset + 1, &[size]);
46}
47
48pub fn write_map_data<'a, K, V, I>(
49    iter: I,
50    length: usize,
51    context: &mut WriteContext,
52    has_generics: bool,
53) -> Result<(), Error>
54where
55    K: Serializer,
56    V: Serializer,
57    I: Iterator<Item = (&'a K, &'a V)>,
58{
59    context.writer.write_var_u32(length as u32);
60    if length == 0 {
61        return Ok(());
62    }
63    let reserved_space = (K::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length
64        + (V::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length;
65    context.writer.reserve(reserved_space);
66
67    if K::fory_is_polymorphic()
68        || K::fory_is_shared_ref()
69        || V::fory_is_polymorphic()
70        || V::fory_is_shared_ref()
71    {
72        return write_map_data_dyn_ref(iter, context, has_generics);
73    }
74    let mut header_offset = 0;
75    let mut pair_counter: u8 = 0;
76    let mut need_write_header = true;
77    let key_static_type_id = K::fory_static_type_id();
78    let val_static_type_id = V::fory_static_type_id();
79    let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
80    let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
81    for (key, value) in iter {
82        let key_is_none = key.fory_is_none();
83        let value_is_none = value.fory_is_none();
84
85        if key_is_none || value_is_none {
86            if !need_write_header && pair_counter > 0 {
87                write_chunk_size(context, header_offset, pair_counter);
88                pair_counter = 0;
89                need_write_header = true;
90            }
91
92            if key_is_none && value_is_none {
93                context.writer.write_u8(KEY_NULL | VALUE_NULL);
94                continue;
95            }
96
97            if value_is_none {
98                let mut chunk_header = VALUE_NULL;
99                if is_key_declared {
100                    chunk_header |= DECL_KEY_TYPE;
101                    context.writer.write_u8(chunk_header);
102                } else {
103                    context.writer.write_u8(chunk_header);
104                    K::fory_write_type_info(context)?;
105                }
106                key.fory_write_data_generic(context, has_generics)?;
107                continue;
108            }
109
110            // key is None, value is not
111            let mut chunk_header = KEY_NULL;
112            if is_val_declared {
113                chunk_header |= DECL_VALUE_TYPE;
114                context.writer.write_u8(chunk_header);
115            } else {
116                context.writer.write_u8(chunk_header);
117                V::fory_write_type_info(context)?;
118            }
119            value.fory_write_data_generic(context, has_generics)?;
120            continue;
121        }
122
123        if need_write_header {
124            header_offset = context.writer.len();
125            context.writer.write_i16(-1);
126            let mut chunk_header = 0u8;
127            if is_key_declared {
128                chunk_header |= DECL_KEY_TYPE;
129            } else {
130                K::fory_write_type_info(context)?;
131            }
132            if is_val_declared {
133                chunk_header |= DECL_VALUE_TYPE;
134            } else {
135                V::fory_write_type_info(context)?;
136            }
137            context.writer.set_bytes(header_offset, &[chunk_header]);
138            need_write_header = false;
139        }
140
141        key.fory_write_data_generic(context, has_generics)?;
142        value.fory_write_data_generic(context, has_generics)?;
143        pair_counter += 1;
144        if pair_counter == MAX_CHUNK_SIZE {
145            write_chunk_size(context, header_offset, pair_counter);
146            pair_counter = 0;
147            need_write_header = true;
148        }
149    }
150    if pair_counter > 0 {
151        write_chunk_size(context, header_offset, pair_counter);
152    }
153    Ok(())
154}
155
156/// slow but versatile map serialization for dynamic trait object and shared/circular reference.
157fn write_map_data_dyn_ref<'a, K, V, I>(
158    iter: I,
159    context: &mut WriteContext,
160    has_generics: bool,
161) -> Result<(), Error>
162where
163    K: Serializer,
164    V: Serializer,
165    I: Iterator<Item = (&'a K, &'a V)>,
166{
167    let mut header_offset = 0;
168    let mut pair_counter: u8 = 0;
169    let mut need_write_header = true;
170    let key_static_type_id = K::fory_static_type_id();
171    let val_static_type_id = V::fory_static_type_id();
172    let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
173    let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
174    let key_is_polymorphic = K::fory_is_polymorphic();
175    let val_is_polymorphic = V::fory_is_polymorphic();
176    let key_is_shared_ref = K::fory_is_shared_ref();
177    let val_is_shared_ref = V::fory_is_shared_ref();
178
179    // Track the current chunk's key and value types (for polymorphic types)
180    let mut current_key_type_id: Option<std::any::TypeId> = None;
181    let mut current_val_type_id: Option<std::any::TypeId> = None;
182
183    for (key, value) in iter {
184        // Handle null key/value entries (write as separate single-entry chunks)
185        if key.fory_is_none() || value.fory_is_none() {
186            // Finish current chunk if any
187            if pair_counter > 0 {
188                write_chunk_size(context, header_offset, pair_counter);
189                pair_counter = 0;
190                need_write_header = true;
191            }
192
193            if key.fory_is_none() && value.fory_is_none() {
194                context.writer.write_u8(KEY_NULL | VALUE_NULL);
195                continue;
196            } else if value.fory_is_none() {
197                let mut chunk_header = VALUE_NULL;
198                if key_is_shared_ref {
199                    chunk_header |= TRACKING_KEY_REF;
200                }
201                if is_key_declared && !key_is_polymorphic {
202                    chunk_header |= DECL_KEY_TYPE;
203                    context.writer.write_u8(chunk_header);
204                } else {
205                    context.writer.write_u8(chunk_header);
206                    if key_is_polymorphic {
207                        context.write_any_type_info(
208                            K::fory_static_type_id() as u32,
209                            key.fory_concrete_type_id(),
210                        )?;
211                    } else {
212                        K::fory_write_type_info(context)?;
213                    }
214                }
215                if key_is_shared_ref {
216                    key.fory_write(context, RefMode::Tracking, false, has_generics)?;
217                } else {
218                    key.fory_write_data_generic(context, has_generics)?;
219                }
220                continue;
221            } else {
222                // key.fory_is_none()
223                let mut chunk_header = KEY_NULL;
224                if val_is_shared_ref {
225                    chunk_header |= TRACKING_VALUE_REF;
226                }
227                if is_val_declared && !val_is_polymorphic {
228                    chunk_header |= DECL_VALUE_TYPE;
229                    context.writer.write_u8(chunk_header);
230                } else {
231                    context.writer.write_u8(chunk_header);
232                    if val_is_polymorphic {
233                        context.write_any_type_info(
234                            V::fory_static_type_id() as u32,
235                            value.fory_concrete_type_id(),
236                        )?;
237                    } else {
238                        V::fory_write_type_info(context)?;
239                    }
240                }
241                if val_is_shared_ref {
242                    value.fory_write(context, RefMode::Tracking, false, has_generics)?;
243                } else {
244                    value.fory_write_data_generic(context, has_generics)?;
245                }
246                continue;
247            }
248        }
249
250        // Get type IDs for polymorphic types
251        let key_type_id = if key_is_polymorphic {
252            Some(key.fory_concrete_type_id())
253        } else {
254            None
255        };
256        let val_type_id = if val_is_polymorphic {
257            Some(value.fory_concrete_type_id())
258        } else {
259            None
260        };
261
262        // Check if we need to start a new chunk due to type changes
263        let types_changed = if key_is_polymorphic || val_is_polymorphic {
264            key_type_id != current_key_type_id || val_type_id != current_val_type_id
265        } else {
266            false
267        };
268
269        if need_write_header || types_changed {
270            // Finish previous chunk if types changed
271            if types_changed && pair_counter > 0 {
272                write_chunk_size(context, header_offset, pair_counter);
273                pair_counter = 0;
274            }
275
276            // Write new chunk header
277            header_offset = context.writer.len();
278            context.writer.write_i16(-1); // Placeholder for header and size
279
280            let mut chunk_header = 0u8;
281
282            // Set key flags
283            if key_is_shared_ref {
284                chunk_header |= TRACKING_KEY_REF;
285            }
286            if is_key_declared && !key_is_polymorphic {
287                chunk_header |= DECL_KEY_TYPE;
288            } else {
289                // Write type info for key
290                if key_is_polymorphic {
291                    context.write_any_type_info(
292                        K::fory_static_type_id() as u32,
293                        key.fory_concrete_type_id(),
294                    )?;
295                } else {
296                    K::fory_write_type_info(context)?;
297                }
298            }
299
300            // Set value flags
301            if val_is_shared_ref {
302                chunk_header |= TRACKING_VALUE_REF;
303            }
304            if is_val_declared && !val_is_polymorphic {
305                chunk_header |= DECL_VALUE_TYPE;
306            } else {
307                // Write type info for value
308                if val_is_polymorphic {
309                    context.write_any_type_info(
310                        V::fory_static_type_id() as u32,
311                        value.fory_concrete_type_id(),
312                    )?;
313                } else {
314                    V::fory_write_type_info(context)?;
315                }
316            }
317
318            context.writer.set_bytes(header_offset, &[chunk_header]);
319            need_write_header = false;
320            current_key_type_id = key_type_id;
321            current_val_type_id = val_type_id;
322        }
323
324        // Write key-value pair
325        if key_is_shared_ref {
326            key.fory_write(context, RefMode::Tracking, false, has_generics)?;
327        } else {
328            key.fory_write_data_generic(context, has_generics)?;
329        }
330        if val_is_shared_ref {
331            value.fory_write(context, RefMode::Tracking, false, has_generics)?;
332        } else {
333            value.fory_write_data_generic(context, has_generics)?;
334        }
335        pair_counter += 1;
336        if pair_counter == MAX_CHUNK_SIZE {
337            write_chunk_size(context, header_offset, pair_counter);
338            pair_counter = 0;
339            need_write_header = true;
340            current_key_type_id = None;
341            current_val_type_id = None;
342        }
343    }
344
345    // Write final chunk size if any
346    if pair_counter > 0 {
347        write_chunk_size(context, header_offset, pair_counter);
348    }
349
350    Ok(())
351}
352
353/// Macro to generate read_*_data_dyn_ref functions for HashMap and BTreeMap.
354/// This avoids code duplication while maintaining zero runtime cost.
355macro_rules! impl_read_map_dyn_ref {
356    ($fn_name:ident, $map_type:ty, $($extra_trait_bounds:tt)*) => {
357        fn $fn_name<K, V>(
358            context: &mut ReadContext,
359            mut map: $map_type,
360            length: u32,
361        ) -> Result<$map_type, Error>
362        where
363            K: Serializer + ForyDefault + $($extra_trait_bounds)*,
364            V: Serializer + ForyDefault,
365        {
366            let key_is_polymorphic = K::fory_is_polymorphic();
367            let val_is_polymorphic = V::fory_is_polymorphic();
368            let mut len_counter = 0u32;
369
370            while len_counter < length {
371                let header = context.reader.read_u8()?;
372
373                // Handle null key/value entries
374                if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
375                    // Both key and value are null
376                    map.insert(K::fory_default(), V::fory_default());
377                    len_counter += 1;
378                    continue;
379                }
380
381                if header & KEY_NULL != 0 {
382                    // Null key, non-null value
383                    let value_declared = (header & DECL_VALUE_TYPE) != 0;
384                    let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
385
386                    // Determine value type info (if any)
387                    let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
388                        if val_is_polymorphic {
389                            Some(context.read_any_type_info()?)
390                        } else {
391                            V::fory_read_type_info(context)?;
392                            None
393                        }
394                    } else {
395                        None
396                    };
397
398                    // Read value payload
399                    let ref_mode = if track_value_ref {
400                        RefMode::Tracking
401                    } else {
402                        RefMode::None
403                    };
404                    let value = if let Some(type_info) = value_type_info {
405                        V::fory_read_with_type_info(context, ref_mode, type_info)?
406                    } else if track_value_ref {
407                        V::fory_read(context, ref_mode, false)?
408                    } else {
409                        V::fory_read_data(context)?
410                    };
411
412                    map.insert(K::fory_default(), value);
413                    len_counter += 1;
414                    continue;
415                }
416
417                if header & VALUE_NULL != 0 {
418                    // Non-null key, null value
419                    let key_declared = (header & DECL_KEY_TYPE) != 0;
420                    let track_key_ref = (header & TRACKING_KEY_REF) != 0;
421
422                    let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
423                        if key_is_polymorphic {
424                            Some(context.read_any_type_info()?)
425                        } else {
426                            K::fory_read_type_info(context)?;
427                            None
428                        }
429                    } else {
430                        None
431                    };
432
433                    let ref_mode = if track_key_ref {
434                        RefMode::Tracking
435                    } else {
436                        RefMode::None
437                    };
438                    let key = if let Some(type_info) = key_type_info {
439                        K::fory_read_with_type_info(context, ref_mode, type_info)?
440                    } else if track_key_ref {
441                        K::fory_read(context, ref_mode, false)?
442                    } else {
443                        K::fory_read_data(context)?
444                    };
445
446                    map.insert(key, V::fory_default());
447                    len_counter += 1;
448                    continue;
449                }
450
451                // Non-null key and value chunk
452                let chunk_size = context.reader.read_u8()?;
453                let key_declared = (header & DECL_KEY_TYPE) != 0;
454                let value_declared = (header & DECL_VALUE_TYPE) != 0;
455                // IMPORTANT: map readers must obey the sender-written key/value
456                // ref bits in the wire header. Local Rust type metadata must
457                // not "fix up" this decision while reading. Shared xlang tests
458                // intentionally deserialize one ref policy and then serialize a
459                // new local payload. DO NOT REMOVE this comment.
460                let track_key_ref = (header & TRACKING_KEY_REF) != 0;
461                let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
462
463                let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
464                    if key_is_polymorphic {
465                        Some(context.read_any_type_info()?)
466                    } else {
467                        K::fory_read_type_info(context)?;
468                        None
469                    }
470                } else {
471                    None
472                };
473                let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
474                    if val_is_polymorphic {
475                        Some(context.read_any_type_info()?)
476                    } else {
477                        V::fory_read_type_info(context)?;
478                        None
479                    }
480                } else {
481                    None
482                };
483
484                let cur_len = len_counter + chunk_size as u32;
485                ensure!(
486                    cur_len <= length,
487                    Error::invalid_data(
488                        format!("current length {} exceeds total length {}", cur_len, length)
489                    )
490                );
491
492                // Read chunk_size pairs of key-value
493                let key_ref_mode = if track_key_ref {
494                    RefMode::Tracking
495                } else {
496                    RefMode::None
497                };
498                let val_ref_mode = if track_value_ref {
499                    RefMode::Tracking
500                } else {
501                    RefMode::None
502                };
503                for _ in 0..chunk_size {
504                    let key = if let Some(type_info) = key_type_info.as_ref() {
505                        K::fory_read_with_type_info(context, key_ref_mode, type_info.clone())?
506                    } else if track_key_ref {
507                        K::fory_read(context, key_ref_mode, false)?
508                    } else {
509                        K::fory_read_data(context)?
510                    };
511
512                    let value = if let Some(type_info) = value_type_info.as_ref() {
513                        V::fory_read_with_type_info(context, val_ref_mode, type_info.clone())?
514                    } else if track_value_ref {
515                        V::fory_read(context, val_ref_mode, false)?
516                    } else {
517                        V::fory_read_data(context)?
518                    };
519
520                    map.insert(key, value);
521                }
522
523                len_counter += chunk_size as u32;
524            }
525
526            Ok(map)
527        }
528    };
529}
530
531// Generate read_hashmap_data_dyn_ref for HashMap
532impl_read_map_dyn_ref!(
533    read_hashmap_data_dyn_ref,
534    HashMap<K, V>,
535    Eq + std::hash::Hash
536);
537
538// Generate read_btreemap_data_dyn_ref for BTreeMap
539impl_read_map_dyn_ref!(
540    read_btreemap_data_dyn_ref,
541    BTreeMap<K, V>,
542    Ord
543);
544
545impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDefault> Serializer
546    for HashMap<K, V>
547{
548    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
549        write_map_data(self.iter(), self.len(), context, false)
550    }
551
552    fn fory_write_data_generic(
553        &self,
554        context: &mut WriteContext,
555        has_generics: bool,
556    ) -> Result<(), Error> {
557        write_map_data(self.iter(), self.len(), context, has_generics)
558    }
559
560    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
561        let len = context.reader.read_var_u32()?;
562        if len == 0 {
563            return Ok(HashMap::new());
564        }
565        let capacity = check_map_len(context, len)?;
566        if K::fory_is_polymorphic()
567            || K::fory_is_shared_ref()
568            || V::fory_is_polymorphic()
569            || V::fory_is_shared_ref()
570        {
571            let map: HashMap<K, V> = HashMap::with_capacity(capacity);
572            return read_hashmap_data_dyn_ref(context, map, len);
573        }
574        let mut map = HashMap::<K, V>::with_capacity(capacity);
575        let mut len_counter = 0;
576        loop {
577            if len_counter == len {
578                break;
579            }
580            let header = context.reader.read_u8()?;
581            if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
582                map.insert(K::fory_default(), V::fory_default());
583                len_counter += 1;
584                continue;
585            }
586            let key_declared = (header & DECL_KEY_TYPE) != 0;
587            let value_declared = (header & DECL_VALUE_TYPE) != 0;
588            let track_key_ref = (header & TRACKING_KEY_REF) != 0;
589            let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
590            if header & KEY_NULL != 0 {
591                // Null case is handled by KEY_NULL flag, so use None (no ref flag) unless tracking
592                let ref_mode = if track_value_ref {
593                    RefMode::Tracking
594                } else {
595                    RefMode::None
596                };
597                let value = V::fory_read(context, ref_mode, !value_declared)?;
598                map.insert(K::fory_default(), value);
599                len_counter += 1;
600                continue;
601            }
602            if header & VALUE_NULL != 0 {
603                // Null case is handled by VALUE_NULL flag, so use None (no ref flag) unless tracking
604                let ref_mode = if track_key_ref {
605                    RefMode::Tracking
606                } else {
607                    RefMode::None
608                };
609                let key = K::fory_read(context, ref_mode, !key_declared)?;
610                map.insert(key, V::fory_default());
611                len_counter += 1;
612                continue;
613            }
614            let chunk_size = context.reader.read_u8()?;
615            if header & DECL_KEY_TYPE == 0 {
616                K::fory_read_type_info(context)?;
617            }
618            if header & DECL_VALUE_TYPE == 0 {
619                V::fory_read_type_info(context)?;
620            }
621            let cur_len = len_counter + chunk_size as u32;
622            ensure!(
623                cur_len <= len,
624                Error::invalid_data(format!(
625                    "current length {} exceeds total length {}",
626                    cur_len, len
627                ))
628            );
629            if !track_key_ref && !track_value_ref {
630                for _ in 0..chunk_size {
631                    let key = K::fory_read_data(context)?;
632                    let value = V::fory_read_data(context)?;
633                    map.insert(key, value);
634                }
635            } else {
636                let key_ref_mode = if track_key_ref {
637                    RefMode::Tracking
638                } else {
639                    RefMode::None
640                };
641                let val_ref_mode = if track_value_ref {
642                    RefMode::Tracking
643                } else {
644                    RefMode::None
645                };
646                for _ in 0..chunk_size {
647                    let key = K::fory_read(context, key_ref_mode, false)?;
648                    let value = V::fory_read(context, val_ref_mode, false)?;
649                    map.insert(key, value);
650                }
651            }
652            // advance the counter after processing the chunk
653            len_counter += chunk_size as u32;
654        }
655        Ok(map)
656    }
657
658    fn fory_reserved_space() -> usize {
659        size_of::<i32>()
660    }
661
662    fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
663        Ok(TypeId::MAP)
664    }
665
666    fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
667        Ok(TypeId::MAP)
668    }
669
670    fn fory_static_type_id() -> TypeId
671    where
672        Self: Sized,
673    {
674        TypeId::MAP
675    }
676
677    fn as_any(&self) -> &dyn std::any::Any {
678        self
679    }
680
681    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
682        context.writer.write_u8(TypeId::MAP as u8);
683        Ok(())
684    }
685
686    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
687        read_basic_type_info::<Self>(context)
688    }
689}
690
691impl<K, V> ForyDefault for HashMap<K, V> {
692    fn fory_default() -> Self {
693        HashMap::new()
694    }
695}
696
697impl<K: Serializer + ForyDefault + Ord + std::hash::Hash, V: Serializer + ForyDefault> Serializer
698    for BTreeMap<K, V>
699{
700    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
701        write_map_data(self.iter(), self.len(), context, false)
702    }
703
704    fn fory_write_data_generic(
705        &self,
706        context: &mut WriteContext,
707        has_generics: bool,
708    ) -> Result<(), Error> {
709        write_map_data(self.iter(), self.len(), context, has_generics)
710    }
711
712    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
713        let len = context.reader.read_var_u32()?;
714        if len == 0 {
715            return Ok(BTreeMap::new());
716        }
717        let _ = check_map_len(context, len)?;
718        let mut map = BTreeMap::<K, V>::new();
719        if K::fory_is_polymorphic()
720            || K::fory_is_shared_ref()
721            || V::fory_is_polymorphic()
722            || V::fory_is_shared_ref()
723        {
724            let map: BTreeMap<K, V> = BTreeMap::new();
725            return read_btreemap_data_dyn_ref(context, map, len);
726        }
727        let mut len_counter = 0;
728        loop {
729            if len_counter == len {
730                break;
731            }
732            let header = context.reader.read_u8()?;
733            if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
734                map.insert(K::fory_default(), V::fory_default());
735                len_counter += 1;
736                continue;
737            }
738            let key_declared = (header & DECL_KEY_TYPE) != 0;
739            let value_declared = (header & DECL_VALUE_TYPE) != 0;
740            let track_key_ref = (header & TRACKING_KEY_REF) != 0;
741            let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
742            if header & KEY_NULL != 0 {
743                // Null case is handled by KEY_NULL flag, so use None (no ref flag) unless tracking
744                let ref_mode = if track_value_ref {
745                    RefMode::Tracking
746                } else {
747                    RefMode::None
748                };
749                let value = V::fory_read(context, ref_mode, !value_declared)?;
750                map.insert(K::fory_default(), value);
751                len_counter += 1;
752                continue;
753            }
754            if header & VALUE_NULL != 0 {
755                // Null case is handled by VALUE_NULL flag, so use None (no ref flag) unless tracking
756                let ref_mode = if track_key_ref {
757                    RefMode::Tracking
758                } else {
759                    RefMode::None
760                };
761                let key = K::fory_read(context, ref_mode, !key_declared)?;
762                map.insert(key, V::fory_default());
763                len_counter += 1;
764                continue;
765            }
766            let chunk_size = context.reader.read_u8()?;
767            if header & DECL_KEY_TYPE == 0 {
768                K::fory_read_type_info(context)?;
769            }
770            if header & DECL_VALUE_TYPE == 0 {
771                V::fory_read_type_info(context)?;
772            }
773            let cur_len = len_counter + chunk_size as u32;
774            ensure!(
775                cur_len <= len,
776                Error::invalid_data(format!(
777                    "current length {} exceeds total length {}",
778                    cur_len, len
779                ))
780            );
781            if !track_key_ref && !track_value_ref {
782                for _ in 0..chunk_size {
783                    let key = K::fory_read_data(context)?;
784                    let value = V::fory_read_data(context)?;
785                    map.insert(key, value);
786                }
787            } else {
788                let key_ref_mode = if track_key_ref {
789                    RefMode::Tracking
790                } else {
791                    RefMode::None
792                };
793                let val_ref_mode = if track_value_ref {
794                    RefMode::Tracking
795                } else {
796                    RefMode::None
797                };
798                for _ in 0..chunk_size {
799                    let key = K::fory_read(context, key_ref_mode, false)?;
800                    let value = V::fory_read(context, val_ref_mode, false)?;
801                    map.insert(key, value);
802                }
803            }
804            len_counter += chunk_size as u32;
805        }
806        Ok(map)
807    }
808
809    fn fory_reserved_space() -> usize {
810        size_of::<i32>()
811    }
812
813    fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
814        Ok(TypeId::MAP)
815    }
816
817    fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
818        Ok(TypeId::MAP)
819    }
820
821    fn fory_static_type_id() -> TypeId
822    where
823        Self: Sized,
824    {
825        TypeId::MAP
826    }
827
828    fn as_any(&self) -> &dyn std::any::Any {
829        self
830    }
831
832    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
833        context.writer.write_u8(TypeId::MAP as u8);
834        Ok(())
835    }
836
837    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
838        read_basic_type_info::<Self>(context)
839    }
840}
841
842impl<K, V> ForyDefault for BTreeMap<K, V> {
843    fn fory_default() -> Self {
844        BTreeMap::new()
845    }
846}