1use 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 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
149fn 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 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 if key.fory_is_none() || value.fory_is_none() {
179 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 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 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 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 if types_changed && pair_counter > 0 {
265 write_chunk_size(context, header_offset, pair_counter);
266 pair_counter = 0;
267 }
268
269 header_offset = context.writer.len();
271 context.writer.write_i16(-1); let mut chunk_header = 0u8;
274
275 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 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 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 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 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 if pair_counter > 0 {
340 write_chunk_size(context, header_offset, pair_counter);
341 }
342
343 Ok(())
344}
345
346macro_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 if header & KEY_NULL != 0 && header & VALUE_NULL != 0 {
371 map.insert(K::fory_default(), V::fory_default());
373 len_counter += 1;
374 continue;
375 }
376
377 if header & KEY_NULL != 0 {
378 let value_declared = (header & DECL_VALUE_TYPE) != 0;
380 let track_value_ref = (header & TRACKING_VALUE_REF) != 0;
381
382 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 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 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 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 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
506impl_read_map_dyn_ref!(
508 read_hashmap_data_dyn_ref,
509 HashMap<K, V>,
510 Eq + std::hash::Hash
511);
512
513impl_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 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}