diff options
author | Josh Matthews <josh@joshmatthews.net> | 2025-03-15 09:58:56 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-15 13:58:56 +0000 |
commit | d8fc1d8bb88d291233022f52550628e6fc0376a4 (patch) | |
tree | 3c99cae670682dbf5d7cf8cbffa151c8c55aef65 /components/script/dom/blob.rs | |
parent | 21ecfdd088faa68ba470b15fff6eee61c05e6bba (diff) | |
download | servo-d8fc1d8bb88d291233022f52550628e6fc0376a4.tar.gz servo-d8fc1d8bb88d291233022f52550628e6fc0376a4.zip |
Refactor common boilerplate out of serialize/transfer implementations (#35831)
* script: Create infrastructure for reducing hand-written serializable/transferrable implementations.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Clone all serializable DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Deserialize all serializable DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Serialize all serializable DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Transfer-receive all transferable DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Transfer all transferable DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Formatting.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Extract boilerplate from serialize/deserialize implementations.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Extract boilerplate from transfer-receive.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Extract boilerplate from transfer operation.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Tidy fixes.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* script: Check transferability of all DOM interfaces.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Clippy fixes.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Clippy fixes.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Remove unnecessary duplicate crate.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
* Formatting.
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
---------
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Diffstat (limited to 'components/script/dom/blob.rs')
-rw-r--r-- | components/script/dom/blob.rs | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index a357fddfaa9..75fa65deff0 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -25,9 +25,9 @@ use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlo use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{Serializable, StorageKey}; +use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; use crate::dom::bindings::str::DOMString; -use crate::dom::bindings::structuredclone::{StructuredDataReader, StructuredDataWriter}; +use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::dom::readablestream::ReadableStream; @@ -94,8 +94,11 @@ impl Blob { } impl Serializable for Blob { + type Id = BlobId; + type Data = BlobImpl; + /// <https://w3c.github.io/FileAPI/#ref-for-serialization-steps> - fn serialize(&self, sc_writer: &mut StructuredDataWriter) -> Result<StorageKey, ()> { + fn serialize(&self) -> Result<(BlobId, BlobImpl), ()> { let blob_id = self.blob_id; // 1. Get a clone of the blob impl. @@ -104,62 +107,52 @@ impl Serializable for Blob { // We clone the data, but the clone gets its own Id. let new_blob_id = blob_impl.blob_id(); - // 2. Store the object at a given key. - let blobs = sc_writer.blobs.get_or_insert_with(HashMap::new); - blobs.insert(new_blob_id, blob_impl); - - let PipelineNamespaceId(name_space) = new_blob_id.namespace_id; - let BlobIndex(index) = new_blob_id.index; - let index = index.get(); - - let name_space = name_space.to_ne_bytes(); - let index = index.to_ne_bytes(); - - let storage_key = StorageKey { - index: u32::from_ne_bytes(index), - name_space: u32::from_ne_bytes(name_space), - }; - - // 3. Return the storage key. - Ok(storage_key) + Ok((new_blob_id, blob_impl)) } /// <https://w3c.github.io/FileAPI/#ref-for-deserialization-steps> fn deserialize( owner: &GlobalScope, - sc_reader: &mut StructuredDataReader, - storage_key: StorageKey, + serialized: BlobImpl, can_gc: CanGc, - ) -> Result<(), ()> { - // 1. Re-build the key for the storage location - // of the serialized object. + ) -> Result<DomRoot<Self>, ()> { + let deserialized_blob = Blob::new(owner, serialized, can_gc); + Ok(deserialized_blob) + } + + fn serialized_storage( + reader: StructuredData<'_>, + ) -> &mut Option<HashMap<Self::Id, Self::Data>> { + match reader { + StructuredData::Reader(r) => &mut r.blob_impls, + StructuredData::Writer(w) => &mut w.blobs, + } + } + + fn deserialized_storage( + data: &mut StructuredDataReader, + ) -> &mut Option<HashMap<StorageKey, DomRoot<Self>>> { + &mut data.blobs + } +} + +impl From<StorageKey> for BlobId { + fn from(storage_key: StorageKey) -> BlobId { let namespace_id = PipelineNamespaceId(storage_key.name_space); let index = BlobIndex(NonZeroU32::new(storage_key.index).expect("Deserialized blob index is zero")); - let id = BlobId { + BlobId { namespace_id, index, - }; - - // 2. Get the transferred object from its storage, using the key. - let blob_impls_map = sc_reader - .blob_impls - .as_mut() - .expect("The SC holder does not have any blob impls"); - let blob_impl = blob_impls_map - .remove(&id) - .expect("No blob to be deserialized found."); - if blob_impls_map.is_empty() { - sc_reader.blob_impls = None; } + } +} - let deserialized_blob = Blob::new(owner, blob_impl, can_gc); - - let blobs = sc_reader.blobs.get_or_insert_with(HashMap::new); - blobs.insert(storage_key, deserialized_blob); - - Ok(()) +impl IntoStorageKey for BlobId { + fn into_storage_key(self) -> StorageKey { + let BlobIndex(index) = self.index; + StorageKey::new(self.namespace_id, index) } } |