mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #1243 from mpajkowski/zlib_module
Implement zlib module
This commit is contained in:
76
Cargo.lock
generated
76
Cargo.lock
generated
@@ -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"
|
||||
|
||||
62
tests/snippets/stdlib_zlib.py
Normal file
62
tests/snippets/stdlib_zlib.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import zlib
|
||||
from testutils import assert_raises
|
||||
|
||||
# checksum functions
|
||||
assert zlib.crc32(b"123") == 2286445522
|
||||
assert zlib.crc32(b"123", 1) == 2307525093
|
||||
assert zlib.crc32(b"123", 2) == 2345449404
|
||||
assert zlib.crc32(b"123", 3) == 2316230027
|
||||
assert zlib.crc32(b"123", 4) == 2403453710
|
||||
assert zlib.crc32(b"123", 5) == 2390991161
|
||||
assert zlib.crc32(b"123", 6) == 2361728864
|
||||
assert zlib.crc32(b"123", -123) == 3515918521
|
||||
assert zlib.crc32(b"123", -122) == 3554023136
|
||||
assert zlib.crc32(b"123", -121) == 3524558039
|
||||
assert zlib.crc32(b"123", -120) == 3645389802
|
||||
assert zlib.crc32(b"123", -119) == 3632943581
|
||||
assert zlib.crc32(b"123", -118) == 3670863748
|
||||
assert zlib.crc32(b"123") == zlib.crc32(b"123", 0)
|
||||
|
||||
assert zlib.adler32(b"456") == 20906144
|
||||
assert zlib.adler32(b"456", 1) == 20906144
|
||||
assert zlib.adler32(b"456", 2) == 21102753
|
||||
assert zlib.adler32(b"456", 3) == 21299362
|
||||
assert zlib.adler32(b"456", 4) == 21495971
|
||||
assert zlib.adler32(b"456", 5) == 21692580
|
||||
assert zlib.adler32(b"456", 6) == 21889189
|
||||
assert zlib.adler32(b"456", -123) == 393267
|
||||
assert zlib.adler32(b"456", -122) == 589876
|
||||
assert zlib.adler32(b"456", -121) == 786485
|
||||
assert zlib.adler32(b"456", -120) == 983094
|
||||
assert zlib.adler32(b"456", -119) == 1179703
|
||||
assert zlib.adler32(b"456", -118) == 1376312
|
||||
assert zlib.adler32(b"456") == zlib.adler32(b"456", 1)
|
||||
|
||||
# compression
|
||||
lorem = bytes("Lorem ipsum dolor sit amet", "utf-8")
|
||||
|
||||
compressed_lorem_list = [
|
||||
b"x\x01\x01\x1a\x00\xe5\xffLorem ipsum dolor sit amet\x83\xd5\t\xc5",
|
||||
b"x\x01\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x\x9c\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
||||
]
|
||||
|
||||
for level, text in enumerate(compressed_lorem_list):
|
||||
assert zlib.compress(lorem, level) == text
|
||||
|
||||
# default level
|
||||
assert zlib.compress(lorem) == zlib.compress(lorem, -1) == zlib.compress(lorem, 6)
|
||||
|
||||
# decompression
|
||||
for text in compressed_lorem_list:
|
||||
assert zlib.decompress(text) == lorem
|
||||
|
||||
assert_raises(zlib.error, lambda: zlib.compress(b"123", -40))
|
||||
assert_raises(zlib.error, lambda: zlib.compress(b"123", 10))
|
||||
@@ -72,5 +72,9 @@ flamer = { version = "0.3", optional = true }
|
||||
pwd = "1"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
crc32fast = "1.2.0"
|
||||
adler32 = "1.0.3"
|
||||
flate2 = { version = "1.0", features = ["zlib"], default-features = false }
|
||||
libz-sys = "1.0.25"
|
||||
gethostname = "0.2.0"
|
||||
subprocess = "0.1.18"
|
||||
|
||||
@@ -43,6 +43,8 @@ mod pwd;
|
||||
pub mod signal;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod subprocess;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod zlib;
|
||||
|
||||
use crate::pyobject::PyObjectRef;
|
||||
|
||||
@@ -99,6 +101,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||
modules.insert("socket".to_string(), Box::new(socket::make_module));
|
||||
modules.insert("signal".to_string(), Box::new(signal::make_module));
|
||||
modules.insert("subprocess".to_string(), Box::new(subprocess::make_module));
|
||||
modules.insert("zlib".to_string(), Box::new(zlib::make_module));
|
||||
}
|
||||
|
||||
// Unix-only
|
||||
|
||||
153
vm/src/stdlib/zlib.rs
Normal file
153
vm/src/stdlib/zlib.rs
Normal file
@@ -0,0 +1,153 @@
|
||||
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),
|
||||
})
|
||||
}
|
||||
|
||||
/// Compute an Adler-32 checksum of data.
|
||||
fn zlib_adler32(
|
||||
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(1);
|
||||
|
||||
let mut hasher = Adler32::from_value(begin_state as u32);
|
||||
hasher.update_buffer(data);
|
||||
|
||||
let checksum: u32 = hasher.hash();
|
||||
|
||||
Ok(vm.new_int(checksum))
|
||||
}
|
||||
|
||||
/// Compute a CRC-32 checksum of data.
|
||||
fn zlib_crc32(
|
||||
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(0);
|
||||
|
||||
let mut hasher = Crc32::new_with_initial(begin_state as u32);
|
||||
hasher.update(data);
|
||||
|
||||
let checksum: u32 = hasher.finalize();
|
||||
|
||||
Ok(vm.new_int(checksum))
|
||||
}
|
||||
|
||||
/// 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