servo: Merge #16884 - Create higher-level APIs for manipulating custom structured clones (from jdm:structuredclone); r=jdm

Rebase of #16321.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #16031
- [X] There are tests for these changes

Source-Repo: https://github.com/servo/servo
Source-Revision: a7b77306f985b79d3b8b4d9b2cb51fa38f45bd39

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 95dcc98b1fcc1fe4fd238bf676125b14c211bf2c
This commit is contained in:
alajara 2017-05-17 03:53:10 -05:00
Родитель da257b4b59
Коммит 317573b3b5
1 изменённых файлов: 38 добавлений и 14 удалений

Просмотреть файл

@ -67,16 +67,44 @@ unsafe fn read_length(r: *mut JSStructuredCloneReader)
return length as usize;
}
struct StructuredCloneWriter {
w: *mut JSStructuredCloneWriter,
}
impl StructuredCloneWriter {
unsafe fn write_slice(&self, v: &[u8]) {
let type_length = v.len();
write_length(self.w, type_length);
assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length));
}
unsafe fn write_str(&self, s: &str) {
self.write_slice(s.as_bytes());
}
}
struct StructuredCloneReader {
r: *mut JSStructuredCloneReader,
}
impl StructuredCloneReader {
unsafe fn read_bytes(&self) -> Vec<u8> {
let mut bytes = vec![0u8; read_length(self.r)];
let blob_length = bytes.len();
assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length));
return bytes;
}
unsafe fn read_str(&self) -> String {
let str_buffer = self.read_bytes();
return String::from_utf8_unchecked(str_buffer);
}
}
unsafe fn read_blob(cx: *mut JSContext,
r: *mut JSStructuredCloneReader)
-> *mut JSObject {
let blob_length = read_length(r);
let type_str_length = read_length(r);
let mut blob_buffer = vec![0u8; blob_length];
assert!(JS_ReadBytes(r, blob_buffer.as_mut_ptr() as *mut raw::c_void, blob_length));
let mut type_str_buffer = vec![0u8; type_str_length];
assert!(JS_ReadBytes(r, type_str_buffer.as_mut_ptr() as *mut raw::c_void, type_str_length));
let type_str = String::from_utf8_unchecked(type_str_buffer);
let structured_reader = StructuredCloneReader { r: r };
let blob_buffer = structured_reader.read_bytes();
let type_str = structured_reader.read_str();
let target_global = GlobalScope::from_context(cx);
let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str);
return blob.reflector().get_jsobject().get()
@ -85,15 +113,11 @@ unsafe fn read_blob(cx: *mut JSContext,
unsafe fn write_blob(blob: Root<Blob>,
w: *mut JSStructuredCloneWriter)
-> Result<(), ()> {
let structured_writer = StructuredCloneWriter { w: w };
let blob_vec = try!(blob.get_bytes());
let blob_length = blob_vec.len();
let type_string_bytes = blob.type_string().as_bytes().to_vec();
let type_string_length = type_string_bytes.len();
assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0));
write_length(w, blob_length);
write_length(w, type_string_length);
assert!(JS_WriteBytes(w, blob_vec.as_ptr() as *const raw::c_void, blob_length));
assert!(JS_WriteBytes(w, type_string_bytes.as_ptr() as *const raw::c_void, type_string_length));
structured_writer.write_slice(&blob_vec);
structured_writer.write_str(&blob.type_string());
return Ok(())
}