diff options
author | Gregory Terzian <gterzian@users.noreply.github.com> | 2019-09-01 03:18:42 +0800 |
---|---|---|
committer | Gregory Terzian <gterzian@users.noreply.github.com> | 2019-12-11 22:46:50 +0800 |
commit | 6e8a85482c2068d4dbccb992954271f725570f91 (patch) | |
tree | b30f6d82a018df0b196fa4d47d3b6667d708313e /components/script_traits | |
parent | 7aa68c8fe7ca0865a7323ab1e5b9526efa588ca2 (diff) | |
download | servo-6e8a85482c2068d4dbccb992954271f725570f91.tar.gz servo-6e8a85482c2068d4dbccb992954271f725570f91.zip |
re-structure blob, structured serialization
Diffstat (limited to 'components/script_traits')
-rw-r--r-- | components/script_traits/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 8 | ||||
-rw-r--r-- | components/script_traits/serializable.rs | 148 |
3 files changed, 156 insertions, 1 deletions
diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml index 87cb044d902..0635d99dda3 100644 --- a/components/script_traits/Cargo.toml +++ b/components/script_traits/Cargo.toml @@ -39,6 +39,7 @@ servo_url = {path = "../url"} style_traits = {path = "../style_traits", features = ["servo"]} time = "0.1.12" url = "2.0" +uuid = {version = "0.8", features = ["v4"]} webdriver = "0.40" webgpu = {path = "../webgpu"} webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 13429a13251..440a412a979 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -17,9 +17,11 @@ extern crate malloc_size_of_derive; extern crate serde; mod script_msg; +pub mod serializable; pub mod transferable; pub mod webdriver_msg; +use crate::serializable::BlobImpl; use crate::transferable::MessagePortImpl; use crate::webdriver_msg::{LoadStatus, WebDriverScriptCommand}; use bluetooth_traits::BluetoothRequest; @@ -39,7 +41,9 @@ use libc::c_void; use log::warn; use media::WindowGLContext; use msg::constellation_msg::BackgroundHangMonitorRegister; -use msg::constellation_msg::{BrowsingContextId, HistoryStateId, MessagePortId, PipelineId}; +use msg::constellation_msg::{ + BlobId, BrowsingContextId, HistoryStateId, MessagePortId, PipelineId, +}; use msg::constellation_msg::{PipelineNamespaceId, TopLevelBrowsingContextId, TraversalDirection}; use net_traits::image::base::Image; use net_traits::image_cache::ImageCache; @@ -1039,6 +1043,8 @@ impl ScriptToConstellationChan { pub struct StructuredSerializedData { /// Data serialized by SpiderMonkey. pub serialized: Vec<u8>, + /// Serialized in a structured callback, + pub blobs: Option<HashMap<BlobId, BlobImpl>>, /// Transferred objects. pub ports: Option<HashMap<MessagePortId, MessagePortImpl>>, } diff --git a/components/script_traits/serializable.rs b/components/script_traits/serializable.rs new file mode 100644 index 00000000000..73840fb2c50 --- /dev/null +++ b/components/script_traits/serializable.rs @@ -0,0 +1,148 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! This module contains implementations in script that are serializable, +//! as per https://html.spec.whatwg.org/multipage/#serializable-objects. +//! The implementations are here instead of in script +//! so that the other modules involved in the serialization don't have +//! to depend on script. + +use msg::constellation_msg::BlobId; +use net_traits::filemanager_thread::RelativePos; +use std::cell::RefCell; +use std::path::PathBuf; +use uuid::Uuid; + +/// File-based blob +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] +pub struct FileBlob { + #[ignore_malloc_size_of = "Uuid are hard(not really)"] + id: Uuid, + #[ignore_malloc_size_of = "PathBuf are hard"] + name: Option<PathBuf>, + cache: RefCell<Option<Vec<u8>>>, + size: u64, +} + +impl FileBlob { + /// Create a new file blob. + pub fn new(id: Uuid, name: Option<PathBuf>, cache: Option<Vec<u8>>, size: u64) -> FileBlob { + FileBlob { + id, + name, + cache: RefCell::new(cache), + size, + } + } + + /// Get the size of the file. + pub fn get_size(&self) -> u64 { + self.size.clone() + } + + /// Get the cached file data, if any. + pub fn get_cache(&self) -> Option<Vec<u8>> { + self.cache.borrow().clone() + } + + /// Cache data. + pub fn cache_bytes(&self, bytes: Vec<u8>) { + *self.cache.borrow_mut() = Some(bytes); + } + + /// Get the file id. + pub fn get_id(&self) -> Uuid { + self.id.clone() + } +} + +/// The data backing a DOM Blob. +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] +pub struct BlobImpl { + /// UUID of the blob. + blob_id: BlobId, + /// Content-type string + type_string: String, + /// Blob data-type. + blob_data: BlobData, + /// Sliced blobs referring to this one. + slices: Vec<BlobId>, +} + +/// Different backends of Blob +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] +pub enum BlobData { + /// File-based blob, whose content lives in the net process + File(FileBlob), + /// Memory-based blob, whose content lives in the script process + Memory(Vec<u8>), + /// Sliced blob, including parent blob-id and + /// relative positions of current slicing range, + /// IMPORTANT: The depth of tree is only two, i.e. the parent Blob must be + /// either File-based or Memory-based + Sliced(BlobId, RelativePos), +} + +impl BlobImpl { + /// Construct memory-backed BlobImpl + pub fn new_from_bytes(bytes: Vec<u8>, type_string: String) -> BlobImpl { + let blob_id = BlobId::new(); + let blob_data = BlobData::Memory(bytes); + BlobImpl { + blob_id, + type_string, + blob_data, + slices: vec![], + } + } + + /// Construct file-backed BlobImpl from File ID + pub fn new_from_file(file_id: Uuid, name: PathBuf, size: u64, type_string: String) -> BlobImpl { + let blob_id = BlobId::new(); + let blob_data = BlobData::File(FileBlob { + id: file_id, + name: Some(name), + cache: RefCell::new(None), + size: size, + }); + BlobImpl { + blob_id, + type_string, + blob_data, + slices: vec![], + } + } + + /// Construct a BlobImpl from a slice of a parent. + pub fn new_sliced(rel_pos: RelativePos, parent: BlobId, type_string: String) -> BlobImpl { + let blob_id = BlobId::new(); + let blob_data = BlobData::Sliced(parent, rel_pos); + BlobImpl { + blob_id, + type_string, + blob_data, + slices: vec![], + } + } + + /// Get a clone of the blob-id + pub fn blob_id(&self) -> BlobId { + self.blob_id.clone() + } + + /// Get a clone of the type-string + pub fn type_string(&self) -> String { + self.type_string.clone() + } + + /// Get a mutable ref to the data + pub fn blob_data(&self) -> &BlobData { + &self.blob_data + } + + /// Get a mutable ref to the data + pub fn blob_data_mut(&mut self) -> &mut BlobData { + &mut self.blob_data + } +} |