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