1use std::cell::RefCell;
11use std::path::PathBuf;
12
13use euclid::default::Transform3D;
14use malloc_size_of_derive::MallocSizeOf;
15use net_traits::filemanager_thread::RelativePos;
16use pixels::SharedSnapshot;
17use rustc_hash::FxHashMap;
18use serde::{Deserialize, Serialize};
19use servo_base::id::{
20 BlobId, DomExceptionId, DomMatrixId, DomPointId, DomQuadId, DomRectId, FileId, FileListId,
21 ImageBitmapId, ImageDataId, QuotaExceededErrorId,
22};
23use servo_url::ImmutableOrigin;
24use strum::EnumIter;
25use uuid::Uuid;
26
27use super::StructuredSerializedData;
28
29pub(crate) trait BroadcastClone
30where
31 Self: Sized,
32{
33 type Id: Eq + std::hash::Hash + Copy;
35 fn clone_for_broadcast(&self) -> Option<Self>;
38 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>>;
40 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>>;
42}
43
44#[derive(Clone, Copy, Debug, EnumIter)]
49pub enum Serializable {
50 File,
52 FileList,
54 Blob,
56 DomPoint,
58 DomPointReadOnly,
60 DomRect,
62 DomRectReadOnly,
64 DomQuad,
66 DomMatrix,
68 DomMatrixReadOnly,
70 QuotaExceededError,
72 DomException,
74 ImageBitmap,
76 ImageData,
78}
79
80impl Serializable {
81 pub(super) fn clone_values(
82 &self,
83 ) -> fn(&StructuredSerializedData, &mut StructuredSerializedData) {
84 match self {
85 Serializable::File => StructuredSerializedData::clone_all_of_type::<SerializableFile>,
86 Serializable::FileList => {
87 StructuredSerializedData::clone_all_of_type::<SerializableFileList>
88 },
89 Serializable::Blob => StructuredSerializedData::clone_all_of_type::<BlobImpl>,
90 Serializable::DomPoint => StructuredSerializedData::clone_all_of_type::<DomPoint>,
91 Serializable::DomPointReadOnly => {
92 StructuredSerializedData::clone_all_of_type::<DomPoint>
93 },
94 Serializable::DomRect => StructuredSerializedData::clone_all_of_type::<DomRect>,
95 Serializable::DomRectReadOnly => StructuredSerializedData::clone_all_of_type::<DomRect>,
96 Serializable::DomQuad => StructuredSerializedData::clone_all_of_type::<DomQuad>,
97 Serializable::DomMatrix => StructuredSerializedData::clone_all_of_type::<DomMatrix>,
98 Serializable::DomMatrixReadOnly => {
99 StructuredSerializedData::clone_all_of_type::<DomMatrix>
100 },
101 Serializable::DomException => {
102 StructuredSerializedData::clone_all_of_type::<DomException>
103 },
104 Serializable::ImageBitmap => {
105 StructuredSerializedData::clone_all_of_type::<SerializableImageBitmap>
106 },
107 Serializable::QuotaExceededError => {
108 StructuredSerializedData::clone_all_of_type::<SerializableQuotaExceededError>
109 },
110 Serializable::ImageData => {
111 StructuredSerializedData::clone_all_of_type::<SerializableImageData>
112 },
113 }
114 }
115}
116
117#[derive(Debug, Deserialize, Serialize)]
119pub struct BroadcastChannelMsg {
120 pub origin: ImmutableOrigin,
122 pub channel_name: String,
124 pub data: StructuredSerializedData,
126}
127
128impl Clone for BroadcastChannelMsg {
129 fn clone(&self) -> BroadcastChannelMsg {
130 BroadcastChannelMsg {
131 data: self.data.clone_for_broadcast(),
132 origin: self.origin.clone(),
133 channel_name: self.channel_name.clone(),
134 }
135 }
136}
137
138#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
139pub struct SerializableFile {
140 pub blob_impl: BlobImpl,
141 pub name: String,
142 pub modified: i64,
143}
144
145impl BroadcastClone for SerializableFile {
146 type Id = FileId;
147
148 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
149 &data.files
150 }
151
152 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
153 &mut data.files
154 }
155
156 fn clone_for_broadcast(&self) -> Option<Self> {
157 let blob_impl = self.blob_impl.clone_for_broadcast()?;
158 Some(SerializableFile {
159 blob_impl,
160 name: self.name.clone(),
161 modified: self.modified,
162 })
163 }
164}
165
166#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
167pub struct SerializableFileList {
168 pub files: Vec<SerializableFile>,
169}
170
171impl BroadcastClone for SerializableFileList {
172 type Id = FileListId;
173
174 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
175 &data.file_lists
176 }
177
178 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
179 &mut data.file_lists
180 }
181
182 fn clone_for_broadcast(&self) -> Option<Self> {
183 let files = self
184 .files
185 .iter()
186 .map(|file| file.clone_for_broadcast())
187 .collect::<Option<Vec<_>>>()?;
188 Some(SerializableFileList { files })
189 }
190}
191
192#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
194pub struct FileBlob {
195 #[ignore_malloc_size_of = "Uuid are hard(not really)"]
196 id: Uuid,
197 #[ignore_malloc_size_of = "PathBuf are hard"]
198 name: Option<PathBuf>,
199 cache: RefCell<Option<Vec<u8>>>,
200 size: u64,
201}
202
203impl FileBlob {
204 pub fn new(id: Uuid, name: Option<PathBuf>, cache: Option<Vec<u8>>, size: u64) -> FileBlob {
206 FileBlob {
207 id,
208 name,
209 cache: RefCell::new(cache),
210 size,
211 }
212 }
213
214 pub fn get_size(&self) -> u64 {
216 self.size
217 }
218
219 pub fn get_cache(&self) -> Option<Vec<u8>> {
221 self.cache.borrow().clone()
222 }
223
224 pub fn cache_bytes(&self, bytes: Vec<u8>) {
226 *self.cache.borrow_mut() = Some(bytes);
227 }
228
229 pub fn get_id(&self) -> Uuid {
231 self.id
232 }
233}
234
235impl BroadcastClone for BlobImpl {
236 type Id = BlobId;
237
238 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
239 &data.blobs
240 }
241
242 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
243 &mut data.blobs
244 }
245
246 fn clone_for_broadcast(&self) -> Option<Self> {
247 let type_string = self.type_string();
248
249 if let BlobData::Memory(bytes) = self.blob_data() {
250 let blob_clone = BlobImpl::new_from_bytes(bytes.clone(), type_string);
251
252 return Some(blob_clone);
256 } else {
257 log::warn!("Serialized blob not in memory format(should never happen).");
259 }
260 None
261 }
262}
263
264#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
266pub struct BlobImpl {
267 blob_id: BlobId,
269 type_string: String,
271 blob_data: BlobData,
273 slices: Vec<BlobId>,
275}
276
277#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
279pub enum BlobData {
280 File(FileBlob),
282 Memory(Vec<u8>),
284 Sliced(BlobId, RelativePos),
289}
290
291impl BlobImpl {
292 pub fn new_from_bytes(bytes: Vec<u8>, type_string: String) -> BlobImpl {
294 let blob_id = BlobId::new();
295 let blob_data = BlobData::Memory(bytes);
296 BlobImpl {
297 blob_id,
298 type_string,
299 blob_data,
300 slices: vec![],
301 }
302 }
303
304 pub fn new_from_file(file_id: Uuid, name: PathBuf, size: u64, type_string: String) -> BlobImpl {
306 let blob_id = BlobId::new();
307 let blob_data = BlobData::File(FileBlob {
308 id: file_id,
309 name: Some(name),
310 cache: RefCell::new(None),
311 size,
312 });
313 BlobImpl {
314 blob_id,
315 type_string,
316 blob_data,
317 slices: vec![],
318 }
319 }
320
321 pub fn new_sliced(range: RelativePos, parent: BlobId, type_string: String) -> BlobImpl {
323 let blob_id = BlobId::new();
324 let blob_data = BlobData::Sliced(parent, range);
325 BlobImpl {
326 blob_id,
327 type_string,
328 blob_data,
329 slices: vec![],
330 }
331 }
332
333 pub fn blob_id(&self) -> BlobId {
335 self.blob_id
336 }
337
338 pub fn type_string(&self) -> String {
340 self.type_string.clone()
341 }
342
343 pub fn blob_data(&self) -> &BlobData {
345 &self.blob_data
346 }
347
348 pub fn blob_data_mut(&mut self) -> &mut BlobData {
350 &mut self.blob_data
351 }
352}
353
354#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
355pub struct DomPoint {
357 pub x: f64,
359 pub y: f64,
361 pub z: f64,
363 pub w: f64,
365}
366
367impl BroadcastClone for DomPoint {
368 type Id = DomPointId;
369
370 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
371 &data.points
372 }
373
374 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
375 &mut data.points
376 }
377
378 fn clone_for_broadcast(&self) -> Option<Self> {
379 Some(self.clone())
380 }
381}
382
383#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
384pub struct DomRect {
386 pub x: f64,
388 pub y: f64,
390 pub width: f64,
392 pub height: f64,
394}
395
396impl BroadcastClone for DomRect {
397 type Id = DomRectId;
398
399 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
400 &data.rects
401 }
402
403 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
404 &mut data.rects
405 }
406
407 fn clone_for_broadcast(&self) -> Option<Self> {
408 Some(self.clone())
409 }
410}
411
412#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
413pub struct DomQuad {
415 pub p1: DomPoint,
417 pub p2: DomPoint,
419 pub p3: DomPoint,
421 pub p4: DomPoint,
423}
424
425impl BroadcastClone for DomQuad {
426 type Id = DomQuadId;
427
428 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
429 &data.quads
430 }
431
432 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
433 &mut data.quads
434 }
435
436 fn clone_for_broadcast(&self) -> Option<Self> {
437 Some(self.clone())
438 }
439}
440
441#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
442pub struct DomMatrix {
444 pub matrix: Transform3D<f64>,
446 pub is_2d: bool,
448}
449
450impl BroadcastClone for DomMatrix {
451 type Id = DomMatrixId;
452
453 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
454 &data.matrices
455 }
456
457 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
458 &mut data.matrices
459 }
460
461 fn clone_for_broadcast(&self) -> Option<Self> {
462 Some(self.clone())
463 }
464}
465
466#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
467pub struct DomException {
469 pub message: String,
470 pub name: String,
471}
472
473impl BroadcastClone for DomException {
474 type Id = DomExceptionId;
475
476 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
477 &data.exceptions
478 }
479
480 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
481 &mut data.exceptions
482 }
483
484 fn clone_for_broadcast(&self) -> Option<Self> {
485 Some(self.clone())
486 }
487}
488
489#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
490pub struct SerializableQuotaExceededError {
492 pub dom_exception: DomException,
493 pub quota: Option<f64>,
494 pub requested: Option<f64>,
495}
496
497impl BroadcastClone for SerializableQuotaExceededError {
498 type Id = QuotaExceededErrorId;
499
500 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
501 &data.quota_exceeded_errors
502 }
503
504 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
505 &mut data.quota_exceeded_errors
506 }
507
508 fn clone_for_broadcast(&self) -> Option<Self> {
509 Some(self.clone())
510 }
511}
512
513#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
514pub struct SerializableImageBitmap {
516 pub bitmap_data: SharedSnapshot,
517}
518
519impl BroadcastClone for SerializableImageBitmap {
520 type Id = ImageBitmapId;
521
522 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
523 &data.image_bitmaps
524 }
525
526 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
527 &mut data.image_bitmaps
528 }
529
530 fn clone_for_broadcast(&self) -> Option<Self> {
531 Some(self.clone())
532 }
533}
534
535#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
536pub struct SerializableImageData {
537 pub data: Vec<u8>,
538 pub width: u32,
539 pub height: u32,
540}
541
542impl BroadcastClone for SerializableImageData {
543 type Id = ImageDataId;
544
545 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
546 &data.image_data
547 }
548
549 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
550 &mut data.image_data
551 }
552
553 fn clone_for_broadcast(&self) -> Option<Self> {
554 Some(self.clone())
555 }
556}