mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Remove DataSlice, fix #12249
This commit is contained in:
parent
1cba3b3e98
commit
ab14777312
12 changed files with 61 additions and 163 deletions
|
@ -19,71 +19,15 @@ use net_traits::blob_url_store::BlobURLStoreEntry;
|
|||
use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::cell::Cell;
|
||||
use std::ops::Range;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, JSTraceable)]
|
||||
pub struct DataSlice {
|
||||
bytes: Arc<Vec<u8>>,
|
||||
bytes_start: usize,
|
||||
bytes_end: usize
|
||||
}
|
||||
|
||||
impl DataSlice {
|
||||
/// Construct DataSlice from reference counted bytes
|
||||
pub fn new(bytes: Arc<Vec<u8>>, start: Option<i64>, end: Option<i64>) -> DataSlice {
|
||||
let range = RelativePos::from_opts(start, end).to_abs_range(bytes.len());
|
||||
|
||||
DataSlice {
|
||||
bytes: bytes,
|
||||
bytes_start: range.start,
|
||||
bytes_end: range.end,
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct data slice from a vector of bytes
|
||||
pub fn from_bytes(bytes: Vec<u8>) -> DataSlice {
|
||||
DataSlice::new(Arc::new(bytes), None, None)
|
||||
}
|
||||
|
||||
/// Construct an empty data slice
|
||||
pub fn empty() -> DataSlice {
|
||||
DataSlice {
|
||||
bytes: Arc::new(Vec::new()),
|
||||
bytes_start: 0,
|
||||
bytes_end: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get sliced bytes
|
||||
pub fn get_bytes(&self) -> &[u8] {
|
||||
&self.bytes[self.bytes_start..self.bytes_end]
|
||||
}
|
||||
|
||||
/// Get length of sliced bytes
|
||||
pub fn size(&self) -> u64 {
|
||||
(self.bytes_end as u64) - (self.bytes_start as u64)
|
||||
}
|
||||
|
||||
/// Further adjust the slice range based on passed-in relative positions
|
||||
pub fn slice(&self, pos: &RelativePos) -> DataSlice {
|
||||
let old_size = self.size();
|
||||
let range = pos.to_abs_range(old_size as usize);
|
||||
DataSlice {
|
||||
bytes: self.bytes.clone(),
|
||||
bytes_start: self.bytes_start + range.start,
|
||||
bytes_end: self.bytes_start + range.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
use std::ops::Index;
|
||||
|
||||
#[must_root]
|
||||
#[derive(JSTraceable)]
|
||||
pub enum BlobImpl {
|
||||
/// File-based blob, including id and possibly cached content
|
||||
File(SelectedFileId, DOMRefCell<Option<DataSlice>>),
|
||||
File(SelectedFileId, DOMRefCell<Option<Vec<u8>>>),
|
||||
/// Memory-based blob
|
||||
Memory(DataSlice),
|
||||
Memory(Vec<u8>),
|
||||
/// Sliced blob, including parent blob and
|
||||
/// relative positions representing current slicing range,
|
||||
/// it is leaf of a two-layer fat tree
|
||||
|
@ -91,20 +35,16 @@ pub enum BlobImpl {
|
|||
}
|
||||
|
||||
impl BlobImpl {
|
||||
/// Construct memory-backed BlobImpl from DataSlice
|
||||
pub fn new_from_slice(slice: DataSlice) -> BlobImpl {
|
||||
BlobImpl::Memory(slice)
|
||||
/// Construct memory-backed BlobImpl
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn new_from_bytes(bytes: Vec<u8>) -> BlobImpl {
|
||||
BlobImpl::Memory(bytes)
|
||||
}
|
||||
|
||||
/// Construct file-backed BlobImpl from File ID
|
||||
pub fn new_from_file(file_id: SelectedFileId) -> BlobImpl {
|
||||
BlobImpl::File(file_id, DOMRefCell::new(None))
|
||||
}
|
||||
|
||||
/// Construct empty, memory-backed BlobImpl
|
||||
pub fn new_from_empty_slice() -> BlobImpl {
|
||||
BlobImpl::new_from_slice(DataSlice::empty())
|
||||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#blob
|
||||
|
@ -178,12 +118,11 @@ impl Blob {
|
|||
}
|
||||
};
|
||||
|
||||
let slice = DataSlice::from_bytes(bytes);
|
||||
Ok(Blob::new(global, BlobImpl::new_from_slice(slice), blobPropertyBag.get_typestring()))
|
||||
Ok(Blob::new(global, BlobImpl::new_from_bytes(bytes), blobPropertyBag.get_typestring()))
|
||||
}
|
||||
|
||||
/// Get a slice to inner data, this might incur synchronous read and caching
|
||||
pub fn get_slice(&self) -> Result<DataSlice, ()> {
|
||||
pub fn get_bytes(&self) -> Result<Vec<u8>, ()> {
|
||||
match *self.blob_impl.borrow() {
|
||||
BlobImpl::File(ref id, ref cached) => {
|
||||
let buffer = match *cached.borrow() {
|
||||
|
@ -204,17 +143,14 @@ impl Blob {
|
|||
}
|
||||
BlobImpl::Memory(ref s) => Ok(s.clone()),
|
||||
BlobImpl::Sliced(ref parent, ref rel_pos) => {
|
||||
let dataslice = parent.get_slice_or_empty();
|
||||
Ok(dataslice.slice(rel_pos))
|
||||
parent.get_bytes().map(|v| {
|
||||
let range = rel_pos.to_abs_range(v.len());
|
||||
v.index(range).to_vec()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to get a slice, and if any exception happens, return the empty slice
|
||||
pub fn get_slice_or_empty(&self) -> DataSlice {
|
||||
self.get_slice().unwrap_or(DataSlice::empty())
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> SelectedFileId {
|
||||
match *self.blob_impl.borrow() {
|
||||
BlobImpl::File(ref id, _) => id.clone(),
|
||||
|
@ -228,8 +164,8 @@ impl Blob {
|
|||
}
|
||||
BlobImpl::File(ref parent_id, _) =>
|
||||
self.create_sliced_id(parent_id, rel_pos),
|
||||
BlobImpl::Memory(ref parent_slice) => {
|
||||
let parent_id = parent.promote_to_file(parent_slice);
|
||||
BlobImpl::Memory(ref bytes) => {
|
||||
let parent_id = parent.promote_to_file(bytes);
|
||||
*self.blob_impl.borrow_mut() = BlobImpl::Sliced(parent.clone(), rel_pos.clone());
|
||||
self.create_sliced_id(&parent_id, rel_pos)
|
||||
}
|
||||
|
@ -240,15 +176,10 @@ impl Blob {
|
|||
|
||||
/// Promite memory-based Blob to file-based,
|
||||
/// The bytes in data slice will be transferred to file manager thread
|
||||
fn promote_to_file(&self, self_slice: &DataSlice) -> SelectedFileId {
|
||||
fn promote_to_file(&self, bytes: &[u8]) -> SelectedFileId {
|
||||
let global = self.global();
|
||||
let origin = global.r().get_url().origin().unicode_serialization();
|
||||
let filemanager = global.r().resource_threads().sender();
|
||||
let bytes = self_slice.get_bytes();
|
||||
let rel_pos = RelativePos::from_abs_range(Range {
|
||||
start: self_slice.bytes_start,
|
||||
end: self_slice.bytes_end,
|
||||
}, self_slice.bytes.len());
|
||||
|
||||
let entry = BlobURLStoreEntry {
|
||||
type_string: self.typeString.clone(),
|
||||
|
@ -257,7 +188,7 @@ impl Blob {
|
|||
};
|
||||
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
let _ = filemanager.send(FileManagerThreadMsg::TransferMemory(entry, rel_pos, tx, origin.clone()));
|
||||
let _ = filemanager.send(FileManagerThreadMsg::TransferMemory(entry, tx, origin.clone()));
|
||||
|
||||
match rx.recv().unwrap() {
|
||||
Ok(new_id) => SelectedFileId(new_id.0),
|
||||
|
@ -285,7 +216,7 @@ impl Blob {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<DataSlice, ()> {
|
||||
fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<Vec<u8>, ()> {
|
||||
let file_manager = global.filemanager_thread();
|
||||
let (chan, recv) = ipc::channel().map_err(|_|())?;
|
||||
let origin = global.get_url().origin().unicode_serialization();
|
||||
|
@ -300,8 +231,7 @@ fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<DataSlice, ()> {
|
|||
}
|
||||
};
|
||||
|
||||
let bytes = result.map_err(|_|())?;
|
||||
Ok(DataSlice::from_bytes(bytes))
|
||||
result.map_err(|_|())
|
||||
}
|
||||
|
||||
/// Extract bytes from BlobParts, used by Blob and File constructor
|
||||
|
@ -316,7 +246,8 @@ pub fn blob_parts_to_bytes(blobparts: Vec<BlobOrString>) -> Result<Vec<u8>, ()>
|
|||
ret.append(&mut bytes);
|
||||
},
|
||||
&BlobOrString::Blob(ref b) => {
|
||||
ret.append(&mut b.get_slice_or_empty().bytes.to_vec());
|
||||
let mut bytes = b.get_bytes().unwrap_or(vec![]);
|
||||
ret.append(&mut bytes);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +258,11 @@ pub fn blob_parts_to_bytes(blobparts: Vec<BlobOrString>) -> Result<Vec<u8>, ()>
|
|||
impl BlobMethods for Blob {
|
||||
// https://w3c.github.io/FileAPI/#dfn-size
|
||||
fn Size(&self) -> u64 {
|
||||
self.get_slice_or_empty().size()
|
||||
// XXX: This will incur reading if file-based
|
||||
match self.get_bytes() {
|
||||
Ok(s) => s.len() as u64,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#dfn-type
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue