1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(ext/web): make CompressionResource garbage collectable (#24884)

This commit is contained in:
Divy Srivastava 2024-08-06 00:01:11 -07:00 committed by GitHub
parent 646de0f7e2
commit f0cd2c45fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3,10 +3,6 @@
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
use deno_core::ToJsBuffer;
use flate2::write::DeflateDecoder;
use flate2::write::DeflateEncoder;
use flate2::write::GzDecoder;
@ -14,13 +10,13 @@ use flate2::write::GzEncoder;
use flate2::write::ZlibDecoder;
use flate2::write::ZlibEncoder;
use flate2::Compression;
use std::borrow::Cow;
use std::cell::RefCell;
use std::io::Write;
use std::rc::Rc;
#[derive(Debug)]
struct CompressionResource(RefCell<Inner>);
struct CompressionResource(RefCell<Option<Inner>>);
impl deno_core::GarbageCollected for CompressionResource {}
/// https://wicg.github.io/compression/#supported-formats
#[derive(Debug)]
@ -33,19 +29,12 @@ enum Inner {
GzEncoder(GzEncoder<Vec<u8>>),
}
impl Resource for CompressionResource {
fn name(&self) -> Cow<str> {
"compression".into()
}
}
#[op2(fast)]
#[smi]
#[op2]
#[cppgc]
pub fn op_compression_new(
state: &mut OpState,
#[string] format: &str,
is_decoder: bool,
) -> ResourceId {
) -> Result<CompressionResource, AnyError> {
let w = Vec::new();
let inner = match (format, is_decoder) {
("deflate", true) => Inner::DeflateDecoder(ZlibDecoder::new(w)),
@ -60,21 +49,21 @@ pub fn op_compression_new(
("gzip", false) => {
Inner::GzEncoder(GzEncoder::new(w, Compression::default()))
}
_ => unreachable!(),
_ => return Err(type_error("Unsupported format")),
};
let resource = CompressionResource(RefCell::new(inner));
state.resource_table.add(resource)
Ok(CompressionResource(RefCell::new(Some(inner))))
}
#[op2]
#[serde]
#[buffer]
pub fn op_compression_write(
state: &mut OpState,
#[smi] rid: ResourceId,
#[cppgc] resource: &CompressionResource,
#[anybuffer] input: &[u8],
) -> Result<ToJsBuffer, AnyError> {
let resource = state.resource_table.get::<CompressionResource>(rid)?;
) -> Result<Vec<u8>, AnyError> {
let mut inner = resource.0.borrow_mut();
let inner = inner
.as_mut()
.ok_or_else(|| type_error("resource is closed"))?;
let out: Vec<u8> = match &mut *inner {
Inner::DeflateDecoder(d) => {
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
@ -108,19 +97,20 @@ pub fn op_compression_write(
}
}
.collect();
Ok(out.into())
Ok(out)
}
#[op2]
#[serde]
#[buffer]
pub fn op_compression_finish(
state: &mut OpState,
#[smi] rid: ResourceId,
#[cppgc] resource: &CompressionResource,
report_errors: bool,
) -> Result<ToJsBuffer, AnyError> {
let resource = state.resource_table.take::<CompressionResource>(rid)?;
let resource = Rc::try_unwrap(resource).unwrap();
let inner = resource.0.into_inner();
) -> Result<Vec<u8>, AnyError> {
let inner = resource
.0
.borrow_mut()
.take()
.ok_or_else(|| type_error("resource is closed"))?;
let out = match inner {
Inner::DeflateDecoder(d) => {
d.finish().map_err(|e| type_error(e.to_string()))
@ -142,9 +132,9 @@ pub fn op_compression_finish(
if report_errors {
Err(err)
} else {
Ok(Vec::with_capacity(0).into())
Ok(Vec::with_capacity(0))
}
}
Ok(out) => Ok(out.into()),
Ok(out) => Ok(out),
}
}