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 id: Uuid,
196 name: Option<PathBuf>,
197 cache: RefCell<Option<Vec<u8>>>,
198 size: u64,
199}
200
201impl FileBlob {
202 pub fn new(id: Uuid, name: Option<PathBuf>, cache: Option<Vec<u8>>, size: u64) -> FileBlob {
204 FileBlob {
205 id,
206 name,
207 cache: RefCell::new(cache),
208 size,
209 }
210 }
211
212 pub fn get_size(&self) -> u64 {
214 self.size
215 }
216
217 pub fn get_cache(&self) -> Option<Vec<u8>> {
219 self.cache.borrow().clone()
220 }
221
222 pub fn cache_bytes(&self, bytes: Vec<u8>) {
224 *self.cache.borrow_mut() = Some(bytes);
225 }
226
227 pub fn get_id(&self) -> Uuid {
229 self.id
230 }
231}
232
233impl BroadcastClone for BlobImpl {
234 type Id = BlobId;
235
236 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
237 &data.blobs
238 }
239
240 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
241 &mut data.blobs
242 }
243
244 fn clone_for_broadcast(&self) -> Option<Self> {
245 let type_string = self.type_string();
246
247 if let BlobData::Memory(bytes) = self.blob_data() {
248 let blob_clone = BlobImpl::new_from_bytes(bytes.clone(), type_string);
249
250 return Some(blob_clone);
254 } else {
255 log::warn!("Serialized blob not in memory format(should never happen).");
257 }
258 None
259 }
260}
261
262#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
264pub struct BlobImpl {
265 blob_id: BlobId,
267 type_string: String,
269 blob_data: BlobData,
271 slices: Vec<BlobId>,
273}
274
275#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
277pub enum BlobData {
278 File(FileBlob),
280 Memory(Vec<u8>),
282 Sliced(BlobId, RelativePos),
287}
288
289impl BlobImpl {
290 pub fn new_from_bytes(bytes: Vec<u8>, type_string: String) -> BlobImpl {
292 let blob_id = BlobId::new();
293 let blob_data = BlobData::Memory(bytes);
294 BlobImpl {
295 blob_id,
296 type_string,
297 blob_data,
298 slices: vec![],
299 }
300 }
301
302 pub fn new_from_file(file_id: Uuid, name: PathBuf, size: u64, type_string: String) -> BlobImpl {
304 let blob_id = BlobId::new();
305 let blob_data = BlobData::File(FileBlob {
306 id: file_id,
307 name: Some(name),
308 cache: RefCell::new(None),
309 size,
310 });
311 BlobImpl {
312 blob_id,
313 type_string,
314 blob_data,
315 slices: vec![],
316 }
317 }
318
319 pub fn new_sliced(range: RelativePos, parent: BlobId, type_string: String) -> BlobImpl {
321 let blob_id = BlobId::new();
322 let blob_data = BlobData::Sliced(parent, range);
323 BlobImpl {
324 blob_id,
325 type_string,
326 blob_data,
327 slices: vec![],
328 }
329 }
330
331 pub fn blob_id(&self) -> BlobId {
333 self.blob_id
334 }
335
336 pub fn type_string(&self) -> String {
338 self.type_string.clone()
339 }
340
341 pub fn blob_data(&self) -> &BlobData {
343 &self.blob_data
344 }
345
346 pub fn blob_data_mut(&mut self) -> &mut BlobData {
348 &mut self.blob_data
349 }
350}
351
352#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
353pub struct DomPoint {
355 pub x: f64,
357 pub y: f64,
359 pub z: f64,
361 pub w: f64,
363}
364
365impl BroadcastClone for DomPoint {
366 type Id = DomPointId;
367
368 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
369 &data.points
370 }
371
372 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
373 &mut data.points
374 }
375
376 fn clone_for_broadcast(&self) -> Option<Self> {
377 Some(self.clone())
378 }
379}
380
381#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
382pub struct DomRect {
384 pub x: f64,
386 pub y: f64,
388 pub width: f64,
390 pub height: f64,
392}
393
394impl BroadcastClone for DomRect {
395 type Id = DomRectId;
396
397 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
398 &data.rects
399 }
400
401 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
402 &mut data.rects
403 }
404
405 fn clone_for_broadcast(&self) -> Option<Self> {
406 Some(self.clone())
407 }
408}
409
410#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
411pub struct DomQuad {
413 pub p1: DomPoint,
415 pub p2: DomPoint,
417 pub p3: DomPoint,
419 pub p4: DomPoint,
421}
422
423impl BroadcastClone for DomQuad {
424 type Id = DomQuadId;
425
426 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
427 &data.quads
428 }
429
430 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
431 &mut data.quads
432 }
433
434 fn clone_for_broadcast(&self) -> Option<Self> {
435 Some(self.clone())
436 }
437}
438
439#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
440pub struct DomMatrix {
442 pub matrix: Transform3D<f64>,
444 pub is_2d: bool,
446}
447
448impl BroadcastClone for DomMatrix {
449 type Id = DomMatrixId;
450
451 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
452 &data.matrices
453 }
454
455 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
456 &mut data.matrices
457 }
458
459 fn clone_for_broadcast(&self) -> Option<Self> {
460 Some(self.clone())
461 }
462}
463
464#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
465pub struct DomException {
467 pub message: String,
468 pub name: String,
469}
470
471impl BroadcastClone for DomException {
472 type Id = DomExceptionId;
473
474 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
475 &data.exceptions
476 }
477
478 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
479 &mut data.exceptions
480 }
481
482 fn clone_for_broadcast(&self) -> Option<Self> {
483 Some(self.clone())
484 }
485}
486
487#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
488pub struct SerializableQuotaExceededError {
490 pub dom_exception: DomException,
491 pub quota: Option<f64>,
492 pub requested: Option<f64>,
493}
494
495impl BroadcastClone for SerializableQuotaExceededError {
496 type Id = QuotaExceededErrorId;
497
498 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
499 &data.quota_exceeded_errors
500 }
501
502 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
503 &mut data.quota_exceeded_errors
504 }
505
506 fn clone_for_broadcast(&self) -> Option<Self> {
507 Some(self.clone())
508 }
509}
510
511#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
512pub struct SerializableImageBitmap {
514 pub bitmap_data: SharedSnapshot,
515}
516
517impl BroadcastClone for SerializableImageBitmap {
518 type Id = ImageBitmapId;
519
520 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
521 &data.image_bitmaps
522 }
523
524 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
525 &mut data.image_bitmaps
526 }
527
528 fn clone_for_broadcast(&self) -> Option<Self> {
529 Some(self.clone())
530 }
531}
532
533#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
534pub struct SerializableImageData {
535 pub data: Vec<u8>,
536 pub width: u32,
537 pub height: u32,
538}
539
540impl BroadcastClone for SerializableImageData {
541 type Id = ImageDataId;
542
543 fn source(data: &StructuredSerializedData) -> &Option<FxHashMap<Self::Id, Self>> {
544 &data.image_data
545 }
546
547 fn destination(data: &mut StructuredSerializedData) -> &mut Option<FxHashMap<Self::Id, Self>> {
548 &mut data.image_data
549 }
550
551 fn clone_for_broadcast(&self) -> Option<Self> {
552 Some(self.clone())
553 }
554}