Skip to main content

script/dom/file/
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::{ArrayBufferU8, HeapArrayBuffer};
11use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
12use script_bindings::trace::RootedTraceableBox;
13
14use crate::dom::bindings::buffer_source::create_buffer_source;
15use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
16use crate::dom::bindings::codegen::Bindings::FileReaderSyncBinding::FileReaderSyncMethods;
17use crate::dom::bindings::error::{Error, Fallible};
18use crate::dom::bindings::root::DomRoot;
19use crate::dom::bindings::str::DOMString;
20use crate::dom::blob::Blob;
21use crate::dom::filereader::FileReaderSharedFunctionality;
22use crate::dom::globalscope::GlobalScope;
23use crate::script_runtime::{CanGc, JSContext};
24
25#[dom_struct]
26pub(crate) struct FileReaderSync {
27    reflector: Reflector,
28}
29
30impl FileReaderSync {
31    pub(crate) fn new_inherited() -> FileReaderSync {
32        FileReaderSync {
33            reflector: Reflector::new(),
34        }
35    }
36
37    fn new(
38        global: &GlobalScope,
39        proto: Option<HandleObject>,
40        can_gc: CanGc,
41    ) -> DomRoot<FileReaderSync> {
42        reflect_dom_object_with_proto(
43            Box::new(FileReaderSync::new_inherited()),
44            global,
45            proto,
46            can_gc,
47        )
48    }
49
50    fn get_blob_bytes(blob: &Blob) -> Result<Vec<u8>, Error> {
51        blob.get_bytes().map_err(|_| Error::NotReadable(None))
52    }
53}
54
55impl FileReaderSyncMethods<crate::DomTypeHolder> for FileReaderSync {
56    /// <https://w3c.github.io/FileAPI/#filereadersyncConstrctr>
57    fn Constructor(
58        global: &GlobalScope,
59        proto: Option<HandleObject>,
60        can_gc: CanGc,
61    ) -> Fallible<DomRoot<FileReaderSync>> {
62        Ok(FileReaderSync::new(global, proto, can_gc))
63    }
64
65    /// <https://w3c.github.io/FileAPI/#readAsBinaryStringSyncSection>
66    fn ReadAsBinaryString(&self, blob: &Blob) -> Fallible<DOMString> {
67        // step 1
68        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
69
70        // step 2.
71        Ok(FileReaderSharedFunctionality::binary_string_for_bytes(
72            &blob_contents,
73        ))
74    }
75
76    /// <https://w3c.github.io/FileAPI/#readAsTextSync>
77    fn ReadAsText(&self, blob: &Blob, label: Option<DOMString>) -> Fallible<DOMString> {
78        // step 1
79        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
80
81        // step 2
82        let blob_label = label.map(String::from);
83        let blob_type = String::from(blob.Type());
84
85        Ok(FileReaderSharedFunctionality::text_for_bytes(
86            &blob_contents,
87            &blob_type,
88            &blob_label,
89        ))
90    }
91
92    /// <https://w3c.github.io/FileAPI/#readAsDataURLSync-section>
93    fn ReadAsDataURL(&self, blob: &Blob) -> Fallible<DOMString> {
94        // step 1
95        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
96
97        // step 2. package data.
98        // https://w3c.github.io/FileAPI/#blob-package-data
99        let output =
100            FileReaderSharedFunctionality::dataurl_for_bytes(&blob_contents, &blob.Type().str());
101
102        Ok(output)
103    }
104
105    /// <https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection>
106    fn ReadAsArrayBuffer(
107        &self,
108        cx: JSContext,
109        blob: &Blob,
110        can_gc: CanGc,
111    ) -> Fallible<RootedTraceableBox<HeapArrayBuffer>> {
112        // step 1
113        let blob_contents = FileReaderSync::get_blob_bytes(blob)?;
114
115        // step 2
116        rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
117
118        create_buffer_source::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut(), can_gc)
119            .map_err(|_| Error::JSFailed)
120    }
121}