summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/node/lib.rs1
-rw-r--r--ext/node/ops/zlib/mod.rs10
-rw-r--r--ext/node/polyfills/zlib.ts53
3 files changed, 64 insertions, 0 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index 9ca21e994..6d320b92c 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -345,6 +345,7 @@ deno_core::extension!(deno_node,
ops::zlib::op_zlib_write,
ops::zlib::op_zlib_init,
ops::zlib::op_zlib_reset,
+ ops::zlib::op_zlib_crc32,
ops::zlib::brotli::op_brotli_compress,
ops::zlib::brotli::op_brotli_compress_async,
ops::zlib::brotli::op_create_brotli_compress,
diff --git a/ext/node/ops/zlib/mod.rs b/ext/node/ops/zlib/mod.rs
index e75ef050d..991c0925d 100644
--- a/ext/node/ops/zlib/mod.rs
+++ b/ext/node/ops/zlib/mod.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::op2;
+use libc::c_ulong;
use std::borrow::Cow;
use std::cell::RefCell;
use zlib::*;
@@ -381,6 +382,15 @@ pub fn op_zlib_close_if_pending(
Ok(())
}
+#[op2(fast)]
+#[smi]
+pub fn op_zlib_crc32(#[buffer] data: &[u8], #[smi] value: u32) -> u32 {
+ // SAFETY: `data` is a valid buffer.
+ unsafe {
+ zlib::crc32(value as c_ulong, data.as_ptr(), data.len() as u32) as u32
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/ext/node/polyfills/zlib.ts b/ext/node/polyfills/zlib.ts
index 3fe5f8bbd..6e5d02b5b 100644
--- a/ext/node/polyfills/zlib.ts
+++ b/ext/node/polyfills/zlib.ts
@@ -40,6 +40,58 @@ import {
createBrotliCompress,
createBrotliDecompress,
} from "ext:deno_node/_brotli.js";
+import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts";
+import { validateUint32 } from "ext:deno_node/internal/validators.mjs";
+import { op_zlib_crc32 } from "ext:core/ops";
+import { core, primordials } from "ext:core/mod.js";
+import { TextEncoder } from "ext:deno_web/08_text_encoding.js";
+const {
+ Uint8Array,
+ TypedArrayPrototypeGetBuffer,
+ TypedArrayPrototypeGetByteLength,
+ TypedArrayPrototypeGetByteOffset,
+ DataViewPrototypeGetBuffer,
+ DataViewPrototypeGetByteLength,
+ DataViewPrototypeGetByteOffset,
+} = primordials;
+const { isTypedArray, isDataView } = core;
+
+const enc = new TextEncoder();
+const toU8 = (input) => {
+ if (typeof input === "string") {
+ return enc.encode(input);
+ }
+
+ if (isTypedArray(input)) {
+ return new Uint8Array(
+ TypedArrayPrototypeGetBuffer(input),
+ TypedArrayPrototypeGetByteOffset(input),
+ TypedArrayPrototypeGetByteLength(input),
+ );
+ } else if (isDataView(input)) {
+ return new Uint8Array(
+ DataViewPrototypeGetBuffer(input),
+ DataViewPrototypeGetByteOffset(input),
+ DataViewPrototypeGetByteLength(input),
+ );
+ }
+
+ return input;
+};
+
+export function crc32(data, value = 0) {
+ if (typeof data !== "string" && !isArrayBufferView(data)) {
+ throw new ERR_INVALID_ARG_TYPE("data", [
+ "Buffer",
+ "TypedArray",
+ "DataView",
+ "string",
+ ], data);
+ }
+ validateUint32(value, "value");
+
+ return op_zlib_crc32(toU8(data), value);
+}
export class Options {
constructor() {
@@ -87,6 +139,7 @@ export default {
BrotliOptions,
codes,
constants,
+ crc32,
createBrotliCompress,
createBrotliDecompress,
createDeflate,