aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-10-31 14:01:18 -0500
committerGitHub <noreply@github.com>2016-10-31 14:01:18 -0500
commitceb18e7d8624a6d78e3f712dc335928adaa7dc79 (patch)
tree51b4bef11b185ad804d3319e9c1e4d438743e50b /components/script
parentccefef5be43b6d174933196fd7552cbbfbdf53d6 (diff)
parent51ef05bf3dce801be0eb3a777b5ade72e4ece3dd (diff)
downloadservo-ceb18e7d8624a6d78e3f712dc335928adaa7dc79.tar.gz
servo-ceb18e7d8624a6d78e3f712dc335928adaa7dc79.zip
Auto merge of #13729 - cynicaldevil:readAsArrayBuffer, r=Ms2ger
Implemented FileReader::readAsArrayBuffer <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #12555 <!-- Either: --> - [X] There are tests for these changes There's still some small issues, but I suppose most of the work is done: - test-tidy mentions a `method declared in webidl is missing a comment with a specification link` for the `getResult` method. - I get an 'unused code' warning for code present in `UnionTypes.rs`, which is auto-generated. Passing tests: - [x] `FileAPI/reading-data-section/filereader_result.html` - [x] `FileAPI/reading-data-section/filereader_readAsArrayBuffer.html` - [x] `FileAPI/idlharness.html` - [ ] `FileAPI/reading-data-section/FileReader-multiple-reads.html` <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13729) <!-- Reviewable:end -->
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py13
-rw-r--r--components/script/dom/filereader.rs74
-rw-r--r--components/script/dom/webidls/FileReader.webidl9
3 files changed, 73 insertions, 23 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 4c67f61af2d..b65d2e65cdb 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2237,6 +2237,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'js::error::throw_type_error',
'js::jsapi::HandleValue',
'js::jsapi::JSContext',
+ 'js::jsapi::JSObject',
'js::jsapi::MutableHandleValue',
'js::jsval::JSVal',
]
@@ -4047,6 +4048,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
elif type.isPrimitive():
name = type.name
typeName = builtinNames[type.tag()]
+ elif type.isObject():
+ name = type.name
+ typeName = "*mut JSObject"
else:
raise TypeError("Can't handle %s in unions yet" % type)
@@ -4056,7 +4060,6 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
isDefinitelyObject=True)
template = info.template
- assert not type.isObject()
jsConversion = string.Template(template).substitute({
"val": "value",
})
@@ -4176,7 +4179,10 @@ class CGUnionConversionStruct(CGThing):
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
if len(objectMemberTypes) > 0:
- raise TypeError("Can't handle objects in unions.")
+ assert len(objectMemberTypes) == 1
+ typeName = objectMemberTypes[0].name
+ object = CGGeneric(get_match(typeName))
+ names.append(typeName)
else:
object = None
@@ -4191,7 +4197,8 @@ class CGUnionConversionStruct(CGThing):
hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object or mozMapObject
if hasObjectTypes:
- assert interfaceObject or arrayObject or mozMapObject
+ # "object" is not distinguishable from other types
+ assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
templateBody = CGList([], "\n")
if interfaceObject:
templateBody.append(interfaceObject)
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 296a6461b55..d9fd00630de 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -6,6 +6,7 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConstants, FileReaderMethods};
+use dom::bindings::codegen::UnionTypes::StringOrObject;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -22,9 +23,15 @@ use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label;
use encoding::types::{DecoderTrap, EncodingRef};
use hyper::mime::{Attr, Mime};
+use js::jsapi::Heap;
+use js::jsapi::JSAutoCompartment;
+use js::jsapi::JSContext;
+use js::jsval::{self, JSVal};
+use js::typedarray::Uint8Array;
use rustc_serialize::base64::{CharacterSet, Config, Newline, ToBase64};
use script_thread::RunnableWrapper;
use std::cell::Cell;
+use std::ptr;
use std::sync::Arc;
use string_cache::Atom;
use task_source::TaskSource;
@@ -35,6 +42,7 @@ use util::thread::spawn_named;
pub enum FileReaderFunction {
ReadAsText,
ReadAsDataUrl,
+ ReadAsArrayBuffer,
}
pub type TrustedFileReader = Trusted<FileReader>;
@@ -68,12 +76,18 @@ pub enum FileReaderReadyState {
Done = FileReaderConstants::DONE,
}
+#[derive(HeapSizeOf, JSTraceable)]
+pub enum FileReaderResult {
+ ArrayBuffer(Heap<JSVal>),
+ String(DOMString),
+}
+
#[dom_struct]
pub struct FileReader {
eventtarget: EventTarget,
ready_state: Cell<FileReaderReadyState>,
error: MutNullableHeap<JS<DOMException>>,
- result: DOMRefCell<Option<DOMString>>,
+ result: DOMRefCell<Option<FileReaderResult>>,
generation_id: Cell<GenerationId>,
}
@@ -159,6 +173,7 @@ impl FileReader {
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
+ #[allow(unsafe_code)]
pub fn process_read_eof(filereader: TrustedFileReader, gen_id: GenerationId,
data: ReadMetaData, blob_contents: Arc<Vec<u8>>) {
let fr = filereader.root();
@@ -176,15 +191,17 @@ impl FileReader {
fr.change_ready_state(FileReaderReadyState::Done);
// Step 8.2
- let output = match data.function {
+ match data.function {
FileReaderFunction::ReadAsDataUrl =>
- FileReader::perform_readasdataurl(data, &blob_contents),
+ FileReader::perform_readasdataurl(&fr.result, data, &blob_contents),
FileReaderFunction::ReadAsText =>
- FileReader::perform_readastext(data, &blob_contents),
+ FileReader::perform_readastext(&fr.result, data, &blob_contents),
+ FileReaderFunction::ReadAsArrayBuffer => {
+ let _ac = JSAutoCompartment::new(fr.global().get_cx(), *fr.reflector().get_jsobject());
+ FileReader::perform_readasarraybuffer(&fr.result, fr.global().get_cx(), data, &blob_contents)
+ },
};
- *fr.result.borrow_mut() = Some(output);
-
// Step 8.3
fr.dispatch_progress_event(atom!("load"), 0, None);
return_on_abort!();
@@ -198,8 +215,7 @@ impl FileReader {
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
- fn perform_readastext(data: ReadMetaData, blob_bytes: &[u8])
- -> DOMString {
+ fn perform_readastext(result: &DOMRefCell<Option<FileReaderResult>>, data: ReadMetaData, blob_bytes: &[u8]) {
let blob_label = &data.label;
let blob_type = &data.blobtype;
@@ -225,12 +241,11 @@ impl FileReader {
let convert = blob_bytes;
// Step 7
let output = enc.decode(convert, DecoderTrap::Replace).unwrap();
- DOMString::from(output)
+ *result.borrow_mut() = Some(FileReaderResult::String(DOMString::from(output)));
}
//https://w3c.github.io/FileAPI/#dfn-readAsDataURL
- fn perform_readasdataurl(data: ReadMetaData, bytes: &[u8])
- -> DOMString {
+ fn perform_readasdataurl(result: &DOMRefCell<Option<FileReaderResult>>, data: ReadMetaData, bytes: &[u8]) {
let config = Config {
char_set: CharacterSet::UrlSafe,
newline: Newline::LF,
@@ -245,7 +260,23 @@ impl FileReader {
format!("data:{};base64,{}", data.blobtype, base64)
};
- DOMString::from(output)
+ *result.borrow_mut() = Some(FileReaderResult::String(DOMString::from(output)));
+ }
+
+ // https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
+ #[allow(unsafe_code)]
+ fn perform_readasarraybuffer(result: &DOMRefCell<Option<FileReaderResult>>,
+ cx: *mut JSContext, _: ReadMetaData, bytes: &[u8]) {
+ unsafe {
+ rooted!(in(cx) let mut array_buffer = ptr::null_mut());
+ assert!(Uint8Array::create(cx, bytes.len() as u32, Some(bytes), array_buffer.handle_mut()).is_ok());
+
+ *result.borrow_mut() = Some(FileReaderResult::ArrayBuffer(Heap::default()));
+
+ if let Some(FileReaderResult::ArrayBuffer(ref mut heap)) = *result.borrow_mut() {
+ heap.set(jsval::ObjectValue(&*array_buffer.get()));
+ };
+ }
}
}
@@ -268,7 +299,11 @@ impl FileReaderMethods for FileReader {
// https://w3c.github.io/FileAPI/#dfn-onloadend
event_handler!(loadend, GetOnloadend, SetOnloadend);
- //TODO https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
+ // https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
+ fn ReadAsArrayBuffer(&self, blob: &Blob) -> ErrorResult {
+ self.read(FileReaderFunction::ReadAsArrayBuffer, blob, None)
+ }
+
// https://w3c.github.io/FileAPI/#dfn-readAsDataURL
fn ReadAsDataURL(&self, blob: &Blob) -> ErrorResult {
self.read(FileReaderFunction::ReadAsDataUrl, blob, None)
@@ -302,9 +337,18 @@ impl FileReaderMethods for FileReader {
self.error.get()
}
+ #[allow(unsafe_code)]
// https://w3c.github.io/FileAPI/#dfn-result
- fn GetResult(&self) -> Option<DOMString> {
- self.result.borrow().clone()
+ fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> {
+ self.result.borrow().as_ref().map(|r| match *r {
+ FileReaderResult::String(ref string) =>
+ StringOrObject::String(string.clone()),
+ FileReaderResult::ArrayBuffer(ref arr_buffer) => {
+ unsafe {
+ StringOrObject::Object((*arr_buffer.ptr.get()).to_object())
+ }
+ }
+ })
}
// https://w3c.github.io/FileAPI/#dfn-readyState
diff --git a/components/script/dom/webidls/FileReader.webidl b/components/script/dom/webidls/FileReader.webidl
index 45ae6ea1b2c..be00e39fd77 100644
--- a/components/script/dom/webidls/FileReader.webidl
+++ b/components/script/dom/webidls/FileReader.webidl
@@ -4,13 +4,13 @@
// http://dev.w3.org/2006/webapi/FileAPI/#APIASynch
-//typedef (DOMString or ArrayBuffer) FileReaderResult;
+typedef (DOMString or object) FileReaderResult;
[Constructor, Exposed=(Window,Worker)]
interface FileReader: EventTarget {
// async read methods
- //[Throws]
- //void readAsArrayBuffer(Blob blob);
+ [Throws]
+ void readAsArrayBuffer(Blob blob);
[Throws]
void readAsText(Blob blob, optional DOMString label);
[Throws]
@@ -25,8 +25,7 @@ interface FileReader: EventTarget {
readonly attribute unsigned short readyState;
// File or Blob data
- //readonly attribute FileReaderResult? result;
- readonly attribute DOMString? result;
+ readonly attribute FileReaderResult? result;
readonly attribute DOMException? error;