servo_constellation_traits/structured_data/
mod.rs1mod serializable;
9mod transferable;
10
11use log::warn;
12use malloc_size_of_derive::MallocSizeOf;
13use rustc_hash::{FxBuildHasher, FxHashMap};
14use serde::{Deserialize, Serialize};
15pub use serializable::*;
16use servo_base::id::{
17 BlobId, CryptoKeyId, DomExceptionId, DomMatrixId, DomPointId, DomQuadId, DomRectId, FileId,
18 FileListId, ImageBitmapId, ImageDataId, MessagePortId, OffscreenCanvasId, QuotaExceededErrorId,
19};
20use strum::IntoEnumIterator;
21pub use transferable::*;
22
23#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
26pub struct StructuredSerializedData {
27 pub serialized: Vec<u8>,
29 pub blobs: Option<FxHashMap<BlobId, BlobImpl>>,
31 pub files: Option<FxHashMap<FileId, SerializableFile>>,
33 pub file_lists: Option<FxHashMap<FileListId, SerializableFileList>>,
35 pub points: Option<FxHashMap<DomPointId, DomPoint>>,
37 pub rects: Option<FxHashMap<DomRectId, DomRect>>,
39 pub quads: Option<FxHashMap<DomQuadId, DomQuad>>,
41 pub matrices: Option<FxHashMap<DomMatrixId, DomMatrix>>,
43 pub exceptions: Option<FxHashMap<DomExceptionId, DomException>>,
45 pub quota_exceeded_errors:
47 Option<FxHashMap<QuotaExceededErrorId, SerializableQuotaExceededError>>,
48 pub ports: Option<FxHashMap<MessagePortId, MessagePortImpl>>,
50 pub transform_streams: Option<FxHashMap<MessagePortId, TransformStreamData>>,
52 pub image_bitmaps: Option<FxHashMap<ImageBitmapId, SerializableImageBitmap>>,
54 pub transferred_image_bitmaps: Option<FxHashMap<ImageBitmapId, SerializableImageBitmap>>,
56 pub offscreen_canvases: Option<FxHashMap<OffscreenCanvasId, TransferableOffscreenCanvas>>,
58 pub image_data: Option<FxHashMap<ImageDataId, SerializableImageData>>,
60 pub crypto_keys: Option<FxHashMap<CryptoKeyId, SerializableCryptoKey>>,
62}
63
64impl StructuredSerializedData {
65 fn is_empty(&self, val: Transferrable) -> bool {
66 fn is_field_empty<K, V>(field: &Option<FxHashMap<K, V>>) -> bool {
67 field.as_ref().is_none_or(|h| h.is_empty())
68 }
69 match val {
70 Transferrable::ImageBitmap => is_field_empty(&self.transferred_image_bitmaps),
71 Transferrable::MessagePort => is_field_empty(&self.ports),
72 Transferrable::OffscreenCanvas => is_field_empty(&self.offscreen_canvases),
73 Transferrable::ReadableStream => is_field_empty(&self.ports),
74 Transferrable::WritableStream => is_field_empty(&self.ports),
75 Transferrable::TransformStream => is_field_empty(&self.ports),
76 }
77 }
78
79 fn clone_all_of_type<T: BroadcastClone>(&self, cloned: &mut StructuredSerializedData) {
82 let existing = T::source(self);
83 let Some(existing) = existing else { return };
84 let mut clones = FxHashMap::with_capacity_and_hasher(existing.len(), FxBuildHasher);
85
86 for (original_id, obj) in existing.iter() {
87 if let Some(clone) = obj.clone_for_broadcast() {
88 clones.insert(*original_id, clone);
89 }
90 }
91
92 *T::destination(cloned) = Some(clones);
93 }
94
95 pub fn clone_for_broadcast(&self) -> StructuredSerializedData {
97 for transferrable in Transferrable::iter() {
98 if !self.is_empty(transferrable) {
99 warn!(
101 "Attempt to broadcast structured serialized data including {:?} (should never happen).",
102 transferrable,
103 );
104 }
105 }
106
107 let serialized = self.serialized.clone();
108
109 let mut cloned = StructuredSerializedData {
110 serialized,
111 ..Default::default()
112 };
113
114 for serializable in Serializable::iter() {
115 let clone_impl = serializable.clone_values();
116 clone_impl(self, &mut cloned);
117 }
118
119 cloned
120 }
121}