2024-01-01 19:58:21 +00:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2022-01-24 17:03:06 +00:00
|
|
|
|
2023-07-30 13:15:29 +00:00
|
|
|
use deno_core::error::type_error;
|
2022-01-24 17:03:06 +00:00
|
|
|
use deno_core::error::AnyError;
|
2023-10-05 12:34:38 +00:00
|
|
|
use deno_core::op2;
|
2022-01-24 17:03:06 +00:00
|
|
|
use deno_core::OpState;
|
|
|
|
use deno_core::Resource;
|
|
|
|
use deno_core::ResourceId;
|
2023-06-22 21:37:56 +00:00
|
|
|
use deno_core::ToJsBuffer;
|
2022-06-14 16:10:28 +00:00
|
|
|
use flate2::write::DeflateDecoder;
|
|
|
|
use flate2::write::DeflateEncoder;
|
2022-01-24 17:03:06 +00:00
|
|
|
use flate2::write::GzDecoder;
|
|
|
|
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>);
|
|
|
|
|
2022-06-14 16:10:28 +00:00
|
|
|
/// https://wicg.github.io/compression/#supported-formats
|
2022-01-24 17:03:06 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
enum Inner {
|
|
|
|
DeflateDecoder(ZlibDecoder<Vec<u8>>),
|
|
|
|
DeflateEncoder(ZlibEncoder<Vec<u8>>),
|
2022-06-14 16:10:28 +00:00
|
|
|
DeflateRawDecoder(DeflateDecoder<Vec<u8>>),
|
|
|
|
DeflateRawEncoder(DeflateEncoder<Vec<u8>>),
|
2022-01-24 17:03:06 +00:00
|
|
|
GzDecoder(GzDecoder<Vec<u8>>),
|
|
|
|
GzEncoder(GzEncoder<Vec<u8>>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resource for CompressionResource {
|
|
|
|
fn name(&self) -> Cow<str> {
|
|
|
|
"compression".into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-05 12:34:38 +00:00
|
|
|
#[op2(fast)]
|
|
|
|
#[smi]
|
2022-01-24 17:03:06 +00:00
|
|
|
pub fn op_compression_new(
|
|
|
|
state: &mut OpState,
|
2023-10-05 12:34:38 +00:00
|
|
|
#[string] format: &str,
|
2022-01-24 17:03:06 +00:00
|
|
|
is_decoder: bool,
|
2022-05-13 08:36:31 +00:00
|
|
|
) -> ResourceId {
|
2022-01-24 17:03:06 +00:00
|
|
|
let w = Vec::new();
|
2023-03-03 13:34:10 +00:00
|
|
|
let inner = match (format, is_decoder) {
|
2022-01-24 17:03:06 +00:00
|
|
|
("deflate", true) => Inner::DeflateDecoder(ZlibDecoder::new(w)),
|
|
|
|
("deflate", false) => {
|
|
|
|
Inner::DeflateEncoder(ZlibEncoder::new(w, Compression::default()))
|
|
|
|
}
|
2022-06-14 16:10:28 +00:00
|
|
|
("deflate-raw", true) => Inner::DeflateRawDecoder(DeflateDecoder::new(w)),
|
|
|
|
("deflate-raw", false) => {
|
|
|
|
Inner::DeflateRawEncoder(DeflateEncoder::new(w, Compression::default()))
|
|
|
|
}
|
2022-01-24 17:03:06 +00:00
|
|
|
("gzip", true) => Inner::GzDecoder(GzDecoder::new(w)),
|
|
|
|
("gzip", false) => {
|
|
|
|
Inner::GzEncoder(GzEncoder::new(w, Compression::default()))
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
let resource = CompressionResource(RefCell::new(inner));
|
2022-05-13 08:36:31 +00:00
|
|
|
state.resource_table.add(resource)
|
2022-01-24 17:03:06 +00:00
|
|
|
}
|
|
|
|
|
2023-10-05 12:34:38 +00:00
|
|
|
#[op2]
|
|
|
|
#[serde]
|
2022-01-24 17:03:06 +00:00
|
|
|
pub fn op_compression_write(
|
|
|
|
state: &mut OpState,
|
2023-10-05 12:34:38 +00:00
|
|
|
#[smi] rid: ResourceId,
|
|
|
|
#[anybuffer] input: &[u8],
|
2023-06-22 21:37:56 +00:00
|
|
|
) -> Result<ToJsBuffer, AnyError> {
|
2022-01-24 17:03:06 +00:00
|
|
|
let resource = state.resource_table.get::<CompressionResource>(rid)?;
|
|
|
|
let mut inner = resource.0.borrow_mut();
|
|
|
|
let out: Vec<u8> = match &mut *inner {
|
|
|
|
Inner::DeflateDecoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-01-24 17:03:06 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
|
|
|
Inner::DeflateEncoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-01-24 17:03:06 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
2022-06-14 16:10:28 +00:00
|
|
|
Inner::DeflateRawDecoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-06-14 16:10:28 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
|
|
|
Inner::DeflateRawEncoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-06-14 16:10:28 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
2022-01-24 17:03:06 +00:00
|
|
|
Inner::GzDecoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-01-24 17:03:06 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
|
|
|
Inner::GzEncoder(d) => {
|
2023-07-30 13:15:29 +00:00
|
|
|
d.write_all(input).map_err(|e| type_error(e.to_string()))?;
|
2022-01-24 17:03:06 +00:00
|
|
|
d.flush()?;
|
|
|
|
d.get_mut().drain(..)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.collect();
|
|
|
|
Ok(out.into())
|
|
|
|
}
|
|
|
|
|
2023-10-05 12:34:38 +00:00
|
|
|
#[op2]
|
|
|
|
#[serde]
|
2022-01-24 17:03:06 +00:00
|
|
|
pub fn op_compression_finish(
|
|
|
|
state: &mut OpState,
|
2023-10-05 12:34:38 +00:00
|
|
|
#[smi] rid: ResourceId,
|
2024-02-13 21:45:23 +00:00
|
|
|
report_errors: bool,
|
2023-06-22 21:37:56 +00:00
|
|
|
) -> Result<ToJsBuffer, AnyError> {
|
2022-01-24 17:03:06 +00:00
|
|
|
let resource = state.resource_table.take::<CompressionResource>(rid)?;
|
|
|
|
let resource = Rc::try_unwrap(resource).unwrap();
|
|
|
|
let inner = resource.0.into_inner();
|
2024-02-13 21:45:23 +00:00
|
|
|
let out = match inner {
|
2023-07-30 13:15:29 +00:00
|
|
|
Inner::DeflateDecoder(d) => {
|
2024-02-13 21:45:23 +00:00
|
|
|
d.finish().map_err(|e| type_error(e.to_string()))
|
2023-07-30 13:15:29 +00:00
|
|
|
}
|
|
|
|
Inner::DeflateEncoder(d) => {
|
2024-02-13 21:45:23 +00:00
|
|
|
d.finish().map_err(|e| type_error(e.to_string()))
|
2023-07-30 13:15:29 +00:00
|
|
|
}
|
|
|
|
Inner::DeflateRawDecoder(d) => {
|
2024-02-13 21:45:23 +00:00
|
|
|
d.finish().map_err(|e| type_error(e.to_string()))
|
2023-07-30 13:15:29 +00:00
|
|
|
}
|
|
|
|
Inner::DeflateRawEncoder(d) => {
|
2024-02-13 21:45:23 +00:00
|
|
|
d.finish().map_err(|e| type_error(e.to_string()))
|
2023-07-30 13:15:29 +00:00
|
|
|
}
|
2024-02-13 21:45:23 +00:00
|
|
|
Inner::GzDecoder(d) => d.finish().map_err(|e| type_error(e.to_string())),
|
|
|
|
Inner::GzEncoder(d) => d.finish().map_err(|e| type_error(e.to_string())),
|
2022-01-24 17:03:06 +00:00
|
|
|
};
|
2024-02-13 21:45:23 +00:00
|
|
|
match out {
|
|
|
|
Err(err) => {
|
|
|
|
if report_errors {
|
|
|
|
Err(err)
|
|
|
|
} else {
|
|
|
|
Ok(Vec::with_capacity(0).into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(out) => Ok(out.into()),
|
|
|
|
}
|
2022-01-24 17:03:06 +00:00
|
|
|
}
|