diff options
author | Shing Lyu <slyu@mozilla.com> | 2014-11-14 23:56:48 +0800 |
---|---|---|
committer | Shing Lyu <shing.lyu@gmail.com> | 2014-12-09 22:52:19 +0800 |
commit | f2885b8fc75d9c38ff4557d711e67d38bee20069 (patch) | |
tree | db3fa793380e1966c1fe13ebb06d04b49d148ad5 /components/script/dom/blob.rs | |
parent | bdb3a2538b9f10aad4c911cc0118257d8311cd26 (diff) | |
download | servo-f2885b8fc75d9c38ff4557d711e67d38bee20069.tar.gz servo-f2885b8fc75d9c38ff4557d711e67d38bee20069.zip |
Issue #1820 - Improve the Blob implementation
Diffstat (limited to 'components/script/dom/blob.rs')
-rw-r--r-- | components/script/dom/blob.rs | 101 |
1 files changed, 92 insertions, 9 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 3380670d4f5..b0d0b155821 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -3,11 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::InheritTypes::FileDerived; -use dom::bindings::global::GlobalRef; -use dom::bindings::js::Temporary; +use dom::bindings::global::{GlobalRef, GlobalField}; +use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::bindings::codegen::Bindings::BlobBinding; +use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods; + +use servo_util::str::DOMString; +use std::cmp::{min, max}; #[jstraceable] pub enum BlobType { @@ -18,28 +22,107 @@ pub enum BlobType { #[dom_struct] pub struct Blob { reflector_: Reflector, - type_: BlobType + type_: BlobType, + bytes: Option<Vec<u8>>, + typeString: DOMString, + global: GlobalField + // isClosed_: bool } impl Blob { - pub fn new_inherited() -> Blob { + pub fn new_inherited(global: &GlobalRef, bytes: Option<Vec<u8>>) -> Blob { Blob { reflector_: Reflector::new(), - type_: BlobTypeId + type_: BlobTypeId, + bytes: bytes, + typeString: "".to_string(), + global: GlobalField::from_rooted(global) + //isClosed_: false } } - pub fn new(global: GlobalRef) -> Temporary<Blob> { - reflect_dom_object(box Blob::new_inherited(), - global, + pub fn new(global: &GlobalRef, bytes: Option<Vec<u8>>) -> Temporary<Blob> { + reflect_dom_object(box Blob::new_inherited(global, bytes), + *global, BlobBinding::Wrap) } pub fn Constructor(global: &GlobalRef) -> Fallible<Temporary<Blob>> { - Ok(Blob::new(*global)) + Ok(Blob::new(global, None)) + } + + pub fn Constructor_(global: &GlobalRef, blobParts: DOMString) -> Fallible<Temporary<Blob>> { + //TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView or Blob + //TODO: accept options parameter + let bytes: Option<Vec<u8>> = Some(blobParts.into_bytes()); + Ok(Blob::new(global, bytes)) } } +impl<'a> BlobMethods for JSRef<'a, Blob> { + fn Size(self) -> u64{ + match self.bytes { + None => 0, + Some(ref bytes) => bytes.len() as u64 + } + } + + fn Type(self) -> DOMString { + self.typeString.clone() + } + + fn Slice(self, start: Option<i64>, end: Option<i64>, + _contentType: Option<DOMString>) -> Temporary<Blob> { + let size: i64 = self.Size().to_i64().unwrap(); + let relativeStart: i64 = match start { + None => 0, + Some(start) => { + if start < 0 { + max(size.to_i64().unwrap() + start, 0) + } else { + min(start, size) + } + } + }; + let relativeEnd: i64 = match end { + None => size, + Some(end) => { + if end < 0 { + max(size + end, 0) + } else { + min(end, size) + } + } + }; + /* + let relativeContentType = match contentType { + None => "".to_string(), + Some(str) => str + }; + */ + //TODO: actually use relativeContentType in constructor + let span: i64 = max(relativeEnd - relativeStart, 0); + let global = self.global.root(); + match self.bytes { + None => Blob::new(&global.root_ref(), None), + Some(ref vec) => { + let start = relativeStart.to_uint().unwrap(); + let end = (relativeStart + span).to_uint().unwrap(); + let mut bytes: Vec<u8> = Vec::new(); + bytes.push_all(vec.slice(start, end)); + Blob::new(&global.root_ref(), Some(bytes)) + } + } + } + + //fn IsClosed(self) -> bool { + // self.isClosed_.clone() + //} + + //fn Close(self) { + // TODO + //} +} impl Reflectable for Blob { fn reflector<'a>(&'a self) -> &'a Reflector { &self.reflector_ |