1use 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
38#[cold]
39fn map_size_limit_exceeded(len: u32, max: u32) -> Error {
40 Error::size_limit_exceeded(format!("Map size {} exceeds limit {}", len, max))
41}
42
43fn check_map_len(context: &ReadContext, len: u32) -> Result<(), Error> {
44 let len = len as usize;
45 let remaining = context.reader.slice_after_cursor().len();
46 if len > remaining {
47 let cursor = context.reader.get_cursor();
48 return Err(Error::buffer_out_of_bound(cursor, len, cursor + remaining));
49 }
50 Ok(())
51}
52
53fn write_chunk_size(context: &mut WriteContext, header_offset: usize, size: u8) {
54 context.writer.set_bytes(header_offset + 1, &[size]);
55}
56
57pub fn write_map_data<'a, K, V, I>(
58 iter: I,
59 length: usize,
60 context: &mut WriteContext,
61 has_generics: bool,
62) -> Result<(), Error>
63where
64 K: Serializer,
65 V: Serializer,
66 I: Iterator<Item = (&'a K, &'a V)>,
67{
68 context.writer.write_var_u32(length as u32);
69 if length == 0 {
70 return Ok(());
71 }
72 let reserved_space = (K::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length
73 + (V::fory_reserved_space() + SIZE_OF_REF_AND_TYPE) * length;
74 context.writer.reserve(reserved_space);
75
76 if K::fory_is_polymorphic()
77 || K::fory_is_shared_ref()
78 || V::fory_is_polymorphic()
79 || V::fory_is_shared_ref()
80 {
81 return write_map_data_dyn_ref(iter, context, has_generics);
82 }
83 let mut header_offset = 0;
84 let mut pair_counter: u8 = 0;
85 let mut need_write_header = true;
86 let key_static_type_id = K::fory_static_type_id();
87 let val_static_type_id = V::fory_static_type_id();
88 let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
89 let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
90 for (key, value) in iter {
91 let key_is_none = key.fory_is_none();
92 let value_is_none = value.fory_is_none();
93
94 if key_is_none || value_is_none {
95 if !need_write_header && pair_counter > 0 {
96 write_chunk_size(context, header_offset, pair_counter);
97 pair_counter = 0;
98 need_write_header = true;
99 }
100
101 if key_is_none && value_is_none {
102 context.writer.write_u8(KEY_NULL | VALUE_NULL);
103 continue;
104 }
105
106 if value_is_none {
107 let mut chunk_header = VALUE_NULL;
108 if is_key_declared {
109 chunk_header |= DECL_KEY_TYPE;
110 context.writer.write_u8(chunk_header);
111 } else {
112 context.writer.write_u8(chunk_header);
113 K::fory_write_type_info(context)?;
114 }
115 key.fory_write_data_generic(context, has_generics)?;
116 continue;
117 }
118
119 let mut chunk_header = KEY_NULL;
121 if is_val_declared {
122 chunk_header |= DECL_VALUE_TYPE;
123 context.writer.write_u8(chunk_header);
124 } else {
125 context.writer.write_u8(chunk_header);
126 V::fory_write_type_info(context)?;
127 }
128 value.fory_write_data_generic(context, has_generics)?;
129 continue;
130 }
131
132 if need_write_header {
133 header_offset = context.writer.len();
134 context.writer.write_i16(-1);
135 let mut chunk_header = 0u8;
136 if is_key_declared {
137 chunk_header |= DECL_KEY_TYPE;
138 } else {
139 K::fory_write_type_info(context)?;
140 }
141 if is_val_declared {
142 chunk_header |= DECL_VALUE_TYPE;
143 } else {
144 V::fory_write_type_info(context)?;
145 }
146 context.writer.set_bytes(header_offset, &[chunk_header]);
147 need_write_header = false;
148 }
149
150 key.fory_write_data_generic(context, has_generics)?;
151 value.fory_write_data_generic(context, has_generics)?;
152 pair_counter += 1;
153 if pair_counter == MAX_CHUNK_SIZE {
154 write_chunk_size(context, header_offset, pair_counter);
155 pair_counter = 0;
156 need_write_header = true;
157 }
158 }
159 if pair_counter > 0 {
160 write_chunk_size(context, header_offset, pair_counter);
161 }
162 Ok(())
163}
164
165fn write_map_data_dyn_ref<'a, K, V, I>(
167 iter: I,
168 context: &mut WriteContext,
169 has_generics: bool,
170) -> Result<(), Error>
171where
172 K: Serializer,
173 V: Serializer,
174 I: Iterator<Item = (&'a K, &'a V)>,
175{
176 let mut header_offset = 0;
177 let mut pair_counter: u8 = 0;
178 let mut need_write_header = true;
179 let key_static_type_id = K::fory_static_type_id();
180 let val_static_type_id = V::fory_static_type_id();
181 let is_key_declared = has_generics && !need_to_write_type_for_field(key_static_type_id);
182 let is_val_declared = has_generics && !need_to_write_type_for_field(val_static_type_id);
183 let key_is_polymorphic = K::fory_is_polymorphic();
184 let val_is_polymorphic = V::fory_is_polymorphic();
185 let key_is_shared_ref = K::fory_is_shared_ref();
186 let val_is_shared_ref = V::fory_is_shared_ref();
187
188 let mut current_key_type_id: Option<std::any::TypeId> = None;
190 let mut current_val_type_id: Option<std::any::TypeId> = None;
191
192 for (key, value) in iter {
193 if key.fory_is_none() || value.fory_is_none() {
195 if pair_counter > 0 {
197 write_chunk_size(context, header_offset, pair_counter);
198 pair_counter = 0;
199 need_write_header = true;
200 }
201
202 if key.fory_is_none() && value.fory_is_none() {
203 context.writer.write_u8(KEY_NULL | VALUE_NULL);
204 continue;
205 } else if value.fory_is_none() {
206 let mut chunk_header = VALUE_NULL;
207 if key_is_shared_ref {
208 chunk_header |= TRACKING_KEY_REF;
209 }
210 if is_key_declared && !key_is_polymorphic {
211 chunk_header |= DECL_KEY_TYPE;
212 context.writer.write_u8(chunk_header);
213 } else {
214 context.writer.write_u8(chunk_header);
215 if key_is_polymorphic {
216 context.write_any_type_info(
217 K::fory_static_type_id() as u32,
218 key.fory_concrete_type_id(),
219 )?;
220 } else {
221 K::fory_write_type_info(context)?;
222 }
223 }
224 if key_is_shared_ref {
225 key.fory_write(context, RefMode::Tracking, false, has_generics)?;
226 } else {
227 key.fory_write_data_generic(context, has_generics)?;
228 }
229 continue;
230 } else {
231 let mut chunk_header = KEY_NULL;
233 if val_is_shared_ref {
234 chunk_header |= TRACKING_VALUE_REF;
235 }
236 if is_val_declared && !val_is_polymorphic {
237 chunk_header |= DECL_VALUE_TYPE;
238 context.writer.write_u8(chunk_header);
239 } else {
240 context.writer.write_u8(chunk_header);
241 if val_is_polymorphic {
242 context.write_any_type_info(
243 V::fory_static_type_id() as u32,
244 value.fory_concrete_type_id(),
245 )?;
246 } else {
247 V::fory_write_type_info(context)?;
248 }
249 }
250 if val_is_shared_ref {
251 value.fory_write(context, RefMode::Tracking, false, has_generics)?;
252 } else {
253 value.fory_write_data_generic(context, has_generics)?;
254 }
255 continue;
256 }
257 }
258
259 let key_type_id = if key_is_polymorphic {
261 Some(key.fory_concrete_type_id())
262 } else {
263 None
264 };
265 let val_type_id = if val_is_polymorphic {
266 Some(value.fory_concrete_type_id())
267 } else {
268 None
269 };
270
271 let types_changed = if key_is_polymorphic || val_is_polymorphic {
273 key_type_id != current_key_type_id || val_type_id != current_val_type_id
274 } else {
275 false
276 };
277
278 if need_write_header || types_changed {
279 if types_changed && pair_counter > 0 {
281 write_chunk_size(context, header_offset, pair_counter);
282 pair_counter = 0;
283 }
284
285 header_offset = context.writer.len();
287 context.writer.write_i16(-1); let mut chunk_header = 0u8;
290
291 if key_is_shared_ref {
293 chunk_header |= TRACKING_KEY_REF;
294 }
295 if is_key_declared && !key_is_polymorphic {
296 chunk_header |= DECL_KEY_TYPE;
297 } else {
298 if key_is_polymorphic {
300 context.write_any_type_info(
301 K::fory_static_type_id() as u32,
302 key.fory_concrete_type_id(),
303 )?;
304 } else {
305 K::fory_write_type_info(context)?;
306 }
307 }
308
309 if val_is_shared_ref {
311 chunk_header |= TRACKING_VALUE_REF;
312 }
313 if is_val_declared && !val_is_polymorphic {
314 chunk_header |= DECL_VALUE_TYPE;
315 } else {
316 if val_is_polymorphic {
318 context.write_any_type_info(
319 V::fory_static_type_id() as u32,
320 value.fory_concrete_type_id(),
321 )?;
322 } else {
323 V::fory_write_type_info(context)?;
324 }
325 }
326
327 context.writer.set_bytes(header_offset, &[chunk_header]);
328 need_write_header = false;
329 current_key_type_id = key_type_id;
330 current_val_type_id = val_type_id;
331 }
332
333 if key_is_shared_ref {
335 key.fory_write(context, RefMode::Tracking, false, has_generics)?;
336 } else {
337 key.fory_write_data_generic(context, has_generics)?;
338 }
339 if val_is_shared_ref {
340 value.fory_write(context, RefMode::Tracking, false, has_generics)?;
341 } else {
342 value.fory_write_data_generic(context, has_generics)?;
343 }
344 pair_counter += 1;
345 if pair_counter == MAX_CHUNK_SIZE {
346 write_chunk_size(context, header_offset, pair_counter);
347 pair_counter = 0;
348 need_write_header = true;
349 current_key_type_id = None;
350 current_val_type_id = None;
351 }
352 }
353
354 if pair_counter > 0 {
356 write_chunk_size(context, header_offset, pair_counter);
357 }
358
359 Ok(())
360}
361
362macro_rules! impl_read_map_dyn_ref {
365 ($fn_name:ident, $map_type:ty, $($extra_trait_bounds:tt)*) => {
366 fn $fn_name<K, V>(
367 context: &mut ReadContext,
368 mut map: $map_type,
369 length: u32,
370 ) -> Result<$map_type, Error>
371 where
372 K: Serializer + ForyDefault + $($extra_trait_bounds)*,
373 V: Serializer + ForyDefault,
374 {
375 let key_is_polymorphic = K::fory_is_polymorphic();
376 let val_is_polymorphic = V::fory_is_polymorphic();
377 let mut len_counter = 0u32;
378
379 while len_counter < length {
380 let header = context.reader.read_u8()?;
381
382 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
384 map.insert(K::fory_default(), V::fory_default());
386 len_counter += 1;
387 continue;
388 }
389
390 if header & KEY_NULL != 0 {
391 let value_declared = (header & DECL_VALUE_TYPE) != 0;
393 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
394
395 let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
397 if val_is_polymorphic {
398 Some(context.read_any_type_info()?)
399 } else {
400 V::fory_read_type_info(context)?;
401 None
402 }
403 } else {
404 None
405 };
406
407 let ref_mode = if track_value_ref {
409 RefMode::Tracking
410 } else {
411 RefMode::None
412 };
413 let value = if let Some(type_info) = value_type_info {
414 V::fory_read_with_type_info(context, ref_mode, type_info)?
415 } else if track_value_ref {
416 V::fory_read(context, ref_mode, false)?
417 } else {
418 V::fory_read_data(context)?
419 };
420
421 map.insert(K::fory_default(), value);
422 len_counter += 1;
423 continue;
424 }
425
426 if header & VALUE_NULL != 0 {
427 let key_declared = (header & DECL_KEY_TYPE) != 0;
429 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
430
431 let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
432 if key_is_polymorphic {
433 Some(context.read_any_type_info()?)
434 } else {
435 K::fory_read_type_info(context)?;
436 None
437 }
438 } else {
439 None
440 };
441
442 let ref_mode = if track_key_ref {
443 RefMode::Tracking
444 } else {
445 RefMode::None
446 };
447 let key = if let Some(type_info) = key_type_info {
448 K::fory_read_with_type_info(context, ref_mode, type_info)?
449 } else if track_key_ref {
450 K::fory_read(context, ref_mode, false)?
451 } else {
452 K::fory_read_data(context)?
453 };
454
455 map.insert(key, V::fory_default());
456 len_counter += 1;
457 continue;
458 }
459
460 let chunk_size = context.reader.read_u8()?;
462 let key_declared = (header & DECL_KEY_TYPE) != 0;
463 let value_declared = (header & DECL_VALUE_TYPE) != 0;
464 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
470 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
471
472 let key_type_info: Option<Rc<TypeInfo>> = if !key_declared {
473 if key_is_polymorphic {
474 Some(context.read_any_type_info()?)
475 } else {
476 K::fory_read_type_info(context)?;
477 None
478 }
479 } else {
480 None
481 };
482 let value_type_info: Option<Rc<TypeInfo>> = if !value_declared {
483 if val_is_polymorphic {
484 Some(context.read_any_type_info()?)
485 } else {
486 V::fory_read_type_info(context)?;
487 None
488 }
489 } else {
490 None
491 };
492
493 let cur_len = len_counter + chunk_size as u32;
494 ensure!(
495 cur_len <= length,
496 Error::invalid_data(
497 format!("current length {} exceeds total length {}", cur_len, length)
498 )
499 );
500
501 let key_ref_mode = if track_key_ref {
503 RefMode::Tracking
504 } else {
505 RefMode::None
506 };
507 let val_ref_mode = if track_value_ref {
508 RefMode::Tracking
509 } else {
510 RefMode::None
511 };
512 for _ in 0..chunk_size {
513 let key = if let Some(type_info) = key_type_info.as_ref() {
514 K::fory_read_with_type_info(context, key_ref_mode, type_info.clone())?
515 } else if track_key_ref {
516 K::fory_read(context, key_ref_mode, false)?
517 } else {
518 K::fory_read_data(context)?
519 };
520
521 let value = if let Some(type_info) = value_type_info.as_ref() {
522 V::fory_read_with_type_info(context, val_ref_mode, type_info.clone())?
523 } else if track_value_ref {
524 V::fory_read(context, val_ref_mode, false)?
525 } else {
526 V::fory_read_data(context)?
527 };
528
529 map.insert(key, value);
530 }
531
532 len_counter += chunk_size as u32;
533 }
534
535 Ok(map)
536 }
537 };
538}
539
540impl_read_map_dyn_ref!(
542 read_hashmap_data_dyn_ref,
543 HashMap<K, V>,
544 Eq + std::hash::Hash
545);
546
547impl_read_map_dyn_ref!(
549 read_btreemap_data_dyn_ref,
550 BTreeMap<K, V>,
551 Ord
552);
553
554impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDefault> Serializer
555 for HashMap<K, V>
556{
557 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
558 write_map_data(self.iter(), self.len(), context, false)
559 }
560
561 fn fory_write_data_generic(
562 &self,
563 context: &mut WriteContext,
564 has_generics: bool,
565 ) -> Result<(), Error> {
566 write_map_data(self.iter(), self.len(), context, has_generics)
567 }
568
569 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
570 let len = context.reader.read_var_u32()?;
571 if len == 0 {
572 return Ok(HashMap::new());
573 }
574 let max = context.max_collection_size();
575 if len > max {
576 return Err(map_size_limit_exceeded(len, max));
577 }
578 check_map_len(context, len)?;
579 if K::fory_is_polymorphic()
580 || K::fory_is_shared_ref()
581 || V::fory_is_polymorphic()
582 || V::fory_is_shared_ref()
583 {
584 let map: HashMap<K, V> = HashMap::with_capacity(len as usize);
585 return read_hashmap_data_dyn_ref(context, map, len);
586 }
587 let mut map = HashMap::<K, V>::with_capacity(len as usize);
588 let mut len_counter = 0;
589 loop {
590 if len_counter == len {
591 break;
592 }
593 let header = context.reader.read_u8()?;
594 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
595 map.insert(K::fory_default(), V::fory_default());
596 len_counter += 1;
597 continue;
598 }
599 let key_declared = (header & DECL_KEY_TYPE) != 0;
600 let value_declared = (header & DECL_VALUE_TYPE) != 0;
601 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
602 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
603 if header & KEY_NULL != 0 {
604 let ref_mode = if track_value_ref {
606 RefMode::Tracking
607 } else {
608 RefMode::None
609 };
610 let value = V::fory_read(context, ref_mode, !value_declared)?;
611 map.insert(K::fory_default(), value);
612 len_counter += 1;
613 continue;
614 }
615 if header & VALUE_NULL != 0 {
616 let ref_mode = if track_key_ref {
618 RefMode::Tracking
619 } else {
620 RefMode::None
621 };
622 let key = K::fory_read(context, ref_mode, !key_declared)?;
623 map.insert(key, V::fory_default());
624 len_counter += 1;
625 continue;
626 }
627 let chunk_size = context.reader.read_u8()?;
628 if header & DECL_KEY_TYPE == 0 {
629 K::fory_read_type_info(context)?;
630 }
631 if header & DECL_VALUE_TYPE == 0 {
632 V::fory_read_type_info(context)?;
633 }
634 let cur_len = len_counter + chunk_size as u32;
635 ensure!(
636 cur_len <= len,
637 Error::invalid_data(format!(
638 "current length {} exceeds total length {}",
639 cur_len, len
640 ))
641 );
642 if !track_key_ref && !track_value_ref {
643 for _ in 0..chunk_size {
644 let key = K::fory_read_data(context)?;
645 let value = V::fory_read_data(context)?;
646 map.insert(key, value);
647 }
648 } else {
649 let key_ref_mode = if track_key_ref {
650 RefMode::Tracking
651 } else {
652 RefMode::None
653 };
654 let val_ref_mode = if track_value_ref {
655 RefMode::Tracking
656 } else {
657 RefMode::None
658 };
659 for _ in 0..chunk_size {
660 let key = K::fory_read(context, key_ref_mode, false)?;
661 let value = V::fory_read(context, val_ref_mode, false)?;
662 map.insert(key, value);
663 }
664 }
665 len_counter += chunk_size as u32;
667 }
668 Ok(map)
669 }
670
671 fn fory_reserved_space() -> usize {
672 size_of::<i32>()
673 }
674
675 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
676 Ok(TypeId::MAP)
677 }
678
679 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
680 Ok(TypeId::MAP)
681 }
682
683 fn fory_static_type_id() -> TypeId
684 where
685 Self: Sized,
686 {
687 TypeId::MAP
688 }
689
690 fn as_any(&self) -> &dyn std::any::Any {
691 self
692 }
693
694 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
695 context.writer.write_u8(TypeId::MAP as u8);
696 Ok(())
697 }
698
699 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
700 read_basic_type_info::<Self>(context)
701 }
702}
703
704impl<K, V> ForyDefault for HashMap<K, V> {
705 fn fory_default() -> Self {
706 HashMap::new()
707 }
708}
709
710impl<K: Serializer + ForyDefault + Ord + std::hash::Hash, V: Serializer + ForyDefault> Serializer
711 for BTreeMap<K, V>
712{
713 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
714 write_map_data(self.iter(), self.len(), context, false)
715 }
716
717 fn fory_write_data_generic(
718 &self,
719 context: &mut WriteContext,
720 has_generics: bool,
721 ) -> Result<(), Error> {
722 write_map_data(self.iter(), self.len(), context, has_generics)
723 }
724
725 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
726 let len = context.reader.read_var_u32()?;
727 if len == 0 {
728 return Ok(BTreeMap::new());
729 }
730 let max = context.max_collection_size();
731 if len > max {
732 return Err(map_size_limit_exceeded(len, max));
733 }
734 check_map_len(context, len)?;
735 let mut map = BTreeMap::<K, V>::new();
736 if K::fory_is_polymorphic()
737 || K::fory_is_shared_ref()
738 || V::fory_is_polymorphic()
739 || V::fory_is_shared_ref()
740 {
741 let map: BTreeMap<K, V> = BTreeMap::new();
742 return read_btreemap_data_dyn_ref(context, map, len);
743 }
744 let mut len_counter = 0;
745 loop {
746 if len_counter == len {
747 break;
748 }
749 let header = context.reader.read_u8()?;
750 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
751 map.insert(K::fory_default(), V::fory_default());
752 len_counter += 1;
753 continue;
754 }
755 let key_declared = (header & DECL_KEY_TYPE) != 0;
756 let value_declared = (header & DECL_VALUE_TYPE) != 0;
757 let track_key_ref = (header & TRACKING_KEY_REF) != 0;
758 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
759 if header & KEY_NULL != 0 {
760 let ref_mode = if track_value_ref {
762 RefMode::Tracking
763 } else {
764 RefMode::None
765 };
766 let value = V::fory_read(context, ref_mode, !value_declared)?;
767 map.insert(K::fory_default(), value);
768 len_counter += 1;
769 continue;
770 }
771 if header & VALUE_NULL != 0 {
772 let ref_mode = if track_key_ref {
774 RefMode::Tracking
775 } else {
776 RefMode::None
777 };
778 let key = K::fory_read(context, ref_mode, !key_declared)?;
779 map.insert(key, V::fory_default());
780 len_counter += 1;
781 continue;
782 }
783 let chunk_size = context.reader.read_u8()?;
784 if header & DECL_KEY_TYPE == 0 {
785 K::fory_read_type_info(context)?;
786 }
787 if header & DECL_VALUE_TYPE == 0 {
788 V::fory_read_type_info(context)?;
789 }
790 let cur_len = len_counter + chunk_size as u32;
791 ensure!(
792 cur_len <= len,
793 Error::invalid_data(format!(
794 "current length {} exceeds total length {}",
795 cur_len, len
796 ))
797 );
798 if !track_key_ref && !track_value_ref {
799 for _ in 0..chunk_size {
800 let key = K::fory_read_data(context)?;
801 let value = V::fory_read_data(context)?;
802 map.insert(key, value);
803 }
804 } else {
805 let key_ref_mode = if track_key_ref {
806 RefMode::Tracking
807 } else {
808 RefMode::None
809 };
810 let val_ref_mode = if track_value_ref {
811 RefMode::Tracking
812 } else {
813 RefMode::None
814 };
815 for _ in 0..chunk_size {
816 let key = K::fory_read(context, key_ref_mode, false)?;
817 let value = V::fory_read(context, val_ref_mode, false)?;
818 map.insert(key, value);
819 }
820 }
821 len_counter += chunk_size as u32;
822 }
823 Ok(map)
824 }
825
826 fn fory_reserved_space() -> usize {
827 size_of::<i32>()
828 }
829
830 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
831 Ok(TypeId::MAP)
832 }
833
834 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
835 Ok(TypeId::MAP)
836 }
837
838 fn fory_static_type_id() -> TypeId
839 where
840 Self: Sized,
841 {
842 TypeId::MAP
843 }
844
845 fn as_any(&self) -> &dyn std::any::Any {
846 self
847 }
848
849 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
850 context.writer.write_u8(TypeId::MAP as u8);
851 Ok(())
852 }
853
854 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
855 read_basic_type_info::<Self>(context)
856 }
857}
858
859impl<K, V> ForyDefault for BTreeMap<K, V> {
860 fn fory_default() -> Self {
861 BTreeMap::new()
862 }
863}