diff options
Diffstat (limited to 'op_crates')
-rw-r--r-- | op_crates/file/03_blob_url.js | 63 | ||||
-rw-r--r-- | op_crates/file/Cargo.toml | 1 | ||||
-rw-r--r-- | op_crates/file/lib.rs | 82 | ||||
-rw-r--r-- | op_crates/url/00_url.js | 8 | ||||
-rw-r--r-- | op_crates/url/lib.deno_url.d.ts | 4 |
5 files changed, 148 insertions, 10 deletions
diff --git a/op_crates/file/03_blob_url.js b/op_crates/file/03_blob_url.js new file mode 100644 index 000000000..29019cd84 --- /dev/null +++ b/op_crates/file/03_blob_url.js @@ -0,0 +1,63 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// <reference no-default-lib="true" /> +/// <reference path="../../core/lib.deno_core.d.ts" /> +/// <reference path="../webidl/internal.d.ts" /> +/// <reference path="../web/internal.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> +/// <reference path="../url/internal.d.ts" /> +/// <reference path="../url/lib.deno_url.d.ts" /> +/// <reference path="./internal.d.ts" /> +/// <reference path="./lib.deno_file.d.ts" /> +/// <reference lib="esnext" /> +"use strict"; + +((window) => { + const core = Deno.core; + // const webidl = window.__bootstrap.webidl; + const { _byteSequence } = window.__bootstrap.file; + const { URL } = window.__bootstrap.url; + + /** + * @param {Blob} blob + * @returns {string} + */ + function createObjectURL(blob) { + // const prefix = "Failed to execute 'createObjectURL' on 'URL'"; + // webidl.requiredArguments(arguments.length, 1, { prefix }); + // blob = webidl.converters["Blob"](blob, { + // context: "Argument 1", + // prefix, + // }); + + const url = core.jsonOpSync( + "op_file_create_object_url", + blob.type, + blob[_byteSequence], + ); + + return url; + } + + /** + * @param {string} url + * @returns {void} + */ + function revokeObjectURL(url) { + // const prefix = "Failed to execute 'revokeObjectURL' on 'URL'"; + // webidl.requiredArguments(arguments.length, 1, { prefix }); + // url = webidl.converters["DOMString"](url, { + // context: "Argument 1", + // prefix, + // }); + + core.jsonOpSync( + "op_file_revoke_object_url", + url, + ); + } + + URL.createObjectURL = createObjectURL; + URL.revokeObjectURL = revokeObjectURL; +})(globalThis); diff --git a/op_crates/file/Cargo.toml b/op_crates/file/Cargo.toml index 54476c783..9897e8cf4 100644 --- a/op_crates/file/Cargo.toml +++ b/op_crates/file/Cargo.toml @@ -15,3 +15,4 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.83.0", path = "../../core" } +uuid = { version = "0.8.2", features = ["v4"] } diff --git a/op_crates/file/lib.rs b/op_crates/file/lib.rs index c7e690433..4cfe4eed4 100644 --- a/op_crates/file/lib.rs +++ b/op_crates/file/lib.rs @@ -1,7 +1,85 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +use deno_core::error::null_opbuf; +use deno_core::error::AnyError; +use deno_core::url::Url; use deno_core::JsRuntime; +use deno_core::ModuleSpecifier; +use deno_core::ZeroCopyBuf; +use std::collections::HashMap; use std::path::PathBuf; +use std::sync::Arc; +use std::sync::Mutex; +use uuid::Uuid; + +#[derive(Clone)] +pub struct Blob { + pub data: Vec<u8>, + pub media_type: String, +} + +pub struct Location(pub Url); + +#[derive(Default, Clone)] +pub struct BlobUrlStore(Arc<Mutex<HashMap<Url, Blob>>>); + +impl BlobUrlStore { + pub fn get(&self, url: &ModuleSpecifier) -> Result<Option<Blob>, AnyError> { + let blob_store = self.0.lock().unwrap(); + Ok(blob_store.get(url).cloned()) + } + + pub fn insert(&self, blob: Blob, maybe_location: Option<Url>) -> Url { + let origin = if let Some(location) = maybe_location { + location.origin().ascii_serialization() + } else { + "null".to_string() + }; + let id = Uuid::new_v4(); + let url = Url::parse(&format!("blob:{}/{}", origin, id)).unwrap(); + + let mut blob_store = self.0.lock().unwrap(); + blob_store.insert(url.clone(), blob); + + url + } + + pub fn remove(&self, url: &ModuleSpecifier) { + let mut blob_store = self.0.lock().unwrap(); + blob_store.remove(&url); + } +} + +pub fn op_file_create_object_url( + state: &mut deno_core::OpState, + media_type: String, + zero_copy: Option<ZeroCopyBuf>, +) -> Result<String, AnyError> { + let data = zero_copy.ok_or_else(null_opbuf)?; + let blob = Blob { + data: data.to_vec(), + media_type, + }; + + let maybe_location = state.try_borrow::<Location>(); + let blob_store = state.borrow::<BlobUrlStore>(); + + let url = + blob_store.insert(blob, maybe_location.map(|location| location.0.clone())); + + Ok(url.to_string()) +} + +pub fn op_file_revoke_object_url( + state: &mut deno_core::OpState, + url: String, + _zero_copy: Option<ZeroCopyBuf>, +) -> Result<(), AnyError> { + let url = Url::parse(&url)?; + let blob_store = state.borrow::<BlobUrlStore>(); + blob_store.remove(&url); + Ok(()) +} /// Load and execute the javascript code. pub fn init(isolate: &mut JsRuntime) { @@ -11,6 +89,10 @@ pub fn init(isolate: &mut JsRuntime) { "deno:op_crates/file/02_filereader.js", include_str!("02_filereader.js"), ), + ( + "deno:op_crates/file/03_blob_url.js", + include_str!("03_blob_url.js"), + ), ]; for (url, source_code) in files { isolate.execute(url, source_code).unwrap(); diff --git a/op_crates/url/00_url.js b/op_crates/url/00_url.js index 9dd2b7800..bf1ed6059 100644 --- a/op_crates/url/00_url.js +++ b/op_crates/url/00_url.js @@ -389,14 +389,6 @@ toJSON() { return this.href; } - - static createObjectURL() { - throw new Error("Not implemented"); - } - - static revokeObjectURL() { - throw new Error("Not implemented"); - } } window.__bootstrap.url = { diff --git a/op_crates/url/lib.deno_url.d.ts b/op_crates/url/lib.deno_url.d.ts index 2a27fe693..3f9745352 100644 --- a/op_crates/url/lib.deno_url.d.ts +++ b/op_crates/url/lib.deno_url.d.ts @@ -155,8 +155,8 @@ declare class URLSearchParams { /** The URL interface represents an object providing static methods used for creating object URLs. */ declare class URL { constructor(url: string, base?: string | URL); - createObjectURL(object: any): string; - revokeObjectURL(url: string): void; + static createObjectURL(blob: Blob): string; + static revokeObjectURL(url: string): void; hash: string; host: string; |