mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Implemented FileReader::readAsArrayBuffer
This commit is contained in:
parent
7e96f87565
commit
51ef05bf3d
7 changed files with 73 additions and 55 deletions
|
@ -2237,6 +2237,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
|
||||||
'js::error::throw_type_error',
|
'js::error::throw_type_error',
|
||||||
'js::jsapi::HandleValue',
|
'js::jsapi::HandleValue',
|
||||||
'js::jsapi::JSContext',
|
'js::jsapi::JSContext',
|
||||||
|
'js::jsapi::JSObject',
|
||||||
'js::jsapi::MutableHandleValue',
|
'js::jsapi::MutableHandleValue',
|
||||||
'js::jsval::JSVal',
|
'js::jsval::JSVal',
|
||||||
]
|
]
|
||||||
|
@ -4047,6 +4048,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
|
||||||
elif type.isPrimitive():
|
elif type.isPrimitive():
|
||||||
name = type.name
|
name = type.name
|
||||||
typeName = builtinNames[type.tag()]
|
typeName = builtinNames[type.tag()]
|
||||||
|
elif type.isObject():
|
||||||
|
name = type.name
|
||||||
|
typeName = "*mut JSObject"
|
||||||
else:
|
else:
|
||||||
raise TypeError("Can't handle %s in unions yet" % type)
|
raise TypeError("Can't handle %s in unions yet" % type)
|
||||||
|
|
||||||
|
@ -4056,7 +4060,6 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
|
||||||
isDefinitelyObject=True)
|
isDefinitelyObject=True)
|
||||||
template = info.template
|
template = info.template
|
||||||
|
|
||||||
assert not type.isObject()
|
|
||||||
jsConversion = string.Template(template).substitute({
|
jsConversion = string.Template(template).substitute({
|
||||||
"val": "value",
|
"val": "value",
|
||||||
})
|
})
|
||||||
|
@ -4176,7 +4179,10 @@ class CGUnionConversionStruct(CGThing):
|
||||||
|
|
||||||
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
|
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
|
||||||
if len(objectMemberTypes) > 0:
|
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:
|
else:
|
||||||
object = None
|
object = None
|
||||||
|
|
||||||
|
@ -4191,7 +4197,8 @@ class CGUnionConversionStruct(CGThing):
|
||||||
|
|
||||||
hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object or mozMapObject
|
hasObjectTypes = interfaceObject or arrayObject or dateObject or nonPlatformObject or object or mozMapObject
|
||||||
if hasObjectTypes:
|
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")
|
templateBody = CGList([], "\n")
|
||||||
if interfaceObject:
|
if interfaceObject:
|
||||||
templateBody.append(interfaceObject)
|
templateBody.append(interfaceObject)
|
||||||
|
|
|
@ -6,6 +6,7 @@ use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConstants, FileReaderMethods};
|
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::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
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::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::{DecoderTrap, EncodingRef};
|
use encoding::types::{DecoderTrap, EncodingRef};
|
||||||
use hyper::mime::{Attr, Mime};
|
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 rustc_serialize::base64::{CharacterSet, Config, Newline, ToBase64};
|
||||||
use script_thread::RunnableWrapper;
|
use script_thread::RunnableWrapper;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use task_source::TaskSource;
|
use task_source::TaskSource;
|
||||||
|
@ -35,6 +42,7 @@ use util::thread::spawn_named;
|
||||||
pub enum FileReaderFunction {
|
pub enum FileReaderFunction {
|
||||||
ReadAsText,
|
ReadAsText,
|
||||||
ReadAsDataUrl,
|
ReadAsDataUrl,
|
||||||
|
ReadAsArrayBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TrustedFileReader = Trusted<FileReader>;
|
pub type TrustedFileReader = Trusted<FileReader>;
|
||||||
|
@ -68,12 +76,18 @@ pub enum FileReaderReadyState {
|
||||||
Done = FileReaderConstants::DONE,
|
Done = FileReaderConstants::DONE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(HeapSizeOf, JSTraceable)]
|
||||||
|
pub enum FileReaderResult {
|
||||||
|
ArrayBuffer(Heap<JSVal>),
|
||||||
|
String(DOMString),
|
||||||
|
}
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct FileReader {
|
pub struct FileReader {
|
||||||
eventtarget: EventTarget,
|
eventtarget: EventTarget,
|
||||||
ready_state: Cell<FileReaderReadyState>,
|
ready_state: Cell<FileReaderReadyState>,
|
||||||
error: MutNullableHeap<JS<DOMException>>,
|
error: MutNullableHeap<JS<DOMException>>,
|
||||||
result: DOMRefCell<Option<DOMString>>,
|
result: DOMRefCell<Option<FileReaderResult>>,
|
||||||
generation_id: Cell<GenerationId>,
|
generation_id: Cell<GenerationId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +173,7 @@ impl FileReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn process_read_eof(filereader: TrustedFileReader, gen_id: GenerationId,
|
pub fn process_read_eof(filereader: TrustedFileReader, gen_id: GenerationId,
|
||||||
data: ReadMetaData, blob_contents: Arc<Vec<u8>>) {
|
data: ReadMetaData, blob_contents: Arc<Vec<u8>>) {
|
||||||
let fr = filereader.root();
|
let fr = filereader.root();
|
||||||
|
@ -176,15 +191,17 @@ impl FileReader {
|
||||||
fr.change_ready_state(FileReaderReadyState::Done);
|
fr.change_ready_state(FileReaderReadyState::Done);
|
||||||
// Step 8.2
|
// Step 8.2
|
||||||
|
|
||||||
let output = match data.function {
|
match data.function {
|
||||||
FileReaderFunction::ReadAsDataUrl =>
|
FileReaderFunction::ReadAsDataUrl =>
|
||||||
FileReader::perform_readasdataurl(data, &blob_contents),
|
FileReader::perform_readasdataurl(&fr.result, data, &blob_contents),
|
||||||
FileReaderFunction::ReadAsText =>
|
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
|
// Step 8.3
|
||||||
fr.dispatch_progress_event(atom!("load"), 0, None);
|
fr.dispatch_progress_event(atom!("load"), 0, None);
|
||||||
return_on_abort!();
|
return_on_abort!();
|
||||||
|
@ -198,8 +215,7 @@ impl FileReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
||||||
fn perform_readastext(data: ReadMetaData, blob_bytes: &[u8])
|
fn perform_readastext(result: &DOMRefCell<Option<FileReaderResult>>, data: ReadMetaData, blob_bytes: &[u8]) {
|
||||||
-> DOMString {
|
|
||||||
let blob_label = &data.label;
|
let blob_label = &data.label;
|
||||||
let blob_type = &data.blobtype;
|
let blob_type = &data.blobtype;
|
||||||
|
|
||||||
|
@ -225,12 +241,11 @@ impl FileReader {
|
||||||
let convert = blob_bytes;
|
let convert = blob_bytes;
|
||||||
// Step 7
|
// Step 7
|
||||||
let output = enc.decode(convert, DecoderTrap::Replace).unwrap();
|
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
|
//https://w3c.github.io/FileAPI/#dfn-readAsDataURL
|
||||||
fn perform_readasdataurl(data: ReadMetaData, bytes: &[u8])
|
fn perform_readasdataurl(result: &DOMRefCell<Option<FileReaderResult>>, data: ReadMetaData, bytes: &[u8]) {
|
||||||
-> DOMString {
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
char_set: CharacterSet::UrlSafe,
|
char_set: CharacterSet::UrlSafe,
|
||||||
newline: Newline::LF,
|
newline: Newline::LF,
|
||||||
|
@ -245,7 +260,23 @@ impl FileReader {
|
||||||
format!("data:{};base64,{}", data.blobtype, base64)
|
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
|
// https://w3c.github.io/FileAPI/#dfn-onloadend
|
||||||
event_handler!(loadend, GetOnloadend, SetOnloadend);
|
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
|
// https://w3c.github.io/FileAPI/#dfn-readAsDataURL
|
||||||
fn ReadAsDataURL(&self, blob: &Blob) -> ErrorResult {
|
fn ReadAsDataURL(&self, blob: &Blob) -> ErrorResult {
|
||||||
self.read(FileReaderFunction::ReadAsDataUrl, blob, None)
|
self.read(FileReaderFunction::ReadAsDataUrl, blob, None)
|
||||||
|
@ -302,9 +337,18 @@ impl FileReaderMethods for FileReader {
|
||||||
self.error.get()
|
self.error.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
// https://w3c.github.io/FileAPI/#dfn-result
|
// https://w3c.github.io/FileAPI/#dfn-result
|
||||||
fn GetResult(&self) -> Option<DOMString> {
|
fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> {
|
||||||
self.result.borrow().clone()
|
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
|
// https://w3c.github.io/FileAPI/#dfn-readyState
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
// http://dev.w3.org/2006/webapi/FileAPI/#APIASynch
|
// http://dev.w3.org/2006/webapi/FileAPI/#APIASynch
|
||||||
|
|
||||||
//typedef (DOMString or ArrayBuffer) FileReaderResult;
|
typedef (DOMString or object) FileReaderResult;
|
||||||
[Constructor, Exposed=(Window,Worker)]
|
[Constructor, Exposed=(Window,Worker)]
|
||||||
interface FileReader: EventTarget {
|
interface FileReader: EventTarget {
|
||||||
|
|
||||||
// async read methods
|
// async read methods
|
||||||
//[Throws]
|
[Throws]
|
||||||
//void readAsArrayBuffer(Blob blob);
|
void readAsArrayBuffer(Blob blob);
|
||||||
[Throws]
|
[Throws]
|
||||||
void readAsText(Blob blob, optional DOMString label);
|
void readAsText(Blob blob, optional DOMString label);
|
||||||
[Throws]
|
[Throws]
|
||||||
|
@ -25,8 +25,7 @@ interface FileReader: EventTarget {
|
||||||
readonly attribute unsigned short readyState;
|
readonly attribute unsigned short readyState;
|
||||||
|
|
||||||
// File or Blob data
|
// File or Blob data
|
||||||
//readonly attribute FileReaderResult? result;
|
readonly attribute FileReaderResult? result;
|
||||||
readonly attribute DOMString? result;
|
|
||||||
|
|
||||||
readonly attribute DOMException? error;
|
readonly attribute DOMException? error;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[fileReader.html]
|
|
||||||
type: testharness
|
|
||||||
[FileReader States -- abort]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader States -- events]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -21,15 +21,6 @@
|
||||||
[FileReaderSync interface: operation readAsDataURL(Blob)]
|
[FileReaderSync interface: operation readAsDataURL(Blob)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[FileReader interface: operation readAsArrayBuffer(Blob)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader interface: new FileReader() must inherit property "readAsArrayBuffer" with the proper type (0)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader interface: operation readAsBinaryString(Blob)]
|
[FileReader interface: operation readAsBinaryString(Blob)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,6 @@
|
||||||
[URL interface: operation createFor(Blob)]
|
[URL interface: operation createFor(Blob)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[FileReader interface: operation readAsArrayBuffer(Blob)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader interface: new FileReader() must inherit property "readAsArrayBuffer" with the proper type (0)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[FileReaderSync interface: operation readAsArrayBuffer(Blob)]
|
[FileReaderSync interface: operation readAsArrayBuffer(Blob)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,3 @@
|
||||||
[test FileReader no InvalidStateError exception in onloadstart event for readAsArrayBuffer]
|
[test FileReader no InvalidStateError exception in onloadstart event for readAsArrayBuffer]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test FileReader InvalidStateError exception for readAsArrayBuffer]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test FileReader InvalidStateError exception in onloadstart event for readAsArrayBuffer]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue