/* 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 http://mozilla.org/MPL/2.0/. */ //! This module implements structured cloning, as defined by [HTML] //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use js::jsapi::{HandleValue, MutableHandleValue}; use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_STRUCTURED_CLONE_VERSION}; use js::jsapi::{JS_ClearPendingException, JS_WriteStructuredClone}; use libc::size_t; use script_traits::DOMMessage; use std::ptr; use std::slice; /// A buffer for a structured clone. pub struct StructuredCloneData { data: *mut u64, nbytes: size_t, } impl StructuredCloneData { /// Writes a structured clone. Returns a `DataClone` error if that fails. pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible { let mut data = ptr::null_mut(); let mut nbytes = 0; let result = unsafe { JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes, ptr::null(), ptr::null_mut(), HandleValue::undefined()) }; if !result { unsafe { JS_ClearPendingException(cx); } return Err(Error::DataClone); } Ok(StructuredCloneData { data: data, nbytes: nbytes, }) } /// Converts a StructuredCloneData to Vec for inter-thread sharing pub fn move_to_arraybuffer(self) -> DOMMessage { unsafe { DOMMessage(slice::from_raw_parts(self.data as *mut u8, self.nbytes).to_vec()) } } /// Converts back to StructuredCloneData pub fn make_structured_clone(data: DOMMessage) -> StructuredCloneData { let DOMMessage(mut data) = data; let nbytes = data.len(); let data = data.as_mut_ptr() as *mut u64; StructuredCloneData { data: data, nbytes: nbytes } } /// Reads a structured clone. /// /// Panics if `JS_ReadStructuredClone` fails. pub fn read(self, global: GlobalRef, rval: MutableHandleValue) { unsafe { assert!(JS_ReadStructuredClone(global.get_cx(), self.data, self.nbytes, JS_STRUCTURED_CLONE_VERSION, rval, ptr::null(), ptr::null_mut())); } } } unsafe impl Send for StructuredCloneData {}