mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Add zlib module
+ Implement following functions: * zlib.compress * zlib.decompress * zlib.crc32 * zlib.adler32 + Add compression level constants
This commit is contained in:
1 parent
96bd5a693c
commit
128bd8c836
4 files changed
+232
No files matched your search
Generated
+76
@@ -1,5 +1,10 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.10"
|
||||
@@ -263,6 +268,14 @@ dependencies = [
|
||||
"build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.5.0"
|
||||
@@ -399,6 +412,17 @@ dependencies = [
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
@@ -563,6 +587,17 @@ name = "libc"
|
||||
version = "0.2.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
@@ -604,6 +639,25 @@ name = "memchr"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide_c_api"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.3"
|
||||
@@ -725,6 +779,11 @@ dependencies = [
|
||||
"siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
@@ -1045,6 +1104,7 @@ dependencies = [
|
||||
name = "rustpython-vm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arr_macro 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1053,9 +1113,11 @@ dependencies = [
|
||||
"caseless 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flame 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flamer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gethostname 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hexf-parse 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1064,6 +1126,7 @@ dependencies = [
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lexical 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1734,6 +1797,11 @@ name = "utf8parse"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
@@ -1899,6 +1967,7 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
||||
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
|
||||
"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
@@ -1932,6 +2001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
||||
"checksum cpython 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b489034e723e7f5109fecd19b719e664f89ef925be785885252469e9822fa940"
|
||||
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
|
||||
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
|
||||
@@ -1948,6 +2018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum flame 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc2706461e1ee94f55cab2ed2e3d34ae9536cfa830358ef80acff1a3dacab30"
|
||||
"checksum flamer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2add1a5e84b1ed7b5d00cdc21789a28e0a8f4e427b677313c773880ba3c4dac"
|
||||
"checksum flamescope 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e3e6aee625a28b97be4308bccc2eb5f81d9ec606b3f29e13c0f459ce20dd136"
|
||||
"checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
|
||||
@@ -1970,12 +2041,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum lexical 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93de1b2ed9c7f01aac327bf84542a053b6cd15761defdcfaceb27e1d1b871e74"
|
||||
"checksum lexical-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8673fab7063c2cac37d299c8a1a7beb720e78f71500098e4a3c137fdf025bf"
|
||||
"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
|
||||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3"
|
||||
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
|
||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
"checksum md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
|
||||
"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4"
|
||||
"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
|
||||
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
|
||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||
@@ -1991,6 +2065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
|
||||
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af"
|
||||
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
"checksum proc-macro-hack 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "982a35d1194084ba319d65c4a68d24ca28f5fdb5b8bc20899e4eef8641ea5178"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
@@ -2093,6 +2168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"
|
||||
"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
|
||||
"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
@@ -64,6 +64,10 @@ libc = "0.2"
|
||||
nix = "0.14.1"
|
||||
wtf8 = "0.0.3"
|
||||
arr_macro = "0.1.2"
|
||||
crc32fast = "1.2.0"
|
||||
adler32 = "1.0.3"
|
||||
flate2 = { version = "1.0", features = ["zlib"], default-features = false }
|
||||
libz-sys = "1.0.25"
|
||||
|
||||
flame = { version = "0.2", optional = true }
|
||||
flamer = { version = "0.3", optional = true }
|
||||
|
||||
@@ -29,6 +29,7 @@ mod tokenize;
|
||||
mod unicodedata;
|
||||
mod warnings;
|
||||
mod weakref;
|
||||
mod zlib;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -72,6 +73,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||
"_imp".to_string() => Box::new(imp::make_module),
|
||||
"unicodedata".to_string() => Box::new(unicodedata::make_module),
|
||||
"_warnings".to_string() => Box::new(warnings::make_module),
|
||||
"zlib".to_string() => Box::new(zlib::make_module),
|
||||
};
|
||||
|
||||
// Insert parser related modules:
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
use crate::function::OptionalArg;
|
||||
use crate::obj::{objbytes::PyBytesRef, objint::PyIntRef};
|
||||
use crate::pyobject::{create_type, ItemProtocol, PyObjectRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use adler32::RollingAdler32 as Adler32;
|
||||
use crc32fast::Hasher as Crc32;
|
||||
use flate2::{write::ZlibEncoder, Compression, Decompress, FlushDecompress, Status};
|
||||
use libz_sys as libz;
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
// copied from zlibmodule.c (commit 530f506ac91338)
|
||||
const MAX_WBITS: u8 = 15;
|
||||
const DEF_BUF_SIZE: usize = 16 * 1024;
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let zlib_error = create_type("error", &ctx.type_type, &ctx.exceptions.exception_type);
|
||||
|
||||
py_module!(vm, "zlib", {
|
||||
"crc32" => ctx.new_rustfunc(zlib_crc32),
|
||||
"adler32" => ctx.new_rustfunc(zlib_adler32),
|
||||
"compress" => ctx.new_rustfunc(zlib_compress),
|
||||
"decompress" => ctx.new_rustfunc(zlib_decompress),
|
||||
"error" => zlib_error,
|
||||
"Z_DEFAULT_COMPRESSION" => ctx.new_int(libz::Z_DEFAULT_COMPRESSION),
|
||||
"Z_NO_COMPRESSION" => ctx.new_int(libz::Z_NO_COMPRESSION),
|
||||
"Z_BEST_SPEED" => ctx.new_int(libz::Z_BEST_SPEED),
|
||||
"Z_BEST_COMPRESSION" => ctx.new_int(libz::Z_BEST_COMPRESSION),
|
||||
"DEF_BUF_SIZE" => ctx.new_int(DEF_BUF_SIZE),
|
||||
"MAX_WBITS" => ctx.new_int(MAX_WBITS),
|
||||
})
|
||||
}
|
||||
|
||||
macro_rules! checksum_fn {
|
||||
($fn_name: ident, $h_new: expr, $h_update: expr, $h_compute: expr, $begin_state: expr) => {
|
||||
fn $fn_name(
|
||||
data: PyBytesRef,
|
||||
begin_state: OptionalArg<PyIntRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyObjectRef> {
|
||||
let data = data.get_value();
|
||||
|
||||
let begin_state = begin_state
|
||||
.into_option()
|
||||
.as_ref()
|
||||
.map(|v| v.as_bigint().to_i32().unwrap())
|
||||
.unwrap_or($begin_state);
|
||||
|
||||
let mut hasher = $h_new(begin_state as u32);
|
||||
$h_update(&mut hasher, &data);
|
||||
|
||||
let checksum: u32 = $h_compute(hasher);
|
||||
|
||||
Ok(vm.new_int(checksum))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
checksum_fn!(
|
||||
zlib_adler32,
|
||||
|value| Adler32::from_value(value),
|
||||
|hasher: &mut Adler32, buffer| hasher.update_buffer(buffer),
|
||||
|hasher: Adler32| hasher.hash(),
|
||||
1
|
||||
);
|
||||
|
||||
checksum_fn!(
|
||||
zlib_crc32,
|
||||
|value| Crc32::new_with_initial(value),
|
||||
|hasher: &mut Crc32, buffer| hasher.update(buffer),
|
||||
|hasher: Crc32| hasher.finalize(),
|
||||
0
|
||||
);
|
||||
|
||||
/// Returns a bytes object containing compressed data.
|
||||
fn zlib_compress(
|
||||
data: PyBytesRef,
|
||||
level: OptionalArg<PyIntRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyObjectRef> {
|
||||
let input_bytes = data.get_value();
|
||||
|
||||
let level = level
|
||||
.into_option()
|
||||
.as_ref()
|
||||
.map(|v| v.as_bigint().to_i32().unwrap())
|
||||
.unwrap_or(libz::Z_DEFAULT_COMPRESSION);
|
||||
|
||||
let compression = match level {
|
||||
valid_level @ libz::Z_NO_COMPRESSION...libz::Z_BEST_COMPRESSION => {
|
||||
Compression::new(valid_level as u32)
|
||||
}
|
||||
libz::Z_DEFAULT_COMPRESSION => Compression::default(),
|
||||
_ => return Err(zlib_error("Bad compression level", vm)),
|
||||
};
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), compression);
|
||||
encoder.write_all(input_bytes).unwrap();
|
||||
let encoded_bytes = encoder.finish().unwrap();
|
||||
|
||||
Ok(vm.ctx.new_bytes(encoded_bytes))
|
||||
}
|
||||
|
||||
/// Returns a bytes object containing the uncompressed data.
|
||||
fn zlib_decompress(
|
||||
data: PyBytesRef,
|
||||
wbits: OptionalArg<PyIntRef>,
|
||||
bufsize: OptionalArg<PyIntRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyObjectRef> {
|
||||
let encoded_bytes = data.get_value();
|
||||
|
||||
let wbits = wbits
|
||||
.into_option()
|
||||
.as_ref()
|
||||
.map(|wbits| wbits.as_bigint().to_u8().unwrap())
|
||||
.unwrap_or(MAX_WBITS);
|
||||
|
||||
let bufsize = bufsize
|
||||
.into_option()
|
||||
.as_ref()
|
||||
.map(|bufsize| bufsize.as_bigint().to_usize().unwrap())
|
||||
.unwrap_or(DEF_BUF_SIZE);
|
||||
|
||||
let mut decompressor = Decompress::new_with_window_bits(true, wbits);
|
||||
let mut decoded_bytes = Vec::with_capacity(bufsize);
|
||||
|
||||
match decompressor.decompress_vec(&encoded_bytes, &mut decoded_bytes, FlushDecompress::Finish) {
|
||||
Ok(Status::BufError) => Err(zlib_error("inconsistent or truncated state", vm)),
|
||||
Err(_) => Err(zlib_error("invalid input data", vm)),
|
||||
_ => Ok(vm.ctx.new_bytes(decoded_bytes)),
|
||||
}
|
||||
}
|
||||
|
||||
fn zlib_error(message: &str, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let module = vm
|
||||
.get_attribute(vm.sys_module.clone(), "modules")
|
||||
.unwrap()
|
||||
.get_item("zlib", vm)
|
||||
.unwrap();
|
||||
|
||||
let zlib_error = vm.get_attribute(module, "error").unwrap();
|
||||
let zlib_error = zlib_error.downcast().unwrap();
|
||||
|
||||
vm.new_exception(zlib_error, message.to_string())
|
||||
}
|
||||
Reference in new issue
Block a user