script/dom/
filereadersync.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::ptr;
6
7use dom_struct::dom_struct;
8use js::jsapi::JSObject;
9use js::rust::HandleObject;
10use js::typedarray::{ArrayBuffer, ArrayBufferU8};
11
12use crate::dom::bindings::buffer_source::create_buffer_source;
13use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
14use crate::dom::bindings::codegen::Bindings::FileReaderSyncBinding::FileReaderSyncMethods;
15use crate::dom::bindings::error::{Error, Fallible};
16use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::blob::Blob;
20use crate::dom::filereader::FileReaderSharedFunctionality;
21use crate::dom::globalscope::GlobalScope;
22use crate::script_runtime::{CanGc, JSContext};
23
24#[dom_struct]
25pub(crate) struct FileReaderSync {
26    reflector: Reflector,
27}
28
29impl FileReaderSync {
30    pub(crate) fn new_inherited() -> FileReaderSync {
31        FileReaderSync {
32            reflector: Reflector::new(),
33        }
34    }
35
36    fn new(
37        global: &GlobalScope,
38        proto: Option<HandleObject>,
39        can_gc: CanGc,
40    ) -> DomRoot<FileReaderSync> {
41        reflect_dom_object_with_proto(
42            Box::new(FileReaderSync::new_inherited()),
43            global,
44            proto,
45            can_gc,
46        )
47    }
48
49    fn get_blob_bytes(blob: &Blob) -> Result<Vec<u8>, Error> {
50        blob.get_bytes().map_err(|_| Error::NotReadable)
51    }
52}
53
54impl FileReaderSyncMethods<crate::DomTypeHolder> for FileReaderSync {
55    /// <https://w3c.github.io/FileAPI/#filereadersyncConstrctr>
56    fn Constructor(
57        global: &GlobalScope,
58        proto: Option<HandleObject>,
59        can_gc: CanGc,
60    ) -> Fallible<DomRoot<FileReaderSync>> {
61        Ok(FileReaderSync::new(global, proto, can_gc))
62    }
63
64    /// <https://w3c.github.io/FileAPI/#readAsBinaryStringSyncSection>
65    fn ReadAsBinaryString(&self, blob: &Blob) -> Fallible<DOMString> {
66        // step 1
67        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
68
69        // step 2
70        Ok(DOMString::from(String::from_utf8_lossy(&blob_contents)))
71    }
72
73    /// <https://w3c.github.io/FileAPI/#readAsTextSync>
74    fn ReadAsText(&self, blob: &Blob, label: Option<DOMString>) -> Fallible<DOMString> {
75        // step 1
76        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
77
78        // step 2
79        let blob_label = label.map(String::from);
80        let blob_type = String::from(blob.Type());
81
82        let output =
83            FileReaderSharedFunctionality::text_decode(&blob_contents, &blob_type, &blob_label);
84
85        Ok(output)
86    }
87
88    /// <https://w3c.github.io/FileAPI/#readAsDataURLSync-section>
89    fn ReadAsDataURL(&self, blob: &Blob) -> Fallible<DOMString> {
90        // step 1
91        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
92
93        // step 2
94        let output =
95            FileReaderSharedFunctionality::dataurl_format(&blob_contents, blob.Type().to_string());
96
97        Ok(output)
98    }
99
100    /// <https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection>
101    fn ReadAsArrayBuffer(
102        &self,
103        cx: JSContext,
104        blob: &Blob,
105        can_gc: CanGc,
106    ) -> Fallible<ArrayBuffer> {
107        // step 1
108        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
109
110        // step 2
111        rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
112
113        create_buffer_source::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut(), can_gc)
114            .map_err(|_| Error::JSFailed)
115    }
116}