mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Implement read methods on FileReaderSync
This commit is contained in:
parent
3e8caa4679
commit
0fdafb08c8
9 changed files with 277 additions and 104 deletions
|
@ -69,6 +69,8 @@ pub enum Error {
|
||||||
TypeMismatch,
|
TypeMismatch,
|
||||||
/// InvalidModificationError DOMException
|
/// InvalidModificationError DOMException
|
||||||
InvalidModification,
|
InvalidModification,
|
||||||
|
/// NotReadableError DOMException
|
||||||
|
NotReadable,
|
||||||
|
|
||||||
/// TypeError JavaScript Error
|
/// TypeError JavaScript Error
|
||||||
Type(String),
|
Type(String),
|
||||||
|
@ -110,6 +112,7 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: &GlobalScope, resu
|
||||||
Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
|
Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
|
||||||
Error::TypeMismatch => DOMErrorName::TypeMismatchError,
|
Error::TypeMismatch => DOMErrorName::TypeMismatchError,
|
||||||
Error::InvalidModification => DOMErrorName::InvalidModificationError,
|
Error::InvalidModification => DOMErrorName::InvalidModificationError,
|
||||||
|
Error::NotReadable => DOMErrorName::NotReadableError,
|
||||||
Error::Type(message) => {
|
Error::Type(message) => {
|
||||||
assert!(!JS_IsExceptionPending(cx));
|
assert!(!JS_IsExceptionPending(cx));
|
||||||
throw_type_error(cx, &message);
|
throw_type_error(cx, &message);
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub enum DOMErrorName {
|
||||||
TimeoutError = DOMExceptionConstants::TIMEOUT_ERR,
|
TimeoutError = DOMExceptionConstants::TIMEOUT_ERR,
|
||||||
InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR,
|
InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR,
|
||||||
DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR,
|
DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR,
|
||||||
|
NotReadableError = DOMExceptionConstants::NOT_READABLE_ERR,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -94,6 +95,7 @@ impl DOMExceptionMethods for DOMException {
|
||||||
DOMErrorName::InvalidNodeTypeError =>
|
DOMErrorName::InvalidNodeTypeError =>
|
||||||
"The supplied node is incorrect or has an incorrect ancestor for this operation.",
|
"The supplied node is incorrect or has an incorrect ancestor for this operation.",
|
||||||
DOMErrorName::DataCloneError => "The object can not be cloned.",
|
DOMErrorName::DataCloneError => "The object can not be cloned.",
|
||||||
|
DOMErrorName::NotReadableError => "The I/O read operation failed."
|
||||||
};
|
};
|
||||||
|
|
||||||
DOMString::from(message)
|
DOMString::from(message)
|
||||||
|
|
|
@ -51,12 +51,15 @@ pub type TrustedFileReader = Trusted<FileReader>;
|
||||||
pub struct ReadMetaData {
|
pub struct ReadMetaData {
|
||||||
pub blobtype: String,
|
pub blobtype: String,
|
||||||
pub label: Option<String>,
|
pub label: Option<String>,
|
||||||
pub function: FileReaderFunction
|
pub function: FileReaderFunction,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadMetaData {
|
impl ReadMetaData {
|
||||||
pub fn new(blobtype: String,
|
pub fn new(
|
||||||
label: Option<String>, function: FileReaderFunction) -> ReadMetaData {
|
blobtype: String,
|
||||||
|
label: Option<String>,
|
||||||
|
function: FileReaderFunction,
|
||||||
|
) -> ReadMetaData {
|
||||||
ReadMetaData {
|
ReadMetaData {
|
||||||
blobtype: blobtype,
|
blobtype: blobtype,
|
||||||
label: label,
|
label: label,
|
||||||
|
@ -82,6 +85,54 @@ pub enum FileReaderResult {
|
||||||
String(DOMString),
|
String(DOMString),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FileReaderSharedFunctionality;
|
||||||
|
|
||||||
|
impl FileReaderSharedFunctionality {
|
||||||
|
pub fn dataurl_format(blob_contents: &[u8], blob_type: String) -> DOMString {
|
||||||
|
let base64 = base64::encode(&blob_contents);
|
||||||
|
|
||||||
|
let dataurl = if blob_type.is_empty() {
|
||||||
|
format!("data:base64,{}", base64)
|
||||||
|
} else {
|
||||||
|
format!("data:{};base64,{}", blob_type, base64)
|
||||||
|
};
|
||||||
|
|
||||||
|
DOMString::from(dataurl)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_decode(
|
||||||
|
blob_contents: &[u8],
|
||||||
|
blob_type: &str,
|
||||||
|
blob_label: &Option<String>,
|
||||||
|
) -> DOMString {
|
||||||
|
//https://w3c.github.io/FileAPI/#encoding-determination
|
||||||
|
// Steps 1 & 2 & 3
|
||||||
|
let mut encoding = blob_label
|
||||||
|
.as_ref()
|
||||||
|
.map(|string| string.as_bytes())
|
||||||
|
.and_then(Encoding::for_label);
|
||||||
|
|
||||||
|
// Step 4 & 5
|
||||||
|
encoding = encoding.or_else(|| {
|
||||||
|
let resultmime = blob_type.parse::<Mime>().ok();
|
||||||
|
resultmime.and_then(|Mime(_, _, ref parameters)| {
|
||||||
|
parameters
|
||||||
|
.iter()
|
||||||
|
.find(|&&(ref k, _)| &Attr::Charset == k)
|
||||||
|
.and_then(|&(_, ref v)| Encoding::for_label(v.as_str().as_bytes()))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 6
|
||||||
|
let enc = encoding.unwrap_or(UTF_8);
|
||||||
|
|
||||||
|
let convert = blob_contents;
|
||||||
|
// Step 7
|
||||||
|
let (output, _, _) = enc.decode(convert);
|
||||||
|
DOMString::from(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct FileReader {
|
pub struct FileReader {
|
||||||
eventtarget: EventTarget,
|
eventtarget: EventTarget,
|
||||||
|
@ -103,8 +154,11 @@ impl FileReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope) -> DomRoot<FileReader> {
|
pub fn new(global: &GlobalScope) -> DomRoot<FileReader> {
|
||||||
reflect_dom_object(Box::new(FileReader::new_inherited()),
|
reflect_dom_object(
|
||||||
global, FileReaderBinding::Wrap)
|
Box::new(FileReader::new_inherited()),
|
||||||
|
global,
|
||||||
|
FileReaderBinding::Wrap,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReader>> {
|
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReader>> {
|
||||||
|
@ -112,7 +166,11 @@ impl FileReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://w3c.github.io/FileAPI/#dfn-error-steps
|
//https://w3c.github.io/FileAPI/#dfn-error-steps
|
||||||
pub fn process_read_error(filereader: TrustedFileReader, gen_id: GenerationId, error: DOMErrorName) {
|
pub fn process_read_error(
|
||||||
|
filereader: TrustedFileReader,
|
||||||
|
gen_id: GenerationId,
|
||||||
|
error: DOMErrorName,
|
||||||
|
) {
|
||||||
let fr = filereader.root();
|
let fr = filereader.root();
|
||||||
|
|
||||||
macro_rules! return_on_abort(
|
macro_rules! return_on_abort(
|
||||||
|
@ -174,8 +232,12 @@ impl FileReader {
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn process_read_eof(filereader: TrustedFileReader, gen_id: GenerationId,
|
pub fn process_read_eof(
|
||||||
data: ReadMetaData, blob_contents: Arc<Vec<u8>>) {
|
filereader: TrustedFileReader,
|
||||||
|
gen_id: GenerationId,
|
||||||
|
data: ReadMetaData,
|
||||||
|
blob_contents: Arc<Vec<u8>>,
|
||||||
|
) {
|
||||||
let fr = filereader.root();
|
let fr = filereader.root();
|
||||||
|
|
||||||
macro_rules! return_on_abort(
|
macro_rules! return_on_abort(
|
||||||
|
@ -192,13 +254,21 @@ impl FileReader {
|
||||||
// Step 8.2
|
// Step 8.2
|
||||||
|
|
||||||
match data.function {
|
match data.function {
|
||||||
FileReaderFunction::ReadAsDataUrl =>
|
FileReaderFunction::ReadAsDataUrl => {
|
||||||
FileReader::perform_readasdataurl(&fr.result, data, &blob_contents),
|
FileReader::perform_readasdataurl(&fr.result, data, &blob_contents)
|
||||||
FileReaderFunction::ReadAsText =>
|
},
|
||||||
FileReader::perform_readastext(&fr.result, data, &blob_contents),
|
FileReaderFunction::ReadAsText => {
|
||||||
|
FileReader::perform_readastext(&fr.result, data, &blob_contents)
|
||||||
|
},
|
||||||
FileReaderFunction::ReadAsArrayBuffer => {
|
FileReaderFunction::ReadAsArrayBuffer => {
|
||||||
let _ac = JSAutoCompartment::new(fr.global().get_cx(), *fr.reflector().get_jsobject());
|
let _ac =
|
||||||
FileReader::perform_readasarraybuffer(&fr.result, fr.global().get_cx(), data, &blob_contents)
|
JSAutoCompartment::new(fr.global().get_cx(), *fr.reflector().get_jsobject());
|
||||||
|
FileReader::perform_readasarraybuffer(
|
||||||
|
&fr.result,
|
||||||
|
fr.global().get_cx(),
|
||||||
|
data,
|
||||||
|
&blob_contents,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -215,55 +285,43 @@ impl FileReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
||||||
fn perform_readastext(result: &DomRefCell<Option<FileReaderResult>>, data: ReadMetaData, blob_bytes: &[u8]) {
|
fn perform_readastext(
|
||||||
|
result: &DomRefCell<Option<FileReaderResult>>,
|
||||||
|
data: ReadMetaData,
|
||||||
|
blob_bytes: &[u8],
|
||||||
|
) {
|
||||||
let blob_label = &data.label;
|
let blob_label = &data.label;
|
||||||
let blob_type = &data.blobtype;
|
let blob_type = &data.blobtype;
|
||||||
|
|
||||||
//https://w3c.github.io/FileAPI/#encoding-determination
|
let output = FileReaderSharedFunctionality::text_decode(blob_bytes, blob_type, blob_label);
|
||||||
// Steps 1 & 2 & 3
|
*result.borrow_mut() = Some(FileReaderResult::String(output));
|
||||||
let mut encoding = blob_label.as_ref()
|
|
||||||
.map(|string| string.as_bytes())
|
|
||||||
.and_then(Encoding::for_label);
|
|
||||||
|
|
||||||
// Step 4 & 5
|
|
||||||
encoding = encoding.or_else(|| {
|
|
||||||
let resultmime = blob_type.parse::<Mime>().ok();
|
|
||||||
resultmime.and_then(|Mime(_, _, ref parameters)| {
|
|
||||||
parameters.iter()
|
|
||||||
.find(|&&(ref k, _)| &Attr::Charset == k)
|
|
||||||
.and_then(|&(_, ref v)| Encoding::for_label(v.as_str().as_bytes()))
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
// Step 6
|
|
||||||
let enc = encoding.unwrap_or(UTF_8);
|
|
||||||
|
|
||||||
let convert = blob_bytes;
|
|
||||||
// Step 7
|
|
||||||
let (output, _, _) = enc.decode(convert);
|
|
||||||
*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(result: &DomRefCell<Option<FileReaderResult>>, data: ReadMetaData, bytes: &[u8]) {
|
fn perform_readasdataurl(
|
||||||
let base64 = base64::encode(bytes);
|
result: &DomRefCell<Option<FileReaderResult>>,
|
||||||
|
data: ReadMetaData,
|
||||||
|
bytes: &[u8],
|
||||||
|
) {
|
||||||
|
let output = FileReaderSharedFunctionality::dataurl_format(bytes, data.blobtype);
|
||||||
|
|
||||||
let output = if data.blobtype.is_empty() {
|
*result.borrow_mut() = Some(FileReaderResult::String(output));
|
||||||
format!("data:base64,{}", base64)
|
|
||||||
} else {
|
|
||||||
format!("data:{};base64,{}", data.blobtype, base64)
|
|
||||||
};
|
|
||||||
|
|
||||||
*result.borrow_mut() = Some(FileReaderResult::String(DOMString::from(output)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
|
// https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn perform_readasarraybuffer(result: &DomRefCell<Option<FileReaderResult>>,
|
fn perform_readasarraybuffer(
|
||||||
cx: *mut JSContext, _: ReadMetaData, bytes: &[u8]) {
|
result: &DomRefCell<Option<FileReaderResult>>,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
_: ReadMetaData,
|
||||||
|
bytes: &[u8],
|
||||||
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||||
assert!(ArrayBuffer::create(cx, CreateWith::Slice(bytes), array_buffer.handle_mut()).is_ok());
|
assert!(
|
||||||
|
ArrayBuffer::create(cx, CreateWith::Slice(bytes), array_buffer.handle_mut())
|
||||||
|
.is_ok()
|
||||||
|
);
|
||||||
|
|
||||||
*result.borrow_mut() = Some(FileReaderResult::ArrayBuffer(Heap::default()));
|
*result.borrow_mut() = Some(FileReaderResult::ArrayBuffer(Heap::default()));
|
||||||
|
|
||||||
|
@ -335,13 +393,12 @@ impl FileReaderMethods for FileReader {
|
||||||
// https://w3c.github.io/FileAPI/#dfn-result
|
// https://w3c.github.io/FileAPI/#dfn-result
|
||||||
unsafe fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> {
|
unsafe fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> {
|
||||||
self.result.borrow().as_ref().map(|r| match *r {
|
self.result.borrow().as_ref().map(|r| match *r {
|
||||||
FileReaderResult::String(ref string) =>
|
FileReaderResult::String(ref string) => StringOrObject::String(string.clone()),
|
||||||
StringOrObject::String(string.clone()),
|
|
||||||
FileReaderResult::ArrayBuffer(ref arr_buffer) => {
|
FileReaderResult::ArrayBuffer(ref arr_buffer) => {
|
||||||
let result = RootedTraceableBox::new(Heap::default());
|
let result = RootedTraceableBox::new(Heap::default());
|
||||||
result.set((*arr_buffer.ptr.get()).to_object());
|
result.set((*arr_buffer.ptr.get()).to_object());
|
||||||
StringOrObject::Object(result)
|
StringOrObject::Object(result)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,12 +408,17 @@ impl FileReaderMethods for FileReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl FileReader {
|
impl FileReader {
|
||||||
fn dispatch_progress_event(&self, type_: Atom, loaded: u64, total: Option<u64>) {
|
fn dispatch_progress_event(&self, type_: Atom, loaded: u64, total: Option<u64>) {
|
||||||
let progressevent = ProgressEvent::new(&self.global(),
|
let progressevent = ProgressEvent::new(
|
||||||
type_, EventBubbles::DoesNotBubble, EventCancelable::NotCancelable,
|
&self.global(),
|
||||||
total.is_some(), loaded, total.unwrap_or(0));
|
type_,
|
||||||
|
EventBubbles::DoesNotBubble,
|
||||||
|
EventCancelable::NotCancelable,
|
||||||
|
total.is_some(),
|
||||||
|
loaded,
|
||||||
|
total.unwrap_or(0),
|
||||||
|
);
|
||||||
progressevent.upcast::<Event>().fire(self.upcast());
|
progressevent.upcast::<Event>().fire(self.upcast());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +427,12 @@ impl FileReader {
|
||||||
self.generation_id.set(GenerationId(prev_id + 1));
|
self.generation_id.set(GenerationId(prev_id + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, function: FileReaderFunction, blob: &Blob, label: Option<DOMString>) -> ErrorResult {
|
fn read(
|
||||||
|
&self,
|
||||||
|
function: FileReaderFunction,
|
||||||
|
blob: &Blob,
|
||||||
|
label: Option<DOMString>,
|
||||||
|
) -> ErrorResult {
|
||||||
// Step 1
|
// Step 1
|
||||||
if self.ready_state.get() == FileReaderReadyState::Loading {
|
if self.ready_state.get() == FileReaderReadyState::Loading {
|
||||||
return Err(Error::InvalidState);
|
return Err(Error::InvalidState);
|
||||||
|
@ -388,16 +455,19 @@ impl FileReader {
|
||||||
let canceller = global.task_canceller();
|
let canceller = global.task_canceller();
|
||||||
let task_source = global.file_reading_task_source();
|
let task_source = global.file_reading_task_source();
|
||||||
|
|
||||||
thread::Builder::new().name("file reader async operation".to_owned()).spawn(move || {
|
thread::Builder::new()
|
||||||
perform_annotated_read_operation(
|
.name("file reader async operation".to_owned())
|
||||||
gen_id,
|
.spawn(move || {
|
||||||
load_data,
|
perform_annotated_read_operation(
|
||||||
blob_contents,
|
gen_id,
|
||||||
fr,
|
load_data,
|
||||||
task_source,
|
blob_contents,
|
||||||
canceller,
|
fr,
|
||||||
)
|
task_source,
|
||||||
}).expect("Thread spawning failed");
|
canceller,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.expect("Thread spawning failed");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,25 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::FileReaderSyncBinding;
|
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::codegen::Bindings::FileReaderSyncBinding::{FileReaderSyncBinding, FileReaderSyncMethods};
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::reflector::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::bindings::root::DomRoot;
|
use dom::bindings::root::DomRoot;
|
||||||
|
use dom::bindings::str::DOMString;
|
||||||
|
use dom::blob::Blob;
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
|
use dom::filereader::FileReaderSharedFunctionality;
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use js::jsapi::{JSContext, JSObject};
|
||||||
|
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||||
|
use std::ptr;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct FileReaderSync {
|
pub struct FileReaderSync {
|
||||||
eventtarget: EventTarget
|
eventtarget: EventTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileReaderSync {
|
impl FileReaderSync {
|
||||||
|
@ -23,11 +31,79 @@ impl FileReaderSync {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope) -> DomRoot<FileReaderSync> {
|
pub fn new(global: &GlobalScope) -> DomRoot<FileReaderSync> {
|
||||||
reflect_dom_object(Box::new(FileReaderSync::new_inherited()),
|
reflect_dom_object(
|
||||||
global, FileReaderSyncBinding::Wrap)
|
Box::new(FileReaderSync::new_inherited()),
|
||||||
|
global,
|
||||||
|
FileReaderSyncBinding::Wrap,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReaderSync>> {
|
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReaderSync>> {
|
||||||
Ok(FileReaderSync::new(global))
|
Ok(FileReaderSync::new(global))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_blob_bytes(blob: &Blob) -> Result<Vec<u8>, Error> {
|
||||||
|
blob.get_bytes().map_err(|_| Error::NotReadable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileReaderSyncMethods for FileReaderSync {
|
||||||
|
// https://w3c.github.io/FileAPI/#readAsBinaryStringSyncSection
|
||||||
|
fn ReadAsBinaryString(&self, blob: &Blob) -> Fallible<DOMString> {
|
||||||
|
// step 1
|
||||||
|
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
Ok(DOMString::from(String::from_utf8_lossy(&blob_contents)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/FileAPI/#readAsTextSync
|
||||||
|
fn ReadAsText(&self, blob: &Blob, label: Option<DOMString>) -> Fallible<DOMString> {
|
||||||
|
// step 1
|
||||||
|
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
let blob_label = label.map(String::from);
|
||||||
|
let blob_type = String::from(blob.Type());
|
||||||
|
|
||||||
|
let output =
|
||||||
|
FileReaderSharedFunctionality::text_decode(&blob_contents, &blob_type, &blob_label);
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/FileAPI/#readAsDataURLSync-section
|
||||||
|
fn ReadAsDataURL(&self, blob: &Blob) -> Fallible<DOMString> {
|
||||||
|
// step 1
|
||||||
|
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
let output =
|
||||||
|
FileReaderSharedFunctionality::dataurl_format(&blob_contents, blob.Type().to_string());
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
// https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection
|
||||||
|
unsafe fn ReadAsArrayBuffer(
|
||||||
|
&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
blob: &Blob,
|
||||||
|
) -> Fallible<NonNull<JSObject>> {
|
||||||
|
// step 1
|
||||||
|
let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||||
|
assert!(
|
||||||
|
ArrayBuffer::create(
|
||||||
|
cx,
|
||||||
|
CreateWith::Slice(&blob_contents),
|
||||||
|
array_buffer.handle_mut()
|
||||||
|
).is_ok()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(NonNull::new_unchecked(array_buffer.get()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ interface DOMException {
|
||||||
const unsigned short TIMEOUT_ERR = 23;
|
const unsigned short TIMEOUT_ERR = 23;
|
||||||
const unsigned short INVALID_NODE_TYPE_ERR = 24;
|
const unsigned short INVALID_NODE_TYPE_ERR = 24;
|
||||||
const unsigned short DATA_CLONE_ERR = 25;
|
const unsigned short DATA_CLONE_ERR = 25;
|
||||||
|
const unsigned short NOT_READABLE_ERR = 26;
|
||||||
|
|
||||||
// Error code as u16
|
// Error code as u16
|
||||||
readonly attribute unsigned short code;
|
readonly attribute unsigned short code;
|
||||||
|
|
|
@ -8,8 +8,12 @@
|
||||||
interface FileReaderSync {
|
interface FileReaderSync {
|
||||||
// Synchronously return strings
|
// Synchronously return strings
|
||||||
|
|
||||||
// ArrayBuffer readAsArrayBuffer(Blob blob);
|
[Throws]
|
||||||
// DOMString readAsBinaryString(Blob blob);
|
ArrayBuffer readAsArrayBuffer(Blob blob);
|
||||||
// DOMString readAsText(Blob blob, optional DOMString label);
|
[Throws]
|
||||||
// DOMString readAsDataURL(Blob blob);
|
DOMString readAsBinaryString(Blob blob);
|
||||||
|
[Throws]
|
||||||
|
DOMString readAsText(Blob blob, optional DOMString label);
|
||||||
|
[Throws]
|
||||||
|
DOMString readAsDataURL(Blob blob);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
[FileReaderSync.worker.html]
|
|
||||||
type: testharness
|
|
||||||
[readAsText]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[readAsDataURL]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[readAsArrayBuffer]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -409016,7 +409016,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"FileAPI/FileReaderSync.worker.js": [
|
"FileAPI/FileReaderSync.worker.js": [
|
||||||
"19741fbd0498bf9135408ceb6128221cbeb4e2f3",
|
"9d9a2b77b7fbd8ad4edb75228bd7bca1f915ad61",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"FileAPI/OWNERS": [
|
"FileAPI/OWNERS": [
|
||||||
|
|
|
@ -1,28 +1,56 @@
|
||||||
importScripts("/resources/testharness.js");
|
importScripts("/resources/testharness.js");
|
||||||
|
|
||||||
var blob, readerSync;
|
var blob, empty_blob, readerSync;
|
||||||
setup(function() {
|
setup(() => {
|
||||||
readerSync = new FileReaderSync();
|
readerSync = new FileReaderSync();
|
||||||
blob = new Blob(["test"]);
|
blob = new Blob(["test"]);
|
||||||
|
empty_blob = new Blob();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function() {
|
test(() => {
|
||||||
assert_true(readerSync instanceof FileReaderSync);
|
assert_true(readerSync instanceof FileReaderSync);
|
||||||
}, "Interface");
|
}, "Interface");
|
||||||
|
|
||||||
test(function() {
|
test(() => {
|
||||||
var text = readerSync.readAsText(blob);
|
var text = readerSync.readAsText(blob);
|
||||||
assert_equals(text, "test");
|
assert_equals(text, "test");
|
||||||
}, "readAsText");
|
}, "readAsText");
|
||||||
|
|
||||||
test(function() {
|
test(() => {
|
||||||
var data = readerSync.readAsDataURL(blob);
|
var text = readerSync.readAsText(empty_blob);
|
||||||
assert_equals(data.indexOf("data:"), 0);
|
assert_equals(text, "");
|
||||||
|
}, "readAsText with empty blob");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var data = readerSync.readAsDataURL(blob);
|
||||||
|
assert_equals(data.indexOf("data:"), 0);
|
||||||
}, "readAsDataURL");
|
}, "readAsDataURL");
|
||||||
|
|
||||||
test(function() {
|
test(() => {
|
||||||
var data = readerSync.readAsArrayBuffer(blob);
|
var data = readerSync.readAsDataURL(empty_blob);
|
||||||
assert_true(data instanceof ArrayBuffer);
|
assert_equals(data.indexOf("data:"), 0);
|
||||||
|
}, "readAsDataURL with empty blob");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var data = readerSync.readAsBinaryString(blob);
|
||||||
|
assert_equals(data, "test");
|
||||||
|
}, "readAsBinaryString");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var data = readerSync.readAsBinaryString(empty_blob);
|
||||||
|
assert_equals(data, "");
|
||||||
|
}, "readAsBinaryString with empty blob");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var data = readerSync.readAsArrayBuffer(blob);
|
||||||
|
assert_true(data instanceof ArrayBuffer);
|
||||||
|
assert_equals(data.byteLength, "test".length);
|
||||||
}, "readAsArrayBuffer");
|
}, "readAsArrayBuffer");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
var data = readerSync.readAsArrayBuffer(empty_blob);
|
||||||
|
assert_true(data instanceof ArrayBuffer);
|
||||||
|
assert_equals(data.byteLength, 0);
|
||||||
|
}, "readAsArrayBuffer with empty blob");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue