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