mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -05:00
fix(ext/web): make CompressionResource garbage collectable (#24884)
This commit is contained in:
parent
646de0f7e2
commit
f0cd2c45fc
1 changed files with 25 additions and 35 deletions
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue