summaryrefslogtreecommitdiff
path: root/op_crates
diff options
context:
space:
mode:
Diffstat (limited to 'op_crates')
-rw-r--r--op_crates/file/03_blob_url.js63
-rw-r--r--op_crates/file/Cargo.toml1
-rw-r--r--op_crates/file/lib.rs82
-rw-r--r--op_crates/url/00_url.js8
-rw-r--r--op_crates/url/lib.deno_url.d.ts4
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;