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