From 6784c185c7e93920688ab253977d91a9aadfa502 Mon Sep 17 00:00:00 2001 From: Thunderbird Updatebot Date: Tue, 3 Sep 2024 09:52:26 +0000 Subject: [PATCH] Bug 1878375 - Synchronize vendored Rust libraries with mozilla-central. r=darktrojan mozilla-central: d0336fee53a3e4eaee3e4db7c46245b9363084df comm-central: f4b49deb8b6ede47bec8c6d4571069aba42e2b6f Differential Revision: https://phabricator.services.mozilla.com/D220862 --HG-- extra : amend_source : 292d7a1d0bf788fb7491c8763fd733ce99d562e1 --- rust/.cargo/config.toml.in | 5 + rust/Cargo.lock | 14 + rust/checksums.json | 2 +- rust/gkrust/Cargo.toml | 3 +- .../rust/aa-stroke/.cargo-checksum.json | 2 +- third_party/rust/aa-stroke/Cargo.toml | 17 + .../any_all_workaround/.cargo-checksum.json | 2 +- .../rust/any_all_workaround/Cargo.toml | 14 + .../audioipc2-client/.cargo-checksum.json | 2 +- third_party/rust/audioipc2-client/Cargo.toml | 15 + .../audioipc2-server/.cargo-checksum.json | 2 +- third_party/rust/audioipc2-server/Cargo.toml | 15 + .../rust/audioipc2/.cargo-checksum.json | 2 +- third_party/rust/audioipc2/Cargo.toml | 19 +- .../rust/chardetng/.cargo-checksum.json | 2 +- third_party/rust/chardetng/Cargo.toml | 14 + .../rust/chardetng_c/.cargo-checksum.json | 2 +- third_party/rust/chardetng_c/Cargo.toml | 14 + .../coreaudio-sys-utils/.cargo-checksum.json | 2 +- .../rust/coreaudio-sys-utils/Cargo.toml | 15 + .../rust/coremidi/.cargo-checksum.json | 2 +- third_party/rust/coremidi/Cargo.toml | 41 + third_party/rust/cose/.cargo-checksum.json | 2 +- third_party/rust/cose/Cargo.toml | 12 + .../rust/cubeb-coreaudio/.cargo-checksum.json | 2 +- third_party/rust/cubeb-coreaudio/Cargo.toml | 12 + .../rust/cubeb-pulse/.cargo-checksum.json | 2 +- third_party/rust/cubeb-pulse/Cargo.toml | 12 + .../error-support-macros/.cargo-checksum.json | 2 +- .../rust/error-support-macros/Cargo.toml | 13 + .../rust/error-support/.cargo-checksum.json | 2 +- third_party/rust/error-support/Cargo.toml | 17 +- third_party/rust/ews/.cargo-checksum.json | 2 +- third_party/rust/ews/Cargo.toml | 14 + .../gpu-descriptor-types/.cargo-checksum.json | 2 +- .../rust/gpu-descriptor-types/Cargo.toml | 15 + .../rust/gpu-descriptor/.cargo-checksum.json | 2 +- third_party/rust/gpu-descriptor/Cargo.toml | 14 + .../interrupt-support/.cargo-checksum.json | 2 +- third_party/rust/interrupt-support/Cargo.toml | 18 +- .../rust/jsparagus-ast/.cargo-checksum.json | 2 +- third_party/rust/jsparagus-ast/Cargo.toml | 15 + .../jsparagus-emitter/.cargo-checksum.json | 2 +- third_party/rust/jsparagus-emitter/Cargo.toml | 15 + .../.cargo-checksum.json | 2 +- .../jsparagus-generated-parser/Cargo.toml | 15 + .../jsparagus-json-log/.cargo-checksum.json | 2 +- .../rust/jsparagus-json-log/Cargo.toml | 15 + .../jsparagus-parser/.cargo-checksum.json | 2 +- third_party/rust/jsparagus-parser/Cargo.toml | 15 + .../rust/jsparagus-scope/.cargo-checksum.json | 2 +- third_party/rust/jsparagus-scope/Cargo.toml | 15 + .../jsparagus-stencil/.cargo-checksum.json | 2 +- third_party/rust/jsparagus-stencil/Cargo.toml | 15 + .../rust/jsparagus/.cargo-checksum.json | 2 +- third_party/rust/jsparagus/Cargo.toml | 11 + .../rust/libz-rs-sys/.cargo-checksum.json | 1 + third_party/rust/libz-rs-sys/Cargo.toml | 52 + third_party/rust/libz-rs-sys/LICENSE | 19 + third_party/rust/libz-rs-sys/README.md | 90 + third_party/rust/libz-rs-sys/src/lib.rs | 1668 +++++++ .../rust/mapped_hyph/.cargo-checksum.json | 2 +- third_party/rust/mapped_hyph/Cargo.toml | 24 + third_party/rust/midir/.cargo-checksum.json | 2 +- third_party/rust/midir/Cargo.toml | 50 +- .../rust/mp4parse/.cargo-checksum.json | 2 +- third_party/rust/mp4parse/Cargo.toml | 19 + .../rust/mp4parse_capi/.cargo-checksum.json | 2 +- third_party/rust/mp4parse_capi/Cargo.toml | 44 + third_party/rust/naga/.cargo-checksum.json | 2 +- third_party/rust/naga/Cargo.toml | 44 +- .../rust/neqo-bin/.cargo-checksum.json | 2 +- third_party/rust/neqo-bin/Cargo.toml | 11 + .../rust/neqo-common/.cargo-checksum.json | 2 +- third_party/rust/neqo-common/Cargo.toml | 15 + .../rust/neqo-crypto/.cargo-checksum.json | 2 +- third_party/rust/neqo-crypto/Cargo.toml | 43 + .../rust/neqo-http3/.cargo-checksum.json | 2 +- third_party/rust/neqo-http3/Cargo.toml | 27 + .../rust/neqo-qpack/.cargo-checksum.json | 2 +- third_party/rust/neqo-qpack/Cargo.toml | 12 + .../rust/neqo-transport/.cargo-checksum.json | 2 +- third_party/rust/neqo-transport/Cargo.toml | 37 +- .../rust/neqo-udp/.cargo-checksum.json | 2 +- third_party/rust/neqo-udp/Cargo.toml | 12 + .../nss_build_common/.cargo-checksum.json | 2 +- third_party/rust/nss_build_common/Cargo.toml | 15 + .../rust/payload-support/.cargo-checksum.json | 2 +- third_party/rust/payload-support/Cargo.toml | 15 + .../rust/pulse-ffi/.cargo-checksum.json | 2 +- third_party/rust/pulse-ffi/Cargo.toml | 15 + third_party/rust/pulse/.cargo-checksum.json | 2 +- third_party/rust/pulse/Cargo.toml | 15 + .../rust/relevancy/.cargo-checksum.json | 2 +- third_party/rust/relevancy/Cargo.toml | 17 +- .../rust/remote_settings/.cargo-checksum.json | 2 +- third_party/rust/remote_settings/Cargo.toml | 19 +- .../rust/sql-support/.cargo-checksum.json | 2 +- third_party/rust/sql-support/Cargo.toml | 15 + third_party/rust/suggest/.cargo-checksum.json | 2 +- third_party/rust/suggest/Cargo.toml | 16 +- .../rust/sync-guid/.cargo-checksum.json | 2 +- third_party/rust/sync-guid/Cargo.toml | 15 + third_party/rust/sync15/.cargo-checksum.json | 2 +- third_party/rust/sync15/Cargo.toml | 18 +- third_party/rust/tabs/.cargo-checksum.json | 2 +- third_party/rust/tabs/Cargo.toml | 18 +- third_party/rust/types/.cargo-checksum.json | 2 +- third_party/rust/types/Cargo.toml | 15 + .../rust/unicode-bidi/.cargo-checksum.json | 2 +- third_party/rust/unicode-bidi/Cargo.toml | 20 + third_party/rust/viaduct/.cargo-checksum.json | 2 +- third_party/rust/viaduct/Cargo.toml | 12 + .../rust/webext-storage/.cargo-checksum.json | 2 +- third_party/rust/webext-storage/Cargo.toml | 22 +- .../rust/wgpu-core/.cargo-checksum.json | 2 +- third_party/rust/wgpu-core/Cargo.toml | 61 +- .../rust/wgpu-hal/.cargo-checksum.json | 2 +- third_party/rust/wgpu-hal/Cargo.toml | 123 +- .../rust/wgpu-types/.cargo-checksum.json | 2 +- third_party/rust/wgpu-types/Cargo.toml | 29 +- .../rust/wpf-gpu-raster/.cargo-checksum.json | 2 +- third_party/rust/wpf-gpu-raster/Cargo.toml | 25 + .../rust/xml_struct/.cargo-checksum.json | 2 +- third_party/rust/xml_struct/Cargo.toml | 15 + .../xml_struct_derive/.cargo-checksum.json | 2 +- third_party/rust/xml_struct_derive/Cargo.toml | 13 + third_party/rust/zlib-rs/.cargo-checksum.json | 1 + third_party/rust/zlib-rs/Cargo.toml | 73 + third_party/rust/zlib-rs/LICENSE | 19 + third_party/rust/zlib-rs/README.md | 6 + third_party/rust/zlib-rs/src/adler32.rs | 133 + third_party/rust/zlib-rs/src/adler32/avx2.rs | 257 + .../rust/zlib-rs/src/adler32/generic.rs | 136 + third_party/rust/zlib-rs/src/adler32/neon.rs | 242 + third_party/rust/zlib-rs/src/allocate.rs | 353 ++ third_party/rust/zlib-rs/src/c_api.rs | 228 + third_party/rust/zlib-rs/src/cpu_features.rs | 67 + third_party/rust/zlib-rs/src/crc32.rs | 262 ++ third_party/rust/zlib-rs/src/crc32/acle.rs | 201 + third_party/rust/zlib-rs/src/crc32/braid.rs | 202 + third_party/rust/zlib-rs/src/crc32/combine.rs | 115 + .../rust/zlib-rs/src/crc32/pclmulqdq.rs | 342 ++ third_party/rust/zlib-rs/src/deflate.rs | 4146 +++++++++++++++++ .../zlib-rs/src/deflate/algorithm/fast.rs | 109 + .../zlib-rs/src/deflate/algorithm/huff.rs | 45 + .../zlib-rs/src/deflate/algorithm/medium.rs | 339 ++ .../rust/zlib-rs/src/deflate/algorithm/mod.rs | 82 + .../zlib-rs/src/deflate/algorithm/quick.rs | 145 + .../rust/zlib-rs/src/deflate/algorithm/rle.rs | 83 + .../zlib-rs/src/deflate/algorithm/slow.rs | 160 + .../zlib-rs/src/deflate/algorithm/stored.rs | 273 ++ .../rust/zlib-rs/src/deflate/compare256.rs | 221 + .../rust/zlib-rs/src/deflate/hash_calc.rs | 295 ++ .../rust/zlib-rs/src/deflate/longest_match.rs | 359 ++ .../rust/zlib-rs/src/deflate/pending.rs | 95 + .../rust/zlib-rs/src/deflate/slide_hash.rs | 164 + .../deflate/test-data/inflate_buf_error.dat | Bin 0 -> 67008 bytes .../src/deflate/test-data/paper-100k.pdf | 598 +++ .../rust/zlib-rs/src/deflate/trees_tbl.rs | 140 + .../rust/zlib-rs/src/deflate/window.rs | 141 + third_party/rust/zlib-rs/src/inflate.rs | 2271 +++++++++ .../rust/zlib-rs/src/inflate/bitreader.rs | 203 + .../rust/zlib-rs/src/inflate/inffixed_tbl.rs | 555 +++ .../rust/zlib-rs/src/inflate/inftrees.rs | 358 ++ .../rust/zlib-rs/src/inflate/window.rs | 267 ++ third_party/rust/zlib-rs/src/lib.rs | 223 + third_party/rust/zlib-rs/src/read_buf.rs | 409 ++ 168 files changed, 17396 insertions(+), 152 deletions(-) create mode 100644 third_party/rust/libz-rs-sys/.cargo-checksum.json create mode 100644 third_party/rust/libz-rs-sys/Cargo.toml create mode 100644 third_party/rust/libz-rs-sys/LICENSE create mode 100644 third_party/rust/libz-rs-sys/README.md create mode 100644 third_party/rust/libz-rs-sys/src/lib.rs create mode 100644 third_party/rust/zlib-rs/.cargo-checksum.json create mode 100644 third_party/rust/zlib-rs/Cargo.toml create mode 100644 third_party/rust/zlib-rs/LICENSE create mode 100644 third_party/rust/zlib-rs/README.md create mode 100644 third_party/rust/zlib-rs/src/adler32.rs create mode 100644 third_party/rust/zlib-rs/src/adler32/avx2.rs create mode 100644 third_party/rust/zlib-rs/src/adler32/generic.rs create mode 100644 third_party/rust/zlib-rs/src/adler32/neon.rs create mode 100644 third_party/rust/zlib-rs/src/allocate.rs create mode 100644 third_party/rust/zlib-rs/src/c_api.rs create mode 100644 third_party/rust/zlib-rs/src/cpu_features.rs create mode 100644 third_party/rust/zlib-rs/src/crc32.rs create mode 100644 third_party/rust/zlib-rs/src/crc32/acle.rs create mode 100644 third_party/rust/zlib-rs/src/crc32/braid.rs create mode 100644 third_party/rust/zlib-rs/src/crc32/combine.rs create mode 100644 third_party/rust/zlib-rs/src/crc32/pclmulqdq.rs create mode 100644 third_party/rust/zlib-rs/src/deflate.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/fast.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/huff.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/medium.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/mod.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/quick.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/rle.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/slow.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/algorithm/stored.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/compare256.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/hash_calc.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/longest_match.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/pending.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/slide_hash.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/test-data/inflate_buf_error.dat create mode 100644 third_party/rust/zlib-rs/src/deflate/test-data/paper-100k.pdf create mode 100644 third_party/rust/zlib-rs/src/deflate/trees_tbl.rs create mode 100644 third_party/rust/zlib-rs/src/deflate/window.rs create mode 100644 third_party/rust/zlib-rs/src/inflate.rs create mode 100644 third_party/rust/zlib-rs/src/inflate/bitreader.rs create mode 100644 third_party/rust/zlib-rs/src/inflate/inffixed_tbl.rs create mode 100644 third_party/rust/zlib-rs/src/inflate/inftrees.rs create mode 100644 third_party/rust/zlib-rs/src/inflate/window.rs create mode 100644 third_party/rust/zlib-rs/src/lib.rs create mode 100644 third_party/rust/zlib-rs/src/read_buf.rs diff --git a/rust/.cargo/config.toml.in b/rust/.cargo/config.toml.in index 6a29a37189..7f875e8e39 100644 --- a/rust/.cargo/config.toml.in +++ b/rust/.cargo/config.toml.in @@ -46,6 +46,11 @@ git = "https://github.com/jfkthame/mapped_hyph.git" rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b" replace-with = "vendored-sources" +[source."git+https://github.com/memorysafety/zlib-rs?rev=4aa430ccb77537d0d60dab8db993ca51bb1194c5"] +git = "https://github.com/memorysafety/zlib-rs" +rev = "4aa430ccb77537d0d60dab8db993ca51bb1194c5" +replace-with = "vendored-sources" + [source."git+https://github.com/mozilla-spidermonkey/jsparagus?rev=61f399c53a641ebd3077c1f39f054f6d396a633c"] git = "https://github.com/mozilla-spidermonkey/jsparagus" rev = "61f399c53a641ebd3077c1f39f054f6d396a633c" diff --git a/rust/Cargo.lock b/rust/Cargo.lock index cd49b34c4d..035c719278 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2125,6 +2125,7 @@ dependencies = [ "kvstore", "l10nregistry", "l10nregistry-ffi", + "libz-rs-sys", "lmdb-rkv-sys", "localization-ffi", "log", @@ -3023,6 +3024,14 @@ dependencies = [ "libc", ] +[[package]] +name = "libz-rs-sys" +version = "0.2.1" +source = "git+https://github.com/memorysafety/zlib-rs?rev=4aa430ccb77537d0d60dab8db993ca51bb1194c5#4aa430ccb77537d0d60dab8db993ca51bb1194c5" +dependencies = [ + "zlib-rs", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -6403,6 +6412,11 @@ dependencies = [ "syn", ] +[[package]] +name = "zlib-rs" +version = "0.2.1" +source = "git+https://github.com/memorysafety/zlib-rs?rev=4aa430ccb77537d0d60dab8db993ca51bb1194c5#4aa430ccb77537d0d60dab8db993ca51bb1194c5" + [[patch.unused]] name = "any_all_workaround" version = "0.1.0" diff --git a/rust/checksums.json b/rust/checksums.json index f3847d7dbb..3b6afdda24 100644 --- a/rust/checksums.json +++ b/rust/checksums.json @@ -1 +1 @@ -{"mc_workspace_toml": "948ffb790b7c291e164071ecffb81aaf89d0956d12d36ff97634362396a45fac3e5a3bb98e7c2864873c1d18e2f854c292fcc736a5ab4d6589ea2947c44a3eca", "mc_gkrust_toml": "9e4671d426a453a7743cb0f3e0efff735e44b33d81f2ea514d652acb20cc032fe4b50073586cf81647571cda974a885afb2256223fcb0cd62c4141b71c2af0f2", "mc_hack_toml": "0be5955346b278ea0611209027bbee30ee54d0d8ed7ffb48b5705db70de2bdd285e16e22c297b5f65acb18427f7937567ed8fd6a7ff26b8579000faf00095f59", "mc_cargo_lock": "2a3814693ffdbed0d8f5c391c1b7483fe3e7e4f3003f34224da8fbb5fb6d837a3ff66d0f4994e00ed7918e9e175b4184855046f3f2e752e1a1cd0e52c2b36f7c"} \ No newline at end of file +{"mc_workspace_toml": "948ffb790b7c291e164071ecffb81aaf89d0956d12d36ff97634362396a45fac3e5a3bb98e7c2864873c1d18e2f854c292fcc736a5ab4d6589ea2947c44a3eca", "mc_gkrust_toml": "522d8c92ca3a3c089a1479dc20cc9015c16a1f550579346c328a46fd74ffc3e957656bb445cd3cade971a8fbf892dfe47ea73d7f7153ba59de5a2ac68357739b", "mc_hack_toml": "0be5955346b278ea0611209027bbee30ee54d0d8ed7ffb48b5705db70de2bdd285e16e22c297b5f65acb18427f7937567ed8fd6a7ff26b8579000faf00095f59", "mc_cargo_lock": "1be4813e9988e6365aaaf63a86502f4cadcd78b812b2a6b381f359719ca228ff6c0555745ebdad25276cf53a4ea40177795b86724c167951008612aa66a50dae"} \ No newline at end of file diff --git a/rust/gkrust/Cargo.toml b/rust/gkrust/Cargo.toml index 6d8130dc50..823dde25f9 100644 --- a/rust/gkrust/Cargo.toml +++ b/rust/gkrust/Cargo.toml @@ -16,8 +16,8 @@ harness = false [dependencies] mozilla-central-workspace-hack = { version = "0.1", features = ['gkrust'], optional = true } gkrust-shared = { version = "0.1.0", path = "../../../toolkit/library/rust/shared" } -ews_xpcom = { version = "0.1.0", path = "../ews_xpcom" } sys_tray = { version = "0.1.0", path = "../sys_tray" } +ews_xpcom = { version = "0.1.0", path = "../ews_xpcom" } aa-stroke = { git = "https://github.com/FirefoxGraphics/aa-stroke", rev = "d94278ed9c7020f50232689a26d1277eb0eb74d2" } app_services_logger = { path = "../../../services/common/app_services_logger" } audio_thread_priority = { version = "0.32" } @@ -61,6 +61,7 @@ jsrust_shared = { path = "../../../js/src/rust/shared" } kvstore = { path = "../../../toolkit/components/kvstore" } l10nregistry = { path = "../../../intl/l10n/rust/l10nregistry-rs" } l10nregistry-ffi = { path = "../../../intl/l10n/rust/l10nregistry-ffi" } +libz-rs-sys = { git = "https://github.com/memorysafety/zlib-rs", rev = "4aa430ccb77537d0d60dab8db993ca51bb1194c5", features = ['custom-prefix'], optional = true } lmdb-rkv-sys = { version = "0.11", features = ['mdb_idl_logn_9'] } localization-ffi = { path = "../../../intl/l10n/rust/localization-ffi" } log = { version = "0.4", features = ['release_max_level_info'] } diff --git a/third_party/rust/aa-stroke/.cargo-checksum.json b/third_party/rust/aa-stroke/.cargo-checksum.json index 7fd07daa0a..f897fd9c7d 100644 --- a/third_party/rust/aa-stroke/.cargo-checksum.json +++ b/third_party/rust/aa-stroke/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".github/workflows/rust.yml":"6a9f1b122ea02367a2f1ff1fc7b9a728284ceb47fad12e1610cde9d760f4efc3","Cargo.toml":"f507cac11c3c26af28420d68ec3748a5453322d51ef1379a340fdd3b1c9b187a","README.md":"60b34cfa653114d5054009696df2ed2ea1d4926a6bc312d0cac4b84845c2beff","examples/simple.rs":"c196e79568fe4be31a08374aa451c70c9377db5428aef924a985e069c12ed91e","src/bezierflattener.rs":"c7183a850d51525db4389d5c0badb76e1d8c4110697bfa51ef746fda6a858bb9","src/c_bindings.rs":"06225ddd132ae959eda1b445f4e375cead4d8e135c5cba81e828815fe6a5e88b","src/lib.rs":"3009746efe5f6753cd999258077a4baea30a740190e7a8ccaec0d78f4719fdfb","src/tri_rasterize.rs":"fb6f595ab9340d8ea6429b41638c378bbd772c8e4d8f7793e225624c12cd3a21"},"package":null} \ No newline at end of file +{"files":{".github/workflows/rust.yml":"6a9f1b122ea02367a2f1ff1fc7b9a728284ceb47fad12e1610cde9d760f4efc3","Cargo.toml":"8462d3a039a219717eca97fd03a9a57d77ffd182837d32c2aec126588b6ab281","README.md":"60b34cfa653114d5054009696df2ed2ea1d4926a6bc312d0cac4b84845c2beff","examples/simple.rs":"c196e79568fe4be31a08374aa451c70c9377db5428aef924a985e069c12ed91e","src/bezierflattener.rs":"c7183a850d51525db4389d5c0badb76e1d8c4110697bfa51ef746fda6a858bb9","src/c_bindings.rs":"06225ddd132ae959eda1b445f4e375cead4d8e135c5cba81e828815fe6a5e88b","src/lib.rs":"3009746efe5f6753cd999258077a4baea30a740190e7a8ccaec0d78f4719fdfb","src/tri_rasterize.rs":"fb6f595ab9340d8ea6429b41638c378bbd772c8e4d8f7793e225624c12cd3a21"},"package":null} \ No newline at end of file diff --git a/third_party/rust/aa-stroke/Cargo.toml b/third_party/rust/aa-stroke/Cargo.toml index 55928c67de..3c2afc0766 100644 --- a/third_party/rust/aa-stroke/Cargo.toml +++ b/third_party/rust/aa-stroke/Cargo.toml @@ -9,13 +9,30 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +test = [] +bench = [] + [package] edition = "2021" name = "aa-stroke" version = "0.1.0" +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MIT" +[lib] +name = "aa_stroke" +path = "src/lib.rs" + +[[example]] +name = "simple" +path = "examples/simple.rs" + [dependencies] euclid = "0.22.7" diff --git a/third_party/rust/any_all_workaround/.cargo-checksum.json b/third_party/rust/any_all_workaround/.cargo-checksum.json index 8d16e68a7e..a96ada70d6 100644 --- a/third_party/rust/any_all_workaround/.cargo-checksum.json +++ b/third_party/rust/any_all_workaround/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f8c127449dc9432d404c21c99833e4617ab88a797445af249a7fe3c989985d6d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","LICENSE-MIT-QCMS":"36d847ae882f6574ebc72f56a4f354e4f104fde4a584373496482e97d52d31bc","README.md":"4c617b8ced3a27b7edecf0e5e41ed451c04e88dab529e7a35fccc4e1551efbd7","build.rs":"56b29ab6da3e49075bfd0a7b690267c8016298bf0d332e2e68bbaf19decbbf71","src/lib.rs":"7118106690b9d25c5d0a3e2079feb83d76f1d434d0da36b9d0351806d27c850d"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"16fde74bf294988b3d600c49f8c3897347d121127676169442b4bf2bc3656778","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","LICENSE-MIT-QCMS":"36d847ae882f6574ebc72f56a4f354e4f104fde4a584373496482e97d52d31bc","README.md":"4c617b8ced3a27b7edecf0e5e41ed451c04e88dab529e7a35fccc4e1551efbd7","build.rs":"56b29ab6da3e49075bfd0a7b690267c8016298bf0d332e2e68bbaf19decbbf71","src/lib.rs":"7118106690b9d25c5d0a3e2079feb83d76f1d434d0da36b9d0351806d27c850d"},"package":null} \ No newline at end of file diff --git a/third_party/rust/any_all_workaround/Cargo.toml b/third_party/rust/any_all_workaround/Cargo.toml index 4b03a35781..cef97bb6d4 100644 --- a/third_party/rust/any_all_workaround/Cargo.toml +++ b/third_party/rust/any_all_workaround/Cargo.toml @@ -9,11 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "any_all_workaround" version = "0.1.0" authors = ["Henri Sivonen "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Workaround for bad LLVM codegen for boolean reductions on 32-bit ARM" homepage = "https://docs.rs/any_all_workaround/" documentation = "https://docs.rs/any_all_workaround/" @@ -21,6 +31,10 @@ readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/hsivonen/any_all_workaround" +[lib] +name = "any_all_workaround" +path = "src/lib.rs" + [dependencies] cfg-if = "1.0" diff --git a/third_party/rust/audioipc2-client/.cargo-checksum.json b/third_party/rust/audioipc2-client/.cargo-checksum.json index 713e1bfb25..b8dd813ad9 100644 --- a/third_party/rust/audioipc2-client/.cargo-checksum.json +++ b/third_party/rust/audioipc2-client/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"b4fad65749eb0988ce4e6b6a2aae51e58ae22eca97cf61dfb011e951a0909f0e","cbindgen.toml":"fb6abe1671497f432a06e40b1db7ed7cd2cceecbd9a2382193ad7534e8855e34","src/context.rs":"a0559e92b554ef3156ab2bf2f1424555c8ef4a7977b9f43ac8500a9f399f8d99","src/lib.rs":"c87d9d57a16a9286cde730978db692df0fbc70cc69dd4f4677198d6843031fd8","src/send_recv.rs":"859abe75b521eb4297c84b30423814b5b87f3c7741ad16fe72189212e123e1ac","src/stream.rs":"90dc6a85552f3569ab1847de4247a46bcff2f5aef0c4d43fa2376589df015b25"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"66d5b42512734c7c6d1605b21c9b94e6d12153e036d2632456cb7c2d1b8a22f2","cbindgen.toml":"fb6abe1671497f432a06e40b1db7ed7cd2cceecbd9a2382193ad7534e8855e34","src/context.rs":"a0559e92b554ef3156ab2bf2f1424555c8ef4a7977b9f43ac8500a9f399f8d99","src/lib.rs":"c87d9d57a16a9286cde730978db692df0fbc70cc69dd4f4677198d6843031fd8","src/send_recv.rs":"859abe75b521eb4297c84b30423814b5b87f3c7741ad16fe72189212e123e1ac","src/stream.rs":"90dc6a85552f3569ab1847de4247a46bcff2f5aef0c4d43fa2376589df015b25"},"package":null} \ No newline at end of file diff --git a/third_party/rust/audioipc2-client/Cargo.toml b/third_party/rust/audioipc2-client/Cargo.toml index ecafb31ad3..df05c7db9f 100644 --- a/third_party/rust/audioipc2-client/Cargo.toml +++ b/third_party/rust/audioipc2-client/Cargo.toml @@ -9,6 +9,11 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "audioipc2-client" @@ -17,9 +22,19 @@ authors = [ "Matthew Gregan ", "Dan Glastonbury ", ] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Cubeb Backend for talking to remote cubeb server." +readme = false license = "ISC" +[lib] +name = "audioipc2_client" +path = "src/lib.rs" + [dependencies] cubeb-backend = "0.13" log = "0.4" diff --git a/third_party/rust/audioipc2-server/.cargo-checksum.json b/third_party/rust/audioipc2-server/.cargo-checksum.json index 747a4f7648..de4d52d882 100644 --- a/third_party/rust/audioipc2-server/.cargo-checksum.json +++ b/third_party/rust/audioipc2-server/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"62eab883f31c0c088ff865fe2e4305d987b7b534f6cdfe1e5812072a2ec13f8b","cbindgen.toml":"fb6abe1671497f432a06e40b1db7ed7cd2cceecbd9a2382193ad7534e8855e34","src/lib.rs":"d70079c66de72c3469504f1f0c9cf5e510644cac17f2d8300b8d12218740e07b","src/server.rs":"20010fbad8111420d2018a14b393eba1362cd68b24a746819ef6a68c2936a1bd"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"0ac0c33adf09f9b4d00a98a8d5599f04266cb865718b2e0303dfab6bf96a994e","cbindgen.toml":"fb6abe1671497f432a06e40b1db7ed7cd2cceecbd9a2382193ad7534e8855e34","src/lib.rs":"d70079c66de72c3469504f1f0c9cf5e510644cac17f2d8300b8d12218740e07b","src/server.rs":"20010fbad8111420d2018a14b393eba1362cd68b24a746819ef6a68c2936a1bd"},"package":null} \ No newline at end of file diff --git a/third_party/rust/audioipc2-server/Cargo.toml b/third_party/rust/audioipc2-server/Cargo.toml index 0326e5e403..aea95c9eba 100644 --- a/third_party/rust/audioipc2-server/Cargo.toml +++ b/third_party/rust/audioipc2-server/Cargo.toml @@ -9,6 +9,11 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "audioipc2-server" @@ -17,9 +22,19 @@ authors = [ "Matthew Gregan ", "Dan Glastonbury ", ] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Remote cubeb server" +readme = false license = "ISC" +[lib] +name = "audioipc2_server" +path = "src/lib.rs" + [dependencies] cubeb-core = "0.13" log = "0.4" diff --git a/third_party/rust/audioipc2/.cargo-checksum.json b/third_party/rust/audioipc2/.cargo-checksum.json index 1f24b92c5d..ef9722012b 100644 --- a/third_party/rust/audioipc2/.cargo-checksum.json +++ b/third_party/rust/audioipc2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"5819c55845b39385dfa8f8ebccbf8304f3061253c9d92a55d71d14d4cfe1915b","benches/serialization.rs":"d56855d868dab6aa22c8b03a61084535351b76c94b68d8b1d20764e352fe473f","build.rs":"65df9a97c6cdaa3faf72581f04ac289197b0b1797d69d22c1796e957ff1089e2","src/codec.rs":"86068272e220696d8d7e369072326349e7598e5a24223d98179c3251bb7b3ff1","src/errors.rs":"67a4a994d0724397657581cde153bdfc05ce86e7efc467f23fafc8f64df80fa4","src/ipccore.rs":"db73e916468c54d3497d75ffcab3bf23067771ed7b2e1a23c714429f56f59ec3","src/lib.rs":"a6fcac8b44318435db60313d3ef32ff3fada390bea8978c8414c40744998b98b","src/messages.rs":"d4f6d4f41b7fd3cc7deae726657e1100f315f4cd10c5fe6ce8a57c03c8e26ca9","src/rpccore.rs":"025b6614f1c42b96b0a8e74fd7881032d338c66e0d67ec0af70f910a9e30ebe1","src/shm.rs":"c00d16f4af510d12e704ae865f7348ad64ddef180e42b18e7dd95c4be35a9c80","src/sys/mod.rs":"e6fa1d260abf093e1f7b50185195e2d3aee0eb8c9774c6f253953b5896d838f3","src/sys/unix/cmsg.rs":"9529e8f8429db86f7c5df132953d3054e603852270f3c6938cdb5f630b2711f1","src/sys/unix/cmsghdr.c":"d7344b3dc15cdce410c68669b848bb81f7fe36362cd3699668cb613fa05180f8","src/sys/unix/mod.rs":"59835f0d5509940078b1820a54f49fc5514adeb3e45e7d21e3ab917431da2e74","src/sys/unix/msg.rs":"25244de3eba920fa42e032f8fa4ea4913a9fdeb5124ade61e707f6cc6dd946b0","src/sys/windows/mod.rs":"7eaabb76e62c6962b636320e2bbf79a78fce61659c799a798f7dd6d56b0be8a1"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"d5d18641a0ab07f86f7c07e6918b8f2a6b70b99267b753d1f8109ff9be4a8c4b","benches/serialization.rs":"d56855d868dab6aa22c8b03a61084535351b76c94b68d8b1d20764e352fe473f","build.rs":"65df9a97c6cdaa3faf72581f04ac289197b0b1797d69d22c1796e957ff1089e2","src/codec.rs":"86068272e220696d8d7e369072326349e7598e5a24223d98179c3251bb7b3ff1","src/errors.rs":"67a4a994d0724397657581cde153bdfc05ce86e7efc467f23fafc8f64df80fa4","src/ipccore.rs":"db73e916468c54d3497d75ffcab3bf23067771ed7b2e1a23c714429f56f59ec3","src/lib.rs":"a6fcac8b44318435db60313d3ef32ff3fada390bea8978c8414c40744998b98b","src/messages.rs":"d4f6d4f41b7fd3cc7deae726657e1100f315f4cd10c5fe6ce8a57c03c8e26ca9","src/rpccore.rs":"025b6614f1c42b96b0a8e74fd7881032d338c66e0d67ec0af70f910a9e30ebe1","src/shm.rs":"c00d16f4af510d12e704ae865f7348ad64ddef180e42b18e7dd95c4be35a9c80","src/sys/mod.rs":"e6fa1d260abf093e1f7b50185195e2d3aee0eb8c9774c6f253953b5896d838f3","src/sys/unix/cmsg.rs":"9529e8f8429db86f7c5df132953d3054e603852270f3c6938cdb5f630b2711f1","src/sys/unix/cmsghdr.c":"d7344b3dc15cdce410c68669b848bb81f7fe36362cd3699668cb613fa05180f8","src/sys/unix/mod.rs":"59835f0d5509940078b1820a54f49fc5514adeb3e45e7d21e3ab917431da2e74","src/sys/unix/msg.rs":"25244de3eba920fa42e032f8fa4ea4913a9fdeb5124ade61e707f6cc6dd946b0","src/sys/windows/mod.rs":"7eaabb76e62c6962b636320e2bbf79a78fce61659c799a798f7dd6d56b0be8a1"},"package":null} \ No newline at end of file diff --git a/third_party/rust/audioipc2/Cargo.toml b/third_party/rust/audioipc2/Cargo.toml index df86116f9c..a05dc8ad46 100644 --- a/third_party/rust/audioipc2/Cargo.toml +++ b/third_party/rust/audioipc2/Cargo.toml @@ -9,6 +9,10 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] + [package] edition = "2018" name = "audioipc2" @@ -17,11 +21,22 @@ authors = [ "Matthew Gregan ", "Dan Glastonbury ", ] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Remote Cubeb IPC" +readme = false license = "ISC" +[lib] +name = "audioipc2" +path = "src/lib.rs" + [[bench]] name = "serialization" +path = "benches/serialization.rs" harness = false [dependencies] @@ -59,10 +74,10 @@ features = ["html_reports"] [build-dependencies] cc = "1.0" -[target."cfg(target_os = \"android\")".dependencies] +[target.'cfg(target_os = "android")'.dependencies] ashmem = "0.1.2" -[target."cfg(target_os = \"linux\")".dependencies.audio_thread_priority] +[target.'cfg(target_os = "linux")'.dependencies.audio_thread_priority] version = "0.32" default-features = false diff --git a/third_party/rust/chardetng/.cargo-checksum.json b/third_party/rust/chardetng/.cargo-checksum.json index 1d6743d4d5..b8e1657f5e 100644 --- a/third_party/rust/chardetng/.cargo-checksum.json +++ b/third_party/rust/chardetng/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CONTRIBUTING.md":"0e64fb3dd5a00e3fd528de6442de3f2ca851bd718c45cca0871aaf4eedac9ee1","COPYRIGHT":"2fd0d7e90bd241b79804de129c5b70089988f82a7bbb0fe580a55b67b2968928","Cargo.toml":"78c3797cfa83e17d06cc9ae9d2603d6fda0ed9f6b371b4479885d4b382a124a9","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"4ad721b5b6a3d39ca3e2202f403d897c4a1d42896486dd58963a81f8e64ef61d","README.md":"a6c97d91989aee4c8afed918340ce6287652cbdd6fed833e20f76367c7953db9","src/data.rs":"be48f1486ef9fc264f6cda2e10944b7dcf8ed0a904b53227340a1384803796c7","src/lib.rs":"16c7c78a56ec917e92db97263f4adddcf3749acaf7de88d088d1f5c86c278107","src/tld.rs":"295c3c90c60c5bb6edd753b77c261eed10be2d431badda4e02168e740a0f2d7e"},"package":null} \ No newline at end of file +{"files":{"CONTRIBUTING.md":"0e64fb3dd5a00e3fd528de6442de3f2ca851bd718c45cca0871aaf4eedac9ee1","COPYRIGHT":"2fd0d7e90bd241b79804de129c5b70089988f82a7bbb0fe580a55b67b2968928","Cargo.toml":"11fdb1e7ac76ba6a6fe3b1e7e35ed09a823161a704eec6988892cfe54cbdc642","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"4ad721b5b6a3d39ca3e2202f403d897c4a1d42896486dd58963a81f8e64ef61d","README.md":"a6c97d91989aee4c8afed918340ce6287652cbdd6fed833e20f76367c7953db9","src/data.rs":"be48f1486ef9fc264f6cda2e10944b7dcf8ed0a904b53227340a1384803796c7","src/lib.rs":"16c7c78a56ec917e92db97263f4adddcf3749acaf7de88d088d1f5c86c278107","src/tld.rs":"295c3c90c60c5bb6edd753b77c261eed10be2d431badda4e02168e740a0f2d7e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/chardetng/Cargo.toml b/third_party/rust/chardetng/Cargo.toml index 4f5110a092..82b7405c7e 100644 --- a/third_party/rust/chardetng/Cargo.toml +++ b/third_party/rust/chardetng/Cargo.toml @@ -9,11 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "chardetng" version = "0.1.9" authors = ["Henri Sivonen "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "A character encoding detector for legacy Web content" homepage = "https://docs.rs/chardetng/" documentation = "https://docs.rs/chardetng/" @@ -33,6 +43,10 @@ categories = [ license = "Apache-2.0 OR MIT" repository = "https://github.com/hsivonen/chardetng" +[lib] +name = "chardetng" +path = "src/lib.rs" + [dependencies] encoding_rs = "0.8.17" memchr = "2.2.0" diff --git a/third_party/rust/chardetng_c/.cargo-checksum.json b/third_party/rust/chardetng_c/.cargo-checksum.json index 404017a483..31b3ade7da 100644 --- a/third_party/rust/chardetng_c/.cargo-checksum.json +++ b/third_party/rust/chardetng_c/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CONTRIBUTING.md":"5f28b63428b92d27d796d6d926447d15a19232236200e161ec870f4fdda1b489","COPYRIGHT":"5fa6d8c0701e5ce051b72b9ed08e3a75d5aee8e4132d876556c3dc04084238c7","Cargo.toml":"4bdc7754f31d433d876bb1055ad3bb1b8061fe7044daa316b7cc43c323cf22bc","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"3fa4ca83dcc9237839b1bdeb2e6d16bdfb5ec0c5ce42b24694d8bbf0dcbef72c","README.md":"f458dc617c487ace6c60096e1bf3ab1b39c151543b40916717596c28e81deebc","include/chardetng.h":"8a781fcbf6441d063abc6c004d485cb2d5a0b304f3bfe5d5978e70437b7b778e","src/lib.rs":"2eeaf976144bab2c9c819934ca0fce36fe2d9b21236d19b506426733d9a57e2b"},"package":null} \ No newline at end of file +{"files":{"CONTRIBUTING.md":"5f28b63428b92d27d796d6d926447d15a19232236200e161ec870f4fdda1b489","COPYRIGHT":"5fa6d8c0701e5ce051b72b9ed08e3a75d5aee8e4132d876556c3dc04084238c7","Cargo.toml":"377bb94d6f6147c42120dbace59e7e5772a39e600c4945f3f82cf05c139b2dd6","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"3fa4ca83dcc9237839b1bdeb2e6d16bdfb5ec0c5ce42b24694d8bbf0dcbef72c","README.md":"f458dc617c487ace6c60096e1bf3ab1b39c151543b40916717596c28e81deebc","include/chardetng.h":"8a781fcbf6441d063abc6c004d485cb2d5a0b304f3bfe5d5978e70437b7b778e","src/lib.rs":"2eeaf976144bab2c9c819934ca0fce36fe2d9b21236d19b506426733d9a57e2b"},"package":null} \ No newline at end of file diff --git a/third_party/rust/chardetng_c/Cargo.toml b/third_party/rust/chardetng_c/Cargo.toml index a4dbace3b2..927049febd 100644 --- a/third_party/rust/chardetng_c/Cargo.toml +++ b/third_party/rust/chardetng_c/Cargo.toml @@ -9,11 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "chardetng_c" version = "0.1.2" authors = ["Henri Sivonen "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "C bindings for chardetng" homepage = "https://docs.rs/chardetng_c/" documentation = "https://docs.rs/chardetng_c/" @@ -33,6 +43,10 @@ categories = [ license = "Apache-2.0 OR MIT" repository = "https://github.com/hsivonen/chardetng-c" +[lib] +name = "chardetng_c" +path = "src/lib.rs" + [dependencies] chardetng = "0.1.1" encoding_rs = "0.8.17" diff --git a/third_party/rust/coreaudio-sys-utils/.cargo-checksum.json b/third_party/rust/coreaudio-sys-utils/.cargo-checksum.json index f22a44473c..49232316e1 100644 --- a/third_party/rust/coreaudio-sys-utils/.cargo-checksum.json +++ b/third_party/rust/coreaudio-sys-utils/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"87292d055a2fc0f070f54abd549a5f79ec8ac33611ecde80ba394f256b88294c","src/aggregate_device.rs":"7d2bd5f5fd7f3d008ebb69ad81f522ca0cb73db6d7b3e50ed1a63ea26ff721f4","src/audio_device_extensions.rs":"5c869d791947d15eec8bffe0bb302fe32d0578111ffe0049213e720eb60a34e1","src/audio_object.rs":"34f7e038c1ed30d503d669d89f01864ae90e009a2fa74ef50fac343a53113ff2","src/audio_unit.rs":"d38007faed2ce4d88efb70054a1fdfadf8249d0e55b900eb3ac8eae04355bf2b","src/cf_mutable_dict.rs":"fc42edd270c6dfb02f123214d2d8e487bbd62b5bd923b71eec13190fd0104d2a","src/dispatch.rs":"24b6bcf0dcaa6618e03039cd060a274c8f9ed48264e14de465ae3aacb2daad57","src/lib.rs":"c93ed1411dd6cc39db44f57e0d7683bbc54745f84a3c9f9533a088895ec97abe","src/string.rs":"28f88b816c768bcfcc674a60d962b93f1c94e5e0f4cc8ed2a1301138b91039e7"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"4da0bb17f136a1f38371bb5d0979eaf4a211e2e395e75b589259c6f6f050a631","src/aggregate_device.rs":"7d2bd5f5fd7f3d008ebb69ad81f522ca0cb73db6d7b3e50ed1a63ea26ff721f4","src/audio_device_extensions.rs":"5c869d791947d15eec8bffe0bb302fe32d0578111ffe0049213e720eb60a34e1","src/audio_object.rs":"34f7e038c1ed30d503d669d89f01864ae90e009a2fa74ef50fac343a53113ff2","src/audio_unit.rs":"d38007faed2ce4d88efb70054a1fdfadf8249d0e55b900eb3ac8eae04355bf2b","src/cf_mutable_dict.rs":"fc42edd270c6dfb02f123214d2d8e487bbd62b5bd923b71eec13190fd0104d2a","src/dispatch.rs":"24b6bcf0dcaa6618e03039cd060a274c8f9ed48264e14de465ae3aacb2daad57","src/lib.rs":"c93ed1411dd6cc39db44f57e0d7683bbc54745f84a3c9f9533a088895ec97abe","src/string.rs":"28f88b816c768bcfcc674a60d962b93f1c94e5e0f4cc8ed2a1301138b91039e7"},"package":null} \ No newline at end of file diff --git a/third_party/rust/coreaudio-sys-utils/Cargo.toml b/third_party/rust/coreaudio-sys-utils/Cargo.toml index 7086422a28..adaa66b8fa 100644 --- a/third_party/rust/coreaudio-sys-utils/Cargo.toml +++ b/third_party/rust/coreaudio-sys-utils/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "coreaudio-sys-utils" version = "0.1.0" authors = ["Chun-Min Chang "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "ISC" +[lib] +name = "coreaudio_sys_utils" +path = "src/lib.rs" + [dependencies.core-foundation-sys] version = "0.8" diff --git a/third_party/rust/coremidi/.cargo-checksum.json b/third_party/rust/coremidi/.cargo-checksum.json index 07faa51931..57e8c16383 100644 --- a/third_party/rust/coremidi/.cargo-checksum.json +++ b/third_party/rust/coremidi/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".idea/.gitignore":"4073be0dd9e3ae38beba97eed085d5f023a5f2cdc101ec35f2877b185b1f1193",".travis.yml":"0d0c4ef138608fde4242675504f63116c8f49c8699f42542718f2f5cc1cebbb4","Cargo.toml":"8ed93b632b7ba2fc80d4bee845b19fd0a7b7d50f5cd60657fb4e8b8a05749aab","LICENSE":"c1c457e1b2794c9044f0e2d66a7010c223d0fb65b06e1dfbab6e21888ab09c16","README.md":"b77d39ce7ffe042c2cd3eee3e65c57323c217d1eb650ed19c56ccacd4e8854aa","ci/build-docs.sh":"644c0b2e90dc72092295152a00bf2ad6367017082f28d8fe36ee7be9821caa32","ci/publish.sh":"cc63e14aa05b503d378df854baadecd2d35bb445db06f9cdf7465fc1346fa5e3","ci/update-version.sh":"d91eedac8f507c2e4727887d2d15f27420676f46449fd0115d0ccae8e72fc95c","examples/endpoints.rs":"9327ce3dc03e49b8d2c1cf16161c9b03fc059aca9216b6d67c9ae4796fd43e40","examples/notifications.rs":"3b97c5348321dbbb172625c7b7219f1c60a47fa36d820c426d9cb7c6cc099ccf","examples/properties.rs":"1362ec194c43bcaaa1bcf7d3726eb4408eda85d290d0d706ac05ad2f71df4a33","examples/receive.rs":"28dab3891aacc2af44bffaf518eb39c69926d957a0f29f940ed44f7b16ec287a","examples/send.rs":"28e4d2558e8cf95f431c48e344101132cb499495084b59c0b6bd3107147701e4","examples/virtual-destination.rs":"f06e55093fe5117f2587d7a9799aa628c770eba2b0ca0f4804db1a72aa0bbcfc","examples/virtual-source.rs":"f0807ee9f13f27236bab8f86718d9e1645772a7d5a8095f59d0f4e5b7aeb72e9","rust-toolchain":"f6a0b9759d1af128dd09bb3f49812c052c89168e7b159e6d269036a2faba3260","src/callback.rs":"1200934d86f16ac4f678db1f2b9e2c8f621c00835de88fff36e4a317ce64aec1","src/client.rs":"05c6ecdd2fedc6f719ff93b7b6b98e911e920aa9094b342152fbcbe6d47cc64d","src/devices.rs":"33e7e85fda187a8ce0063f4db67486a96cde2794d07ecd1a73a97f5ec5ef9a13","src/endpoints/destinations.rs":"f165076d0193fc975e16e201c2d549462c87d2114095b3b4ca32b66418fb6cba","src/endpoints/mod.rs":"76dd40f64e5bda497ce84787d42035c59e3eb7cf1298307b0cb14e9eecd3e9d1","src/endpoints/sources.rs":"1fcadc52167a864dff1df09d584182e7666921af7ea72fa097f5b76ed031ddba","src/lib.rs":"ca9005ca22c90acf7379b588d268ffbbb0561760a9c10adde3356838dd994861","src/notifications.rs":"e2cec6e17c3b10e631f01c880d9637145742194cc4edbd24c7ad795f95f7b6d4","src/object.rs":"2ba5d6e17a7a99716dd9e435beffb47e169bb1e78b00713a29ea816399603a2f","src/packets.rs":"c18491c05fe2a61598b56a2ec86dbfc1490c9aea5b78534978aeb79372756e66","src/ports.rs":"25b91051635677479e2521bc3c7fbbfe29c9a2920aa19c34f95faa67b1fbb3fb","src/properties.rs":"c21b96a1265e04b59ca9cd3656d625188ce182e4afa36d849881c4521d0b8cb1"},"package":null} \ No newline at end of file +{"files":{".idea/.gitignore":"4073be0dd9e3ae38beba97eed085d5f023a5f2cdc101ec35f2877b185b1f1193",".travis.yml":"0d0c4ef138608fde4242675504f63116c8f49c8699f42542718f2f5cc1cebbb4","Cargo.toml":"10cc746ad63c9d4f1277e9e01be21277a3a626acefd062e2ed4973c82d0581ac","LICENSE":"c1c457e1b2794c9044f0e2d66a7010c223d0fb65b06e1dfbab6e21888ab09c16","README.md":"b77d39ce7ffe042c2cd3eee3e65c57323c217d1eb650ed19c56ccacd4e8854aa","ci/build-docs.sh":"644c0b2e90dc72092295152a00bf2ad6367017082f28d8fe36ee7be9821caa32","ci/publish.sh":"cc63e14aa05b503d378df854baadecd2d35bb445db06f9cdf7465fc1346fa5e3","ci/update-version.sh":"d91eedac8f507c2e4727887d2d15f27420676f46449fd0115d0ccae8e72fc95c","examples/endpoints.rs":"9327ce3dc03e49b8d2c1cf16161c9b03fc059aca9216b6d67c9ae4796fd43e40","examples/notifications.rs":"3b97c5348321dbbb172625c7b7219f1c60a47fa36d820c426d9cb7c6cc099ccf","examples/properties.rs":"1362ec194c43bcaaa1bcf7d3726eb4408eda85d290d0d706ac05ad2f71df4a33","examples/receive.rs":"28dab3891aacc2af44bffaf518eb39c69926d957a0f29f940ed44f7b16ec287a","examples/send.rs":"28e4d2558e8cf95f431c48e344101132cb499495084b59c0b6bd3107147701e4","examples/virtual-destination.rs":"f06e55093fe5117f2587d7a9799aa628c770eba2b0ca0f4804db1a72aa0bbcfc","examples/virtual-source.rs":"f0807ee9f13f27236bab8f86718d9e1645772a7d5a8095f59d0f4e5b7aeb72e9","rust-toolchain":"f6a0b9759d1af128dd09bb3f49812c052c89168e7b159e6d269036a2faba3260","src/callback.rs":"1200934d86f16ac4f678db1f2b9e2c8f621c00835de88fff36e4a317ce64aec1","src/client.rs":"05c6ecdd2fedc6f719ff93b7b6b98e911e920aa9094b342152fbcbe6d47cc64d","src/devices.rs":"33e7e85fda187a8ce0063f4db67486a96cde2794d07ecd1a73a97f5ec5ef9a13","src/endpoints/destinations.rs":"f165076d0193fc975e16e201c2d549462c87d2114095b3b4ca32b66418fb6cba","src/endpoints/mod.rs":"76dd40f64e5bda497ce84787d42035c59e3eb7cf1298307b0cb14e9eecd3e9d1","src/endpoints/sources.rs":"1fcadc52167a864dff1df09d584182e7666921af7ea72fa097f5b76ed031ddba","src/lib.rs":"ca9005ca22c90acf7379b588d268ffbbb0561760a9c10adde3356838dd994861","src/notifications.rs":"e2cec6e17c3b10e631f01c880d9637145742194cc4edbd24c7ad795f95f7b6d4","src/object.rs":"2ba5d6e17a7a99716dd9e435beffb47e169bb1e78b00713a29ea816399603a2f","src/packets.rs":"c18491c05fe2a61598b56a2ec86dbfc1490c9aea5b78534978aeb79372756e66","src/ports.rs":"25b91051635677479e2521bc3c7fbbfe29c9a2920aa19c34f95faa67b1fbb3fb","src/properties.rs":"c21b96a1265e04b59ca9cd3656d625188ce182e4afa36d849881c4521d0b8cb1"},"package":null} \ No newline at end of file diff --git a/third_party/rust/coremidi/Cargo.toml b/third_party/rust/coremidi/Cargo.toml index fba5458f81..77b4da6136 100644 --- a/third_party/rust/coremidi/Cargo.toml +++ b/third_party/rust/coremidi/Cargo.toml @@ -9,11 +9,20 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +test = [] +bench = [] + [package] edition = "2018" name = "coremidi" version = "0.6.0" authors = ["Christian Perez-Llamas"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "CoreMIDI library for Rust" homepage = "https://github.com/chris-zen/coremidi" documentation = "https://chris-zen.github.io/coremidi/coremidi/" @@ -28,6 +37,38 @@ keywords = [ license = "MIT" repository = "https://github.com/chris-zen/coremidi" +[lib] +name = "coremidi" +path = "src/lib.rs" + +[[example]] +name = "endpoints" +path = "examples/endpoints.rs" + +[[example]] +name = "notifications" +path = "examples/notifications.rs" + +[[example]] +name = "properties" +path = "examples/properties.rs" + +[[example]] +name = "receive" +path = "examples/receive.rs" + +[[example]] +name = "send" +path = "examples/send.rs" + +[[example]] +name = "virtual-destination" +path = "examples/virtual-destination.rs" + +[[example]] +name = "virtual-source" +path = "examples/virtual-source.rs" + [dependencies] core-foundation = "0.9.1" core-foundation-sys = "0.8.2" diff --git a/third_party/rust/cose/.cargo-checksum.json b/third_party/rust/cose/.cargo-checksum.json index 851cac0db6..4f0d67ad4a 100644 --- a/third_party/rust/cose/.cargo-checksum.json +++ b/third_party/rust/cose/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".travis.yml":"423ecb6dd6dbc8b00fb3d2789ddc89ab4d9c1040ea3d5e467f437728164cd5b9","Cargo.toml":"e4af309a907a63866cc85b7e8d878d083790ef9b5733a5129906eb26eedfd80c","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"981c13c037304ca06c34d8518f2d2e0021867dfd36cb711efb8f6c5e2fdb0123","build.rs":"a2b798bbeaf8ef19a9bd8c1e24b3fd3899a5b4b3e121e5e09794e4e2b35971dd","examples/sign_verify/main.rs":"fbe4b9c73b23e1ef364126f453f749fefb67ab45703bf809a5eed910a25e461e","examples/sign_verify/nss.rs":"a1d133142efc0ac6564f0b9587890587f1ecaa7404ac0c4c8907de6d43de3267","examples/sign_verify/test_nss.rs":"be41ebe0a82b6172297b10c13767e4768f0b613ac331b554f6e8c2c7a20c0bc8","examples/sign_verify/test_setup.rs":"d323c3818525a43b71c3a121b39043c5debdff303fa3cfec230853c96ff477eb","examples/sign_verify/util_test.rs":"48d52f3ca3e93b670a1d69f8443358260c1ae61d7977a59d922696811320d4c3","rustfmt.toml":"e97717e906fcd3eeb86dcee52ed26f13e1884597b016a27172229d9c78dd3d57","src/cose.rs":"104e06843f4cdffe2ca6f42f46c51c79d685c18d2ad92b65811e3ceffbd90e07","src/decoder.rs":"d84fc785715823963551466175af0bb86a16cee58ae95b54bfd613d390bc4d82","src/test_cose.rs":"849ec936a00eb438a08eb85380b3e4ba8d8c5a5cf674b272e0fd8e671ab6d5ca","src/test_setup.rs":"e26f290831343cbb4e2b2ec7d1be34c7b900eb8c87abd6f40629372a87b6e992","src/util.rs":"8cdcdc8a120e71a772af61fa63ffa2d2d2eb572d8a53da3b5f1ce9da784f2662","tools/certs/certs.md":"7a1acd946f5bb5b9b21ebd7653ef9d5746a1ea237131a69218a91dc26eda545a","tools/certs/certs.sh":"a06e1a7bf99316c7800e388d20c1630da7449937635600d9f21d8d93907011bf","tools/certs/ee-p256.certspec":"5a7246c0abf1ee08edb858ce2fd38010de7785a0e8652f2d9a0b7eee7aa39213","tools/certs/ee-p256.keyspec":"eabd2839f9e57cf2c372e686e5856cf651d7f07d0d396b3699d1d228b5931945","tools/certs/ee-p384.certspec":"d2e4fdd6d8f02f22bffa800ac2b7f899f5d826528e7b7d3248e1abea15cd33bd","tools/certs/ee-p521.certspec":"7ad1fc3cdf024dfa7213f3a2875af0ccfa2bd73fddcfaf73223aa25b24ee2cad","tools/certs/ee-rsa.certspec":"dd69ecbb1cdf322fb8ef6eb50c2f033b62e7983b5448b96f1965eee8f85b7bde","tools/certs/int-p256.certspec":"b42a2286339455626b9a8b6c0811b031bf269440c6fcef7478796d02c5491364","tools/certs/int-rsa.certspec":"a0942438c72a3ce83b54c04e4a5d4bff08036c2c9feb7d75a7105bfa4fdc5499","tools/certs/root-p256.certspec":"99c1bb07505ddfc3ada5737d8a1bf4cff7b1a70a79abda9fd45fc3a6e72061fc","tools/certs/root-rsa.certspec":"67903313b6058aa98be0d98564577b0c878c868b6f2a8758f27bb7af17616d8e"},"package":null} \ No newline at end of file +{"files":{".travis.yml":"423ecb6dd6dbc8b00fb3d2789ddc89ab4d9c1040ea3d5e467f437728164cd5b9","Cargo.toml":"81254de1acf78857cd8e88a7c3385cacebb1ca292d76e8fcac775429912a34a9","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"981c13c037304ca06c34d8518f2d2e0021867dfd36cb711efb8f6c5e2fdb0123","build.rs":"a2b798bbeaf8ef19a9bd8c1e24b3fd3899a5b4b3e121e5e09794e4e2b35971dd","examples/sign_verify/main.rs":"fbe4b9c73b23e1ef364126f453f749fefb67ab45703bf809a5eed910a25e461e","examples/sign_verify/nss.rs":"a1d133142efc0ac6564f0b9587890587f1ecaa7404ac0c4c8907de6d43de3267","examples/sign_verify/test_nss.rs":"be41ebe0a82b6172297b10c13767e4768f0b613ac331b554f6e8c2c7a20c0bc8","examples/sign_verify/test_setup.rs":"d323c3818525a43b71c3a121b39043c5debdff303fa3cfec230853c96ff477eb","examples/sign_verify/util_test.rs":"48d52f3ca3e93b670a1d69f8443358260c1ae61d7977a59d922696811320d4c3","rustfmt.toml":"e97717e906fcd3eeb86dcee52ed26f13e1884597b016a27172229d9c78dd3d57","src/cose.rs":"104e06843f4cdffe2ca6f42f46c51c79d685c18d2ad92b65811e3ceffbd90e07","src/decoder.rs":"d84fc785715823963551466175af0bb86a16cee58ae95b54bfd613d390bc4d82","src/test_cose.rs":"849ec936a00eb438a08eb85380b3e4ba8d8c5a5cf674b272e0fd8e671ab6d5ca","src/test_setup.rs":"e26f290831343cbb4e2b2ec7d1be34c7b900eb8c87abd6f40629372a87b6e992","src/util.rs":"8cdcdc8a120e71a772af61fa63ffa2d2d2eb572d8a53da3b5f1ce9da784f2662","tools/certs/certs.md":"7a1acd946f5bb5b9b21ebd7653ef9d5746a1ea237131a69218a91dc26eda545a","tools/certs/certs.sh":"a06e1a7bf99316c7800e388d20c1630da7449937635600d9f21d8d93907011bf","tools/certs/ee-p256.certspec":"5a7246c0abf1ee08edb858ce2fd38010de7785a0e8652f2d9a0b7eee7aa39213","tools/certs/ee-p256.keyspec":"eabd2839f9e57cf2c372e686e5856cf651d7f07d0d396b3699d1d228b5931945","tools/certs/ee-p384.certspec":"d2e4fdd6d8f02f22bffa800ac2b7f899f5d826528e7b7d3248e1abea15cd33bd","tools/certs/ee-p521.certspec":"7ad1fc3cdf024dfa7213f3a2875af0ccfa2bd73fddcfaf73223aa25b24ee2cad","tools/certs/ee-rsa.certspec":"dd69ecbb1cdf322fb8ef6eb50c2f033b62e7983b5448b96f1965eee8f85b7bde","tools/certs/int-p256.certspec":"b42a2286339455626b9a8b6c0811b031bf269440c6fcef7478796d02c5491364","tools/certs/int-rsa.certspec":"a0942438c72a3ce83b54c04e4a5d4bff08036c2c9feb7d75a7105bfa4fdc5499","tools/certs/root-p256.certspec":"99c1bb07505ddfc3ada5737d8a1bf4cff7b1a70a79abda9fd45fc3a6e72061fc","tools/certs/root-rsa.certspec":"67903313b6058aa98be0d98564577b0c878c868b6f2a8758f27bb7af17616d8e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/cose/Cargo.toml b/third_party/rust/cose/Cargo.toml index c52276245f..3ce9221243 100644 --- a/third_party/rust/cose/Cargo.toml +++ b/third_party/rust/cose/Cargo.toml @@ -9,6 +9,10 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +test = [] +bench = [] + [package] name = "cose" version = "0.1.4" @@ -17,6 +21,10 @@ authors = [ "David Keeler ", ] build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Library to use COSE (https://tools.ietf.org/html/rfc8152) in Rust" readme = "README.md" keywords = [ @@ -30,6 +38,10 @@ repository = "https://github.com/franziskuskiefer/cose-rust" name = "cose" path = "src/cose.rs" +[[example]] +name = "sign_verify" +path = "examples/sign_verify/main.rs" + [dependencies] moz_cbor = "0.1.0" diff --git a/third_party/rust/cubeb-coreaudio/.cargo-checksum.json b/third_party/rust/cubeb-coreaudio/.cargo-checksum.json index b92a226a94..222d5c0f3c 100644 --- a/third_party/rust/cubeb-coreaudio/.cargo-checksum.json +++ b/third_party/rust/cubeb-coreaudio/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"cf6ebe6d41b022897360866b526d19ba8843aa82ae99a1d28393985576b6a782",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"bd7f9d71d7b83bb7b5516058b4af37c81eede73f11975b56cc6885b721c407a7","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"967448b6cd46a8e60d465d56be0b1e6794a18110592a30939d2cb0650c4e5bc6","run_sanitizers.sh":"84e93a0da137803018f37403511e8c92760be730426bf6cea34419d93d1a7ff8","run_tests.sh":"bae82f66dd47a060b6fdcc238520084aec1079d5b1b1d66d103baa1ffaa8773d","src/backend/aggregate_device.rs":"a910b9d596b1971cb4fee34f5030809ade584f41eb5cbad73a09abe7352ebd15","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"e9bcf964347daa8952f98caa2746e34a31ea8908375204896593f56e4b6147ca","src/backend/device_property.rs":"30ceeceee4fc1f6f872c6c61765e41d582ccd91d2d1ac3ca9b1e5ac18dd11a71","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"1f96b4bc17d67d4a20df974e81030c5d286454d1d85b372f3fa5bd8f207d3e35","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"afbdf1da1fcaddcad2986bd3146bf93ca75c24b3362f5f23a09517a926290ca2","src/backend/tests/api.rs":"3b0936810b3afa84cb80428c471e1097701fd790460d00c0a5715fd8026d0a4d","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"bb4f7df992d915723222f62a4f995896cce861821c73351d831cb01a34cef0c4","src/backend/tests/device_property.rs":"4ef3ab625809fe95e944c19cc5dc1cc79f473520a4314d123b1f80c6b7e11411","src/backend/tests/interfaces.rs":"a96d1432afd381bf74dcbe73e892dfc4ddc68721a956606c94fd4128c6589adc","src/backend/tests/manual.rs":"f72625c05110534775c4608ccc45472ea108286657ffc1f029844a13d0b883bf","src/backend/tests/mod.rs":"8dba770023d7f9c4228f0e11915347f0e07da5fd818e3ee4478c4b197af9aa2a","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"9f4f486b3d59081747785dae4828ec22a4ecbab755ac4c09ff2c0c065865a358","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"be88c967e470bf6c120f3e42f7155fe89a4718f56a35524ea4c17181856757d5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null} \ No newline at end of file +{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"cf6ebe6d41b022897360866b526d19ba8843aa82ae99a1d28393985576b6a782",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"30055d2e57f01a13858b0605333add2c5afc02e7d55515eedf561deebb327046","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"967448b6cd46a8e60d465d56be0b1e6794a18110592a30939d2cb0650c4e5bc6","run_sanitizers.sh":"84e93a0da137803018f37403511e8c92760be730426bf6cea34419d93d1a7ff8","run_tests.sh":"bae82f66dd47a060b6fdcc238520084aec1079d5b1b1d66d103baa1ffaa8773d","src/backend/aggregate_device.rs":"a910b9d596b1971cb4fee34f5030809ade584f41eb5cbad73a09abe7352ebd15","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"e9bcf964347daa8952f98caa2746e34a31ea8908375204896593f56e4b6147ca","src/backend/device_property.rs":"30ceeceee4fc1f6f872c6c61765e41d582ccd91d2d1ac3ca9b1e5ac18dd11a71","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"1f96b4bc17d67d4a20df974e81030c5d286454d1d85b372f3fa5bd8f207d3e35","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"afbdf1da1fcaddcad2986bd3146bf93ca75c24b3362f5f23a09517a926290ca2","src/backend/tests/api.rs":"3b0936810b3afa84cb80428c471e1097701fd790460d00c0a5715fd8026d0a4d","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"bb4f7df992d915723222f62a4f995896cce861821c73351d831cb01a34cef0c4","src/backend/tests/device_property.rs":"4ef3ab625809fe95e944c19cc5dc1cc79f473520a4314d123b1f80c6b7e11411","src/backend/tests/interfaces.rs":"a96d1432afd381bf74dcbe73e892dfc4ddc68721a956606c94fd4128c6589adc","src/backend/tests/manual.rs":"f72625c05110534775c4608ccc45472ea108286657ffc1f029844a13d0b883bf","src/backend/tests/mod.rs":"8dba770023d7f9c4228f0e11915347f0e07da5fd818e3ee4478c4b197af9aa2a","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"9f4f486b3d59081747785dae4828ec22a4ecbab755ac4c09ff2c0c065865a358","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"be88c967e470bf6c120f3e42f7155fe89a4718f56a35524ea4c17181856757d5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null} \ No newline at end of file diff --git a/third_party/rust/cubeb-coreaudio/Cargo.toml b/third_party/rust/cubeb-coreaudio/Cargo.toml index e55840520b..2e04a62560 100644 --- a/third_party/rust/cubeb-coreaudio/Cargo.toml +++ b/third_party/rust/cubeb-coreaudio/Cargo.toml @@ -9,6 +9,11 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] name = "cubeb-coreaudio" version = "0.1.0" @@ -16,14 +21,21 @@ authors = [ "Chun-Min Chang ", "Paul Adenot ", ] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "ISC" [lib] +name = "cubeb_coreaudio" crate-type = [ "staticlib", "rlib", ] +path = "src/lib.rs" [dependencies] atomic = "0.4" diff --git a/third_party/rust/cubeb-pulse/.cargo-checksum.json b/third_party/rust/cubeb-pulse/.cargo-checksum.json index 769b8c77af..04fe71d3e5 100644 --- a/third_party/rust/cubeb-pulse/.cargo-checksum.json +++ b/third_party/rust/cubeb-pulse/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".github/workflows/build.yml":"477366d58c9dc059dbe4a158a6e910f23a3e9ecac7411f73616e06375583b764","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"8a0a450ae4990e1df322464867212e48587b474dfdc7f8c270fac06980be176a","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"0079450bb4b013bac065ed1750851e461a3710ebad1f323817da1cb82db0bc4f","src/backend/context.rs":"c0db5f2447de1d6df5aa2812fa342a085e73156a072c221c7379b9a6a9b86786","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mod.rs":"dfb30ec497d6215e4535e936fea8fe3a407ef24dc1cec43b52c0ffa923d9229c","src/backend/stream.rs":"dfe5b747e100cae4aeae36cf2ebb9dc4715b411b4116721a40eec2944eb0ec23","src/capi.rs":"fa0fa020f0d0efe55aa0fc3596405e8407bbe2cbe6c7a558345304e6da87994e","src/lib.rs":"b41bbdc562cbfb130ed7c1e53fe69944774f515705341d8ce48a2f82c8c0c2c5"},"package":null} \ No newline at end of file +{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".github/workflows/build.yml":"477366d58c9dc059dbe4a158a6e910f23a3e9ecac7411f73616e06375583b764","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"5783bef893723cfef7fe9139ba018d20710dae3f3390b6695d7552c367fbcaa5","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"0079450bb4b013bac065ed1750851e461a3710ebad1f323817da1cb82db0bc4f","src/backend/context.rs":"c0db5f2447de1d6df5aa2812fa342a085e73156a072c221c7379b9a6a9b86786","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mod.rs":"dfb30ec497d6215e4535e936fea8fe3a407ef24dc1cec43b52c0ffa923d9229c","src/backend/stream.rs":"dfe5b747e100cae4aeae36cf2ebb9dc4715b411b4116721a40eec2944eb0ec23","src/capi.rs":"fa0fa020f0d0efe55aa0fc3596405e8407bbe2cbe6c7a558345304e6da87994e","src/lib.rs":"b41bbdc562cbfb130ed7c1e53fe69944774f515705341d8ce48a2f82c8c0c2c5"},"package":null} \ No newline at end of file diff --git a/third_party/rust/cubeb-pulse/Cargo.toml b/third_party/rust/cubeb-pulse/Cargo.toml index eec888a5f5..127ae48e89 100644 --- a/third_party/rust/cubeb-pulse/Cargo.toml +++ b/third_party/rust/cubeb-pulse/Cargo.toml @@ -9,19 +9,31 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] name = "cubeb-pulse" version = "0.5.0" authors = ["Dan Glastonbury "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Cubeb backed for PulseAudio written in Rust" readme = "README.md" license = "ISC" [lib] +name = "cubeb_pulse" crate-type = [ "staticlib", "rlib", ] +path = "src/lib.rs" [dependencies] cubeb-backend = "0.13" diff --git a/third_party/rust/error-support-macros/.cargo-checksum.json b/third_party/rust/error-support-macros/.cargo-checksum.json index 65c2ea5e04..60ecfcf6f7 100644 --- a/third_party/rust/error-support-macros/.cargo-checksum.json +++ b/third_party/rust/error-support-macros/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"7143b51f48478384002380c7d6a5a071c7e985b1fc86cf2c74d4e738ba41b541","src/lib.rs":"67740f320fb8012c7df017ed2ad5ebe130940a3bb73d42e0445b31b39f844d79"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"3f77e73d49fc92f0d73bcac4efa475a9404f8feed5e9bc1cf73c3a3f5c871040","src/lib.rs":"67740f320fb8012c7df017ed2ad5ebe130940a3bb73d42e0445b31b39f844d79"},"package":null} \ No newline at end of file diff --git a/third_party/rust/error-support-macros/Cargo.toml b/third_party/rust/error-support-macros/Cargo.toml index 4d194ddc60..b0f0e3e83a 100644 --- a/third_party/rust/error-support-macros/Cargo.toml +++ b/third_party/rust/error-support-macros/Cargo.toml @@ -9,14 +9,27 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "error-support-macros" version = "0.1.0" +build = false publish = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" [lib] +name = "error_support_macros" +path = "src/lib.rs" proc-macro = true [dependencies] diff --git a/third_party/rust/error-support/.cargo-checksum.json b/third_party/rust/error-support/.cargo-checksum.json index cfd085d1f5..f602db9bff 100644 --- a/third_party/rust/error-support/.cargo-checksum.json +++ b/third_party/rust/error-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"bd2f0908b3576a3ad9a416ecb0e4f8441a48a95036cf0439a65e37d836178142","README.md":"99fb739e79beb2c2d34f38d502cd758a1470b3ecf22c8f7fb05b97f324918cf4","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"e793034d01a2608298528051757f38405e006ee1abc4cf65dc6f18c53590ace8","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"96ae3cc2c1077ae45442ace6b5b5311b86267d0b9067f3ff58396af30ccbbc07","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"b8e03402edf3111718fc9c2ec179622307f4a117db05ac220ead631c9de28362","uniffi.toml":"644fe81c12fe3c01ee81e017ca3c00d0e611f014b7eade51aadaf208179a3450"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"94e027935f3f804f464831ad7717936e7068517252b1f0e6fd0a025220bc2c35","README.md":"99fb739e79beb2c2d34f38d502cd758a1470b3ecf22c8f7fb05b97f324918cf4","build.rs":"c8d3c38c1208eea36224662b284d8daf3e7ad1b07d22d750524f3da1cc66ccca","src/errorsupport.udl":"e793034d01a2608298528051757f38405e006ee1abc4cf65dc6f18c53590ace8","src/handling.rs":"6e0568b18d426531cb2ae9967c8dd0d51ece5a065f68b15eeb308b995edaa167","src/lib.rs":"96ae3cc2c1077ae45442ace6b5b5311b86267d0b9067f3ff58396af30ccbbc07","src/macros.rs":"0d03f82fab20c96a182f941baf3fcf2a286b00fea871ee7fd8e339abc14f9522","src/redact.rs":"c9a4df1a87be68b15d583587bda941d4c60a1d0449e2d43ff99f3611a290a863","src/reporting.rs":"b8e03402edf3111718fc9c2ec179622307f4a117db05ac220ead631c9de28362","uniffi.toml":"644fe81c12fe3c01ee81e017ca3c00d0e611f014b7eade51aadaf208179a3450"},"package":null} \ No newline at end of file diff --git a/third_party/rust/error-support/Cargo.toml b/third_party/rust/error-support/Cargo.toml index 074ad4a32d..a425a3d548 100644 --- a/third_party/rust/error-support/Cargo.toml +++ b/third_party/rust/error-support/Cargo.toml @@ -9,19 +9,31 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "error-support" version = "0.1.0" authors = ["Thom Chiovoloni "] +build = "build.rs" exclude = ["/android"] +autobins = false +autoexamples = false autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" +[lib] +name = "error_support" +path = "src/lib.rs" + [dependencies] log = "0.4" -uniffi = "0.27.1" [dependencies.backtrace] version = "0.3" @@ -36,6 +48,9 @@ version = "1.4" [dependencies.parking_lot] version = ">=0.11,<=0.12" +[dependencies.uniffi] +version = "0.27.1" + [build-dependencies.uniffi] version = "0.27.1" features = ["build"] diff --git a/third_party/rust/ews/.cargo-checksum.json b/third_party/rust/ews/.cargo-checksum.json index 471559359e..0f0b7f3b14 100644 --- a/third_party/rust/ews/.cargo-checksum.json +++ b/third_party/rust/ews/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".github/workflows/ci.yaml":"86a41c10a1b90620bb4548c8f18d082e906c2274e8f1d951568e4c070b10d8cb","Cargo.toml":"299ada7eebff29d475c7bc1068d6d1323930a34a4fae7dca303515ff7e25f2e1","LICENSE":"3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04","README.md":"eebefef86e483df98c6b1104101348293fbacbd16639f15044ca37d2949b68f1","src/lib.rs":"20e850b188c53ad1c5d533a4a7d797fd88a18b0aa1ca1486b8cd839ca94749b6","src/types.rs":"afa4bc3d11fdfdfd25fa23d50d2541d04087f0918609fad5db737b68cc7a73d1","src/types/common.rs":"c8e5babb87766a4fb6728b69f5f76c788640bdc08c95c0b32d1644af06268949","src/types/create_item.rs":"25cfd2c4bc266a87b86734af81c6c031e798135f60a20d2c251aa944a8c36a24","src/types/get_folder.rs":"4b26621d2efd40a406afabbd6e4c092c7aafd73e07c11e8cbdad19bed205d238","src/types/get_item.rs":"401f60da2ffb7ccda1dda56e25876c640851597bb137ce34a7f7eb0fc94508d4","src/types/operations.rs":"69a1f976f5fca24bff77765003dc8345df2aebd3f632f3480f41fd9d2011c3c1","src/types/soap.rs":"640b49ecd88d06054e71b8c464e13f34e1010e8bce942158e9d8ede1fd35e212","src/types/soap/de.rs":"6fb603f521a73984e5707988379e562018b179df54647cff89d8ab03c406cff2","src/types/sync_folder_hierarchy.rs":"1f219d9bda6f4685ba962ff0cb891a9925e6a5c7d159d0a3f4561ca8439a71d5","src/types/sync_folder_items.rs":"e8548d6e9b6b847bfafc399b7168092875b7bebf5fca74b47d082a0dc7ef53d1"},"package":null} \ No newline at end of file +{"files":{".github/workflows/ci.yaml":"86a41c10a1b90620bb4548c8f18d082e906c2274e8f1d951568e4c070b10d8cb","Cargo.toml":"e43bfd3732877f47ec58825606b14bfea81d4883bbb0c1ef0067649af1cfafa5","LICENSE":"3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04","README.md":"eebefef86e483df98c6b1104101348293fbacbd16639f15044ca37d2949b68f1","src/lib.rs":"20e850b188c53ad1c5d533a4a7d797fd88a18b0aa1ca1486b8cd839ca94749b6","src/types.rs":"afa4bc3d11fdfdfd25fa23d50d2541d04087f0918609fad5db737b68cc7a73d1","src/types/common.rs":"c8e5babb87766a4fb6728b69f5f76c788640bdc08c95c0b32d1644af06268949","src/types/create_item.rs":"25cfd2c4bc266a87b86734af81c6c031e798135f60a20d2c251aa944a8c36a24","src/types/get_folder.rs":"4b26621d2efd40a406afabbd6e4c092c7aafd73e07c11e8cbdad19bed205d238","src/types/get_item.rs":"401f60da2ffb7ccda1dda56e25876c640851597bb137ce34a7f7eb0fc94508d4","src/types/operations.rs":"69a1f976f5fca24bff77765003dc8345df2aebd3f632f3480f41fd9d2011c3c1","src/types/soap.rs":"640b49ecd88d06054e71b8c464e13f34e1010e8bce942158e9d8ede1fd35e212","src/types/soap/de.rs":"6fb603f521a73984e5707988379e562018b179df54647cff89d8ab03c406cff2","src/types/sync_folder_hierarchy.rs":"1f219d9bda6f4685ba962ff0cb891a9925e6a5c7d159d0a3f4561ca8439a71d5","src/types/sync_folder_items.rs":"e8548d6e9b6b847bfafc399b7168092875b7bebf5fca74b47d082a0dc7ef53d1"},"package":null} \ No newline at end of file diff --git a/third_party/rust/ews/Cargo.toml b/third_party/rust/ews/Cargo.toml index 9e892b4259..79bf401ba2 100644 --- a/third_party/rust/ews/Cargo.toml +++ b/third_party/rust/ews/Cargo.toml @@ -9,12 +9,26 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "ews" version = "0.1.0" +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" +[lib] +name = "ews" +path = "src/lib.rs" + [dependencies] serde_path_to_error = "0.1.11" thiserror = "1.0.57" diff --git a/third_party/rust/gpu-descriptor-types/.cargo-checksum.json b/third_party/rust/gpu-descriptor-types/.cargo-checksum.json index 9a414739ec..c61d03aa48 100644 --- a/third_party/rust/gpu-descriptor-types/.cargo-checksum.json +++ b/third_party/rust/gpu-descriptor-types/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"54164c8c1352852cce6f2330030365868815deb9bd717b8d493071790cd72d7b","src/device.rs":"0f9957fee64c4db767a2abb2e88d34ebbf48ed6062121e081e0116e14190b4fa","src/lib.rs":"0ca3f2a281ba43466fb4d29c05b35c9059806d6114cd929b85afc0c41ea9d3ac","src/types.rs":"d38b838827edf226f6bc82e8f0718d90d6e2376d027c118a6d397260996a12bd"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"60c47399fe6c588dc470b7f1d784a7bba1797a1d0893631b667730ec2d05df66","src/device.rs":"0f9957fee64c4db767a2abb2e88d34ebbf48ed6062121e081e0116e14190b4fa","src/lib.rs":"0ca3f2a281ba43466fb4d29c05b35c9059806d6114cd929b85afc0c41ea9d3ac","src/types.rs":"d38b838827edf226f6bc82e8f0718d90d6e2376d027c118a6d397260996a12bd"},"package":null} \ No newline at end of file diff --git a/third_party/rust/gpu-descriptor-types/Cargo.toml b/third_party/rust/gpu-descriptor-types/Cargo.toml index f63ba9b7b6..5d5904faa9 100644 --- a/third_party/rust/gpu-descriptor-types/Cargo.toml +++ b/third_party/rust/gpu-descriptor-types/Cargo.toml @@ -9,14 +9,25 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "gpu-descriptor-types" version = "0.2.0" authors = ["Zakarum "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Core types of gpu-descriptor crate" homepage = "https://github.com/zakarumych/gpu-descriptor" documentation = "https://docs.rs/gpu-descriptor-types" +readme = false keywords = [ "gpu", "vulkan", @@ -26,6 +37,10 @@ keywords = [ license = "MIT OR Apache-2.0" repository = "https://github.com/zakarumych/gpu-descriptor" +[lib] +name = "gpu_descriptor_types" +path = "src/lib.rs" + [dependencies.bitflags] version = "2.4" default-features = false diff --git a/third_party/rust/gpu-descriptor/.cargo-checksum.json b/third_party/rust/gpu-descriptor/.cargo-checksum.json index f4fb18bc58..d06c082d82 100644 --- a/third_party/rust/gpu-descriptor/.cargo-checksum.json +++ b/third_party/rust/gpu-descriptor/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"0bd7a40cb614fe568b076fd5edd6d6e51791b6d1e0a174ae67a16d56618357e1","src/allocator.rs":"38d173f9b6ca608dee9a7898b6e2ad7e75d199284c99291da0112e4b6e908409","src/lib.rs":"6fb74a08ad9975e561f4fca7bd391f0cbd96a7cab79b17df7d979021099b50f9"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"6940fe7701f7d1ce93e1aca0b7c4b082c3b63560bf09e2c2a188254318688785","src/allocator.rs":"38d173f9b6ca608dee9a7898b6e2ad7e75d199284c99291da0112e4b6e908409","src/lib.rs":"6fb74a08ad9975e561f4fca7bd391f0cbd96a7cab79b17df7d979021099b50f9"},"package":null} \ No newline at end of file diff --git a/third_party/rust/gpu-descriptor/Cargo.toml b/third_party/rust/gpu-descriptor/Cargo.toml index 7524894008..7cc40f31d2 100644 --- a/third_party/rust/gpu-descriptor/Cargo.toml +++ b/third_party/rust/gpu-descriptor/Cargo.toml @@ -9,11 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "gpu-descriptor" version = "0.3.0" authors = ["Zakarum "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Implementation agnostic descriptor allocator for Vulkan like APIs" homepage = "https://github.com/zakarumych/gpu-descriptor" documentation = "https://docs.rs/gpu-descriptor" @@ -26,6 +36,10 @@ keywords = [ license = "MIT OR Apache-2.0" repository = "https://github.com/zakarumych/gpu-descriptor" +[lib] +name = "gpu_descriptor" +path = "src/lib.rs" + [dependencies.bitflags] version = "2.4" default-features = false diff --git a/third_party/rust/interrupt-support/.cargo-checksum.json b/third_party/rust/interrupt-support/.cargo-checksum.json index 38414eddae..fc2244ad2a 100644 --- a/third_party/rust/interrupt-support/.cargo-checksum.json +++ b/third_party/rust/interrupt-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"eb30cf4d9a37bc842d15266d4cf648c8b435653fe91599ca42954880f6304589","README.md":"7f1418b4a7c138ba20bcaea077fe6cf0d6ffbaf6df6b90c80efc52aa0d0e2e9f","build.rs":"49840f26c73c5db19cb4e7f02930e49d7a19648168b83f2313ac1a0303c103df","src/error.rs":"b83cbe8abd22a9d687508d236a2a77e28b3fc6c39673633e5820cc0e3fc86cba","src/interrupt_support.udl":"31181937f89dbc229837484dec47a228955bb1b6c47d3b049d91f23cbe7dc069","src/interruptee.rs":"c56f9ac610d0b24a128a907266432287558c4b73f6c24b82674ca7894181d18f","src/lib.rs":"cf44a84310913be5264e1c4a3e004a9f7a6cd82d01a109bb6ac4d6002b5dd560","src/shutdown.rs":"e4b7a89f1ef319646aee3282a0d60465c3dbf571c52a0295f3b1a8909f345818","src/sql.rs":"db9b93fb2fe813ae0af6313082f07fad0e381691290466a7ac67bec14024722d"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"43f4bde7de7da5eb46d786bb77c57d7d120573c41e41387a3b89b0158810b9e8","README.md":"7f1418b4a7c138ba20bcaea077fe6cf0d6ffbaf6df6b90c80efc52aa0d0e2e9f","build.rs":"49840f26c73c5db19cb4e7f02930e49d7a19648168b83f2313ac1a0303c103df","src/error.rs":"b83cbe8abd22a9d687508d236a2a77e28b3fc6c39673633e5820cc0e3fc86cba","src/interrupt_support.udl":"31181937f89dbc229837484dec47a228955bb1b6c47d3b049d91f23cbe7dc069","src/interruptee.rs":"c56f9ac610d0b24a128a907266432287558c4b73f6c24b82674ca7894181d18f","src/lib.rs":"cf44a84310913be5264e1c4a3e004a9f7a6cd82d01a109bb6ac4d6002b5dd560","src/shutdown.rs":"e4b7a89f1ef319646aee3282a0d60465c3dbf571c52a0295f3b1a8909f345818","src/sql.rs":"db9b93fb2fe813ae0af6313082f07fad0e381691290466a7ac67bec14024722d"},"package":null} \ No newline at end of file diff --git a/third_party/rust/interrupt-support/Cargo.toml b/third_party/rust/interrupt-support/Cargo.toml index f653276a2e..03b87ee304 100644 --- a/third_party/rust/interrupt-support/Cargo.toml +++ b/third_party/rust/interrupt-support/Cargo.toml @@ -9,18 +9,31 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "interrupt-support" version = "0.1.0" authors = ["Sync Team "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" +[lib] +name = "interrupt_support" +path = "src/lib.rs" + [dependencies] lazy_static = "1.4" parking_lot = ">=0.11,<=0.12" -uniffi = "0.27.1" [dependencies.rusqlite] version = "0.31.0" @@ -31,6 +44,9 @@ features = [ "unlock_notify", ] +[dependencies.uniffi] +version = "0.27.1" + [build-dependencies.uniffi] version = "0.27.1" features = ["build"] diff --git a/third_party/rust/jsparagus-ast/.cargo-checksum.json b/third_party/rust/jsparagus-ast/.cargo-checksum.json index 24a6ac623d..fff0841102 100644 --- a/third_party/rust/jsparagus-ast/.cargo-checksum.json +++ b/third_party/rust/jsparagus-ast/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"a2ec3cc2de80074959295ecce7a6c5a491377c73ba5751ccbf59953cf2d0667a","ast.json":"e9c358aedb77bf02059f44179140d900c705af592069f269022bc9b52dc30ac4","generate_ast.py":"0c24431d9c07af42d7d17739c2e21465964151562437cfca093ceddde898bc93","src/arena.rs":"03ef07c963556160a6f1a85fd901833d7322f8a5f265c20d3e3543432dd2a96d","src/associated_data.rs":"5e0d830b0c6db4dcb85ba21ead87d31cd386e2517804333a6f46a1bd1bf59355","src/dump_generated.rs":"8ca0736952ee41fc932807e8450c6eb68e081b3fd5f7a0f701cae8b35dc0c13e","src/lib.rs":"b35553bedec9f6d88cc5194592f857dc13669559cbc8b206048c35299c4f86be","src/source_atom_set.rs":"24ec99be098cab6aa433d7b2e0a2cbc074204276d6c90b17174e50f8003244ee","src/source_location.rs":"3832440ecec6de726262837072810410bddb45c075288386509511c153f6afd9","src/source_location_accessor_generated.rs":"2669efcc5447229429f8fab6123bbd9dec8ed4c69232992af05aca3a59f1c710","src/source_slice_list.rs":"c82413b3081e091a3c4ce5d2c3624e54ecbeb0bb9952f10d373d10faf589955a","src/type_id_generated.rs":"a1e88f0d9d97d61339d0bedd0f6a8472bd39ea13968531ebce7140ca47edbaeb","src/types_generated.rs":"eda341459f8356dc46a6f8ed993740bcf1536c6b6601d885f2a20f4a7a4d4e4a","src/visit_generated.rs":"90ae82f2db8b33f5b23eae1b1b21f1ce4c14a79719bc46e44a838a04c7d838e4"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"e26729e45138f070e83866aaa2b9d6f0278c07449485346a727aea591d31318d","ast.json":"e9c358aedb77bf02059f44179140d900c705af592069f269022bc9b52dc30ac4","generate_ast.py":"0c24431d9c07af42d7d17739c2e21465964151562437cfca093ceddde898bc93","src/arena.rs":"03ef07c963556160a6f1a85fd901833d7322f8a5f265c20d3e3543432dd2a96d","src/associated_data.rs":"5e0d830b0c6db4dcb85ba21ead87d31cd386e2517804333a6f46a1bd1bf59355","src/dump_generated.rs":"8ca0736952ee41fc932807e8450c6eb68e081b3fd5f7a0f701cae8b35dc0c13e","src/lib.rs":"b35553bedec9f6d88cc5194592f857dc13669559cbc8b206048c35299c4f86be","src/source_atom_set.rs":"24ec99be098cab6aa433d7b2e0a2cbc074204276d6c90b17174e50f8003244ee","src/source_location.rs":"3832440ecec6de726262837072810410bddb45c075288386509511c153f6afd9","src/source_location_accessor_generated.rs":"2669efcc5447229429f8fab6123bbd9dec8ed4c69232992af05aca3a59f1c710","src/source_slice_list.rs":"c82413b3081e091a3c4ce5d2c3624e54ecbeb0bb9952f10d373d10faf589955a","src/type_id_generated.rs":"a1e88f0d9d97d61339d0bedd0f6a8472bd39ea13968531ebce7140ca47edbaeb","src/types_generated.rs":"eda341459f8356dc46a6f8ed993740bcf1536c6b6601d885f2a20f4a7a4d4e4a","src/visit_generated.rs":"90ae82f2db8b33f5b23eae1b1b21f1ce4c14a79719bc46e44a838a04c7d838e4"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-ast/Cargo.toml b/third_party/rust/jsparagus-ast/Cargo.toml index e4556efb63..1e4898bbf9 100644 --- a/third_party/rust/jsparagus-ast/Cargo.toml +++ b/third_party/rust/jsparagus-ast/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-ast" version = "0.1.0" authors = ["khyperia "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_ast" +path = "src/lib.rs" + [dependencies] indexmap = "2.0" diff --git a/third_party/rust/jsparagus-emitter/.cargo-checksum.json b/third_party/rust/jsparagus-emitter/.cargo-checksum.json index 5a4fce48c8..809943ecc6 100644 --- a/third_party/rust/jsparagus-emitter/.cargo-checksum.json +++ b/third_party/rust/jsparagus-emitter/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"97ba372ad5ce5a4a16e8e2d0fd086b66e3383d6577b5c68de289e8767085b0a8","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"050858e25f6bab6787771058afe504c66e74e9026e9ce873160bccc6366eca47","src/block_emitter.rs":"78965260d87a66c5324d6f3bdfea0f1938f8037f70adde148dbb2db599d1b2c0","src/compilation_info.rs":"b0d91b0f8d6940cb7087b474c3c814b758c8ce8d9027c415b76ad4af78be6140","src/control_structures.rs":"b32fbfff53bd378dcb45d63620006bea15c2fec1e7bc0bb163567dfe086e4931","src/dis.rs":"4a335d813fa965482ca0f20a7b9295a55ce7625b577d42bd8b33b156b81c6306","src/emitter.rs":"41a6a642d1970e625c264fc58bf245c6975b1e2d86707481ce4f942798c4b48a","src/emitter_scope.rs":"93c2b2a324ccb46b74adb2a28f56360a32652088e59c03641b4f1b608549dc78","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function_declaration_emitter.rs":"0e6ae706ced215882f3a45b6e13f022ec1effa8edf1026b7ba7988810646982b","src/lib.rs":"f91576fb0f1e3cf444dd1d8ee25ee9bfd0b1e890e427a3863fdb6a4ad1611b61","src/object_emitter.rs":"998423b3d6ef8797fadef6763803627df72fde292b1b34d6a41b2e66a331a181","src/reference_op_emitter.rs":"e1507033c17318f59dbbdd1514d1bd1263f0c7d72530d0f2b2ab071d58b39f72","src/script_emitter.rs":"150a3d6330f40099ad1df8c52cd1831e3ef0fd4eecf44a20e3fff7acef2dd640"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"aa006937172e5b7fe128b32826658caf05652bdabf2708d17668fe910d94135d","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"050858e25f6bab6787771058afe504c66e74e9026e9ce873160bccc6366eca47","src/block_emitter.rs":"78965260d87a66c5324d6f3bdfea0f1938f8037f70adde148dbb2db599d1b2c0","src/compilation_info.rs":"b0d91b0f8d6940cb7087b474c3c814b758c8ce8d9027c415b76ad4af78be6140","src/control_structures.rs":"b32fbfff53bd378dcb45d63620006bea15c2fec1e7bc0bb163567dfe086e4931","src/dis.rs":"4a335d813fa965482ca0f20a7b9295a55ce7625b577d42bd8b33b156b81c6306","src/emitter.rs":"41a6a642d1970e625c264fc58bf245c6975b1e2d86707481ce4f942798c4b48a","src/emitter_scope.rs":"93c2b2a324ccb46b74adb2a28f56360a32652088e59c03641b4f1b608549dc78","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function_declaration_emitter.rs":"0e6ae706ced215882f3a45b6e13f022ec1effa8edf1026b7ba7988810646982b","src/lib.rs":"f91576fb0f1e3cf444dd1d8ee25ee9bfd0b1e890e427a3863fdb6a4ad1611b61","src/object_emitter.rs":"998423b3d6ef8797fadef6763803627df72fde292b1b34d6a41b2e66a331a181","src/reference_op_emitter.rs":"e1507033c17318f59dbbdd1514d1bd1263f0c7d72530d0f2b2ab071d58b39f72","src/script_emitter.rs":"150a3d6330f40099ad1df8c52cd1831e3ef0fd4eecf44a20e3fff7acef2dd640"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-emitter/Cargo.toml b/third_party/rust/jsparagus-emitter/Cargo.toml index 0bc772dac6..a043cff506 100644 --- a/third_party/rust/jsparagus-emitter/Cargo.toml +++ b/third_party/rust/jsparagus-emitter/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-emitter" version = "0.1.0" authors = ["khyperia "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_emitter" +path = "src/lib.rs" + [dependencies] bumpalo = "3.4.0" byteorder = "1.3.2" diff --git a/third_party/rust/jsparagus-generated-parser/.cargo-checksum.json b/third_party/rust/jsparagus-generated-parser/.cargo-checksum.json index 588cdb8c91..efb960b1ab 100644 --- a/third_party/rust/jsparagus-generated-parser/.cargo-checksum.json +++ b/third_party/rust/jsparagus-generated-parser/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"e0db416379972a3fa13913fdae9624e6ba664a1e4dd4d37692810e825f88b34f","src/ast_builder.rs":"15eebf519763b94e7c11791a1a90b1f73ec00d447857e230232e1d45599e30e5","src/context_stack.rs":"29331d03cd4c8ee9283cb426ebe893b7ba6ad6d8a69016399c4d92a81cb1363b","src/declaration_kind.rs":"fdfda2fe408cce1c637d17fee0813160619450472c6de9befc36ebeed892cc3c","src/early_error_checker.rs":"89da86f7f78392cb60a909c240e430779eed0fc250b3b3c8466665eeaf2fbc25","src/early_errors.rs":"8674454af7ac5efe51eb6a8e2abe088aad5560e0a0bd88a3eae66c90f1527149","src/error.rs":"507e4dd9c66720f3da2db135c3024392d8aaac5ccdb90c7f7463ccb2eff7efa8","src/lib.rs":"b74105a84c4a141b880439f9ec724f7dc08224342be08a73490ac2c01410af08","src/parser_tables_generated.rs":"cbd34e453df376a54c663991314dcd0e12b0009d09754ff8731360931f6f5358","src/stack_value_generated.rs":"ce8567634ff2bb818593f56c0589b4ba2d508704db943eb0778d79dfd19cce36","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"ba74c71f7218027f8188247bc64df243117613fbc9893d40799402ef1e6dbf59"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"c825e51c6f7319c85557ea73653def128f146283f68de616eb181da398298322","src/ast_builder.rs":"15eebf519763b94e7c11791a1a90b1f73ec00d447857e230232e1d45599e30e5","src/context_stack.rs":"29331d03cd4c8ee9283cb426ebe893b7ba6ad6d8a69016399c4d92a81cb1363b","src/declaration_kind.rs":"fdfda2fe408cce1c637d17fee0813160619450472c6de9befc36ebeed892cc3c","src/early_error_checker.rs":"89da86f7f78392cb60a909c240e430779eed0fc250b3b3c8466665eeaf2fbc25","src/early_errors.rs":"8674454af7ac5efe51eb6a8e2abe088aad5560e0a0bd88a3eae66c90f1527149","src/error.rs":"507e4dd9c66720f3da2db135c3024392d8aaac5ccdb90c7f7463ccb2eff7efa8","src/lib.rs":"b74105a84c4a141b880439f9ec724f7dc08224342be08a73490ac2c01410af08","src/parser_tables_generated.rs":"cbd34e453df376a54c663991314dcd0e12b0009d09754ff8731360931f6f5358","src/stack_value_generated.rs":"ce8567634ff2bb818593f56c0589b4ba2d508704db943eb0778d79dfd19cce36","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"ba74c71f7218027f8188247bc64df243117613fbc9893d40799402ef1e6dbf59"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-generated-parser/Cargo.toml b/third_party/rust/jsparagus-generated-parser/Cargo.toml index b3b773bc52..7a133c9005 100644 --- a/third_party/rust/jsparagus-generated-parser/Cargo.toml +++ b/third_party/rust/jsparagus-generated-parser/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-generated-parser" version = "0.1.0" authors = ["khyperia "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_generated_parser" +path = "src/lib.rs" + [dependencies] bumpalo = "3.4.0" static_assertions = "1.1.0" diff --git a/third_party/rust/jsparagus-json-log/.cargo-checksum.json b/third_party/rust/jsparagus-json-log/.cargo-checksum.json index 61ece706d4..b6b2d6b21e 100644 --- a/third_party/rust/jsparagus-json-log/.cargo-checksum.json +++ b/third_party/rust/jsparagus-json-log/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"215b06c56addd1cb805cf47e588d52ba7b0cb4bc3216a7ab3164b0d362d93b78","src/lib.rs":"09352799b74833de10a95ce1097fb0d1a3f3474468f61dc9adeb58705508e632"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"85a112a13d8c924eb727a3769569f2515fbe11f64336a78b5ce938af87af92ec","src/lib.rs":"09352799b74833de10a95ce1097fb0d1a3f3474468f61dc9adeb58705508e632"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-json-log/Cargo.toml b/third_party/rust/jsparagus-json-log/Cargo.toml index b78e29137c..5e9fbe1e35 100644 --- a/third_party/rust/jsparagus-json-log/Cargo.toml +++ b/third_party/rust/jsparagus-json-log/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-json-log" version = "0.1.0" authors = ["The jsparagus Project Developers"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_json_log" +path = "src/lib.rs" + [dependencies.log] version = "0.4.0" features = [ diff --git a/third_party/rust/jsparagus-parser/.cargo-checksum.json b/third_party/rust/jsparagus-parser/.cargo-checksum.json index f28c683696..63afc18647 100644 --- a/third_party/rust/jsparagus-parser/.cargo-checksum.json +++ b/third_party/rust/jsparagus-parser/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"9ef3ec903b675e57867f02252811185c0da07362e19561e392df741c21e880e1","benches/__finStreamer-proto.js":"44edc00a99a8904f8c6bb0c42c7ba4f96ad611e61191d2702ecb228ae6d7b35d","benches/parser.rs":"6cb13b135513e86b94e1bbe1470156f182355078c2e34bf8d9deba1c67daf4b9","benches/simple.js":"fbb50c1c49c0b1e3740a79407a834248c1f8ebdb1b72530c0fc6df57d079f252","src/lexer.rs":"fc641c9e320652c7f73bdf78080ba73b84a5afcea0fa88759039290ce659d2e0","src/lib.rs":"12fb80fe5b0429f96540385ebfde861f98750ca629769f1bff47f22ab094e882","src/numeric_value.rs":"f429c50640eb35a53aa5ffdf71de305da30747e568dc10219c54b766372f6eca","src/parser.rs":"d7e69fd548d3149bc2aa4ef8e0e35725c9188dcaab470c899c66ba485445625f","src/queue_stack.rs":"5abbcfd65c655507e0fad545242bbff24db523ae962b5d02aac4e7f1debba293","src/simulator.rs":"fe77deff60bdddff4d2e1e243bc1660603506c515f1c88ffda87d0f9c9b341eb","src/tests.rs":"ad30ed0a762dbbde7562ba9eed1d282abdf4640135f1f9cabaef333b9d6e5fe2","src/unicode.rs":"0e5d77d4d6751c6441982ae3d4a8453233443376441c5c01da5c86a5a5051167","src/unicode_data.rs":"5356c11b9ac59300bb29c164b26efc7b1ce263864e47ce90a68734277be1c392"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"f0fb42c461194b402b4e8aa675a9fd971b380f34e1b605f3d67fe833b15374bf","benches/__finStreamer-proto.js":"44edc00a99a8904f8c6bb0c42c7ba4f96ad611e61191d2702ecb228ae6d7b35d","benches/parser.rs":"6cb13b135513e86b94e1bbe1470156f182355078c2e34bf8d9deba1c67daf4b9","benches/simple.js":"fbb50c1c49c0b1e3740a79407a834248c1f8ebdb1b72530c0fc6df57d079f252","src/lexer.rs":"fc641c9e320652c7f73bdf78080ba73b84a5afcea0fa88759039290ce659d2e0","src/lib.rs":"12fb80fe5b0429f96540385ebfde861f98750ca629769f1bff47f22ab094e882","src/numeric_value.rs":"f429c50640eb35a53aa5ffdf71de305da30747e568dc10219c54b766372f6eca","src/parser.rs":"d7e69fd548d3149bc2aa4ef8e0e35725c9188dcaab470c899c66ba485445625f","src/queue_stack.rs":"5abbcfd65c655507e0fad545242bbff24db523ae962b5d02aac4e7f1debba293","src/simulator.rs":"fe77deff60bdddff4d2e1e243bc1660603506c515f1c88ffda87d0f9c9b341eb","src/tests.rs":"ad30ed0a762dbbde7562ba9eed1d282abdf4640135f1f9cabaef333b9d6e5fe2","src/unicode.rs":"0e5d77d4d6751c6441982ae3d4a8453233443376441c5c01da5c86a5a5051167","src/unicode_data.rs":"5356c11b9ac59300bb29c164b26efc7b1ce263864e47ce90a68734277be1c392"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-parser/Cargo.toml b/third_party/rust/jsparagus-parser/Cargo.toml index d1287bf6b9..aeb6cde1da 100644 --- a/third_party/rust/jsparagus-parser/Cargo.toml +++ b/third_party/rust/jsparagus-parser/Cargo.toml @@ -9,15 +9,30 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] + [package] edition = "2018" name = "jsparagus-parser" version = "0.1.0" authors = ["Jason Orendorff "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_parser" +path = "src/lib.rs" + [[bench]] name = "parser" +path = "benches/parser.rs" harness = false [dependencies] diff --git a/third_party/rust/jsparagus-scope/.cargo-checksum.json b/third_party/rust/jsparagus-scope/.cargo-checksum.json index b73043f980..241a9c8bb8 100644 --- a/third_party/rust/jsparagus-scope/.cargo-checksum.json +++ b/third_party/rust/jsparagus-scope/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"d66c27f46f6da2bd7a84f762b938be6f4d0f3e20bdcd22862aba780c1039b5ee","src/builder.rs":"3aa261f329a6f4ee45683f4a69f85408d63e6bd5531b74dbbb4b4abbe8093b2f","src/data.rs":"a3cf1e7b1a96a619bcb8bd87f39bbd44dda0fc554c70a5d4d45b70eb03e69401","src/free_name_tracker.rs":"322228be4262d79d148f954a656b4f09fe953b324393fcc5925675c0e7777828","src/lib.rs":"529f7598a3034b347a20307a752b467091d820df6be67ebc4a3bd8e02568511b","src/pass.rs":"e13b2677ddf03b504efd287963caaa28b8a16c5fc0896f97bea2584f8280063d"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"b369730dd1b25a8900289980322248e5aace78ff184f942a69dc757509ae1405","src/builder.rs":"3aa261f329a6f4ee45683f4a69f85408d63e6bd5531b74dbbb4b4abbe8093b2f","src/data.rs":"a3cf1e7b1a96a619bcb8bd87f39bbd44dda0fc554c70a5d4d45b70eb03e69401","src/free_name_tracker.rs":"322228be4262d79d148f954a656b4f09fe953b324393fcc5925675c0e7777828","src/lib.rs":"529f7598a3034b347a20307a752b467091d820df6be67ebc4a3bd8e02568511b","src/pass.rs":"e13b2677ddf03b504efd287963caaa28b8a16c5fc0896f97bea2584f8280063d"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-scope/Cargo.toml b/third_party/rust/jsparagus-scope/Cargo.toml index 32b17df1c0..82bd2e638c 100644 --- a/third_party/rust/jsparagus-scope/Cargo.toml +++ b/third_party/rust/jsparagus-scope/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-scope" version = "0.1.0" authors = ["The jsparagus Project Developers"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_scope" +path = "src/lib.rs" + [dependencies] indexmap = "2.0" diff --git a/third_party/rust/jsparagus-stencil/.cargo-checksum.json b/third_party/rust/jsparagus-stencil/.cargo-checksum.json index 62807be51a..d3674a1886 100644 --- a/third_party/rust/jsparagus-stencil/.cargo-checksum.json +++ b/third_party/rust/jsparagus-stencil/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"4e07563463b79faddd43c5a74609c1745d2ca78a37e6a2a4aff3eca48637aa86","src/bytecode_offset.rs":"2aa7ba8c3cfbbd832092e65b599ab1c5a28d784ccc65d9e351bba656421b9a69","src/copy/AsyncFunctionResolveKind.h":"3851ecbb4728257595dd6e900749d1d8e02558574c00424a7ff0e3ca007fa6ec","src/copy/BytecodeFormatFlags.h":"48b561791fb2ef7189ffd17a26bb65163c24d398637b8d1cf9a09bc3964adca7","src/copy/CheckIsObjectKind.h":"8f0e112396d966c9221a743d353f62671e04cdace7dd49a59898d94ba0f621b7","src/copy/CompletionKind.h":"a491664ee7423ce75f34af4efa3df47934b42139f1b19741b2aa95f02d9230bf","src/copy/FunctionFlags.h":"03564f057262b73bebf31ab6c8f6a99a22983a87f1b9e7f48219d30af837423f","src/copy/FunctionPrefixKind.h":"f540a5c646a519b2d61aa27e4be865e08a31438def00ad5ba4ba2982ad1f2275","src/copy/GeneratorAndAsyncKind.h":"301668ce705970a51abfa94f89fd5db29ef5f129525110860e9e9bf7586ef187","src/copy/GeneratorResumeKind.h":"9e3cd9dc9c7f50937c6c45d73ec092dbfd92c4b56818ae6d1504bcd77078d0a6","src/copy/Opcodes.h":"6d1d8058b362d7032687737a2fe61c15374309e83c0d00cba05fb9660bd24ca8","src/copy/SourceNotes.h":"46fdf5ee41a309bf12eccf2bad3cc4736bcb8f43c3471a2ef506b9f3624ec91c","src/copy/StencilEnums.h":"fa3c3ff54947e8d876a0c5da549f9fa51393e22d644b909cc7a08a201de6d5ef","src/copy/Symbol.h":"98a827d5bf68567a75686ee0b72b9fb960bde77e96771bbf03fc0a33b601be41","src/copy/ThrowMsgKind.h":"ba180dc8c5c8eb4ff24a5ceb1a4df70e2e9005440766576e5eb2dc5a18b0a9dd","src/env_coord.rs":"0be36a1bd307f5586affe0f3046d8b2ab2f5382b41b7b7bfb364b97d16a7c410","src/frame_slot.rs":"b20c81d67c572f20d06d493b211cd3eaa0432a8294541583643b82df3af2f813","src/function.rs":"5357f3dc871a981c7dc21aac7fe736f0e55302f27ef5c63ed04915a2c845fff6","src/gcthings.rs":"baadc7284c01961a4aa44d464a6f5a0d0be427b6d099c949d4411846738d9a45","src/lib.rs":"b003e085344277d2987ef492dc513048e8ec83217850a22ba7ca06ac01bc9b5c","src/opcode.rs":"804dc73a7adba17f557fa80deaebe0caba1be0aeaa549fae1a0dfcd56dc88f32","src/opcode_info.rs":"a27c6d5602f5ecdcc882a0167614bc7a7754d958124941b4c1c0cdc2b0a894f1","src/regexp.rs":"7436cf545b990bec7dcc51ff28d67deaca9d4ce894468fdad0dd44b25c571cf2","src/result.rs":"62d3a851b8a497eecc350eed3ba6155b01a4d0e8e5bcfdf8dab776333d19825c","src/scope.rs":"3d2269a06d3e55d24f697338fedde95d9c653faec02d4694d0b63c79979e7c5a","src/scope_notes.rs":"9947ba5aba3097321c76adcb5648a478e4a67e088fdc1e01511e51c4ad41a9f3","src/script.rs":"c28883d1f2535cffab2820d6d7c48ed853a6c00f9fb410ab7ee56117667452eb"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"2954587eaef23420e128b590e219e20cd0b92efd55540c6b5709359af0122bd9","src/bytecode_offset.rs":"2aa7ba8c3cfbbd832092e65b599ab1c5a28d784ccc65d9e351bba656421b9a69","src/copy/AsyncFunctionResolveKind.h":"3851ecbb4728257595dd6e900749d1d8e02558574c00424a7ff0e3ca007fa6ec","src/copy/BytecodeFormatFlags.h":"48b561791fb2ef7189ffd17a26bb65163c24d398637b8d1cf9a09bc3964adca7","src/copy/CheckIsObjectKind.h":"8f0e112396d966c9221a743d353f62671e04cdace7dd49a59898d94ba0f621b7","src/copy/CompletionKind.h":"a491664ee7423ce75f34af4efa3df47934b42139f1b19741b2aa95f02d9230bf","src/copy/FunctionFlags.h":"03564f057262b73bebf31ab6c8f6a99a22983a87f1b9e7f48219d30af837423f","src/copy/FunctionPrefixKind.h":"f540a5c646a519b2d61aa27e4be865e08a31438def00ad5ba4ba2982ad1f2275","src/copy/GeneratorAndAsyncKind.h":"301668ce705970a51abfa94f89fd5db29ef5f129525110860e9e9bf7586ef187","src/copy/GeneratorResumeKind.h":"9e3cd9dc9c7f50937c6c45d73ec092dbfd92c4b56818ae6d1504bcd77078d0a6","src/copy/Opcodes.h":"6d1d8058b362d7032687737a2fe61c15374309e83c0d00cba05fb9660bd24ca8","src/copy/SourceNotes.h":"46fdf5ee41a309bf12eccf2bad3cc4736bcb8f43c3471a2ef506b9f3624ec91c","src/copy/StencilEnums.h":"fa3c3ff54947e8d876a0c5da549f9fa51393e22d644b909cc7a08a201de6d5ef","src/copy/Symbol.h":"98a827d5bf68567a75686ee0b72b9fb960bde77e96771bbf03fc0a33b601be41","src/copy/ThrowMsgKind.h":"ba180dc8c5c8eb4ff24a5ceb1a4df70e2e9005440766576e5eb2dc5a18b0a9dd","src/env_coord.rs":"0be36a1bd307f5586affe0f3046d8b2ab2f5382b41b7b7bfb364b97d16a7c410","src/frame_slot.rs":"b20c81d67c572f20d06d493b211cd3eaa0432a8294541583643b82df3af2f813","src/function.rs":"5357f3dc871a981c7dc21aac7fe736f0e55302f27ef5c63ed04915a2c845fff6","src/gcthings.rs":"baadc7284c01961a4aa44d464a6f5a0d0be427b6d099c949d4411846738d9a45","src/lib.rs":"b003e085344277d2987ef492dc513048e8ec83217850a22ba7ca06ac01bc9b5c","src/opcode.rs":"804dc73a7adba17f557fa80deaebe0caba1be0aeaa549fae1a0dfcd56dc88f32","src/opcode_info.rs":"a27c6d5602f5ecdcc882a0167614bc7a7754d958124941b4c1c0cdc2b0a894f1","src/regexp.rs":"7436cf545b990bec7dcc51ff28d67deaca9d4ce894468fdad0dd44b25c571cf2","src/result.rs":"62d3a851b8a497eecc350eed3ba6155b01a4d0e8e5bcfdf8dab776333d19825c","src/scope.rs":"3d2269a06d3e55d24f697338fedde95d9c653faec02d4694d0b63c79979e7c5a","src/scope_notes.rs":"9947ba5aba3097321c76adcb5648a478e4a67e088fdc1e01511e51c4ad41a9f3","src/script.rs":"c28883d1f2535cffab2820d6d7c48ed853a6c00f9fb410ab7ee56117667452eb"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus-stencil/Cargo.toml b/third_party/rust/jsparagus-stencil/Cargo.toml index eb67d949d1..e6eec2647d 100644 --- a/third_party/rust/jsparagus-stencil/Cargo.toml +++ b/third_party/rust/jsparagus-stencil/Cargo.toml @@ -9,12 +9,27 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus-stencil" version = "0.1.0" authors = ["The jsparagus Project Developers"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MIT/Apache-2.0" +[lib] +name = "jsparagus_stencil" +path = "src/lib.rs" + [dependencies.jsparagus-ast] path = "../ast" diff --git a/third_party/rust/jsparagus/.cargo-checksum.json b/third_party/rust/jsparagus/.cargo-checksum.json index d353031fbf..4ed8b05e07 100644 --- a/third_party/rust/jsparagus/.cargo-checksum.json +++ b/third_party/rust/jsparagus/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".flake8":"d0b5a0ca5e524819918726fbc8e8e7e41b4cca3cd06099fa5ed4bf96b0997c93",".githooks/pre-commit":"f37701f35731e8dec0dc0579669069cd720ba2d33dce24fee57735ee614ba654",".github/workflows/ci-daily.yml":"2bc9aa85b1f88ca0474b6fddc62f7182f5ea9e8257b77d60196b1ab5699ad4f8",".github/workflows/ci-generated.yml":"394a805aad7bd4ac66e2ddab7158c9e59183a026cb43d8821c55013e8dcb1e61",".github/workflows/ci-issues.yml":"ab3fa56ceaa65b1afb1a76285598a99befdd8131f68cb4bab0c7502dff9ac03f",".github/workflows/ci-push.yml":"d8133372446aae1437c1f9be88995b2be422b87aace5fce25b3d494656abdced",".github/workflows/real-js-benchmark.yml":"014bfb992808d4cc2158f5b3f47e20c99a7ecea40470595e4a22c0c070c4538f",".github/workflows/rust.yml":"5db3658068f4bef356a24e2a21cc3f7c34b4f19405e24884f1763749e82c5dff",".github/workflows/smoosh-status.yml":"7e6eb19a9fb5c18c5bdaefd477af5d94a374ed0a95f0826e92c9f0c0d15a5b48",".metrics/README.md":"8c963dc571c77f90d0ba1a67e48a32cc8c10166971b9fe8f2926ff00986262c4",".metrics/create-ci-branch.sh":"2dc3130e2eccb474edfdeb9ee1f43140f6f0a2489f013d153c3b3497e37d20c7",".metrics/fuzzbug_count_badge.py":"ad0b0dff8345e64eba17b14d583675df0b9aec4f9ca845166763384e1f1a2c29",".metrics/fuzzbug_date_badge.py":"e938af4faa21cebb9141227c3e3dcd57da3e98e0298d7bc2f9f257346156ad0d",".metrics/generated_README.md":"9be5ea93b90622b6e57969a90073957de4a00f9a05fb074e8146df130072ebb1",".metrics/not_implemented_badge.py":"a550a2e4b1cc151b80b2d6dcfbd8ccfaa3728bc7d759da2bf6eca5981de9e336",".metrics/not_implemented_count.py":"fb2741497b81668511afb761b941609fdc1eb343a3b81a4383561ca394838e26",".metrics/populate_fuzzbug.sh":"97d79de3075113846ff451db87769147427ab3581bc5629d53c7b2fca8dc86cf",".metrics/populate_not_implemented.sh":"75ea57b552dec3c0cd794be2c971a2c085bb99c5526176be860a2fb8af771021","CODE_OF_CONDUCT.md":"baa6d197a7e955ebe93c3b78e2d89d6f6f8d76fdc6c6ffb47ec937034ac2330e","Cargo.lock":"42b56c3499ce495710cffdb69db94b29667ef5f6d6b6849cfee7b113db192cff","Cargo.toml":"354843246df7c3671dd004cb5577a69fcd48a72ca20786713545f03bcdb2b80b","LICENSE":"83cced0d7ea4adca70302518dc44375445900ae8ed1c3d0a311e76474443d978","LICENSE-APACHE-2.0":"c6ac25baa937b3543482a2595950d337eccd6d620848455fd63d1a89c2009330","LICENSE-MIT":"20ad71f83cbf8fec779108327990518af3a87855d086bee40dc138656b94bd61","Makefile":"5bc156d54f4001cfc18484a963faf8d96430f73dbfff5b138ad2ae824d0b1bb4","README.md":"35fa02ac2528c0793d87f9f8dfd0caa683231ccf8c6a754a6de22456efa935fd","benchmarks/compare-spidermonkey-parsers.js":"58859b90cec170ab5103437194f1a751c83ad312b5e32dc78842b0c2720e1f02","gecko-patches.txt":"4c5532351f41e7a2e5af543686f1373f51e74c5908fbd80f2f337caa1bfe2099","journal.md":"e2af8d3ea87eac2afd106f943c13d0a0e5b03d09fb8ebec09ea4aa7d06490851","js-quirks.md":"8f5f0c6bd8cb9477b575716ac67b6a110865b4df60b7fecdcf2dbb606b8cf094","js_parser/README.md":"49370046241a091313cbe29d9171f47248c2fe742c8dfbdd4f7b4860ca961ffa","js_parser/__init__.py":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","js_parser/es-lexical-simplified.esgrammar":"cc5e0f7bd270e35ff04cad1464317cef0377df13e5fcf145f12783faccc90eff","js_parser/es-simplified.esgrammar":"fc2e5617351f964de6ebadfbda50653bb0e3528a67df4ab364a0125b4326ae83","js_parser/es.esgrammar":"14558b604fe62b7421551d1e694b0f4feb84d8ed114589f75885b217e14cfb05","js_parser/esgrammar.pgen":"e0affd8bb7843aece6d628561ce3057079e879eb11260cbd01b5426c9bce6f29","js_parser/extract_es_grammar.py":"04838d2a0555345699f30fb014f806d4b2e15aa36ed9ec772f514fb4ad858570","js_parser/generate_js_parser_tables.py":"2a33156b3d370e10c8f4eaeb3a00e1322fe71707d67f2f96f85f1a069a084b93","js_parser/lexer.py":"94252a6687fff473269b9eda5ee964d748c480c9a5d938569ac77ab9287cff80","js_parser/load_es_grammar.py":"d711fcc302b786551a83c3d5b7630de594732aa2f8c65e05105b355cd1139480","js_parser/parse_esgrammar.py":"3bc67c3aaf3fcaede4f89a4ad14103fe9e548ac035d1547f0cd799d83785d2b6","js_parser/parser.py":"0f2a9476463457aab7df1269373acec7e08a392209226b94a031267e055eb37a","js_parser/slash.esgrammar":"1fb1591a9773621c30fdac04f539452fb13990daece9ec939040fbb03445f434","js_parser/try_it.py":"c31fbdb7ad9164d16d173f23a6ae5e40da8d9c912f66d7751a53e9cecbbdafa9","jsparagus/README.md":"7f26517592e6d9b291a9162300b3157374422c712fd9b0042390ce55b3b3d715","jsparagus/__init__.py":"c277ec16d8ed12646b0d62e91249498fe7a207b5824e2d6e93d3f77e65828244","jsparagus/actions.py":"02f600ca9189d901779deeaeb3acccb9dfb72ab3842dfabdeafe17e6bade110f","jsparagus/aps.py":"9d14d7109c382af5bdf3bde574226afca65dc2caa0b7524f32f85de056730cfe","jsparagus/emit/__init__.py":"dcf1a8b26f7403871907f646c1ba3ef7dc1a593889a8f8d40490a0db791b0aff","jsparagus/emit/python.py":"fc8ad300727e735dab2222319039f2be9f792ebfc4a17f5f9ff03e58ad5a68e1","jsparagus/emit/rust.py":"6ecd3c76a6d9a37cf3ee9c8c440ba5538850a4bfcabe0a2ce662307b8a33f1ee","jsparagus/extension.py":"803c6db89e6d9e2480da4962c7db58b459dc3bd5594fc97fd89f1b43edf90081","jsparagus/gen.py":"1eabba9ce872ad130d878fa852e81efa6688b2f24c2bf9e4cc830a8afa58bd99","jsparagus/grammar.py":"23078e473dc3fc7ae9a85ce82dd928478d72ef8dd189adbcfd49de28f0b88efc","jsparagus/lexer.py":"8ed7b67dda1626ce98884e754c23eedeb1ce118ddd759b1571c131e5cb51ffda","jsparagus/lr0.py":"0bd25a501ca89b2dfdcbc90f9a0f8209e9cbfcaead099426ababdef6979c7ec9","jsparagus/main.py":"bae2377d6e840db55db6abbeffa58777020053d629de2b1bc8068aaf6f077dee","jsparagus/ordered.py":"15ebf9136ba760ee3e38611c76b55c6335002c6f5f98b43e62ed4c38fa0ef5e1","jsparagus/parse_pgen.py":"b68857e1de6fb41bece972d31384201b7e1feffadb07a3229a5d47c069d48160","jsparagus/parse_pgen_generated.py":"e794a794e95435d90654884ecce9ab68f763d13cd575f07228eaf1ebd27b9c18","jsparagus/parse_table.py":"7ce8388a468607a0bb20db0fb8769027af8927fe6e203f7c281ffc0221a6974b","jsparagus/rewrites.py":"3e5f82352237143d0fd2163459aa370e9b1661811b6eb5c1b9d79e3dd01c7f53","jsparagus/runtime.py":"f4f8f318e730cb7107490710868b9021bdbcf8e5e153ed3b858c7338b9b5d919","jsparagus/types.py":"b55d0eb466ffeff0441874b81c2dfeeaace7fa19eadc1d277d753803946e311f","jsparagus/utils.py":"cc26da2f258f0565062c77c61328210e2f8afb5b8866c153d2d1c159966a3913","mozconfigs/smoosh-debug":"422d2911e5f6acf99fd47435ec9cd0d9f43a680521de51d04aded8bed1136318","mozconfigs/smoosh-opt":"e9eab2cb659b5e7c1e88fc731d6c110157816b5a76e840e0bf51f167566e9b18","pgen.pgen":"60f457614f90a9bf022922dad563262f64e627d9aab934722246c20daa50b5de","requirements.txt":"3a392cc4f4db58be78817dc74a88178e6b4afe1e444c0068cb13e49502d7995a","smoosh_status.py":"a3824b4b20fde8fcf643e28de7d1a9a208352c778d1f9dc7d15f506258dbb36a","src/bin/smoosh_tools.rs":"989f3991bc5886664363b839ecae09d0b95c0e1844b5c2cbfc750fc3bcf52b37","src/lib.rs":"93b32cb970f69fa33e11d41db1696bd578095e07db44ed348ed5e21a8d13d21a","test.sh":"31676e86c2e7e6f6f69050766e237d0eee7da3598b11f95a7335292af2802d11","tests/__init__.py":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/test.py":"1ab6b2d002419eac0edc460a5f31b24f0b3ad7c52b79e83f4fd08bded67c6eec","tests/test_js.py":"5f4474eef53d7286d5683c0970a9ba69248a7c843c2c0d9d4111bc432f2f6dbb","tests/test_parse_pgen.py":"6b99e38b2045bae4b0c1b99fe23e1a47ea886b9ce4e902990cc366b8ca9d758e","update.sh":"39986fc0dfe2dd2d2dd2d408cb25577f8ad736b657430233e5a9e214684ce6f1","update_stencil.py":"51a7e79935e664614441491605c8aa6f9cd9fe731faeba6b9c6cd5f23fc6c1ee","update_unicode.py":"18136102a3f38f87a4d6176e07a933711afb42796118293462765a6b271a240e"},"package":null} \ No newline at end of file +{"files":{".flake8":"d0b5a0ca5e524819918726fbc8e8e7e41b4cca3cd06099fa5ed4bf96b0997c93",".githooks/pre-commit":"f37701f35731e8dec0dc0579669069cd720ba2d33dce24fee57735ee614ba654",".github/workflows/ci-daily.yml":"2bc9aa85b1f88ca0474b6fddc62f7182f5ea9e8257b77d60196b1ab5699ad4f8",".github/workflows/ci-generated.yml":"394a805aad7bd4ac66e2ddab7158c9e59183a026cb43d8821c55013e8dcb1e61",".github/workflows/ci-issues.yml":"ab3fa56ceaa65b1afb1a76285598a99befdd8131f68cb4bab0c7502dff9ac03f",".github/workflows/ci-push.yml":"d8133372446aae1437c1f9be88995b2be422b87aace5fce25b3d494656abdced",".github/workflows/real-js-benchmark.yml":"014bfb992808d4cc2158f5b3f47e20c99a7ecea40470595e4a22c0c070c4538f",".github/workflows/rust.yml":"5db3658068f4bef356a24e2a21cc3f7c34b4f19405e24884f1763749e82c5dff",".github/workflows/smoosh-status.yml":"7e6eb19a9fb5c18c5bdaefd477af5d94a374ed0a95f0826e92c9f0c0d15a5b48",".metrics/README.md":"8c963dc571c77f90d0ba1a67e48a32cc8c10166971b9fe8f2926ff00986262c4",".metrics/create-ci-branch.sh":"2dc3130e2eccb474edfdeb9ee1f43140f6f0a2489f013d153c3b3497e37d20c7",".metrics/fuzzbug_count_badge.py":"ad0b0dff8345e64eba17b14d583675df0b9aec4f9ca845166763384e1f1a2c29",".metrics/fuzzbug_date_badge.py":"e938af4faa21cebb9141227c3e3dcd57da3e98e0298d7bc2f9f257346156ad0d",".metrics/generated_README.md":"9be5ea93b90622b6e57969a90073957de4a00f9a05fb074e8146df130072ebb1",".metrics/not_implemented_badge.py":"a550a2e4b1cc151b80b2d6dcfbd8ccfaa3728bc7d759da2bf6eca5981de9e336",".metrics/not_implemented_count.py":"fb2741497b81668511afb761b941609fdc1eb343a3b81a4383561ca394838e26",".metrics/populate_fuzzbug.sh":"97d79de3075113846ff451db87769147427ab3581bc5629d53c7b2fca8dc86cf",".metrics/populate_not_implemented.sh":"75ea57b552dec3c0cd794be2c971a2c085bb99c5526176be860a2fb8af771021","CODE_OF_CONDUCT.md":"baa6d197a7e955ebe93c3b78e2d89d6f6f8d76fdc6c6ffb47ec937034ac2330e","Cargo.lock":"42b56c3499ce495710cffdb69db94b29667ef5f6d6b6849cfee7b113db192cff","Cargo.toml":"ce89744e423565ec9649d3b01e147ede81a0f335c6b22a8194dd1a157815f3e4","LICENSE":"83cced0d7ea4adca70302518dc44375445900ae8ed1c3d0a311e76474443d978","LICENSE-APACHE-2.0":"c6ac25baa937b3543482a2595950d337eccd6d620848455fd63d1a89c2009330","LICENSE-MIT":"20ad71f83cbf8fec779108327990518af3a87855d086bee40dc138656b94bd61","Makefile":"5bc156d54f4001cfc18484a963faf8d96430f73dbfff5b138ad2ae824d0b1bb4","README.md":"35fa02ac2528c0793d87f9f8dfd0caa683231ccf8c6a754a6de22456efa935fd","benchmarks/compare-spidermonkey-parsers.js":"58859b90cec170ab5103437194f1a751c83ad312b5e32dc78842b0c2720e1f02","gecko-patches.txt":"4c5532351f41e7a2e5af543686f1373f51e74c5908fbd80f2f337caa1bfe2099","journal.md":"e2af8d3ea87eac2afd106f943c13d0a0e5b03d09fb8ebec09ea4aa7d06490851","js-quirks.md":"8f5f0c6bd8cb9477b575716ac67b6a110865b4df60b7fecdcf2dbb606b8cf094","js_parser/README.md":"49370046241a091313cbe29d9171f47248c2fe742c8dfbdd4f7b4860ca961ffa","js_parser/__init__.py":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","js_parser/es-lexical-simplified.esgrammar":"cc5e0f7bd270e35ff04cad1464317cef0377df13e5fcf145f12783faccc90eff","js_parser/es-simplified.esgrammar":"fc2e5617351f964de6ebadfbda50653bb0e3528a67df4ab364a0125b4326ae83","js_parser/es.esgrammar":"14558b604fe62b7421551d1e694b0f4feb84d8ed114589f75885b217e14cfb05","js_parser/esgrammar.pgen":"e0affd8bb7843aece6d628561ce3057079e879eb11260cbd01b5426c9bce6f29","js_parser/extract_es_grammar.py":"04838d2a0555345699f30fb014f806d4b2e15aa36ed9ec772f514fb4ad858570","js_parser/generate_js_parser_tables.py":"2a33156b3d370e10c8f4eaeb3a00e1322fe71707d67f2f96f85f1a069a084b93","js_parser/lexer.py":"94252a6687fff473269b9eda5ee964d748c480c9a5d938569ac77ab9287cff80","js_parser/load_es_grammar.py":"d711fcc302b786551a83c3d5b7630de594732aa2f8c65e05105b355cd1139480","js_parser/parse_esgrammar.py":"3bc67c3aaf3fcaede4f89a4ad14103fe9e548ac035d1547f0cd799d83785d2b6","js_parser/parser.py":"0f2a9476463457aab7df1269373acec7e08a392209226b94a031267e055eb37a","js_parser/slash.esgrammar":"1fb1591a9773621c30fdac04f539452fb13990daece9ec939040fbb03445f434","js_parser/try_it.py":"c31fbdb7ad9164d16d173f23a6ae5e40da8d9c912f66d7751a53e9cecbbdafa9","jsparagus/README.md":"7f26517592e6d9b291a9162300b3157374422c712fd9b0042390ce55b3b3d715","jsparagus/__init__.py":"c277ec16d8ed12646b0d62e91249498fe7a207b5824e2d6e93d3f77e65828244","jsparagus/actions.py":"02f600ca9189d901779deeaeb3acccb9dfb72ab3842dfabdeafe17e6bade110f","jsparagus/aps.py":"9d14d7109c382af5bdf3bde574226afca65dc2caa0b7524f32f85de056730cfe","jsparagus/emit/__init__.py":"dcf1a8b26f7403871907f646c1ba3ef7dc1a593889a8f8d40490a0db791b0aff","jsparagus/emit/python.py":"fc8ad300727e735dab2222319039f2be9f792ebfc4a17f5f9ff03e58ad5a68e1","jsparagus/emit/rust.py":"6ecd3c76a6d9a37cf3ee9c8c440ba5538850a4bfcabe0a2ce662307b8a33f1ee","jsparagus/extension.py":"803c6db89e6d9e2480da4962c7db58b459dc3bd5594fc97fd89f1b43edf90081","jsparagus/gen.py":"1eabba9ce872ad130d878fa852e81efa6688b2f24c2bf9e4cc830a8afa58bd99","jsparagus/grammar.py":"23078e473dc3fc7ae9a85ce82dd928478d72ef8dd189adbcfd49de28f0b88efc","jsparagus/lexer.py":"8ed7b67dda1626ce98884e754c23eedeb1ce118ddd759b1571c131e5cb51ffda","jsparagus/lr0.py":"0bd25a501ca89b2dfdcbc90f9a0f8209e9cbfcaead099426ababdef6979c7ec9","jsparagus/main.py":"bae2377d6e840db55db6abbeffa58777020053d629de2b1bc8068aaf6f077dee","jsparagus/ordered.py":"15ebf9136ba760ee3e38611c76b55c6335002c6f5f98b43e62ed4c38fa0ef5e1","jsparagus/parse_pgen.py":"b68857e1de6fb41bece972d31384201b7e1feffadb07a3229a5d47c069d48160","jsparagus/parse_pgen_generated.py":"e794a794e95435d90654884ecce9ab68f763d13cd575f07228eaf1ebd27b9c18","jsparagus/parse_table.py":"7ce8388a468607a0bb20db0fb8769027af8927fe6e203f7c281ffc0221a6974b","jsparagus/rewrites.py":"3e5f82352237143d0fd2163459aa370e9b1661811b6eb5c1b9d79e3dd01c7f53","jsparagus/runtime.py":"f4f8f318e730cb7107490710868b9021bdbcf8e5e153ed3b858c7338b9b5d919","jsparagus/types.py":"b55d0eb466ffeff0441874b81c2dfeeaace7fa19eadc1d277d753803946e311f","jsparagus/utils.py":"cc26da2f258f0565062c77c61328210e2f8afb5b8866c153d2d1c159966a3913","mozconfigs/smoosh-debug":"422d2911e5f6acf99fd47435ec9cd0d9f43a680521de51d04aded8bed1136318","mozconfigs/smoosh-opt":"e9eab2cb659b5e7c1e88fc731d6c110157816b5a76e840e0bf51f167566e9b18","pgen.pgen":"60f457614f90a9bf022922dad563262f64e627d9aab934722246c20daa50b5de","requirements.txt":"3a392cc4f4db58be78817dc74a88178e6b4afe1e444c0068cb13e49502d7995a","smoosh_status.py":"a3824b4b20fde8fcf643e28de7d1a9a208352c778d1f9dc7d15f506258dbb36a","src/bin/smoosh_tools.rs":"989f3991bc5886664363b839ecae09d0b95c0e1844b5c2cbfc750fc3bcf52b37","src/lib.rs":"93b32cb970f69fa33e11d41db1696bd578095e07db44ed348ed5e21a8d13d21a","test.sh":"31676e86c2e7e6f6f69050766e237d0eee7da3598b11f95a7335292af2802d11","tests/__init__.py":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/test.py":"1ab6b2d002419eac0edc460a5f31b24f0b3ad7c52b79e83f4fd08bded67c6eec","tests/test_js.py":"5f4474eef53d7286d5683c0970a9ba69248a7c843c2c0d9d4111bc432f2f6dbb","tests/test_parse_pgen.py":"6b99e38b2045bae4b0c1b99fe23e1a47ea886b9ce4e902990cc366b8ca9d758e","update.sh":"39986fc0dfe2dd2d2dd2d408cb25577f8ad736b657430233e5a9e214684ce6f1","update_stencil.py":"51a7e79935e664614441491605c8aa6f9cd9fe731faeba6b9c6cd5f23fc6c1ee","update_unicode.py":"18136102a3f38f87a4d6176e07a933711afb42796118293462765a6b271a240e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/jsparagus/Cargo.toml b/third_party/rust/jsparagus/Cargo.toml index 7b5653dacb..f324fbe206 100644 --- a/third_party/rust/jsparagus/Cargo.toml +++ b/third_party/rust/jsparagus/Cargo.toml @@ -9,12 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +example = [] +test = [] +bench = [] + [package] edition = "2018" name = "jsparagus" version = "0.1.0" authors = ["The jsparagus Project Developers"] +build = false publish = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "A JavaScript parser" readme = "README.md" license = "MIT/Apache-2.0" @@ -24,6 +33,8 @@ repository = "https://github.com/mozilla-spidermonkey/jsparagus" debug = 2 [lib] +name = "jsparagus" +path = "src/lib.rs" [[bin]] name = "smoosh_tools" diff --git a/third_party/rust/libz-rs-sys/.cargo-checksum.json b/third_party/rust/libz-rs-sys/.cargo-checksum.json new file mode 100644 index 0000000000..479bc9d722 --- /dev/null +++ b/third_party/rust/libz-rs-sys/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"390cdf18d6cf3a95fe56ee064747b95eb2c093d36d3038a3bf59712efdae6832","LICENSE":"7d60612df8fcd9d3714871a95b4d3012563246fdea8f6710b7567f83cfa3c8ef","README.md":"46f48b56018d0efef5738be7d930019631899dede51ee5e92f44bd53f6e26749","src/lib.rs":"44e21c7ccacbf35f483ab9d777802624a0d111d161cfd2778a37aa5f33279c47"},"package":null} \ No newline at end of file diff --git a/third_party/rust/libz-rs-sys/Cargo.toml b/third_party/rust/libz-rs-sys/Cargo.toml new file mode 100644 index 0000000000..c765722429 --- /dev/null +++ b/third_party/rust/libz-rs-sys/Cargo.toml @@ -0,0 +1,52 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +bin = [] +example = [] +test = [] +bench = [] + +[package] +edition = "2021" +rust-version = "1.75" +name = "libz-rs-sys" +version = "0.2.1" +build = false +publish = true +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A memory-safe zlib implementation written in rust" +homepage = "https://github.com/memorysafety/zlib-rs" +readme = "README.md" +license = "Zlib" +repository = "https://github.com/memorysafety/zlib-rs" + +[lib] +name = "libz_rs_sys" +path = "src/lib.rs" + +[dependencies.zlib-rs] +version = "0.2.1" +path = "../zlib-rs" +default-features = false + +[features] +c-allocator = ["zlib-rs/c-allocator"] +custom-prefix = [] +default = [ + "std", + "rust-allocator", +] +rust-allocator = ["zlib-rs/rust-allocator"] +std = ["zlib-rs/std"] +testing-prefix = [] diff --git a/third_party/rust/libz-rs-sys/LICENSE b/third_party/rust/libz-rs-sys/LICENSE new file mode 100644 index 0000000000..8079b948a6 --- /dev/null +++ b/third_party/rust/libz-rs-sys/LICENSE @@ -0,0 +1,19 @@ +(C) 2024 Internet Security Research Group + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/third_party/rust/libz-rs-sys/README.md b/third_party/rust/libz-rs-sys/README.md new file mode 100644 index 0000000000..bbeeca9387 --- /dev/null +++ b/third_party/rust/libz-rs-sys/README.md @@ -0,0 +1,90 @@ +This crate is a C API for [zlib-rs](https://docs.rs/zlib-rs/latest/zlib_rs/). The API is broadly equivalent to [`zlib-sys`](https://docs.rs/libz-sys/latest/libz_sys/) and [`zlib-ng-sys`](https://docs.rs/libz-ng-sys/latest/libz_ng_sys/), but does not currently provide the `gz*` family of functions. + +From a rust perspective, this API is not very ergonomic. Use the [`flate2`](https://crates.io/crates/flate2) crate for a more +ergonomic rust interface to zlib. + +# Features + +**`custom-prefix`** + +Add a custom prefix to all exported symbols. + +The value of the `LIBZ_RS_SYS_PREFIX` is used as a prefix for all exported symbols. For example: + +```ignore +> LIBZ_RS_SYS_PREFIX="MY_CUSTOM_PREFIX" cargo build -p libz-rs-sys --features=custom-prefix + Compiling libz-rs-sys v0.2.1 (/home/folkertdev/rust/zlib-rs/libz-rs-sys) + Finished `dev` profile [optimized + debuginfo] target(s) in 0.21s +> objdump -tT target/debug/liblibz_rs_sys.so | grep "uncompress" +0000000000081028 l O .got 0000000000000000 _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E$got +000000000002c570 l F .text 00000000000001ef _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E +0000000000024330 g F .text 000000000000008e MY_CUSTOM_PREFIXuncompress +0000000000024330 g DF .text 000000000000008e Base MY_CUSTOM_PREFIXuncompress +``` + +**`c-allocator`, `rust-allocator`** + +Pick the default allocator implementation that is used if no `zalloc` and `zfree` are configured in the input `z_stream`. + +- `c-allocator`: use `malloc`/`free` for the implementation of `zalloc` and `zfree` +- `rust-allocator`: the rust global allocator for the implementation of `zalloc` and `zfree` + +The `rust-allocator` is the default when this crate is used as a rust dependency, and slightly more efficient because alignment is handled by the allocator. When building a dynamic library, it may make sense to use `c-allocator` instead. + +**`std`** + +Assume that `std` is available. When this feature is turned off, this crate is compatible with `#![no_std]`. + +# Example + +This example compresses ("deflates") the string `"Hello, World!"` and then decompresses +("inflates") it again. + +```rust +let mut strm = libz_rs_sys::z_stream::default(); + +let version = libz_rs_sys::zlibVersion(); +let stream_size = core::mem::size_of_val(&strm) as i32; + +let level = 6; // the default compression level +let err = unsafe { libz_rs_sys::deflateInit_(&mut strm, level, version, stream_size) }; +assert_eq!(err, libz_rs_sys::Z_OK); + +let input = "Hello, World!"; +strm.avail_in = input.len() as _; +strm.next_in = input.as_ptr(); + +let mut output = [0u8; 32]; +strm.avail_out = output.len() as _; +strm.next_out = output.as_mut_ptr(); + +let err = unsafe { libz_rs_sys::deflate(&mut strm, libz_rs_sys::Z_FINISH) }; +assert_eq!(err, libz_rs_sys::Z_STREAM_END); + +let err = unsafe { libz_rs_sys::deflateEnd(&mut strm) }; +assert_eq!(err, libz_rs_sys::Z_OK); + +let deflated = &mut output[..strm.total_out as usize]; + +let mut strm = libz_rs_sys::z_stream::default(); +let err = unsafe { libz_rs_sys::inflateInit_(&mut strm, version, stream_size) }; +assert_eq!(err, libz_rs_sys::Z_OK); + +strm.avail_in = deflated.len() as _; +strm.next_in = deflated.as_ptr(); + +let mut output = [0u8; 32]; +strm.avail_out = output.len() as _; +strm.next_out = output.as_mut_ptr(); + +let err = unsafe { libz_rs_sys::inflate(&mut strm, libz_rs_sys::Z_FINISH) }; +assert_eq!(err, libz_rs_sys::Z_STREAM_END); + +let err = unsafe { libz_rs_sys::inflateEnd(&mut strm) }; +assert_eq!(err, libz_rs_sys::Z_OK); + +let inflated = &output[..strm.total_out as usize]; + +assert_eq!(inflated, input.as_bytes()) +``` + diff --git a/third_party/rust/libz-rs-sys/src/lib.rs b/third_party/rust/libz-rs-sys/src/lib.rs new file mode 100644 index 0000000000..c648163287 --- /dev/null +++ b/third_party/rust/libz-rs-sys/src/lib.rs @@ -0,0 +1,1668 @@ +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![cfg_attr(not(feature = "std"), no_std)] +#![doc = include_str!("../README.md")] + +//! # Safety +//! +//! Most of the functions in this module are `unsafe fn`s, meaning that their behavior may be +//! undefined if certain assumptions are broken by the caller. In most cases, documentation +//! in this module refers to the safety assumptions of standard library functions. +//! +//! In most cases, pointers must be either `NULL` or satisfy the requirements of `&*ptr` or `&mut +//! *ptr`. This requirement maps to the requirements of [`pointer::as_ref`] and [`pointer::as_mut`] +//! for immutable and mutable pointers respectively. +//! +//! For pointer and length pairs, describing some sequence of elements in memory, the requirements +//! of [`core::slice::from_raw_parts`] or [`core::slice::from_raw_parts_mut`] apply. In some cases, +//! the element type `T` is converted into `MaybeUninit`, meaning that while the slice must be +//! valid, the elements in the slice can be uninitialized. Using uninitialized buffers for output +//! is more performant. +//! +//! Finally, some functions accept a string argument, which must either be `NULL` or satisfy the +//! requirements of [`core::ffi::CStr::from_ptr`]. +//! +//! [`pointer::as_ref`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_ref +//! [`pointer::as_mut`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_mut + +use core::mem::MaybeUninit; + +use core::ffi::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void}; + +use zlib_rs::{ + deflate::{DeflateConfig, DeflateStream, Method, Strategy}, + inflate::{InflateConfig, InflateStream}, + DeflateFlush, InflateFlush, ReturnCode, +}; + +pub use zlib_rs::c_api::*; + +#[cfg(feature = "custom-prefix")] +macro_rules! prefix { + ($name:expr) => { + concat!(env!("LIBZ_RS_SYS_PREFIX"), stringify!($name)) + }; +} + +#[cfg(all( + not(feature = "custom-prefix"), + not(any(test, feature = "testing-prefix")) +))] +macro_rules! prefix { + ($name:expr) => { + stringify!($name) + }; +} + +#[cfg(all(not(feature = "custom-prefix"), any(test, feature = "testing-prefix")))] +macro_rules! prefix { + ($name:expr) => { + concat!("LIBZ_RS_SYS_TEST_", stringify!($name)) + }; +} + +#[cfg(all(feature = "rust-allocator", feature = "c-allocator"))] +const _: () = + compile_error!("Only one of `rust-allocator` and `c-allocator` can be enabled at a time"); + +// In spirit this type is `libc::off_t`, but it would be our only libc dependency, and so we +// hardcode the type here. This should be correct on most operating systems. If we ever run into +// issues with it, we can either special-case or add a feature flag to force a particular width +pub type z_off_t = c_long; + +/// Calculates the [crc32](https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks#CRC-32_algorithm) checksum +/// of a sequence of bytes. +/// +/// When the pointer argument is `NULL`, the initial checksum value is returned. +/// +/// # Safety +/// +/// The caller must guarantee that either: +/// +/// - `buf` is `NULL` +/// - `buf` and `len` satisfy the requirements of [`core::slice::from_raw_parts`] +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::crc32; +/// +/// unsafe { +/// assert_eq!(crc32(0, core::ptr::null(), 0), 0); +/// assert_eq!(crc32(1, core::ptr::null(), 32), 0); +/// +/// let input = [1,2,3]; +/// assert_eq!(crc32(0, input.as_ptr(), input.len() as _), 1438416925); +/// } +/// ``` +#[export_name = prefix!(crc32)] +pub unsafe extern "C-unwind" fn crc32(crc: c_ulong, buf: *const Bytef, len: uInt) -> c_ulong { + match unsafe { slice_from_raw_parts(buf, len as usize) } { + Some(buf) => zlib_rs::crc32(crc as u32, buf) as c_ulong, + None => 0, + } +} + +/// Combines the checksum of two slices into one. +/// +/// The combined value is equivalent to calculating the checksum of the whole input. +/// +/// This function can be used when input arrives in chunks, or when different threads +/// calculate the checksum of different sections of the input. +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::{crc32, crc32_combine}; +/// +/// let input = [1, 2, 3, 4, 5, 6, 7, 8]; +/// let lo = &input[..4]; +/// let hi = &input[4..]; +/// +/// unsafe { +/// let full = crc32(0, input.as_ptr(), input.len() as _); +/// +/// let crc1 = crc32(0, lo.as_ptr(), lo.len() as _); +/// let crc2 = crc32(0, hi.as_ptr(), hi.len() as _); +/// +/// let combined = crc32_combine(crc1, crc2, hi.len() as _); +/// +/// assert_eq!(full, combined); +/// } +/// ``` +#[export_name = prefix!(crc32_combine)] +pub extern "C-unwind" fn crc32_combine(crc1: c_ulong, crc2: c_ulong, len2: z_off_t) -> c_ulong { + zlib_rs::crc32_combine(crc1 as u32, crc2 as u32, len2 as u64) as c_ulong +} + +/// Calculates the [adler32](https://en.wikipedia.org/wiki/Adler-32) checksum +/// of a sequence of bytes. +/// +/// When the pointer argument is `NULL`, the initial checksum value is returned. +/// +/// # Safety +/// +/// The caller must guarantee that either: +/// +/// - `buf` is `NULL` +/// - `buf` and `len` satisfy the requirements of [`core::slice::from_raw_parts`] +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::adler32; +/// +/// unsafe { +/// assert_eq!(adler32(0, core::ptr::null(), 0), 1); +/// assert_eq!(adler32(1, core::ptr::null(), 32), 1); +/// +/// let input = [1,2,3]; +/// assert_eq!(adler32(0, input.as_ptr(), input.len() as _), 655366); +/// } +/// ``` +#[export_name = prefix!(adler32)] +pub unsafe extern "C-unwind" fn adler32(adler: c_ulong, buf: *const Bytef, len: uInt) -> c_ulong { + match unsafe { slice_from_raw_parts(buf, len as usize) } { + Some(buf) => zlib_rs::adler32(adler as u32, buf) as c_ulong, + None => 1, + } +} + +/// Combines the checksum of two slices into one. +/// +/// The combined value is equivalent to calculating the checksum of the whole input. +/// +/// This function can be used when input arrives in chunks, or when different threads +/// calculate the checksum of different sections of the input. +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::{adler32, adler32_combine}; +/// +/// let input = [1, 2, 3, 4, 5, 6, 7, 8]; +/// let lo = &input[..4]; +/// let hi = &input[4..]; +/// +/// unsafe { +/// let full = adler32(1, input.as_ptr(), input.len() as _); +/// +/// let adler1 = adler32(1, lo.as_ptr(), lo.len() as _); +/// let adler2 = adler32(1, hi.as_ptr(), hi.len() as _); +/// +/// let combined = adler32_combine(adler1, adler2, hi.len() as _); +/// +/// assert_eq!(full, combined); +/// } +/// ``` +#[export_name = prefix!(adler32_combine)] +pub extern "C-unwind" fn adler32_combine( + adler1: c_ulong, + adler2: c_ulong, + len2: z_off_t, +) -> c_ulong { + match u64::try_from(len2) { + Ok(len2) => zlib_rs::adler32_combine(adler1 as u32, adler2 as u32, len2) as c_ulong, + Err(_) => { + // for negative len, return invalid adler32 as a clue for debugging + 0xFFFF_FFFF + } + } +} + +/// Inflates `source` into `dest`, and writes the final inflated size into `destLen`. +/// +/// Upon entry, `destLen` is the total size of the destination buffer, which must be large enough to hold the entire +/// uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and +/// transmitted to the decompressor by some mechanism outside the scope of this compression library.) +/// Upon exit, `destLen` is the actual size of the uncompressed data. +/// +/// # Returns +/// +/// * [`Z_OK`] if success +/// * [`Z_MEM_ERROR`] if there was not enough memory +/// * [`Z_BUF_ERROR`] if there was not enough room in the output buffer +/// * [`Z_DATA_ERROR`] if the input data was corrupted or incomplete +/// +/// In the case where there is not enough room, [`uncompress`] will fill the output buffer with the uncompressed data up to that point. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `destLen` is `NULL` +/// - `destLen` satisfies the requirements of `&mut *destLen` +/// * Either +/// - `dest` is `NULL` +/// - `dest` and `*destLen` satisfy the requirements of [`core::slice::from_raw_parts_mut::>`] +/// * Either +/// - `source` is `NULL` +/// - `source` and `sourceLen` satisfy the requirements of [`core::slice::from_raw_parts::`] +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::{Z_OK, uncompress}; +/// +/// let source = [120, 156, 115, 75, 45, 42, 202, 44, 6, 0, 8, 6, 2, 108]; +/// +/// let mut dest = vec![0u8; 100]; +/// let mut dest_len = dest.len() as _; +/// +/// let err = unsafe { +/// uncompress( +/// dest.as_mut_ptr(), +/// &mut dest_len, +/// source.as_ptr(), +/// source.len() as _, +/// ) +/// }; +/// +/// assert_eq!(err, Z_OK); +/// assert_eq!(dest_len, 6); +/// +/// dest.truncate(dest_len as usize); +/// assert_eq!(dest, b"Ferris"); +/// ``` +#[export_name = prefix!(uncompress)] +pub unsafe extern "C-unwind" fn uncompress( + dest: *mut u8, + destLen: *mut c_ulong, + source: *const u8, + sourceLen: c_ulong, +) -> c_int { + // stock zlib will just dereference a NULL pointer: that's UB. + // Hence us returning an error value is compatible + let Some(destLen) = (unsafe { destLen.as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let Some(output) = (unsafe { slice_from_raw_parts_uninit_mut(dest, *destLen as usize) }) else { + return ReturnCode::StreamError as _; + }; + + let Some(input) = (unsafe { slice_from_raw_parts(source, sourceLen as usize) }) else { + return ReturnCode::StreamError as _; + }; + + let config = InflateConfig::default(); + let (output, err) = zlib_rs::inflate::uncompress(output, input, config); + + *destLen = output.len() as c_ulong; + + err as c_int +} + +/// Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_END`] if the end of the compressed data has been reached and all uncompressed output has been produced +/// - [`Z_NEED_DICT`] if a preset dictionary is needed at this point +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// - [`Z_DATA_ERROR`] if the input data was corrupted +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_BUF_ERROR`] if no progress was possible or if there was not enough room in the output buffer when [`Z_FINISH`] is used +/// +/// Note that [`Z_BUF_ERROR`] is not fatal, and [`inflate`] can be called again with more input and more output space to continue decompressing. +/// If [`Z_DATA_ERROR`] is returned, the application may then call [`inflateSync`] to look for a good compression block if a partial recovery of the data is to be attempted. +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflate)] +pub unsafe extern "C-unwind" fn inflate(strm: *mut z_stream, flush: i32) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + let flush = InflateFlush::try_from(flush).unwrap_or_default(); + zlib_rs::inflate::inflate(stream, flush) as _ + } else { + ReturnCode::StreamError as _ + } +} + +/// Deallocates all dynamically allocated data structures for this stream. +/// +/// This function discards any unprocessed input and does not flush any pending output. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateEnd)] +pub unsafe extern "C-unwind" fn inflateEnd(strm: *mut z_stream) -> i32 { + match InflateStream::from_stream_mut(strm) { + Some(stream) => { + zlib_rs::inflate::end(stream); + ReturnCode::Ok as _ + } + None => ReturnCode::StreamError as _, + } +} + +/// Initializes the state for decompression +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_VERSION_ERROR`] if the zlib library version is incompatible with the version assumed by the caller +/// - [`Z_STREAM_ERROR`] if a parameter is invalid, such as a null pointer to the structure +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * Either +/// - `version` is NULL +/// - `version` satisfies the requirements of [`core::ffi::CStr::from_ptr`] +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +#[export_name = prefix!(inflateBackInit_)] +pub unsafe extern "C-unwind" fn inflateBackInit_( + _strm: z_streamp, + _windowBits: c_int, + _window: *mut c_uchar, + _version: *const c_char, + _stream_size: c_int, +) -> c_int { + todo!("inflateBack is not implemented yet") +} + +/// Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. +/// +/// ## Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateBackInit_`] +#[export_name = prefix!(inflateBack)] +pub unsafe extern "C-unwind" fn inflateBack( + _strm: z_streamp, + _in: in_func, + _in_desc: *mut c_void, + _out: out_func, + _out_desc: *mut c_void, +) -> c_int { + todo!("inflateBack is not implemented yet") +} + +/// Deallocates all dynamically allocated data structures for this stream. +/// +/// This function discards any unprocessed input and does not flush any pending output. +/// +/// ## Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// ## Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateBackInit_`] +#[export_name = prefix!(inflateBackEnd)] +pub unsafe extern "C-unwind" fn inflateBackEnd(_strm: z_streamp) -> c_int { + todo!("inflateBack is not implemented yet") +} + +/// Sets the destination stream as a complete copy of the source stream. +/// +/// This function can be useful when randomly accessing a large stream. +/// The first pass through the stream can periodically record the inflate state, +/// allowing restarting inflate at those points when randomly accessing the stream. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent (such as zalloc being NULL) +/// +/// The `msg` field is left unchanged in both source and destination. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `dest` is `NULL` +/// - `dest` satisfies the requirements of `&mut *(dest as *mut MaybeUninit)` +/// * Either +/// - `source` is `NULL` +/// - `source` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateCopy)] +pub unsafe extern "C-unwind" fn inflateCopy(dest: *mut z_stream, source: *const z_stream) -> i32 { + let Some(dest) = (unsafe { dest.cast::>().as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let Some(source) = (unsafe { InflateStream::from_stream_ref(source) }) else { + return ReturnCode::StreamError as _; + }; + + zlib_rs::inflate::copy(dest, source) as _ +} + +/// Gives information about the current location of the input stream. +/// +/// This function marks locations in the input data for random access, which may be at bit positions, and notes those cases where the output of a code may span boundaries of random access blocks. The current location in the input stream can be determined from `avail_in` and `data_type` as noted in the description for the [`Z_BLOCK`] flush parameter for [`inflate`]. +/// +/// A code is being processed if [`inflate`] is waiting for more input to complete decoding of the code, or if it has completed decoding but is waiting for more output space to write the literal or match data. +/// +/// # Returns +/// +/// This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. +/// +/// - If the upper value is `-1` and the lower value is zero, then [`inflate`] is currently decoding information outside of a block. +/// - If the upper value is `-1` and the lower value is non-zero, then [`inflate`] is in the middle of a stored block, with the lower value equaling the number of bytes from the input remaining to copy. +/// - If the upper value is not `-1`, then it is the number of bits back from the current bit position in the input of the code (literal or length/distance pair) currently being processed. In that case the lower value is the number of bytes already emitted for that code. +/// - `-65536` if the provided source stream state was inconsistent. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateMark)] +pub unsafe extern "C-unwind" fn inflateMark(strm: *const z_stream) -> c_long { + if let Some(stream) = InflateStream::from_stream_ref(strm) { + zlib_rs::inflate::mark(stream) + } else { + -65536 + } +} + +/// Skips invalid compressed data until +/// +/// Skip invalid compressed data until a possible full flush point (see the description of deflate with [`Z_FULL_FLUSH`]) can be found, +/// or until all available input is skipped. No output is provided. +/// +/// [`inflateSync`] searches for a `00 00 FF FF` pattern in the compressed data. +/// All full flush points have this pattern, but not all occurrences of this pattern are full flush points. +/// +/// # Returns +/// +/// - [`Z_OK`] if a possible full flush point has been found +/// - [`Z_BUF_ERROR`] if no more input was provided +/// - [`Z_DATA_ERROR`] if no flush point has been found +/// - [`Z_STREAM_ERROR`] if the stream structure was inconsistent +/// +/// In the success case, the application may save the current value of `total_in` which indicates where valid compressed data was found. +/// In the error case, the application may repeatedly call [`inflateSync`], providing more input each time, until success or end of the input data. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateSync)] +pub unsafe extern "C-unwind" fn inflateSync(strm: *mut z_stream) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::sync(stream) as _ + } else { + ReturnCode::StreamError as _ + } +} + +#[doc(hidden)] +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateSyncPoint)] +pub unsafe extern "C-unwind" fn inflateSyncPoint(strm: *mut z_stream) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::sync_point(stream) as i32 + } else { + ReturnCode::StreamError as _ + } +} + +/// Initializes the state for decompression +/// +/// A call to [`inflateInit_`] is equivalent to [`inflateInit2_`] where `windowBits` is 15. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_VERSION_ERROR`] if the zlib library version is incompatible with the version assumed by the caller +/// - [`Z_STREAM_ERROR`] if a parameter is invalid, such as a null pointer to the structure +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * Either +/// - `version` is NULL +/// - `version` satisfies the requirements of [`core::ffi::CStr::from_ptr`] +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +#[export_name = prefix!(inflateInit_)] +pub unsafe extern "C-unwind" fn inflateInit_( + strm: z_streamp, + version: *const c_char, + stream_size: c_int, +) -> c_int { + let config = InflateConfig::default(); + unsafe { inflateInit2_(strm, config.window_bits, version, stream_size) } +} + +/// Initializes the state for decompression +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_VERSION_ERROR`] if the zlib library version is incompatible with the version assumed by the caller +/// - [`Z_STREAM_ERROR`] if a parameter is invalid, such as a null pointer to the structure +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * Either +/// - `version` is NULL +/// - `version` satisfies the requirements of [`core::ffi::CStr::from_ptr`] +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +#[export_name = prefix!(inflateInit2_)] +pub unsafe extern "C-unwind" fn inflateInit2_( + strm: z_streamp, + windowBits: c_int, + version: *const c_char, + stream_size: c_int, +) -> c_int { + if !is_version_compatible(version, stream_size) { + ReturnCode::VersionError as _ + } else { + inflateInit2(strm, windowBits) + } +} + +/// Helper that implements the actual initialization logic +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +unsafe extern "C-unwind" fn inflateInit2(strm: z_streamp, windowBits: c_int) -> c_int { + let Some(strm) = (unsafe { strm.as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let config = InflateConfig { + window_bits: windowBits, + }; + + zlib_rs::inflate::init(strm, config) as _ +} + +/// Inserts bits in the inflate input stream. +/// +/// The intent is that this function is used to start inflating at a bit position in the middle of a byte. +/// The provided bits will be used before any bytes are used from next_in. +/// This function should only be used with raw inflate, and should be used before the first [`inflate`] call after [`inflateInit2_`] or [`inflateReset`]. +/// bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. +/// +/// If bits is negative, then the input stream bit buffer is emptied. Then [`inflatePrime`] can be called again to put bits in the buffer. +/// This is used to clear out bits leftover after feeding inflate a block description prior to feeding inflate codes. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflatePrime)] +pub unsafe extern "C-unwind" fn inflatePrime(strm: *mut z_stream, bits: i32, value: i32) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::prime(stream, bits, value) as _ + } else { + ReturnCode::StreamError as _ + } +} + +/// Equivalent to [`inflateEnd`] followed by [`inflateInit_`], but does not free and reallocate the internal decompression state. +/// +/// The stream will keep attributes that may have been set by [`inflateInit2_`]. +/// The stream's `total_in`, `total_out`, `adler`, and `msg` fields are initialized. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateReset)] +pub unsafe extern "C-unwind" fn inflateReset(strm: *mut z_stream) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::reset(stream) as _ + } else { + ReturnCode::StreamError as _ + } +} + +/// This function is the same as [`inflateReset`], but it also permits changing the wrap and window size requests. +/// +/// The `windowBits` parameter is interpreted the same as it is for [`inflateInit2_`]. +/// If the window size is changed, then the memory allocated for the window is freed, and the window will be reallocated by [`inflate`] if needed. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent, or if the `windowBits` +/// parameter is invalid +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateReset2)] +pub unsafe extern "C-unwind" fn inflateReset2(strm: *mut z_stream, windowBits: c_int) -> i32 { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + let config = InflateConfig { + window_bits: windowBits, + }; + zlib_rs::inflate::reset_with_config(stream, config) as _ + } else { + ReturnCode::StreamError as _ + } +} + +/// Initializes the decompression dictionary from the given uncompressed byte sequence. +/// +/// This function must be called immediately after a call of [`inflate`], if that call returned [`Z_NEED_DICT`]. +/// The dictionary chosen by the compressor can be determined from the Adler-32 value returned by that call of inflate. +/// The compressor and decompressor must use exactly the same dictionary (see [`deflateSetDictionary`]). +/// For raw inflate, this function can be called at any time to set the dictionary. +/// If the provided dictionary is smaller than the window and there is already data in the window, then the provided dictionary will amend what's there. +/// The application must insure that the same dictionary that was used for compression is provided. +/// +/// [`inflateSetDictionary`] does not perform any decompression: this will be done by subsequent calls of [`inflate`]. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent or `dictionary` is `NULL` +/// - [`Z_DATA_ERROR`] if the given dictionary doesn't match the expected one (i.e. it has an incorrect Adler-32 value). +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +/// * Either +/// - `dictionary` is `NULL` +/// - `dictionary` and `dictLength` satisfy the requirements of [`core::slice::from_raw_parts_mut::`] +#[export_name = prefix!(inflateSetDictionary)] +pub unsafe extern "C-unwind" fn inflateSetDictionary( + strm: *mut z_stream, + dictionary: *const u8, + dictLength: c_uint, +) -> c_int { + let Some(stream) = InflateStream::from_stream_mut(strm) else { + return ReturnCode::StreamError as _; + }; + + let dict = match dictLength { + 0 => &[], + _ => unsafe { slice_from_raw_parts(dictionary, dictLength as usize) }.unwrap_or(&[]), + }; + + zlib_rs::inflate::set_dictionary(stream, dict) as _ +} + +/// Requests that gzip header information be stored in the provided [`gz_header`] structure. +/// +/// The [`inflateGetHeader`] function may be called after [`inflateInit2_`] or [`inflateReset`], and before the first call of [`inflate`]. +/// As [`inflate`] processes the gzip stream, `head.done` is zero until the header is completed, at which time `head.done` is set to one. +/// If a zlib stream is being decoded, then `head.done` is set to `-1` to indicate that there will be no gzip header information forthcoming. +/// Note that [`Z_BLOCK`] can be used to force [`inflate`] to return immediately after header processing is complete and before any actual data is decompressed. +/// +/// - The `text`, `time`, `xflags`, and `os` fields are filled in with the gzip header contents. +/// - `hcrc` is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) +/// - If `extra` is not `NULL`, then `extra_max` contains the maximum number of bytes to write to extra. +/// Once `done` is `true`, `extra_len` contains the actual extra field length, +/// and `extra` contains the extra field, or that field truncated if `extra_max` is less than `extra_len`. +/// - If `name` is not `NULL`, then up to `name_max` characters are written there, terminated with a zero unless the length is greater than `name_max`. +/// - If `comment` is not `NULL`, then up to `comm_max` characters are written there, terminated with a zero unless the length is greater than `comm_max`. +/// +/// When any of `extra`, `name`, or `comment` are not `NULL` and the respective field is not present in the header, then that field is set to `NULL` to signal its absence. +/// This allows the use of [`deflateSetHeader`] with the returned structure to duplicate the header. However if those fields are set to allocated memory, +/// then the application will need to save those pointers elsewhere so that they can be eventually freed. +/// +/// If [`inflateGetHeader`] is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. +/// [`inflateReset`] will reset the process to discard the header information. +/// The application would need to call [`inflateGetHeader`] again to retrieve the header from the next gzip stream. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent (such as zalloc being NULL) +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +/// * Either +/// - `head` is `NULL` +/// - `head` satisfies the requirements of `&mut *head` +/// * If `head` is not `NULL`: +/// - if `head.extra` is not NULL, it must be writable for at least `head.extra_max` bytes +/// - if `head.name` is not NULL, it must be writable for at least `head.name_max` bytes +/// - if `head.comment` is not NULL, it must be writable for at least `head.comm_max` bytes +#[export_name = prefix!(inflateGetHeader)] +pub unsafe extern "C-unwind" fn inflateGetHeader(strm: z_streamp, head: gz_headerp) -> c_int { + let Some(stream) = (unsafe { InflateStream::from_stream_mut(strm) }) else { + return ReturnCode::StreamError as _; + }; + + // SAFETY: the caller guarantees the safety of `&mut *` + let header = unsafe { head.as_mut() }; + + zlib_rs::inflate::get_header(stream, header) as i32 +} + +#[doc(hidden)] +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateUndermine)] +pub unsafe extern "C-unwind" fn inflateUndermine(strm: *mut z_stream, subvert: i32) -> c_int { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::undermine(stream, subvert) as i32 + } else { + ReturnCode::StreamError as _ + } +} + +#[doc(hidden)] +/// ## Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`inflateInit_`] or similar +#[export_name = prefix!(inflateResetKeep)] +pub unsafe extern "C-unwind" fn inflateResetKeep(strm: *mut z_stream) -> c_int { + if let Some(stream) = InflateStream::from_stream_mut(strm) { + zlib_rs::inflate::reset_keep(stream) as _ + } else { + ReturnCode::StreamError as _ + } +} + +// undocumented but exposed function +#[doc(hidden)] +/// Returns the number of codes used +/// +/// # Safety +/// +/// The caller must guarantee that either: +/// +/// - `buf` is `NULL` +/// - `buf` and `len` satisfy the requirements of [`core::slice::from_raw_parts`] +#[export_name = prefix!(inflateCodesUsed)] +pub unsafe extern "C-unwind" fn inflateCodesUsed(_strm: *mut z_stream) -> c_ulong { + todo!() +} + +/// Compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_END`] if the end of the compressed data has been reached and all uncompressed output has been produced +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// - [`Z_BUF_ERROR`] if no progress was possible or if there was not enough room in the output buffer when [`Z_FINISH`] is used +/// +/// Note that [`Z_BUF_ERROR`] is not fatal, and [`deflate`] can be called again with more input and more output space to continue decompressing. +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflate)] +pub unsafe extern "C-unwind" fn deflate(strm: *mut z_stream, flush: i32) -> c_int { + if let Some(stream) = DeflateStream::from_stream_mut(strm) { + match DeflateFlush::try_from(flush) { + Ok(flush) => zlib_rs::deflate::deflate(stream, flush) as _, + Err(()) => ReturnCode::StreamError as _, + } + } else { + ReturnCode::StreamError as _ + } +} + +/// Provides gzip header information for when a gzip stream is requested by [`deflateInit2_`]. +/// +/// [`deflateSetHeader`] may be called after [`deflateInit2_`] or [`deflateReset`]) and before the first call of [`deflate`]. The header's `text`, `time`, `os`, `extra`, `name`, and `comment` fields in the provided [`gz_header`] structure are written to the gzip header (xflag is ignored — the extra flags are set according to the compression level). +/// +/// The caller must assure that, if not `NULL`, `name` and `comment` are terminated with a zero byte, and that if `extra` is not NULL, that `extra_len` bytes are available there. +/// If `hcrc` is true, a gzip header crc is included. +/// +/// If [`deflateSetHeader`] is not used, the default gzip header has text false, the time set to zero, and os set to the current operating system, with no extra, name, or comment fields. The gzip header is returned to the default state by [`deflateReset`]. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +/// * Either +/// - `head` is `NULL` +/// - `head` satisfies the requirements of `&mut *head` +#[export_name = prefix!(deflateSetHeader)] +pub unsafe extern "C-unwind" fn deflateSetHeader(strm: *mut z_stream, head: gz_headerp) -> c_int { + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(strm) }) else { + return ReturnCode::StreamError as _; + }; + + let header = unsafe { head.as_mut() }; + + zlib_rs::deflate::set_header(stream, header) as _ +} + +/// Returns an upper bound on the compressed size after deflation of `sourceLen` bytes. +/// +/// This function must be called after [`deflateInit_`] or [`deflateInit2_`]. +/// This would be used to allocate an output buffer for deflation in a single pass, and so would be called before [`deflate`]. +/// If that first [`deflate`] call is provided the `sourceLen` input bytes, an output buffer allocated to the size returned by [`deflateBound`], +/// and the flush value [`Z_FINISH`], then [`deflate`] is guaranteed to return [`Z_STREAM_END`]. +/// +/// Note that it is possible for the compressed size to be larger than the value returned by [`deflateBound`] +/// if flush options other than [`Z_FINISH`] or [`Z_NO_FLUSH`] are used. +/// +/// ## Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateBound)] +pub unsafe extern "C-unwind" fn deflateBound(strm: *mut z_stream, sourceLen: c_ulong) -> c_ulong { + zlib_rs::deflate::bound(DeflateStream::from_stream_mut(strm), sourceLen as usize) as c_ulong +} + +/// Compresses `source` into `dest`, and writes the final deflated size into `destLen`. +/// +///`sourceLen` is the byte length of the source buffer. +/// Upon entry, `destLen` is the total size of the destination buffer, +/// which must be at least the value returned by [`compressBound`]`(sourceLen)`. +/// Upon exit, `destLen` is the actual size of the compressed data. +/// +/// A call to [`compress`] is equivalent to [`compress2`] with a level parameter of [`Z_DEFAULT_COMPRESSION`]. +/// +/// # Returns +/// +/// * [`Z_OK`] if success +/// * [`Z_MEM_ERROR`] if there was not enough memory +/// * [`Z_BUF_ERROR`] if there was not enough room in the output buffer +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * The `destLen` pointer satisfies the requirements of [`core::ptr::read`] +/// * Either +/// - `dest` is `NULL` +/// - `dest` and `*destLen` satisfy the requirements of [`core::slice::from_raw_parts_mut::>`] +/// * Either +/// - `source` is `NULL` +/// - `source` and `sourceLen` satisfy the requirements of [`core::slice::from_raw_parts`] +/// +/// # Example +/// +/// ``` +/// use libz_rs_sys::{Z_OK, compress}; +/// +/// let source = b"Ferris"; +/// +/// let mut dest = vec![0u8; 100]; +/// let mut dest_len = dest.len() as _; +/// +/// let err = unsafe { +/// compress( +/// dest.as_mut_ptr(), +/// &mut dest_len, +/// source.as_ptr(), +/// source.len() as _, +/// ) +/// }; +/// +/// assert_eq!(err, Z_OK); +/// assert_eq!(dest_len, 14); +/// +/// dest.truncate(dest_len as usize); +/// assert_eq!(dest, [120, 156, 115, 75, 45, 42, 202, 44, 6, 0, 8, 6, 2, 108]); +/// ``` +#[export_name = prefix!(compress)] +pub unsafe extern "C-unwind" fn compress( + dest: *mut Bytef, + destLen: *mut c_ulong, + source: *const Bytef, + sourceLen: c_ulong, +) -> c_int { + compress2( + dest, + destLen, + source, + sourceLen, + DeflateConfig::default().level, + ) +} + +/// Compresses `source` into `dest`, and writes the final deflated size into `destLen`. +/// +/// The level parameter has the same meaning as in [`deflateInit_`]. +/// `sourceLen` is the byte length of the source buffer. +/// Upon entry, `destLen` is the total size of the destination buffer, +/// which must be at least the value returned by [`compressBound`]`(sourceLen)`. +/// Upon exit, `destLen` is the actual size of the compressed data. +/// +/// # Returns +/// +/// * [`Z_OK`] if success +/// * [`Z_MEM_ERROR`] if there was not enough memory +/// * [`Z_BUF_ERROR`] if there was not enough room in the output buffer +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `destLen` is `NULL` +/// - `destLen` satisfies the requirements of `&mut *destLen` +/// * Either +/// - `dest` is `NULL` +/// - `dest` and `*destLen` satisfy the requirements of [`core::slice::from_raw_parts_mut::>`] +/// * Either +/// - `source` is `NULL` +/// - `source` and `sourceLen` satisfy the requirements of [`core::slice::from_raw_parts`] +#[export_name = prefix!(compress2)] +pub unsafe extern "C-unwind" fn compress2( + dest: *mut Bytef, + destLen: *mut c_ulong, + source: *const Bytef, + sourceLen: c_ulong, + level: c_int, +) -> c_int { + // stock zlib will just dereference a NULL pointer: that's UB. + // Hence us returning an error value is compatible + let Some(destLen) = (unsafe { destLen.as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let Some(output) = (unsafe { slice_from_raw_parts_uninit_mut(dest, *destLen as usize) }) else { + return ReturnCode::StreamError as _; + }; + + let Some(input) = (unsafe { slice_from_raw_parts(source, sourceLen as usize) }) else { + return ReturnCode::StreamError as _; + }; + + let config = DeflateConfig::new(level); + let (output, err) = zlib_rs::deflate::compress(output, input, config); + + *destLen = output.len() as c_ulong; + + err as c_int +} + +/// Returns an upper bound on the compressed size after [`compress`] or [`compress2`] on `sourceLen` bytes. +/// +/// Can be used before a [`compress`] or [`compress2`] call to allocate the destination buffer. +#[export_name = prefix!(compressBound)] +pub extern "C-unwind" fn compressBound(sourceLen: c_ulong) -> c_ulong { + zlib_rs::deflate::compress_bound(sourceLen as usize) as c_ulong +} + +/// Deallocates all dynamically allocated data structures for this stream. +/// +/// This function discards any unprocessed input and does not flush any pending output. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// - [`Z_DATA_ERROR`] if the stream was freed prematurely (some input or output was discarded) +/// +/// In the error case, `strm.msg` may be set but then points to a static string (which must not be deallocated). +/// +/// # Safety +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateEnd)] +pub unsafe extern "C-unwind" fn deflateEnd(strm: *mut z_stream) -> i32 { + match DeflateStream::from_stream_mut(strm) { + Some(stream) => match zlib_rs::deflate::end(stream) { + Ok(_) => ReturnCode::Ok as _, + Err(_) => ReturnCode::DataError as _, + }, + None => ReturnCode::StreamError as _, + } +} + +/// This function is equivalent to [`deflateEnd`] followed by [`deflateInit_`], but does not free and reallocate the internal compression state. +/// +/// This function will leave the compression level and any other attributes that may have been set unchanged. +/// The stream's `total_in`, `total_out`, `adler`, and `msg` fields are initialized. +/// +/// ## Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// ## Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateReset)] +pub unsafe extern "C-unwind" fn deflateReset(strm: *mut z_stream) -> i32 { + match DeflateStream::from_stream_mut(strm) { + Some(stream) => zlib_rs::deflate::reset(stream) as _, + None => ReturnCode::StreamError as _, + } +} + +/// Dynamically update the compression level and compression strategy. +/// +/// This can be used to switch between compression and straight copy of the input data, +/// or to switch to a different kind of input data requiring a different strategy. +/// +/// The interpretation of level and strategy is as in [`deflateInit2_`]. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent or if a parameter was invalid +/// - [`Z_BUF_ERROR`] if there was not enough output space to complete the compression of the available input data before a change in the strategy or approach. +/// +/// Note that in the case of a [`Z_BUF_ERROR`], the parameters are not changed. +/// A return value of [`Z_BUF_ERROR`] is not fatal, in which case [`deflateParams`] can be retried with more output space. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateParams)] +pub unsafe extern "C-unwind" fn deflateParams( + strm: z_streamp, + level: c_int, + strategy: c_int, +) -> c_int { + let Ok(strategy) = Strategy::try_from(strategy) else { + return ReturnCode::StreamError as _; + }; + + match DeflateStream::from_stream_mut(strm) { + Some(stream) => zlib_rs::deflate::params(stream, level, strategy) as _, + None => ReturnCode::StreamError as _, + } +} + +/// Initializes the compression dictionary from the given byte sequence without producing any compressed output. +/// +/// This function may be called after [`deflateInit_`], [`deflateInit2_`] or [`deflateReset`]) and before the first call of [`deflate`]. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +/// * Either +/// - `dictionary` is `NULL` +/// - `dictionary` and `dictLength` satisfy the requirements of [`core::slice::from_raw_parts_mut::`] +#[export_name = prefix!(deflateSetDictionary)] +pub unsafe extern "C-unwind" fn deflateSetDictionary( + strm: z_streamp, + dictionary: *const Bytef, + dictLength: uInt, +) -> c_int { + let Some(dictionary) = (unsafe { slice_from_raw_parts(dictionary, dictLength as usize) }) + else { + return ReturnCode::StreamError as _; + }; + + match DeflateStream::from_stream_mut(strm) { + Some(stream) => zlib_rs::deflate::set_dictionary(stream, dictionary) as _, + None => ReturnCode::StreamError as _, + } +} + +/// Inserts bits in the deflate output stream. +/// +/// The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. +/// As such, this function can only be used for raw deflate, and must be used before the first [`deflate`] call after a [`deflateInit2_`] or [`deflateReset`]. +/// bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_BUF_ERROR`] if there was not enough room in the internal buffer to insert the bits +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflatePrime)] +pub unsafe extern "C-unwind" fn deflatePrime(strm: z_streamp, bits: c_int, value: c_int) -> c_int { + match DeflateStream::from_stream_mut(strm) { + Some(stream) => zlib_rs::deflate::prime(stream, bits, value) as _, + None => ReturnCode::StreamError as _, + } +} + +/// Returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. +/// +/// The bytes not provided would be due to the available output space having being consumed. +/// The number of bits of output not provided are between `0` and `7`, where they await more bits to join them in order to fill out a full byte. +/// If pending or bits are `NULL`, then those values are not set. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +/// * Either +/// - `pending` is `NULL` +/// - `pending` satisfies the requirements of [`core::ptr::write::`] +/// * Either +/// - `bits` is `NULL` +/// - `bits` satisfies the requirements of [`core::ptr::write::`] +#[export_name = prefix!(deflatePending)] +pub unsafe extern "C-unwind" fn deflatePending( + strm: z_streamp, + pending: *mut c_uint, + bits: *mut c_int, +) -> c_int { + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(strm) }) else { + return ReturnCode::StreamError as _; + }; + + let (current_pending, current_bits) = stream.pending(); + + if let Some(pending) = unsafe { pending.as_mut() } { + *pending = current_pending as c_uint; + } + + if let Some(bits) = unsafe { bits.as_mut() } { + *bits = current_bits as c_int; + } + + ReturnCode::Ok as _ +} + +/// Sets the destination stream as a complete copy of the source stream. +/// +/// This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. +/// The streams that will be discarded should then be freed by calling [`deflateEnd`]. +/// Note that [`deflateCopy`] duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_STREAM_ERROR`] if the source stream state was inconsistent (such as zalloc being NULL) +/// +/// The `msg` field is left unchanged in both source and destination. +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `dest` is `NULL` +/// - `dest` satisfies the requirements of `&mut *(dest as *mut MaybeUninit)` +/// * Either +/// - `source` is `NULL` +/// - `source` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateCopy)] +pub unsafe extern "C-unwind" fn deflateCopy(dest: z_streamp, source: z_streamp) -> c_int { + let Some(dest) = (unsafe { dest.cast::>().as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let Some(source) = (unsafe { DeflateStream::from_stream_mut(source) }) else { + return ReturnCode::StreamError as _; + }; + + zlib_rs::deflate::copy(dest, source) as _ +} + +/// Initializes the state for compression +/// +/// The stream's `zalloc`, `zfree` and `opaque` fields must be initialized before by the caller. +/// If `zalloc` and `zfree` are set to `NULL`, [`deflateInit_`] updates them to use default allocation functions. +/// The `total_in`, `total_out`, `adler`, and `msg` fields are initialized. +/// +/// The compression level must be [`Z_DEFAULT_COMPRESSION`], or between `0` and `9`: +/// +/// - level `0` gives no compression at all (the input data is simply copied a block at a time) +/// - level `1` gives best speed +/// - level `9` gives best compression +/// - [`Z_DEFAULT_COMPRESSION`] requests a default compromise between speed and compression (currently equivalent to level `6`). + +/// +/// A call to [`inflateInit_`] is equivalent to [`inflateInit2_`] where +/// +/// - `method` is `8` (deflate) +/// - `windowBits` is `15` +/// - `memLevel` is `8` +/// - `strategy` is `0` (default) +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_VERSION_ERROR`] if the zlib library version is incompatible with the version assumed by the caller +/// - [`Z_STREAM_ERROR`] if a parameter is invalid, such as a null pointer to the structure +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * Either +/// - `version` is NULL +/// - `version` satisfies the requirements of [`core::ffi::CStr::from_ptr`] +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +/// +/// # Example +/// +/// ``` +/// use core::mem::MaybeUninit; +/// use libz_rs_sys::{z_stream, deflateInit_, zlibVersion, Z_OK}; +/// +/// // the zalloc and zfree fields are initialized as zero/NULL. +/// // `deflateInit_` will set a default allocation and deallocation function. +/// let mut strm = MaybeUninit::zeroed(); +/// +/// let err = unsafe { +/// deflateInit_( +/// strm.as_mut_ptr(), +/// 6, +/// zlibVersion(), +/// core::mem::size_of::() as _, +/// ) +/// }; +/// assert_eq!(err, Z_OK); +/// +/// // the stream is now fully initialized. Prefer `assume_init_mut` over +/// // `assume_init` so the stream does not get moved. +/// let strm = unsafe { strm.assume_init_mut() }; +/// ``` +#[export_name = prefix!(deflateInit_)] +pub unsafe extern "C-unwind" fn deflateInit_( + strm: z_streamp, + level: c_int, + version: *const c_char, + stream_size: c_int, +) -> c_int { + let config = DeflateConfig::new(level); + + unsafe { + deflateInit2_( + strm, + level, + config.method as c_int, + config.window_bits, + config.mem_level, + config.strategy as c_int, + version, + stream_size, + ) + } +} + +/// Initializes the state for compression +/// +/// The stream's `zalloc`, `zfree` and `opaque` fields must be initialized before by the caller. +/// If `zalloc` and `zfree` are set to `NULL`, [`deflateInit_`] updates them to use default allocation functions. +/// The `total_in`, `total_out`, `adler`, and `msg` fields are initialized. +/// +/// The compression level must be [`Z_DEFAULT_COMPRESSION`], or between `0` and `9`: +/// +/// - level `0` gives no compression at all (the input data is simply copied a block at a time) +/// - level `1` gives best speed +/// - level `9` gives best compression +/// - [`Z_DEFAULT_COMPRESSION`] requests a default compromise between speed and compression (currently equivalent to level `6`). + +/// +/// A call to [`inflateInit_`] is equivalent to [`inflateInit2_`] where +/// +/// +/// # Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_MEM_ERROR`] if there was not enough memory +/// - [`Z_VERSION_ERROR`] if the zlib library version is incompatible with the version assumed by the caller +/// - [`Z_STREAM_ERROR`] if a parameter is invalid, such as a null pointer to the structure +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` +/// * Either +/// - `version` is NULL +/// - `version` satisfies the requirements of [`core::ffi::CStr::from_ptr`] +/// * If `strm` is not `NULL`, the following fields contain valid values +/// - `zalloc` +/// - `zfree` +/// - `opaque` +/// +/// # Example +/// +/// ``` +/// use core::mem::MaybeUninit; +/// use libz_rs_sys::{z_stream, deflateInit2_, zlibVersion, Z_OK}; +/// +/// // the zalloc and zfree fields are initialized as zero/NULL. +/// // `deflateInit_` will set a default allocation and deallocation function. +/// let mut strm = MaybeUninit::zeroed(); +/// +/// let err = unsafe { +/// deflateInit2_( +/// strm.as_mut_ptr(), +/// 6, +/// 8, +/// 15, +/// 8, +/// 0, +/// zlibVersion(), +/// core::mem::size_of::() as _, +/// ) +/// }; +/// assert_eq!(err, Z_OK); +/// +/// // the stream is now fully initialized. Prefer `assume_init_mut` over +/// // `assume_init` so the stream does not get moved. +/// let strm = unsafe { strm.assume_init_mut() }; +/// ``` +#[export_name = prefix!(deflateInit2_)] +pub unsafe extern "C-unwind" fn deflateInit2_( + strm: z_streamp, + level: c_int, + method: c_int, + windowBits: c_int, + memLevel: c_int, + strategy: c_int, + version: *const c_char, + stream_size: c_int, +) -> c_int { + if !is_version_compatible(version, stream_size) { + return ReturnCode::VersionError as _; + } + + let Some(strm) = (unsafe { strm.as_mut() }) else { + return ReturnCode::StreamError as _; + }; + + let Ok(method) = Method::try_from(method) else { + return ReturnCode::StreamError as _; + }; + + let Ok(strategy) = Strategy::try_from(strategy) else { + return ReturnCode::StreamError as _; + }; + + let config = DeflateConfig { + level, + method, + window_bits: windowBits, + mem_level: memLevel, + strategy, + }; + + zlib_rs::deflate::init(strm, config) as _ +} + +/// Fine tune deflate's internal compression parameters. +/// +/// This should only be used by someone who understands the algorithm used by zlib's deflate for searching +/// for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out +/// the last compressed bit for their specific input data. Read the `deflate.rs` source code for the meaning +/// of the `max_lazy`, `good_length`, `nice_length`, and `max_chain` parameters. +/// +/// ## Returns +/// +/// - [`Z_OK`] if success +/// - [`Z_STREAM_ERROR`] if the stream state was inconsistent +/// +/// # Safety +/// +/// The caller must guarantee that +/// +/// * Either +/// - `strm` is `NULL` +/// - `strm` satisfies the requirements of `&mut *strm` and was initialized with [`deflateInit_`] or similar +#[export_name = prefix!(deflateTune)] +pub unsafe extern "C-unwind" fn deflateTune( + strm: z_streamp, + good_length: c_int, + max_lazy: c_int, + nice_length: c_int, + max_chain: c_int, +) -> c_int { + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(strm) }) else { + return ReturnCode::StreamError as _; + }; + + zlib_rs::deflate::tune( + stream, + good_length as usize, + max_lazy as usize, + nice_length as usize, + max_chain as usize, + ) as _ +} + +/// Get the error message for an error. This could be the value returned by e.g. [`compress`] or +/// [`inflate`]. +/// +/// The return value is a pointer to a NULL-terminated sequence of bytes +/// +/// ## Example +/// +/// ``` +/// use libz_rs_sys::*; +/// use core::ffi::{c_char, CStr}; +/// +/// fn cstr<'a>(ptr: *const c_char) -> &'a [u8] { +/// // SAFETY: we trust the input +/// unsafe { CStr::from_ptr(ptr) }.to_bytes() +/// } +/// +/// // defined error values give a short message +/// assert_eq!(cstr(zError(Z_NEED_DICT)), b"need dictionary"); +/// assert_eq!(cstr(zError(Z_NEED_DICT)), b"need dictionary"); +/// assert_eq!(cstr(zError(Z_STREAM_END)), b"stream end"); +/// assert_eq!(cstr(zError(Z_OK)), b""); +/// assert_eq!(cstr(zError(Z_ERRNO)), b"file error"); +/// assert_eq!(cstr(zError(Z_STREAM_ERROR)), b"stream error"); +/// assert_eq!(cstr(zError(Z_DATA_ERROR)), b"data error"); +/// assert_eq!(cstr(zError(Z_MEM_ERROR)), b"insufficient memory"); +/// assert_eq!(cstr(zError(Z_BUF_ERROR)), b"buffer error"); +/// assert_eq!(cstr(zError(Z_VERSION_ERROR)), b"incompatible version"); +/// +/// // other inputs return an empty string +/// assert_eq!(cstr(zError(1234)), b""); +/// ``` +#[export_name = prefix!(zError)] +pub const extern "C" fn zError(err: c_int) -> *const c_char { + match ReturnCode::try_from_c_int(err) { + Some(return_code) => return_code.error_message(), + None => [0 as c_char].as_ptr(), + } +} + +macro_rules! libz_rs_sys_version { + () => { + concat!("1.3.0-zlib-rs-", env!("CARGO_PKG_VERSION"), "\0") + }; +} + +// the first part of this version specifies the zlib that we're compatible with (in terms of +// supported functions). In practice in most cases only the major version is checked, unless +// specific functions that were added later are used. +const LIBZ_RS_SYS_VERSION: &str = concat!(libz_rs_sys_version!(), "\0"); + +unsafe fn is_version_compatible(version: *const c_char, stream_size: i32) -> bool { + let Some(expected_major_version) = (unsafe { version.as_ref() }) else { + return false; + }; + + if *expected_major_version as u8 != LIBZ_RS_SYS_VERSION.as_bytes()[0] { + return false; + } + + core::mem::size_of::() as i32 == stream_size +} + +/// The version of the zlib library. +/// +/// Its value is a pointer to a NULL-terminated sequence of bytes. +/// +/// The version string for this release is ` +#[doc = libz_rs_sys_version!()] +/// `: +/// +/// - The first component is the version of stock zlib that this release is compatible with +/// - The final component is the zlib-rs version used to build this release. +#[export_name = prefix!(zlibVersion)] +pub const extern "C" fn zlibVersion() -> *const c_char { + LIBZ_RS_SYS_VERSION.as_ptr().cast::() +} + +/// # Safety +/// +/// Either +/// +/// - `ptr` is `NULL` +/// - `ptr` and `len` satisfy the requirements of [`core::slice::from_raw_parts`] +unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> Option<&'a [T]> { + if ptr.is_null() { + None + } else { + Some(unsafe { core::slice::from_raw_parts(ptr, len) }) + } +} + +/// # Safety +/// +/// Either +/// +/// - `ptr` is `NULL` +/// - `ptr` and `len` satisfy the requirements of [`core::slice::from_raw_parts_mut`] +unsafe fn slice_from_raw_parts_uninit_mut<'a, T>( + ptr: *mut T, + len: usize, +) -> Option<&'a mut [MaybeUninit]> { + if ptr.is_null() { + None + } else { + Some(unsafe { core::slice::from_raw_parts_mut(ptr.cast::>(), len) }) + } +} diff --git a/third_party/rust/mapped_hyph/.cargo-checksum.json b/third_party/rust/mapped_hyph/.cargo-checksum.json index a666e00a8c..dbaccea179 100644 --- a/third_party/rust/mapped_hyph/.cargo-checksum.json +++ b/third_party/rust/mapped_hyph/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".travis.yml":"4d1af7257c9619f7ae66fc271ba2c1be5f063640ae8ceaa235c8c8aaf32f44ea","COPYRIGHT":"4df931055b82b96e13ad475c4cee3de5afa69a54a4c611c9d7dc6252d858d9c8","Cargo.toml":"06a6456cc9fa9929cb0fa7aa762f3b1e6362f8b8903111ad9b01881af26dcad9","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"4ad721b5b6a3d39ca3e2202f403d897c4a1d42896486dd58963a81f8e64ef61d","README.md":"2c91137faee83f0805a9b9123e105670bf60c2fe45ce6536fb92df7ef85017a5","benches/bench.rs":"ed7143e66ecf8bfb12c87d1f9344157d97696b8194de9132d061129bc80d8d52","cbindgen.toml":"452e79bea00e2a0c16a03ac04e454a0c5955becf2d0306ccce7d1c13d3bcc51a","doc/mapped_hyph_format.md":"2f2487cf536fe4b03db6e4b384be06744ec30b3f299519492288306a93127fbb","hyph_en_US.hyf":"6262b4c5118fe277ab4add8689d9524ca72097564652baec67a8fcd5029ec9b0","src/bin/hyf_compile.rs":"85199ddf171219b61a2da0e6acf675bf0f7a9a11ee2c6c5d1d436ec466aa95b5","src/builder.rs":"4169a89fb3a5025b06edeb8a6435a18814d58799d15861c3639a2ed9c63c628b","src/ffi.rs":"09884728df4910bb430e0d59edf770b04e5b11e2423f75c5782c5152af323476","src/lib.rs":"30c007a5f8bf71af3b4b93227c3fbb76198d6333388e5c156aaff13bfe458c8e","src/main.rs":"666befeb39cb1a7dfb66c6b9218d5f7b6c4ed09dbbbc8cfff6b749a33a99ebcf","tests/base.hyf":"d8bf57c6280cfa1d357d3fdba156ce64afbd9df58e28eeb084dfe3f80972b73f","tests/base.hyph":"a3f1fab24c101701fdf21e8359685d80611ab970304e2bd89ef024768b3700c8","tests/base.word":"1136c9a421b242262661b9a65723f87a5ecf77ae38eabcea057832d036d567fd","tests/compound.hyf":"929c1ba6676e4c43bc649d0abf4275ea9e8b02bffaa5acdf704a710813a7a13c","tests/compound4.hyf":"2093287bc41ee30ff9bdbf278f1f8209cb1d1a78236b46e9060af2a881572b8e","tests/compound5.hyf":"0942a5dfbb8d0ef3a937ab9da0418abb41300357cde49f4c477a59a11b2cb6bd","tests/compound6.hyf":"ebad958c2692a5b439b31e324020ed27c42dc05bd5b8c6a6dea4669e6ccf76b4","tests/hyphen.hyf":"92b8a5c86aac6a0b9f0eb7330a057065d6985fd047e851cae47039995c682d4d","tests/lhmin.hyf":"23c886704fafee7d9c54b2478029cf69a5fa946c2f2442bd86697bca5933c88d","tests/num.hyf":"4834fabe78b5c81815434d4562ce3322541649e1ea1edc555a498574bc8b237e","tests/rhmin.hyf":"239cb3d4d7f904abb43b57241e12cc1396e636220c3806e64666aca7ca46cc42","tests/settings2.hyf":"9fc4855e0b952a3593db1efef080b93ce7f1c6fe6798db0440e2bf0cc986ffa2","tests/settings3.hyf":"867db207b485a06e7d60ad10735c9111f10516ee3a5afd6306c683ace3454491","tests/test.rs":"5c81ae59b9384b70d9461407999dac1fde9214398876c4433fbbde9571cc1d94"},"package":null} \ No newline at end of file +{"files":{".travis.yml":"4d1af7257c9619f7ae66fc271ba2c1be5f063640ae8ceaa235c8c8aaf32f44ea","COPYRIGHT":"4df931055b82b96e13ad475c4cee3de5afa69a54a4c611c9d7dc6252d858d9c8","Cargo.toml":"d77a02674cc9cbbb2e3f01398c3eda689b6f41c20240bfec34327df73360641e","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"4ad721b5b6a3d39ca3e2202f403d897c4a1d42896486dd58963a81f8e64ef61d","README.md":"2c91137faee83f0805a9b9123e105670bf60c2fe45ce6536fb92df7ef85017a5","benches/bench.rs":"ed7143e66ecf8bfb12c87d1f9344157d97696b8194de9132d061129bc80d8d52","cbindgen.toml":"452e79bea00e2a0c16a03ac04e454a0c5955becf2d0306ccce7d1c13d3bcc51a","doc/mapped_hyph_format.md":"2f2487cf536fe4b03db6e4b384be06744ec30b3f299519492288306a93127fbb","hyph_en_US.hyf":"6262b4c5118fe277ab4add8689d9524ca72097564652baec67a8fcd5029ec9b0","src/bin/hyf_compile.rs":"85199ddf171219b61a2da0e6acf675bf0f7a9a11ee2c6c5d1d436ec466aa95b5","src/builder.rs":"4169a89fb3a5025b06edeb8a6435a18814d58799d15861c3639a2ed9c63c628b","src/ffi.rs":"09884728df4910bb430e0d59edf770b04e5b11e2423f75c5782c5152af323476","src/lib.rs":"30c007a5f8bf71af3b4b93227c3fbb76198d6333388e5c156aaff13bfe458c8e","src/main.rs":"666befeb39cb1a7dfb66c6b9218d5f7b6c4ed09dbbbc8cfff6b749a33a99ebcf","tests/base.hyf":"d8bf57c6280cfa1d357d3fdba156ce64afbd9df58e28eeb084dfe3f80972b73f","tests/base.hyph":"a3f1fab24c101701fdf21e8359685d80611ab970304e2bd89ef024768b3700c8","tests/base.word":"1136c9a421b242262661b9a65723f87a5ecf77ae38eabcea057832d036d567fd","tests/compound.hyf":"929c1ba6676e4c43bc649d0abf4275ea9e8b02bffaa5acdf704a710813a7a13c","tests/compound4.hyf":"2093287bc41ee30ff9bdbf278f1f8209cb1d1a78236b46e9060af2a881572b8e","tests/compound5.hyf":"0942a5dfbb8d0ef3a937ab9da0418abb41300357cde49f4c477a59a11b2cb6bd","tests/compound6.hyf":"ebad958c2692a5b439b31e324020ed27c42dc05bd5b8c6a6dea4669e6ccf76b4","tests/hyphen.hyf":"92b8a5c86aac6a0b9f0eb7330a057065d6985fd047e851cae47039995c682d4d","tests/lhmin.hyf":"23c886704fafee7d9c54b2478029cf69a5fa946c2f2442bd86697bca5933c88d","tests/num.hyf":"4834fabe78b5c81815434d4562ce3322541649e1ea1edc555a498574bc8b237e","tests/rhmin.hyf":"239cb3d4d7f904abb43b57241e12cc1396e636220c3806e64666aca7ca46cc42","tests/settings2.hyf":"9fc4855e0b952a3593db1efef080b93ce7f1c6fe6798db0440e2bf0cc986ffa2","tests/settings3.hyf":"867db207b485a06e7d60ad10735c9111f10516ee3a5afd6306c683ace3454491","tests/test.rs":"5c81ae59b9384b70d9461407999dac1fde9214398876c4433fbbde9571cc1d94"},"package":null} \ No newline at end of file diff --git a/third_party/rust/mapped_hyph/Cargo.toml b/third_party/rust/mapped_hyph/Cargo.toml index 17b83794a3..5638cedfef 100644 --- a/third_party/rust/mapped_hyph/Cargo.toml +++ b/third_party/rust/mapped_hyph/Cargo.toml @@ -9,17 +9,41 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +example = [] + [package] edition = "2018" name = "mapped_hyph" version = "0.4.3" authors = ["Jonathan Kew "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Hyphenation using precompiled memory-mapped tables" readme = "README.md" license = "MIT/Apache-2.0" +[lib] +name = "mapped_hyph" +path = "src/lib.rs" + +[[bin]] +name = "hyf_compile" +path = "src/bin/hyf_compile.rs" + +[[bin]] +name = "mapped_hyph" +path = "src/main.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + [[bench]] name = "bench" +path = "benches/bench.rs" harness = false [dependencies] diff --git a/third_party/rust/midir/.cargo-checksum.json b/third_party/rust/midir/.cargo-checksum.json index a67e64ff14..c6a4f23e57 100644 --- a/third_party/rust/midir/.cargo-checksum.json +++ b/third_party/rust/midir/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"10db6f8dbb1c5566e75f2eeda6b2ee8bb44fe4a76f57e0bfb98c62f7f8c04f89","Cargo.toml":"f7bd804ec16011e043422d39d027dffa5cdb04dd33e4a2181eebd3d45570b3ec","LICENSE":"6fe6f623b1fa80e90679aee2f917d8978a184988ebb995ebc254cc9633903cac","README.md":"4131b953217e77a4463fde307ba3262b4df11732c1ff209668df12dff3c73ffc","azure-pipelines-template.yml":"c787791a94e654226a299aaa875fcc48f6eedf4dae631855cb5a7067891dbe3a","azure-pipelines.yml":"1b4fab0afacc66732a385cb6e5b213c170fc9717219a03ccda9c5db78cd461dd","examples/test_forward.rs":"6cb060aba7e8c39eaf53ea95a72d4c7939ffb4bebc82c291135fdc35495078ce","examples/test_list_ports.rs":"41ba21ab1e56d76206abc8b291d27050cb1a788372f00f6761c78f03fb5981ff","examples/test_play.rs":"22630e46af9628d8193ad8e19ff095ad02542b7ab697be4e513da78210ad5c0c","examples/test_read_input.rs":"4901f18435c3f8021750ccd4687abe92194ab38f1e7721896a6a31f6650d524c","examples/test_reuse.rs":"fdb3b430aec42c7c648fbecf22e6c726ef8a20638936a1a70fb373dff94c0632","examples/test_sysex.rs":"ea06427a644c3639f1c49271be5d16c9d3890d3741eb6ebf2ff64d2f7fd36e96","src/backend/alsa/mod.rs":"3dfbd12d82988d5c749ec7fba87f7a4c659761cfdf50a2a2dc7afbae9a254bed","src/backend/coremidi/mod.rs":"f827cbc5db7086ea58c5927213a2c3e0246244d5939c2ba0ff787caae7089511","src/backend/jack/mod.rs":"8f2eace3e9046ec6de8c7fc37d3502d2b971a73fe2a96e5c2a423d51445f1505","src/backend/jack/wrappers.rs":"ce47a3d9cdef8e7d24ac0631c567c12403a7cbb2a1745af29596b6626aedeaa2","src/backend/mod.rs":"1a8106889ecd053af27b3a72515bfb286da1b08bb90909fa6d4e7b816b50c447","src/backend/webmidi/mod.rs":"4af5b288833ee99f047a638b368eca293f89356f1e82147c9a9c1633d950955d","src/backend/winmm/handler.rs":"45b36067fd280a38943f385d3d7f6885d7448153f53e9c8f66b58b484535ad1c","src/backend/winmm/mod.rs":"d3d089e7d505dd66f596d7175ba6df2be4260e38f011009e5cbd5ace1de188d1","src/backend/winrt/mod.rs":"ca7ac4ac310e7f6a6c28dd6374bfe97b38ed8656c7ca343494264cce45f93ae6","src/common.rs":"2cab2e987428522ca601544b516b64b858859730fbd1be0e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null} \ No newline at end of file +{"files":{"CHANGELOG.md":"10db6f8dbb1c5566e75f2eeda6b2ee8bb44fe4a76f57e0bfb98c62f7f8c04f89","Cargo.toml":"9b9fa6586ce94c4ed16b09454d5a55b3ab5eb43c8e6b033843e331d6bc221562","LICENSE":"6fe6f623b1fa80e90679aee2f917d8978a184988ebb995ebc254cc9633903cac","README.md":"4131b953217e77a4463fde307ba3262b4df11732c1ff209668df12dff3c73ffc","azure-pipelines-template.yml":"c787791a94e654226a299aaa875fcc48f6eedf4dae631855cb5a7067891dbe3a","azure-pipelines.yml":"1b4fab0afacc66732a385cb6e5b213c170fc9717219a03ccda9c5db78cd461dd","examples/test_forward.rs":"6cb060aba7e8c39eaf53ea95a72d4c7939ffb4bebc82c291135fdc35495078ce","examples/test_list_ports.rs":"41ba21ab1e56d76206abc8b291d27050cb1a788372f00f6761c78f03fb5981ff","examples/test_play.rs":"22630e46af9628d8193ad8e19ff095ad02542b7ab697be4e513da78210ad5c0c","examples/test_read_input.rs":"4901f18435c3f8021750ccd4687abe92194ab38f1e7721896a6a31f6650d524c","examples/test_reuse.rs":"fdb3b430aec42c7c648fbecf22e6c726ef8a20638936a1a70fb373dff94c0632","examples/test_sysex.rs":"ea06427a644c3639f1c49271be5d16c9d3890d3741eb6ebf2ff64d2f7fd36e96","src/backend/alsa/mod.rs":"3dfbd12d82988d5c749ec7fba87f7a4c659761cfdf50a2a2dc7afbae9a254bed","src/backend/coremidi/mod.rs":"f827cbc5db7086ea58c5927213a2c3e0246244d5939c2ba0ff787caae7089511","src/backend/jack/mod.rs":"8f2eace3e9046ec6de8c7fc37d3502d2b971a73fe2a96e5c2a423d51445f1505","src/backend/jack/wrappers.rs":"ce47a3d9cdef8e7d24ac0631c567c12403a7cbb2a1745af29596b6626aedeaa2","src/backend/mod.rs":"1a8106889ecd053af27b3a72515bfb286da1b08bb90909fa6d4e7b816b50c447","src/backend/webmidi/mod.rs":"4af5b288833ee99f047a638b368eca293f89356f1e82147c9a9c1633d950955d","src/backend/winmm/handler.rs":"45b36067fd280a38943f385d3d7f6885d7448153f53e9c8f66b58b484535ad1c","src/backend/winmm/mod.rs":"d3d089e7d505dd66f596d7175ba6df2be4260e38f011009e5cbd5ace1de188d1","src/backend/winrt/mod.rs":"ca7ac4ac310e7f6a6c28dd6374bfe97b38ed8656c7ca343494264cce45f93ae6","src/common.rs":"2cab2e987428522ca601544b516b64b858859730fbd1be0e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null} \ No newline at end of file diff --git a/third_party/rust/midir/Cargo.toml b/third_party/rust/midir/Cargo.toml index 3f220c8738..528df676d1 100644 --- a/third_party/rust/midir/Cargo.toml +++ b/third_party/rust/midir/Cargo.toml @@ -9,10 +9,18 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +bench = [] + [package] name = "midir" version = "0.7.0" authors = ["Patrick Reisert"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "A cross-platform, realtime MIDI processing library, inspired by RtMidi." readme = "README.md" keywords = [ @@ -28,6 +36,38 @@ categories = [ license = "MIT" repository = "https://github.com/Boddlnagg/midir" +[lib] +name = "midir" +path = "src/lib.rs" + +[[example]] +name = "test_forward" +path = "examples/test_forward.rs" + +[[example]] +name = "test_list_ports" +path = "examples/test_list_ports.rs" + +[[example]] +name = "test_play" +path = "examples/test_play.rs" + +[[example]] +name = "test_read_input" +path = "examples/test_read_input.rs" + +[[example]] +name = "test_reuse" +path = "examples/test_reuse.rs" + +[[example]] +name = "test_sysex" +path = "examples/test_sysex.rs" + +[[test]] +name = "virtual" +path = "tests/virtual.rs" + [dependencies] memalloc = "0.1.0" @@ -56,11 +96,11 @@ jack = [ "bitflags", ] -[target."cfg(target_arch = \"wasm32\")".dependencies] +[target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = "0.3" wasm-bindgen = "0.2" -[target."cfg(target_arch = \"wasm32\")".dependencies.web-sys] +[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] version = "0.3" features = [ "Event", @@ -77,14 +117,14 @@ features = [ "MidiPortType", ] -[target."cfg(target_arch = \"wasm32\")".dev-dependencies] +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.2" -[target."cfg(target_os = \"linux\")".dependencies] +[target.'cfg(target_os = "linux")'.dependencies] alsa = "0.8" libc = "0.2.21" -[target."cfg(target_os = \"macos\")".dependencies] +[target.'cfg(target_os = "macos")'.dependencies] coremidi = "0.6.0" [target."cfg(windows)".dependencies.winapi] diff --git a/third_party/rust/mp4parse/.cargo-checksum.json b/third_party/rust/mp4parse/.cargo-checksum.json index 1a1081f89a..40f39472ff 100644 --- a/third_party/rust/mp4parse/.cargo-checksum.json +++ b/third_party/rust/mp4parse/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"c67d586b5c36ce9ad893bf3a79bec9904b08e47de71376fe820785321ba4f8a5","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"86cb40854b93f988e3a63ce6fe39d2ce95367f8ca301a5ba50676ff98a0ad791","benches/avif_benchmark.rs":"17105ee0ec4ff0e3eec90699252939101edd5323514ceb404f367e67ef16cf95","link-u-avif-sample-images/.github/workflows/encode-and-decode-daily.yml":"84b787f721024a100ce09ac5714a1d78a4811893861e89495313f435b9d02359","link-u-avif-sample-images/.gitignore":"ac16d40779ab2d608843a3cb1b0418a1ffdc0e71a06c4d140386fadf007a54a7","link-u-avif-sample-images/LICENSE.txt":"da89f9867822be4b8adb1e601d9e9226c195016c6508015eb7593e68ead0c98a","link-u-avif-sample-images/Makefile":"b5697e8685d2a9ce0f4b4c976a5f707022ed113782d16dc59ae280d3a8ce77b1","link-u-avif-sample-images/README.md":"d249fb7bef4f21359cfc4f2977e1b2f2c6e6dd6e57cb1cdc1da1f0edd8aa55d0","link-u-avif-sample-images/fox.jpg":"927997a90ae88ead007283bf9c1392159d0acd2e9890522146211fda2112a2d9","link-u-avif-sample-images/fox.odd-height.png":"6136247772bd1c0edd50426bca4f3485473ac25a784e5ec8777f7491598e96db","link-u-avif-sample-images/fox.odd-width.odd-height.png":"6f91dc21c137f318d0443ce28bbf3f74d5502180c254327b46e41040a33f1363","link-u-avif-sample-images/fox.odd-width.png":"a8b2328c8700c16280c5ab40a34147edac598d4d48ca101bef649e468ae1492e","link-u-avif-sample-images/fox.png":"c45bfb5780843c70a37426340020e3e7ff41d7cf1df9fec614a5cf429d078573","link-u-avif-sample-images/hato.16bpc.png":"53b550c587cd1d19a1997184e47f4a3ff2a05cedf7cb4e42a9466a6d6cb60d8d","link-u-avif-sample-images/hato.jpg":"6d4804e5e4adf36a6b138544c81b743ed7abdd9a495a43e883ec77689ca28943","link-u-avif-sample-images/hato.png":"313880f4cc51160fec522d78f1fb7f06df70fe1929a731fc86c68ecefd312277","link-u-avif-sample-images/images.html":"9e18453dfe5b205600f158282c6896265281e3b04b2fbc332804fab1dbdb3faf","link-u-avif-sample-images/kimono.crop.png":"0d5605bae0ec9d39aad9dc8e1a371d0327c6a224643983e3ee1f4d44cb00f19d","link-u-avif-sample-images/kimono.jpg":"a6ad58e3cea437ee0c841115ba67ae7354de7af734de50de9d0853dd4e571577","link-u-avif-sample-images/kimono.mirror-horizontal.png":"9af9e839fe6bf6342831970c20291f619570d2fc687951ae00cd81ea766f53fe","link-u-avif-sample-images/kimono.mirror-vertical.png":"4ed003c5868fd2e78c7b2dcbd54a67a0e7593dabb3ac82b1c9e5e2dbdf09b8ec","link-u-avif-sample-images/kimono.mirror-vertical.rotate270.png":"74b9b7ffa8955761f747a0e6e81d5b7ecb5e325383546110e1b6aa9986728035","link-u-avif-sample-images/kimono.png":"84fd6cfb97a27739608e21779f874b4ae7e80342b2588e8b0b092dee2d57c881","link-u-avif-sample-images/kimono.rotate270.png":"1918a47c02b378945a705301abd4250ddc65bb95afce9424572ffd0fdd1f45ef","link-u-avif-sample-images/kimono.rotate90.png":"1a73c61692abe96d0a7a9accdb36a83d51bceac79bbb83a00571570f494cca49","link-u-avif-sample-images/plum-blossom-large.png":"af6ea005b726ca39f342e946aa53bed88e5a140413ce896d166bb35ab0aa3b4f","link-u-avif-sample-images/plum-blossom-small.png":"c859fd97b647e494461f65835b9c1c3476807aee77076599adf18a832b3617a4","link-u-avif-sample-images/plum-blossom.svg":"be1f03dd05f63292c85a96b1c48fb06727283610cc69b1e116d547bab27b171d","link-u-avif-sample-images/red-at-12-oclock-with-color-profile.jpg":"d56f809ea5eda74578af57e2f80b41856a1fe2ff436c741aa58757387af998bd","link-u-avif-sample-images/red-at-12-oclock-with-color-profile.png":"4eab95e358eb48e052c7b8c94d30a8c6cb1c9c3c2dfd9845240281dd5dd7b800","link-u-avif-sample-images/scripts/compare.sh":"0562689bcd40e9fc1322bf037d6f999aa4406a2229f19e74b96cc450e370e429","link-u-avif-sample-images/star-10bpc-with-alpha.avifs":"5643ac1f235ae6599186dd66c66507db6fa46a17b2b18e82ea9344870eb98a9b","link-u-avif-sample-images/star-10bpc.avifs":"c61d899a59dbd8c7b2f7bcfca9069a0e13ff1606899af227938a28502e6cbf88","link-u-avif-sample-images/star-12bpc-with-alpha.avifs":"88a350c3550ce36c1777fe7eb1e906c6829d3ed8b241aa1e0e46f1a4e2567c4b","link-u-avif-sample-images/star-12bpc.avifs":"c1a59db6f180208a3177d77c7f9ab08290e903c7bdaf929331b807a510f8c619","link-u-avif-sample-images/star-8bpc-with-alpha.avifs":"13a12908cb162a855cccc9221a5f9f736e8ea07902ffbdcf007f8fde5ed255f2","link-u-avif-sample-images/star-8bpc.avifs":"ae35b161de67a5afeb195ee401f369c34990f0ff8662f70ab4065bc6931f0a66","link-u-avif-sample-images/star.gif":"389cdd02efbdce4f0205cae6e91c1f64e34fa0ca1fe02351da1b37e16cbb642a","link-u-avif-sample-images/star.input.txt":"970163b942843618616f42233abe91d40fb68f6f5451860db259551711867b55","link-u-avif-sample-images/star.png":"18569167cf7ebd265ab6973d071d259aacfbb46c0408b7d4874c8cc9df9bb1ad","link-u-avif-sample-images/star.svg":"13089d0986b31b87919029fa69f2b68981af4023306bf0f79922f6772396008a","link-u-avif-sample-images/star180.png":"21bc11be2b51334fe4589634507612e7edce96d36e6a99219d029e440164e8b8","link-u-avif-sample-images/star270.png":"5c93f538dcdc70840b9925b4089083acc9c25e95265b3f3dea18d695451b441e","link-u-avif-sample-images/star90.png":"2defc5d21e70447653fec5dc14a697d9dd555d7a0c14e79cb2d9f80796a51a6d","src/boxes.rs":"f6588ae051b76bef8a4c33e4bf221a5fd12bc610e9d2958637f2da75ee8607d3","src/lib.rs":"09bd3ed50fab985b1961118af323275411c150fe6d4d3c2f28a1fe3e4800621d","src/macros.rs":"498bef25c8ea468d8ae0cd89593807d9e9253385cb9456d04f8cb00b721a54cb","src/tests.rs":"468cfb1bbe8908be39280318ea03c32116924cad5811f5067a661a5bd17f77ef","src/unstable.rs":"4fe948d8f2b12844e5bb6bbdf1cea26061eca464e75e8537ed317db80a44698b","tests/amr_nb_1f.3gp":"d1423e3414ad06b69f8b58d5c916ec353ba2d0402d99dec9f1c88acc33b6a127","tests/amr_wb_1f.3gp":"be635b24097e8757b0c04d70ab28e00417ca113e86108b6c269b79b64b89bcd5","tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp":"03e5b1264d0a188d77b9e676ba3ce23a801b17aaa11c0343dfd851d6ea4e3a40","tests/clusterfuzz-testcase-minimized-mp4-6093954524250112":"af7044a470732d4e7e34ac7ab5ff038c58b66f09702cbcd774931d7766bbfd35","tests/corrupt/invalid-avif-colr-multiple.zip":"9abddcbc47fde6da20263a29b770c6a9e76c8ab8dc785ef8512f35d9cb3206ed","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"81be1a2c8019dff3848259e237a7e5040fd59bc1027c6d85295fccacc6ce1fe7"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"1eb6771e0f3f419bc9b78f043090b81ad171d8a4f818a83c0e054ed0ec2016fb","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"86cb40854b93f988e3a63ce6fe39d2ce95367f8ca301a5ba50676ff98a0ad791","benches/avif_benchmark.rs":"17105ee0ec4ff0e3eec90699252939101edd5323514ceb404f367e67ef16cf95","link-u-avif-sample-images/.github/workflows/encode-and-decode-daily.yml":"84b787f721024a100ce09ac5714a1d78a4811893861e89495313f435b9d02359","link-u-avif-sample-images/.gitignore":"ac16d40779ab2d608843a3cb1b0418a1ffdc0e71a06c4d140386fadf007a54a7","link-u-avif-sample-images/LICENSE.txt":"da89f9867822be4b8adb1e601d9e9226c195016c6508015eb7593e68ead0c98a","link-u-avif-sample-images/Makefile":"b5697e8685d2a9ce0f4b4c976a5f707022ed113782d16dc59ae280d3a8ce77b1","link-u-avif-sample-images/README.md":"d249fb7bef4f21359cfc4f2977e1b2f2c6e6dd6e57cb1cdc1da1f0edd8aa55d0","link-u-avif-sample-images/fox.jpg":"927997a90ae88ead007283bf9c1392159d0acd2e9890522146211fda2112a2d9","link-u-avif-sample-images/fox.odd-height.png":"6136247772bd1c0edd50426bca4f3485473ac25a784e5ec8777f7491598e96db","link-u-avif-sample-images/fox.odd-width.odd-height.png":"6f91dc21c137f318d0443ce28bbf3f74d5502180c254327b46e41040a33f1363","link-u-avif-sample-images/fox.odd-width.png":"a8b2328c8700c16280c5ab40a34147edac598d4d48ca101bef649e468ae1492e","link-u-avif-sample-images/fox.png":"c45bfb5780843c70a37426340020e3e7ff41d7cf1df9fec614a5cf429d078573","link-u-avif-sample-images/hato.16bpc.png":"53b550c587cd1d19a1997184e47f4a3ff2a05cedf7cb4e42a9466a6d6cb60d8d","link-u-avif-sample-images/hato.jpg":"6d4804e5e4adf36a6b138544c81b743ed7abdd9a495a43e883ec77689ca28943","link-u-avif-sample-images/hato.png":"313880f4cc51160fec522d78f1fb7f06df70fe1929a731fc86c68ecefd312277","link-u-avif-sample-images/images.html":"9e18453dfe5b205600f158282c6896265281e3b04b2fbc332804fab1dbdb3faf","link-u-avif-sample-images/kimono.crop.png":"0d5605bae0ec9d39aad9dc8e1a371d0327c6a224643983e3ee1f4d44cb00f19d","link-u-avif-sample-images/kimono.jpg":"a6ad58e3cea437ee0c841115ba67ae7354de7af734de50de9d0853dd4e571577","link-u-avif-sample-images/kimono.mirror-horizontal.png":"9af9e839fe6bf6342831970c20291f619570d2fc687951ae00cd81ea766f53fe","link-u-avif-sample-images/kimono.mirror-vertical.png":"4ed003c5868fd2e78c7b2dcbd54a67a0e7593dabb3ac82b1c9e5e2dbdf09b8ec","link-u-avif-sample-images/kimono.mirror-vertical.rotate270.png":"74b9b7ffa8955761f747a0e6e81d5b7ecb5e325383546110e1b6aa9986728035","link-u-avif-sample-images/kimono.png":"84fd6cfb97a27739608e21779f874b4ae7e80342b2588e8b0b092dee2d57c881","link-u-avif-sample-images/kimono.rotate270.png":"1918a47c02b378945a705301abd4250ddc65bb95afce9424572ffd0fdd1f45ef","link-u-avif-sample-images/kimono.rotate90.png":"1a73c61692abe96d0a7a9accdb36a83d51bceac79bbb83a00571570f494cca49","link-u-avif-sample-images/plum-blossom-large.png":"af6ea005b726ca39f342e946aa53bed88e5a140413ce896d166bb35ab0aa3b4f","link-u-avif-sample-images/plum-blossom-small.png":"c859fd97b647e494461f65835b9c1c3476807aee77076599adf18a832b3617a4","link-u-avif-sample-images/plum-blossom.svg":"be1f03dd05f63292c85a96b1c48fb06727283610cc69b1e116d547bab27b171d","link-u-avif-sample-images/red-at-12-oclock-with-color-profile.jpg":"d56f809ea5eda74578af57e2f80b41856a1fe2ff436c741aa58757387af998bd","link-u-avif-sample-images/red-at-12-oclock-with-color-profile.png":"4eab95e358eb48e052c7b8c94d30a8c6cb1c9c3c2dfd9845240281dd5dd7b800","link-u-avif-sample-images/scripts/compare.sh":"0562689bcd40e9fc1322bf037d6f999aa4406a2229f19e74b96cc450e370e429","link-u-avif-sample-images/star-10bpc-with-alpha.avifs":"5643ac1f235ae6599186dd66c66507db6fa46a17b2b18e82ea9344870eb98a9b","link-u-avif-sample-images/star-10bpc.avifs":"c61d899a59dbd8c7b2f7bcfca9069a0e13ff1606899af227938a28502e6cbf88","link-u-avif-sample-images/star-12bpc-with-alpha.avifs":"88a350c3550ce36c1777fe7eb1e906c6829d3ed8b241aa1e0e46f1a4e2567c4b","link-u-avif-sample-images/star-12bpc.avifs":"c1a59db6f180208a3177d77c7f9ab08290e903c7bdaf929331b807a510f8c619","link-u-avif-sample-images/star-8bpc-with-alpha.avifs":"13a12908cb162a855cccc9221a5f9f736e8ea07902ffbdcf007f8fde5ed255f2","link-u-avif-sample-images/star-8bpc.avifs":"ae35b161de67a5afeb195ee401f369c34990f0ff8662f70ab4065bc6931f0a66","link-u-avif-sample-images/star.gif":"389cdd02efbdce4f0205cae6e91c1f64e34fa0ca1fe02351da1b37e16cbb642a","link-u-avif-sample-images/star.input.txt":"970163b942843618616f42233abe91d40fb68f6f5451860db259551711867b55","link-u-avif-sample-images/star.png":"18569167cf7ebd265ab6973d071d259aacfbb46c0408b7d4874c8cc9df9bb1ad","link-u-avif-sample-images/star.svg":"13089d0986b31b87919029fa69f2b68981af4023306bf0f79922f6772396008a","link-u-avif-sample-images/star180.png":"21bc11be2b51334fe4589634507612e7edce96d36e6a99219d029e440164e8b8","link-u-avif-sample-images/star270.png":"5c93f538dcdc70840b9925b4089083acc9c25e95265b3f3dea18d695451b441e","link-u-avif-sample-images/star90.png":"2defc5d21e70447653fec5dc14a697d9dd555d7a0c14e79cb2d9f80796a51a6d","src/boxes.rs":"f6588ae051b76bef8a4c33e4bf221a5fd12bc610e9d2958637f2da75ee8607d3","src/lib.rs":"09bd3ed50fab985b1961118af323275411c150fe6d4d3c2f28a1fe3e4800621d","src/macros.rs":"498bef25c8ea468d8ae0cd89593807d9e9253385cb9456d04f8cb00b721a54cb","src/tests.rs":"468cfb1bbe8908be39280318ea03c32116924cad5811f5067a661a5bd17f77ef","src/unstable.rs":"4fe948d8f2b12844e5bb6bbdf1cea26061eca464e75e8537ed317db80a44698b","tests/amr_nb_1f.3gp":"d1423e3414ad06b69f8b58d5c916ec353ba2d0402d99dec9f1c88acc33b6a127","tests/amr_wb_1f.3gp":"be635b24097e8757b0c04d70ab28e00417ca113e86108b6c269b79b64b89bcd5","tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp":"03e5b1264d0a188d77b9e676ba3ce23a801b17aaa11c0343dfd851d6ea4e3a40","tests/clusterfuzz-testcase-minimized-mp4-6093954524250112":"af7044a470732d4e7e34ac7ab5ff038c58b66f09702cbcd774931d7766bbfd35","tests/corrupt/invalid-avif-colr-multiple.zip":"9abddcbc47fde6da20263a29b770c6a9e76c8ab8dc785ef8512f35d9cb3206ed","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"81be1a2c8019dff3848259e237a7e5040fd59bc1027c6d85295fccacc6ce1fe7"},"package":null} \ No newline at end of file diff --git a/third_party/rust/mp4parse/Cargo.toml b/third_party/rust/mp4parse/Cargo.toml index de277ab39f..0a50c89d89 100644 --- a/third_party/rust/mp4parse/Cargo.toml +++ b/third_party/rust/mp4parse/Cargo.toml @@ -9,6 +9,9 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] + [package] edition = "2018" name = "mp4parse" @@ -20,11 +23,16 @@ authors = [ "Jon Bauman ", "Bryce Seager van Dyk ", ] +build = false exclude = [ "*.mp4", "*.avif", "av1-avif/*", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Parser for ISO base media file format (mp4)" documentation = "https://docs.rs/mp4parse/" readme = "README.md" @@ -33,10 +41,21 @@ license = "MPL-2.0" repository = "https://github.com/mozilla/mp4parse-rust" [lib] +name = "mp4parse" +path = "src/lib.rs" bench = false +[[test]] +name = "overflow" +path = "tests/overflow.rs" + +[[test]] +name = "public" +path = "tests/public.rs" + [[bench]] name = "avif_benchmark" +path = "benches/avif_benchmark.rs" harness = false [dependencies] diff --git a/third_party/rust/mp4parse_capi/.cargo-checksum.json b/third_party/rust/mp4parse_capi/.cargo-checksum.json index 3ca5d1ba71..5d9540f27e 100644 --- a/third_party/rust/mp4parse_capi/.cargo-checksum.json +++ b/third_party/rust/mp4parse_capi/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"6f6ee5f90321878f218e5921480437f439c1e66efd544c8e6aacf424ea00c51b","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"2a3cdebc5ed6f0f6b640e6722cd13fc7f4534774eb057b369a791c2eddb8132d","src/lib.rs":"97c7f8d6a47b395e3e31ac98e66ac08cf5b35a5bd94fcf3fb373b10749916cd8","tests/test_avis.rs":"d480b104ab2dfde7a25afd6705532caf7988aea21fc955dcf2f86fc8a5e85151","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"53ed6a5e8db463ad8dc0300116f470c2aadd39896e6ba4cabcd01c6b9a7b5c59","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"cd0668a3fe357b39cec26e89201b1029467504ec58cb9120a6c299859e236965","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"2a3cdebc5ed6f0f6b640e6722cd13fc7f4534774eb057b369a791c2eddb8132d","src/lib.rs":"97c7f8d6a47b395e3e31ac98e66ac08cf5b35a5bd94fcf3fb373b10749916cd8","tests/test_avis.rs":"d480b104ab2dfde7a25afd6705532caf7988aea21fc955dcf2f86fc8a5e85151","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"d3f805cc2107481ee9a989818af3addbb3ea1faf7422ea7f4416591d03031318","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"53ed6a5e8db463ad8dc0300116f470c2aadd39896e6ba4cabcd01c6b9a7b5c59","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null} \ No newline at end of file diff --git a/third_party/rust/mp4parse_capi/Cargo.toml b/third_party/rust/mp4parse_capi/Cargo.toml index 2f4d573e82..6b07ae3eac 100644 --- a/third_party/rust/mp4parse_capi/Cargo.toml +++ b/third_party/rust/mp4parse_capi/Cargo.toml @@ -9,6 +9,9 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +bench = [] + [package] edition = "2018" name = "mp4parse_capi" @@ -20,16 +23,57 @@ authors = [ "Jon Bauman ", "Bryce Seager van Dyk ", ] +build = false exclude = [ "*.mp4", "*.avif", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Parser for ISO base media file format (mp4)" documentation = "https://docs.rs/mp4parse_capi/" readme = "README.md" license = "MPL-2.0" repository = "https://github.com/mozilla/mp4parse-rust" +[lib] +name = "mp4parse_capi" +path = "src/lib.rs" + +[[example]] +name = "dump" +path = "examples/dump.rs" + +[[test]] +name = "test_avis" +path = "tests/test_avis.rs" + +[[test]] +name = "test_chunk_out_of_range" +path = "tests/test_chunk_out_of_range.rs" + +[[test]] +name = "test_encryption" +path = "tests/test_encryption.rs" + +[[test]] +name = "test_fragment" +path = "tests/test_fragment.rs" + +[[test]] +name = "test_rotation" +path = "tests/test_rotation.rs" + +[[test]] +name = "test_sample_table" +path = "tests/test_sample_table.rs" + +[[test]] +name = "test_workaround_stsc" +path = "tests/test_workaround_stsc.rs" + [dependencies] byteorder = "1.2.1" log = "0.4" diff --git a/third_party/rust/naga/.cargo-checksum.json b/third_party/rust/naga/.cargo-checksum.json index c94f20be05..189bed130f 100644 --- a/third_party/rust/naga/.cargo-checksum.json +++ b/third_party/rust/naga/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo/config.toml":"d7389d2a0c08ec72b79e83a3c76980903e3f9123625c32e69c798721193e2e74","CHANGELOG.md":"fcace5fd54cbe1d42881e5d0148725a456c607d88534ee35bf07279a86d49c04","Cargo.toml":"8348e73a187c366b47d03875234f26c3c86f95ad35b3fef85275aec70252057e","README.md":"00a6070ebadb15a9488f117b286f50e4838a7dd0a28d41c9fcff4781c6b49171","build.rs":"824e90067aa04ad8726a49476b1af51f5c5c16f9a0b372f00398b3748d723662","src/arena/handle.rs":"1bf2edcca03d7cb466e1f8bd4bf1c966b805505ea2ee3641c39aa04811413478","src/arena/handle_set.rs":"f84ca7edafc907e282abea094c0c9b1da1cf4500e0c6389bb3ce2ef655f4c4ea","src/arena/handlevec.rs":"dfc9249478eb6980c13587c740d91234214bc7e0eef90e6f40b3d99decf70a58","src/arena/mod.rs":"14db142163133eb9ca582bc3665450f49cc4b1cfbda043b8b1518590cdda73be","src/arena/range.rs":"88683c36b137499ab537cf906505c2bd0871e0b9177e3a4e55da9db4e86df6a2","src/arena/unique_arena.rs":"22761770dbcbb6ac497ebdcf07173b3f07fc3c74bc0a70990d5fad882f4f471f","src/back/continue_forward.rs":"f95b810164db51fde368362624ce2569826b47dc3460df316b879abba48e5388","src/back/dot/mod.rs":"b9f57441a9491e4a53b6d9dcb253484f9e935419d179513c2d24db08be591fae","src/back/glsl/features.rs":"747285643e28d0ea7d8293a5ee802b4e88482f771c36845cefe7e8c16ef54637","src/back/glsl/keywords.rs":"b8883e5ee8a3d400fa44fef2baffe2853e72ff91e832499c128454d325ceccd9","src/back/glsl/mod.rs":"89e5aaeebaf7c897e98a3d929baecc8b65b447c2ce30497fbe505c650137c98d","src/back/hlsl/conv.rs":"764f62d356b4d5606e39f258156487db4b33907c82e0bd25d0e374cc999fae88","src/back/hlsl/help.rs":"de631bd11ee65fbbeeae80733103789abfa6ff54b7b39b11e7c22cd02b486a1c","src/back/hlsl/keywords.rs":"a7164690a4da866e6bfb18ced20e32cc8c42dd7387e0e84addf0c2674f529cf5","src/back/hlsl/mod.rs":"8a88e0925ad62296349851f3f2f60959a63ae466422d1932bde53dd94eab586a","src/back/hlsl/storage.rs":"2c2a0071cafe487a398e396dddc85bdb319b1a5d74c097d529078e247a904359","src/back/hlsl/writer.rs":"323d32ceb58439a3bb29cbd420d77f03101b134dcfb22246b6050636704bc317","src/back/mod.rs":"9de236c7a5219b2ff371e44a7d97462cce3d1ccef4c7063632f1a6a7718d683d","src/back/msl/keywords.rs":"e6a4ef77363f995de1f8079c0b8591497cbf9520c5d3b2d41c7e1f483e8abd24","src/back/msl/mod.rs":"a03a380bbc8e9183e9f54c34e5326bedc6a2e94ecbf7cfc53190d2accafa6c7e","src/back/msl/sampler.rs":"9b01d68669e12ff7123243284b85e1a9d2c4d49140bd74ca32dedc007cbf15af","src/back/msl/writer.rs":"ad13b7f42046bdeef091ea793e8dc1d992153140abddb5f78a9629fca362ba97","src/back/pipeline_constants.rs":"50b3a87b6f4eb95c8b20dcc77cecf594cb0cf8d6c4fd7b315a6dd97271acda23","src/back/spv/block.rs":"056e2a11d27c41a1f042f3687b237f01d4a84df4756d62e5b7cc3cf4840f0db5","src/back/spv/helpers.rs":"bd666bf519a5d5561c2fab6ff78229739853ae6877d132911e71b57cfd656e42","src/back/spv/image.rs":"32b8f1ccdd54d80519ccf585451dcc6721d2a6a109d295a704e6c61857832556","src/back/spv/index.rs":"14f704d2d9409bbc9345d601725355048aa74471aaeb6aa781fc45a99ceaec38","src/back/spv/instructions.rs":"27ae0fb206b28cb8240b342a28396cb0a30e3a5fb50fa02413e0cfa6d507a5a4","src/back/spv/layout.rs":"e263de53cd2f9a03ad94b82b434ce636609bc1ed435a2d1132951663bfaa8ebd","src/back/spv/mod.rs":"91fa840f044ae40cc955db2278d5abcb03f53185452ba02ac0a78aedd37c24f3","src/back/spv/ray.rs":"a34bf6b26d873f7270caa45841d9ef291aca8d9732ecd086b14d8856038e1e41","src/back/spv/recyclable.rs":"8061e39ea5357c8d55081a81fb836e762fd9793c1c6b04ae5d714af32677e616","src/back/spv/selection.rs":"81e404abfa0a977f7c1f76ccb37a78d13ccadbda229048dad53cc67687cc39db","src/back/spv/subgroup.rs":"cb68fb9581064ec9ef79e56a0c94c802b2f04cc5e2173a953ae9a7b2776042d5","src/back/spv/writer.rs":"e7fdc6a0424a83bb06e2c01919c72bb16a62b46039c92258be251eceaa851601","src/back/wgsl/mod.rs":"2dd12bbea9ace835850192bb68c5760953da6bac6a636073d1eca19381c0c0b6","src/back/wgsl/writer.rs":"b21ec11688e924708f4101417324f4f1547d63bff72f2de0e8849d619684917f","src/block.rs":"e447f7e041fd67052b23d1139cf0574eea93220a818af71691d960bdf026d45f","src/compact/expressions.rs":"a04f5dbc936693280fddc328df623af0b8d1fc0d11bd01987df9104e9c27bea1","src/compact/functions.rs":"27c084ca6b475999a3367f8ea429dbf7326a54c83ef86898b7ba67366f9bb828","src/compact/handle_set_map.rs":"748de9563f0ff897c113ba665f3e59ab3a023050e2206eb7d566a31f61fc32e5","src/compact/mod.rs":"7ec6bea36d11438c391c37d9a193b323d7fb365de6b9dfd45e78a3240dbab7ba","src/compact/statements.rs":"360e2bb6c2b7fdf4f9de368048ae574b2efd171adf34be44f84fbe21a15f5def","src/compact/types.rs":"9e73ac7dfdaf4b10eda1c938b881857392abc1315adcc035fc3980d63236cf37","src/error.rs":"70f7adbb59ea38ee7ebc44e8ad020d6db4f2dd4976913fb194e779d115241861","src/front/atomic_upgrade.rs":"af1386a3ef42e853042d2d08bf7d0e08fb8a4578ddbf44b5f57326643b9ba613","src/front/glsl/ast.rs":"663e815ea3e511f0445ef910340c380ff1bcf63805329ab7ca8cf35de7f902ed","src/front/glsl/builtins.rs":"8665ccc33938ae2d43257f25dd3cb75b604d30ccaf98888889b130ca7651695f","src/front/glsl/context.rs":"00c489ca8cb0e200595122ab1c857e2354625a680ff44ac3d7b33eadc4b991cd","src/front/glsl/error.rs":"2ef5061decd42dfc3054fd0f1a86dc7168e2064572571147117d798e39675722","src/front/glsl/functions.rs":"52802412788f95e1a55b92a72980e04792c876fbedff6e6d71f8fe0d23cbae80","src/front/glsl/lex.rs":"08736ae8beb955da5b0e6e3e0f45995a824995f7096d516a2910417e9c7afa32","src/front/glsl/mod.rs":"bf97bf1710d5d1f8facb77913cb82868697920914a96ed309adf0f19154a2ab4","src/front/glsl/offset.rs":"9358602ca4f9ef21d5066d674dae757bf88fdf5c289c4360534354d13bd41dc0","src/front/glsl/parser.rs":"a752f2abac17e6d35c0eb406f2f1c24d2b622a55b1bececbdd13614edb686622","src/front/glsl/parser/declarations.rs":"796514c1d571b324817bf1236d4c1227a91a512c0660ce5bb1264cd900027158","src/front/glsl/parser/expressions.rs":"7fd1ccb9261eaf1f9966798c2fed62c54c2c1d9d140d3e9d41d81775acbe35de","src/front/glsl/parser/functions.rs":"dd5980bd731bcd8044bbfa16f760cdc77c02422ec116d7ebbbe64fcbe1fb7a04","src/front/glsl/parser/types.rs":"08d708d0bae448bbfc4c79e6128f0b0bc489ae079018e69bf9589b77803e0372","src/front/glsl/parser_tests.rs":"c44ed3252096c83a0ce1ea9be8d2b867784cdc1c11aa4501aee1a85d86c62511","src/front/glsl/token.rs":"c25c489b152ee2d445ace3c2046473abe64d558b8d27fa08709110e58718b6ac","src/front/glsl/types.rs":"91c3a4e4d11b397ea647ff287e17a48baedf2f2c310e81b04618675daeb83f69","src/front/glsl/variables.rs":"6cb3db649a99452bc91f2bbebe425c0447920f7e9a87c38fa84d54c84f48861e","src/front/interpolator.rs":"9b6ca498d5fbd9bc1515510a04e303a00b324121d7285da3c955cfe18eb4224c","src/front/mod.rs":"ba984fc9b933a844fa8dadf05dea70f308911054ad3f10448d652706e158b4bd","src/front/spv/convert.rs":"b4b19b7cf2360d17405ea4ec97d9bf02376150047dfef008c2a358690625802c","src/front/spv/error.rs":"f41593a3ba8d3bb4371fd26e813affc8d8ce1d6581c8af410cf5e2084a308049","src/front/spv/function.rs":"e584dbeaa5f7e1ff107f3e7e5211b0bfb8f7b9878a74dbe29dc7941cb33b2e0f","src/front/spv/image.rs":"a5ac477c01894a9c9ce5ec9d6751f991622d610f5581a759fc2e72034677d9e4","src/front/spv/mod.rs":"1f32a2a8174546075e57bc52bd0bba6e3fbae9a290e75a05332f244554bcf993","src/front/spv/null.rs":"a8ff44e97ffe42a4773d89b88fdb3a8ef8fba58bf6645c73b7a66470234ccf10","src/front/type_gen.rs":"49d8aae89143a0cba182c5271a2aa60972251c1603144bd21567565ff64b2274","src/front/wgsl/error.rs":"eb0d142e9d25ded215131b8f8ee79da72bf9881c1b5af711fccfc42381641d08","src/front/wgsl/index.rs":"c5928ac405ffbd74de60b96360f7e07a3470b39f8f76c6e0b06544b4b5f61f57","src/front/wgsl/lower/construction.rs":"c31aabb26bf7b8b62d7dee2e6b6fd26a0314247dd5665efe2190921ef97e3213","src/front/wgsl/lower/conversion.rs":"492293f4f3fc7786a3a480ca0f43a10ae5ac8557cf1903cdd616ca624093b951","src/front/wgsl/lower/mod.rs":"8c16d6bb6db75fed70c6ce1d397c696678e04e8b21aa6453c8700ab229294b0a","src/front/wgsl/mod.rs":"cebe3f61843cca32d6764b93b07cb369ae22d1240d81eabe25f5c42dc603fca1","src/front/wgsl/parse/ast.rs":"766ff3412f79652a71964a521755fb758f2192f157c62b553d4c53f9f0ba07d7","src/front/wgsl/parse/conv.rs":"860a02ccceb10468a89e28562547092c5dacce24411621e16e7e08ec45e27e09","src/front/wgsl/parse/lexer.rs":"17db87d0017f8f9a80fa151b8545f04e1b40c4e5feef6197f4a117efa03488bf","src/front/wgsl/parse/mod.rs":"61419806f2366812f8c14fed0d87a759eeb899d7e66bfb0b188156053bfbde27","src/front/wgsl/parse/number.rs":"dafd3d8651cfa1389cb359d76d39bd689e54f8d5025aa23e06c6edd871369efd","src/front/wgsl/tests.rs":"7a0a083a5b66af8e7d4b1a02401b27f077eb72d07181b610693f35b11f107c6c","src/front/wgsl/to_wgsl.rs":"20f9e503b26826020f024b9c99ca06e38438ad44f8dbb8c7cbf8ee7828780e61","src/keywords/mod.rs":"47a6fde012bf7d1e70f0fac7762f6a8e7dca6b9bbb99e2cada773c61527cfbfe","src/keywords/wgsl.rs":"c648ac44241ad55c8c8bad3d8f1bab973d11ddb9c380dcca369b735ed3975309","src/lib.rs":"37defb3e1b4cbbb29f18fc7e21b2169e423dec7f8025752d8079316f434d2d6b","src/non_max_u32.rs":"3f4aafc8e2775982187507d49e7aa58befffdaba71c9287be42afdfde28bcb66","src/proc/constant_evaluator.rs":"1cff379df1e1383e97bdaa54e79121bab9b3cc0cfa5b13a13abb5b3d6f3978b0","src/proc/emitter.rs":"39ac886c651e2ad33c06a676a7e4826a0e93de0af660c01e8e4b1f7406742f88","src/proc/index.rs":"7c10d3d89ad8c50d063f39ed5b24492e41b6f2d78a7b92138b1ee214a1ea06a2","src/proc/layouter.rs":"e95fd9defa08e0c610d22d7cd795a6af787610d1ff0d4ed27798b4ffd2098cf1","src/proc/mod.rs":"b0b856056eac4f57f4495ec6ec39e79e50386177b2ee0b042ee4d0dd9f9540da","src/proc/namer.rs":"7328fac41e40890c64c7ee2fa985a4395424f18b08d30f30ca2583fdabd2fd35","src/proc/terminator.rs":"fef2160473fcddd670c6b5806a8ea0ecbdcc0fdf6ed793dce131ecd08cce3944","src/proc/typifier.rs":"0ee6be729fe141399a279a6bc8a6f1f5cb82ee397f4352902ad3b662e2e9a618","src/span.rs":"fd3b338256f9301fc5289c37af9ccec704d2e5db92923b0dec45da371e84ce6a","src/valid/analyzer.rs":"64f0c49988a14e4bf4c9718be69e43d152994756095bb438a3467641c4f4cc1c","src/valid/compose.rs":"83e4c09c39f853cf085b83b87e48b3db571da619132960d3ec954ebdfb0a74f2","src/valid/expression.rs":"50f2fa21d80fd121bc4372dce616e1eeb7507cef29d93273c8c3f86df919b510","src/valid/function.rs":"a624138dc5c4a8d49f68e48fb66e64d14c2da1cd6e8dadfc74bab7a9f63a2f9f","src/valid/handles.rs":"fd9e52370d76b9ff57357c651a951112246ca6c4794b59c021601e9c6b11a0bd","src/valid/interface.rs":"a6d60fcca8c2eb840ddd2cd9148df8b9613d6624d16ab1e3bc1b83a81aef3e03","src/valid/mod.rs":"4130656e5d14c54de38d4f7e7e8cb15ffe60c19ddf93aa976b2fc3e990ddbf45","src/valid/type.rs":"52528d261599f5eb8c61197200b1ffba5dcea6357838edc09f2c51f406af527c"},"package":null} \ No newline at end of file +{"files":{".cargo/config.toml":"d7389d2a0c08ec72b79e83a3c76980903e3f9123625c32e69c798721193e2e74","CHANGELOG.md":"fcace5fd54cbe1d42881e5d0148725a456c607d88534ee35bf07279a86d49c04","Cargo.toml":"dbd37c1a30620a5f0c67085a2b10141ba69b30c58315319109e3e2cbe5ffd737","README.md":"00a6070ebadb15a9488f117b286f50e4838a7dd0a28d41c9fcff4781c6b49171","build.rs":"824e90067aa04ad8726a49476b1af51f5c5c16f9a0b372f00398b3748d723662","src/arena/handle.rs":"1bf2edcca03d7cb466e1f8bd4bf1c966b805505ea2ee3641c39aa04811413478","src/arena/handle_set.rs":"f84ca7edafc907e282abea094c0c9b1da1cf4500e0c6389bb3ce2ef655f4c4ea","src/arena/handlevec.rs":"dfc9249478eb6980c13587c740d91234214bc7e0eef90e6f40b3d99decf70a58","src/arena/mod.rs":"14db142163133eb9ca582bc3665450f49cc4b1cfbda043b8b1518590cdda73be","src/arena/range.rs":"88683c36b137499ab537cf906505c2bd0871e0b9177e3a4e55da9db4e86df6a2","src/arena/unique_arena.rs":"22761770dbcbb6ac497ebdcf07173b3f07fc3c74bc0a70990d5fad882f4f471f","src/back/continue_forward.rs":"f95b810164db51fde368362624ce2569826b47dc3460df316b879abba48e5388","src/back/dot/mod.rs":"b9f57441a9491e4a53b6d9dcb253484f9e935419d179513c2d24db08be591fae","src/back/glsl/features.rs":"747285643e28d0ea7d8293a5ee802b4e88482f771c36845cefe7e8c16ef54637","src/back/glsl/keywords.rs":"b8883e5ee8a3d400fa44fef2baffe2853e72ff91e832499c128454d325ceccd9","src/back/glsl/mod.rs":"89e5aaeebaf7c897e98a3d929baecc8b65b447c2ce30497fbe505c650137c98d","src/back/hlsl/conv.rs":"764f62d356b4d5606e39f258156487db4b33907c82e0bd25d0e374cc999fae88","src/back/hlsl/help.rs":"de631bd11ee65fbbeeae80733103789abfa6ff54b7b39b11e7c22cd02b486a1c","src/back/hlsl/keywords.rs":"a7164690a4da866e6bfb18ced20e32cc8c42dd7387e0e84addf0c2674f529cf5","src/back/hlsl/mod.rs":"8a88e0925ad62296349851f3f2f60959a63ae466422d1932bde53dd94eab586a","src/back/hlsl/storage.rs":"2c2a0071cafe487a398e396dddc85bdb319b1a5d74c097d529078e247a904359","src/back/hlsl/writer.rs":"323d32ceb58439a3bb29cbd420d77f03101b134dcfb22246b6050636704bc317","src/back/mod.rs":"9de236c7a5219b2ff371e44a7d97462cce3d1ccef4c7063632f1a6a7718d683d","src/back/msl/keywords.rs":"e6a4ef77363f995de1f8079c0b8591497cbf9520c5d3b2d41c7e1f483e8abd24","src/back/msl/mod.rs":"a03a380bbc8e9183e9f54c34e5326bedc6a2e94ecbf7cfc53190d2accafa6c7e","src/back/msl/sampler.rs":"9b01d68669e12ff7123243284b85e1a9d2c4d49140bd74ca32dedc007cbf15af","src/back/msl/writer.rs":"ad13b7f42046bdeef091ea793e8dc1d992153140abddb5f78a9629fca362ba97","src/back/pipeline_constants.rs":"50b3a87b6f4eb95c8b20dcc77cecf594cb0cf8d6c4fd7b315a6dd97271acda23","src/back/spv/block.rs":"056e2a11d27c41a1f042f3687b237f01d4a84df4756d62e5b7cc3cf4840f0db5","src/back/spv/helpers.rs":"bd666bf519a5d5561c2fab6ff78229739853ae6877d132911e71b57cfd656e42","src/back/spv/image.rs":"32b8f1ccdd54d80519ccf585451dcc6721d2a6a109d295a704e6c61857832556","src/back/spv/index.rs":"14f704d2d9409bbc9345d601725355048aa74471aaeb6aa781fc45a99ceaec38","src/back/spv/instructions.rs":"27ae0fb206b28cb8240b342a28396cb0a30e3a5fb50fa02413e0cfa6d507a5a4","src/back/spv/layout.rs":"e263de53cd2f9a03ad94b82b434ce636609bc1ed435a2d1132951663bfaa8ebd","src/back/spv/mod.rs":"91fa840f044ae40cc955db2278d5abcb03f53185452ba02ac0a78aedd37c24f3","src/back/spv/ray.rs":"a34bf6b26d873f7270caa45841d9ef291aca8d9732ecd086b14d8856038e1e41","src/back/spv/recyclable.rs":"8061e39ea5357c8d55081a81fb836e762fd9793c1c6b04ae5d714af32677e616","src/back/spv/selection.rs":"81e404abfa0a977f7c1f76ccb37a78d13ccadbda229048dad53cc67687cc39db","src/back/spv/subgroup.rs":"cb68fb9581064ec9ef79e56a0c94c802b2f04cc5e2173a953ae9a7b2776042d5","src/back/spv/writer.rs":"e7fdc6a0424a83bb06e2c01919c72bb16a62b46039c92258be251eceaa851601","src/back/wgsl/mod.rs":"2dd12bbea9ace835850192bb68c5760953da6bac6a636073d1eca19381c0c0b6","src/back/wgsl/writer.rs":"b21ec11688e924708f4101417324f4f1547d63bff72f2de0e8849d619684917f","src/block.rs":"e447f7e041fd67052b23d1139cf0574eea93220a818af71691d960bdf026d45f","src/compact/expressions.rs":"a04f5dbc936693280fddc328df623af0b8d1fc0d11bd01987df9104e9c27bea1","src/compact/functions.rs":"27c084ca6b475999a3367f8ea429dbf7326a54c83ef86898b7ba67366f9bb828","src/compact/handle_set_map.rs":"748de9563f0ff897c113ba665f3e59ab3a023050e2206eb7d566a31f61fc32e5","src/compact/mod.rs":"7ec6bea36d11438c391c37d9a193b323d7fb365de6b9dfd45e78a3240dbab7ba","src/compact/statements.rs":"360e2bb6c2b7fdf4f9de368048ae574b2efd171adf34be44f84fbe21a15f5def","src/compact/types.rs":"9e73ac7dfdaf4b10eda1c938b881857392abc1315adcc035fc3980d63236cf37","src/error.rs":"70f7adbb59ea38ee7ebc44e8ad020d6db4f2dd4976913fb194e779d115241861","src/front/atomic_upgrade.rs":"af1386a3ef42e853042d2d08bf7d0e08fb8a4578ddbf44b5f57326643b9ba613","src/front/glsl/ast.rs":"663e815ea3e511f0445ef910340c380ff1bcf63805329ab7ca8cf35de7f902ed","src/front/glsl/builtins.rs":"8665ccc33938ae2d43257f25dd3cb75b604d30ccaf98888889b130ca7651695f","src/front/glsl/context.rs":"00c489ca8cb0e200595122ab1c857e2354625a680ff44ac3d7b33eadc4b991cd","src/front/glsl/error.rs":"2ef5061decd42dfc3054fd0f1a86dc7168e2064572571147117d798e39675722","src/front/glsl/functions.rs":"52802412788f95e1a55b92a72980e04792c876fbedff6e6d71f8fe0d23cbae80","src/front/glsl/lex.rs":"08736ae8beb955da5b0e6e3e0f45995a824995f7096d516a2910417e9c7afa32","src/front/glsl/mod.rs":"bf97bf1710d5d1f8facb77913cb82868697920914a96ed309adf0f19154a2ab4","src/front/glsl/offset.rs":"9358602ca4f9ef21d5066d674dae757bf88fdf5c289c4360534354d13bd41dc0","src/front/glsl/parser.rs":"a752f2abac17e6d35c0eb406f2f1c24d2b622a55b1bececbdd13614edb686622","src/front/glsl/parser/declarations.rs":"796514c1d571b324817bf1236d4c1227a91a512c0660ce5bb1264cd900027158","src/front/glsl/parser/expressions.rs":"7fd1ccb9261eaf1f9966798c2fed62c54c2c1d9d140d3e9d41d81775acbe35de","src/front/glsl/parser/functions.rs":"dd5980bd731bcd8044bbfa16f760cdc77c02422ec116d7ebbbe64fcbe1fb7a04","src/front/glsl/parser/types.rs":"08d708d0bae448bbfc4c79e6128f0b0bc489ae079018e69bf9589b77803e0372","src/front/glsl/parser_tests.rs":"c44ed3252096c83a0ce1ea9be8d2b867784cdc1c11aa4501aee1a85d86c62511","src/front/glsl/token.rs":"c25c489b152ee2d445ace3c2046473abe64d558b8d27fa08709110e58718b6ac","src/front/glsl/types.rs":"91c3a4e4d11b397ea647ff287e17a48baedf2f2c310e81b04618675daeb83f69","src/front/glsl/variables.rs":"6cb3db649a99452bc91f2bbebe425c0447920f7e9a87c38fa84d54c84f48861e","src/front/interpolator.rs":"9b6ca498d5fbd9bc1515510a04e303a00b324121d7285da3c955cfe18eb4224c","src/front/mod.rs":"ba984fc9b933a844fa8dadf05dea70f308911054ad3f10448d652706e158b4bd","src/front/spv/convert.rs":"b4b19b7cf2360d17405ea4ec97d9bf02376150047dfef008c2a358690625802c","src/front/spv/error.rs":"f41593a3ba8d3bb4371fd26e813affc8d8ce1d6581c8af410cf5e2084a308049","src/front/spv/function.rs":"e584dbeaa5f7e1ff107f3e7e5211b0bfb8f7b9878a74dbe29dc7941cb33b2e0f","src/front/spv/image.rs":"a5ac477c01894a9c9ce5ec9d6751f991622d610f5581a759fc2e72034677d9e4","src/front/spv/mod.rs":"1f32a2a8174546075e57bc52bd0bba6e3fbae9a290e75a05332f244554bcf993","src/front/spv/null.rs":"a8ff44e97ffe42a4773d89b88fdb3a8ef8fba58bf6645c73b7a66470234ccf10","src/front/type_gen.rs":"49d8aae89143a0cba182c5271a2aa60972251c1603144bd21567565ff64b2274","src/front/wgsl/error.rs":"eb0d142e9d25ded215131b8f8ee79da72bf9881c1b5af711fccfc42381641d08","src/front/wgsl/index.rs":"c5928ac405ffbd74de60b96360f7e07a3470b39f8f76c6e0b06544b4b5f61f57","src/front/wgsl/lower/construction.rs":"c31aabb26bf7b8b62d7dee2e6b6fd26a0314247dd5665efe2190921ef97e3213","src/front/wgsl/lower/conversion.rs":"492293f4f3fc7786a3a480ca0f43a10ae5ac8557cf1903cdd616ca624093b951","src/front/wgsl/lower/mod.rs":"8c16d6bb6db75fed70c6ce1d397c696678e04e8b21aa6453c8700ab229294b0a","src/front/wgsl/mod.rs":"cebe3f61843cca32d6764b93b07cb369ae22d1240d81eabe25f5c42dc603fca1","src/front/wgsl/parse/ast.rs":"766ff3412f79652a71964a521755fb758f2192f157c62b553d4c53f9f0ba07d7","src/front/wgsl/parse/conv.rs":"860a02ccceb10468a89e28562547092c5dacce24411621e16e7e08ec45e27e09","src/front/wgsl/parse/lexer.rs":"17db87d0017f8f9a80fa151b8545f04e1b40c4e5feef6197f4a117efa03488bf","src/front/wgsl/parse/mod.rs":"61419806f2366812f8c14fed0d87a759eeb899d7e66bfb0b188156053bfbde27","src/front/wgsl/parse/number.rs":"dafd3d8651cfa1389cb359d76d39bd689e54f8d5025aa23e06c6edd871369efd","src/front/wgsl/tests.rs":"7a0a083a5b66af8e7d4b1a02401b27f077eb72d07181b610693f35b11f107c6c","src/front/wgsl/to_wgsl.rs":"20f9e503b26826020f024b9c99ca06e38438ad44f8dbb8c7cbf8ee7828780e61","src/keywords/mod.rs":"47a6fde012bf7d1e70f0fac7762f6a8e7dca6b9bbb99e2cada773c61527cfbfe","src/keywords/wgsl.rs":"c648ac44241ad55c8c8bad3d8f1bab973d11ddb9c380dcca369b735ed3975309","src/lib.rs":"37defb3e1b4cbbb29f18fc7e21b2169e423dec7f8025752d8079316f434d2d6b","src/non_max_u32.rs":"3f4aafc8e2775982187507d49e7aa58befffdaba71c9287be42afdfde28bcb66","src/proc/constant_evaluator.rs":"1cff379df1e1383e97bdaa54e79121bab9b3cc0cfa5b13a13abb5b3d6f3978b0","src/proc/emitter.rs":"39ac886c651e2ad33c06a676a7e4826a0e93de0af660c01e8e4b1f7406742f88","src/proc/index.rs":"7c10d3d89ad8c50d063f39ed5b24492e41b6f2d78a7b92138b1ee214a1ea06a2","src/proc/layouter.rs":"e95fd9defa08e0c610d22d7cd795a6af787610d1ff0d4ed27798b4ffd2098cf1","src/proc/mod.rs":"b0b856056eac4f57f4495ec6ec39e79e50386177b2ee0b042ee4d0dd9f9540da","src/proc/namer.rs":"7328fac41e40890c64c7ee2fa985a4395424f18b08d30f30ca2583fdabd2fd35","src/proc/terminator.rs":"fef2160473fcddd670c6b5806a8ea0ecbdcc0fdf6ed793dce131ecd08cce3944","src/proc/typifier.rs":"0ee6be729fe141399a279a6bc8a6f1f5cb82ee397f4352902ad3b662e2e9a618","src/span.rs":"fd3b338256f9301fc5289c37af9ccec704d2e5db92923b0dec45da371e84ce6a","src/valid/analyzer.rs":"64f0c49988a14e4bf4c9718be69e43d152994756095bb438a3467641c4f4cc1c","src/valid/compose.rs":"83e4c09c39f853cf085b83b87e48b3db571da619132960d3ec954ebdfb0a74f2","src/valid/expression.rs":"50f2fa21d80fd121bc4372dce616e1eeb7507cef29d93273c8c3f86df919b510","src/valid/function.rs":"a624138dc5c4a8d49f68e48fb66e64d14c2da1cd6e8dadfc74bab7a9f63a2f9f","src/valid/handles.rs":"fd9e52370d76b9ff57357c651a951112246ca6c4794b59c021601e9c6b11a0bd","src/valid/interface.rs":"a6d60fcca8c2eb840ddd2cd9148df8b9613d6624d16ab1e3bc1b83a81aef3e03","src/valid/mod.rs":"4130656e5d14c54de38d4f7e7e8cb15ffe60c19ddf93aa976b2fc3e990ddbf45","src/valid/type.rs":"52528d261599f5eb8c61197200b1ffba5dcea6357838edc09f2c51f406af527c"},"package":null} \ No newline at end of file diff --git a/third_party/rust/naga/Cargo.toml b/third_party/rust/naga/Cargo.toml index 7659c0fc2e..be4a1797d7 100644 --- a/third_party/rust/naga/Cargo.toml +++ b/third_party/rust/naga/Cargo.toml @@ -9,19 +9,27 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +bench = [] + [package] edition = "2021" rust-version = "1.76" name = "naga" version = "22.0.0" authors = ["gfx-rs developers"] +build = "build.rs" exclude = [ "bin/**/*", "tests/**/*", "Cargo.lock", "target/**/*", ] +autobins = false +autoexamples = false autotests = false +autobenches = false description = "Shader translation infrastructure" readme = "README.md" keywords = [ @@ -37,24 +45,31 @@ resolver = "2" [package.metadata.docs.rs] all-features = true +[lib] +name = "naga" +path = "src/lib.rs" + [[test]] name = "naga-test" path = "tests/root.rs" [dependencies] -arrayvec = "0.7" -bit-set = "0.8" -bitflags = "2.6" -indexmap = "2" log = "0.4" -rustc-hash = "1.1.0" -thiserror = "1.0.63" [dependencies.arbitrary] version = "1.3" features = ["derive"] optional = true +[dependencies.arrayvec] +version = "0.7" + +[dependencies.bit-set] +version = "0.8" + +[dependencies.bitflags] +version = "2.6" + [dependencies.codespan-reporting] version = "0.11.0" @@ -62,6 +77,9 @@ version = "0.11.0" version = "0.2.1" optional = true +[dependencies.indexmap] +version = "2" + [dependencies.petgraph] version = "0.6" optional = true @@ -70,6 +88,9 @@ optional = true version = "0.2.1" optional = true +[dependencies.rustc-hash] +version = "1.1.0" + [dependencies.serde] version = "1.0.208" features = ["derive"] @@ -82,15 +103,20 @@ optional = true [dependencies.termcolor] version = "1.4.1" +[dependencies.thiserror] +version = "1.0.63" + [dependencies.unicode-xid] version = "0.2.5" optional = true [dev-dependencies] diff = "0.1" -env_logger = "0.11" ron = "0.8.0" +[dev-dependencies.env_logger] +version = "0.11" + [dev-dependencies.hlsl-snapshots] path = "./hlsl-snapshots" @@ -107,8 +133,8 @@ features = ["derive"] version = "0.3" features = ["deserialize"] -[build-dependencies] -cfg_aliases = "0.1" +[build-dependencies.cfg_aliases] +version = "0.1" [features] arbitrary = [ diff --git a/third_party/rust/neqo-bin/.cargo-checksum.json b/third_party/rust/neqo-bin/.cargo-checksum.json index 4013168b6a..560700176a 100644 --- a/third_party/rust/neqo-bin/.cargo-checksum.json +++ b/third_party/rust/neqo-bin/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"a35a84144abc70ceec5017089f31a5c7ed6fd5d38073e2ba1648dbedbd3d4d0e","benches/main.rs":"aa39bf1f08863e3bace034a991c60a4723f1a7d30b3fc1d1f8c4d7f73bc748c3","src/bin/client.rs":"db77efd75dc0745b6dd983ab8fa3bc8f5f9111967f0d90d23cb19140a940246d","src/bin/server.rs":"2f7ab3c7a98117bd162e6fd07abef1d21791d1bb240db3aae61afa6ff72df83a","src/client/http09.rs":"868a55062e864e7c290e345e3049afbd49796ec3655259a681457540efa3650f","src/client/http3.rs":"7ffba6396ab5875cda5f3ab092d4cc34ab16adad30277b017bc667086d374d18","src/client/mod.rs":"3bf40a6dcc5fde24c823f55ee9d34a2e7d96d2d19980b234d3ec22e33771c14c","src/lib.rs":"e41fe10d5f45b4472ca97a8be531a6b959ec47f094cf2fad3f4f50954ce09046","src/server/http09.rs":"7b0b0459d2b71ecb1d4c93177304a8b7dc0a74dc4cb0a9875df18295ab04b271","src/server/http3.rs":"9d5361a724be1d0e234bbc4b3893a8830825e5886a24a40b96e3f87f35c7b968","src/server/mod.rs":"91f8cd6278c42eef20b6e16f3d903705073d741093bcdf161b58c01914aca2de","src/udp.rs":"81391238621282fae1efc4e5b28be7226733e1bfef7e790f21fb23395cb738bc"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"213791380401f74b5f2407818759035833dbbdcda76e35d791cd352651400f96","benches/main.rs":"aa39bf1f08863e3bace034a991c60a4723f1a7d30b3fc1d1f8c4d7f73bc748c3","src/bin/client.rs":"db77efd75dc0745b6dd983ab8fa3bc8f5f9111967f0d90d23cb19140a940246d","src/bin/server.rs":"2f7ab3c7a98117bd162e6fd07abef1d21791d1bb240db3aae61afa6ff72df83a","src/client/http09.rs":"868a55062e864e7c290e345e3049afbd49796ec3655259a681457540efa3650f","src/client/http3.rs":"7ffba6396ab5875cda5f3ab092d4cc34ab16adad30277b017bc667086d374d18","src/client/mod.rs":"3bf40a6dcc5fde24c823f55ee9d34a2e7d96d2d19980b234d3ec22e33771c14c","src/lib.rs":"e41fe10d5f45b4472ca97a8be531a6b959ec47f094cf2fad3f4f50954ce09046","src/server/http09.rs":"7b0b0459d2b71ecb1d4c93177304a8b7dc0a74dc4cb0a9875df18295ab04b271","src/server/http3.rs":"9d5361a724be1d0e234bbc4b3893a8830825e5886a24a40b96e3f87f35c7b968","src/server/mod.rs":"91f8cd6278c42eef20b6e16f3d903705073d741093bcdf161b58c01914aca2de","src/udp.rs":"81391238621282fae1efc4e5b28be7226733e1bfef7e790f21fb23395cb738bc"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-bin/Cargo.toml b/third_party/rust/neqo-bin/Cargo.toml index 543eee039a..256a4d59a1 100644 --- a/third_party/rust/neqo-bin/Cargo.toml +++ b/third_party/rust/neqo-bin/Cargo.toml @@ -9,12 +9,20 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +example = [] +test = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-bin" version = "0.8.2" authors = ["The Neqo Authors "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "A basic QUIC HTTP/0.9 and HTTP/3 client and server." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -34,6 +42,8 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/mozilla/neqo/" [lib] +name = "neqo_bin" +path = "src/lib.rs" bench = false [[bin]] @@ -48,6 +58,7 @@ bench = false [[bench]] name = "main" +path = "benches/main.rs" harness = false required-features = ["bench"] diff --git a/third_party/rust/neqo-common/.cargo-checksum.json b/third_party/rust/neqo-common/.cargo-checksum.json index bffca252e0..37bbe5022a 100644 --- a/third_party/rust/neqo-common/.cargo-checksum.json +++ b/third_party/rust/neqo-common/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"0393214662d5143db3f4c167c862ca3174738cbd3e1d6b4cf2773df25c91d273","build.rs":"306b2f909a25ae38daf5404a4e128d2a94e8975b70870864c2a71cafec9717c7","src/codec.rs":"549ee76e90898d37102bd4eabfce69a98aaec6862785eaeb4c9af57b7a36a655","src/datagram.rs":"2acecfcbecfbb767ea920e3b22388e67b31fcda776cae5b2d7ecbc67dd9febf7","src/event.rs":"106ca6c4afb107fa49a1bc72f5eb4ae95f4baa1ba19736aa38c8ba973774c160","src/fuzz.rs":"1ca74a34bdc97fedecf8a63c4a13cc487d1b2212398fb76f67792c822002138d","src/header.rs":"480a7848466249a78acddbf0bc0b4a096189abc14a89ad1a0943be571add2c2b","src/hrtime.rs":"93a544743f3994e5d4c494b313a9532ab5bd23541ff63a747cb377ad6d5edc72","src/incrdecoder.rs":"5c45034e61e75c76d2bca8b075c3e7a3cdd8af8c82b67c76283a2b08ab11846b","src/lib.rs":"2381fc00127a7eaf2265c3a13dc1e1d5843e048f3a8a1c97f1e6621c038de380","src/log.rs":"6ed99e15707c4256ae793011ed2f4b33aa81fed70205aaf5f8d3cd11ad451cf0","src/qlog.rs":"1cee4ff3bc9bf735a1bb913e1515ef240a70326a34c56a6ce89de02bc9f3459c","src/tos.rs":"28fd9acfce06f68ac6691efd2609618850182f77ef3717ce2db07bfac19a9396","tests/log.rs":"a11e21fb570258ca93bb40e3923817d381e1e605accbc3aed1df5a0a9918b41d"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"3c2a56e78b593343b3d42f35bf87d0ea7cc628d2ab873ff6992c89336e0a44aa","build.rs":"306b2f909a25ae38daf5404a4e128d2a94e8975b70870864c2a71cafec9717c7","src/codec.rs":"549ee76e90898d37102bd4eabfce69a98aaec6862785eaeb4c9af57b7a36a655","src/datagram.rs":"2acecfcbecfbb767ea920e3b22388e67b31fcda776cae5b2d7ecbc67dd9febf7","src/event.rs":"106ca6c4afb107fa49a1bc72f5eb4ae95f4baa1ba19736aa38c8ba973774c160","src/fuzz.rs":"1ca74a34bdc97fedecf8a63c4a13cc487d1b2212398fb76f67792c822002138d","src/header.rs":"480a7848466249a78acddbf0bc0b4a096189abc14a89ad1a0943be571add2c2b","src/hrtime.rs":"93a544743f3994e5d4c494b313a9532ab5bd23541ff63a747cb377ad6d5edc72","src/incrdecoder.rs":"5c45034e61e75c76d2bca8b075c3e7a3cdd8af8c82b67c76283a2b08ab11846b","src/lib.rs":"2381fc00127a7eaf2265c3a13dc1e1d5843e048f3a8a1c97f1e6621c038de380","src/log.rs":"6ed99e15707c4256ae793011ed2f4b33aa81fed70205aaf5f8d3cd11ad451cf0","src/qlog.rs":"1cee4ff3bc9bf735a1bb913e1515ef240a70326a34c56a6ce89de02bc9f3459c","src/tos.rs":"28fd9acfce06f68ac6691efd2609618850182f77ef3717ce2db07bfac19a9396","tests/log.rs":"a11e21fb570258ca93bb40e3923817d381e1e605accbc3aed1df5a0a9918b41d"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-common/Cargo.toml b/third_party/rust/neqo-common/Cargo.toml index 7bec93a05a..8b17fe9726 100644 --- a/third_party/rust/neqo-common/Cargo.toml +++ b/third_party/rust/neqo-common/Cargo.toml @@ -9,12 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +bench = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-common" version = "0.8.2" authors = ["The Neqo Authors "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -34,8 +43,14 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/mozilla/neqo/" [lib] +name = "neqo_common" +path = "src/lib.rs" bench = false +[[test]] +name = "log" +path = "tests/log.rs" + [dependencies.enum-map] version = "2.7" default-features = false diff --git a/third_party/rust/neqo-crypto/.cargo-checksum.json b/third_party/rust/neqo-crypto/.cargo-checksum.json index a7378c37c1..84d59e991a 100644 --- a/third_party/rust/neqo-crypto/.cargo-checksum.json +++ b/third_party/rust/neqo-crypto/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"652b2c877cd7b9fb9d00ecb9dfead065c9b578d6d294f1f7b89dfdc2b887a3eb","bindings/bindings.toml":"0e06a03035a90ec5f823b30c8b78ec010a332ae0e5ed0c953da2e4c406451793","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"51cfa35860a4c1a0f16e3fc2e2540b02cd9bdf1598f0ca65b74cf4c02fca5be3","min_version.txt":"94ebbba5fc5de230ca467b7e316e9202e4a86c603b3a629cffd647859f48b730","src/aead.rs":"6410bcbe717a6b9ea6f11209b0888033358113ebc05b8a95cec1980d1360be4d","src/aead_null.rs":"81163fafef59bd2800bd0a078d53d0f05ee114f0e22165717823a5ff1cb908af","src/agent.rs":"607f8a648b2099e81750d3d4076a8ca485c79603011d6b0fb2a515aac400c514","src/agentio.rs":"22e63d5efefbff41113cf002a75bb08f15228cb83e9e2cba65eb6da52dad0264","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"8e75e69ec3544474b21f8915a7559463889c2f608b201dee274a8d701880950e","src/constants.rs":"f5c779db128a8b0607841ca18c376971017eb327e102e5e6959a7d8effe4b3a6","src/ech.rs":"75dd192423e8996d9061da5e9c20d30bff5153b9344132eda4fe321c4c141870","src/err.rs":"2366501e0b48933a6a2e1c5b934aa55108c093729c84878b45e1e012e4e45d51","src/exp.rs":"d953873e87430b1c84d4a83c8eb3815041f5585b210bbaf59ae2c4d0057f5edd","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"8745ba761be821c1819cedf6dfd91f8b3148c6718053a4a74f33eb50c7d0cc40","src/hp.rs":"510a4a7f278203aa306ead05608f99397edc3806dc22b0af9e28c665b43ae56c","src/lib.rs":"db01ac68d002055bf12d940442c9b9195cc1331bb779571794eae6dc1223eef6","src/min_version.rs":"c6e1f98b9f56db0622ac38c1be131c55acf4a0f09ed0d6283f4d6308e2d1301a","src/p11.rs":"375397b18fcdf36dcdd22c164c8572dd83caf01b8d0065be3029444b197e1464","src/prio.rs":"5cf0105e78b1db43c65283208174abc3714a41dbb4d5cd80ac547a5a5a7c627c","src/replay.rs":"ad5be8e5d20cde477e7fa734000d880bc36d8288d4689e57332f212f65dde716","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"2c47935c5b8c42363897881eaa0c171e84cf031e57a6e1387b99327080e8dd60","src/selfencrypt.rs":"018c2dacabd3e463fdadd5707715b23c26c261c4c7d86e66c62f0acec986cad9","src/ssl.rs":"59bafcaed7caa66fe448339a1f75ce807ef92fc28247709df4f8058499b0787e","src/time.rs":"ade63a72ae90796d7fcccadbb15efc4594fcdb68913a914a657d4556fde88f62","tests/aead.rs":"e36ae77802df1ea6d17cfd1bd2178a3706089577d6fd1554ca86e748b8b235b9","tests/agent.rs":"cbd0011f1d33281883a45d433228221062424c94e86decade5697731c08a1c52","tests/ext.rs":"57af4e2df211fa8afdb73125d4344ef5c70c1ea4579107c3e6f5746308ee3e7b","tests/handshake.rs":"aa904736d36cc5d5cc0c4f6053b529987f33f944a73411bf08e01d30c4867186","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"ccda23018dac70b3ff3742afcb0fbae0735be9aeb36644a4ae2b1d7c9126801c","tests/init.rs":"3e15150c4b324c06ca5e8935618e4008da53dc0ef4b69325d150831e87dc0b63","tests/selfencrypt.rs":"8d10840b41629bf449a6b3a551377315e8a05ca26c6b041548748196652c5909"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"a4b882fb4d24557b4d365d13d83d46bba448648c834ab5bb488feb369be18188","bindings/bindings.toml":"0e06a03035a90ec5f823b30c8b78ec010a332ae0e5ed0c953da2e4c406451793","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"51cfa35860a4c1a0f16e3fc2e2540b02cd9bdf1598f0ca65b74cf4c02fca5be3","min_version.txt":"94ebbba5fc5de230ca467b7e316e9202e4a86c603b3a629cffd647859f48b730","src/aead.rs":"6410bcbe717a6b9ea6f11209b0888033358113ebc05b8a95cec1980d1360be4d","src/aead_null.rs":"81163fafef59bd2800bd0a078d53d0f05ee114f0e22165717823a5ff1cb908af","src/agent.rs":"607f8a648b2099e81750d3d4076a8ca485c79603011d6b0fb2a515aac400c514","src/agentio.rs":"22e63d5efefbff41113cf002a75bb08f15228cb83e9e2cba65eb6da52dad0264","src/auth.rs":"ced1a18f691894984244088020ea25dc1ee678603317f0c7dfc8b8842fa750b4","src/cert.rs":"8e75e69ec3544474b21f8915a7559463889c2f608b201dee274a8d701880950e","src/constants.rs":"f5c779db128a8b0607841ca18c376971017eb327e102e5e6959a7d8effe4b3a6","src/ech.rs":"75dd192423e8996d9061da5e9c20d30bff5153b9344132eda4fe321c4c141870","src/err.rs":"2366501e0b48933a6a2e1c5b934aa55108c093729c84878b45e1e012e4e45d51","src/exp.rs":"d953873e87430b1c84d4a83c8eb3815041f5585b210bbaf59ae2c4d0057f5edd","src/ext.rs":"cbf7d9f5ecabf4b8c9efd6c334637ab1596ec5266d38ab8d2d6ceae305283deb","src/hkdf.rs":"8745ba761be821c1819cedf6dfd91f8b3148c6718053a4a74f33eb50c7d0cc40","src/hp.rs":"510a4a7f278203aa306ead05608f99397edc3806dc22b0af9e28c665b43ae56c","src/lib.rs":"db01ac68d002055bf12d940442c9b9195cc1331bb779571794eae6dc1223eef6","src/min_version.rs":"c6e1f98b9f56db0622ac38c1be131c55acf4a0f09ed0d6283f4d6308e2d1301a","src/p11.rs":"375397b18fcdf36dcdd22c164c8572dd83caf01b8d0065be3029444b197e1464","src/prio.rs":"5cf0105e78b1db43c65283208174abc3714a41dbb4d5cd80ac547a5a5a7c627c","src/replay.rs":"ad5be8e5d20cde477e7fa734000d880bc36d8288d4689e57332f212f65dde716","src/result.rs":"0587cbb6aace71a7f9765ef7c01dcd9f73a49dcc6331e1d8fe4de2aef6ca65b6","src/secrets.rs":"2c47935c5b8c42363897881eaa0c171e84cf031e57a6e1387b99327080e8dd60","src/selfencrypt.rs":"018c2dacabd3e463fdadd5707715b23c26c261c4c7d86e66c62f0acec986cad9","src/ssl.rs":"59bafcaed7caa66fe448339a1f75ce807ef92fc28247709df4f8058499b0787e","src/time.rs":"ade63a72ae90796d7fcccadbb15efc4594fcdb68913a914a657d4556fde88f62","tests/aead.rs":"e36ae77802df1ea6d17cfd1bd2178a3706089577d6fd1554ca86e748b8b235b9","tests/agent.rs":"cbd0011f1d33281883a45d433228221062424c94e86decade5697731c08a1c52","tests/ext.rs":"57af4e2df211fa8afdb73125d4344ef5c70c1ea4579107c3e6f5746308ee3e7b","tests/handshake.rs":"aa904736d36cc5d5cc0c4f6053b529987f33f944a73411bf08e01d30c4867186","tests/hkdf.rs":"1d2098dc8398395864baf13e4886cfd1da6d36118727c3b264f457ee3da6b048","tests/hp.rs":"ccda23018dac70b3ff3742afcb0fbae0735be9aeb36644a4ae2b1d7c9126801c","tests/init.rs":"3e15150c4b324c06ca5e8935618e4008da53dc0ef4b69325d150831e87dc0b63","tests/selfencrypt.rs":"8d10840b41629bf449a6b3a551377315e8a05ca26c6b041548748196652c5909"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-crypto/Cargo.toml b/third_party/rust/neqo-crypto/Cargo.toml index 41a19f7de2..b866ed8436 100644 --- a/third_party/rust/neqo-crypto/Cargo.toml +++ b/third_party/rust/neqo-crypto/Cargo.toml @@ -9,12 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +bench = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-crypto" version = "0.8.2" authors = ["The Neqo Authors "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -34,8 +43,42 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/mozilla/neqo/" [lib] +name = "neqo_crypto" +path = "src/lib.rs" bench = false +[[test]] +name = "aead" +path = "tests/aead.rs" + +[[test]] +name = "agent" +path = "tests/agent.rs" + +[[test]] +name = "ext" +path = "tests/ext.rs" + +[[test]] +name = "handshake" +path = "tests/handshake.rs" + +[[test]] +name = "hkdf" +path = "tests/hkdf.rs" + +[[test]] +name = "hp" +path = "tests/hp.rs" + +[[test]] +name = "init" +path = "tests/init.rs" + +[[test]] +name = "selfencrypt" +path = "tests/selfencrypt.rs" + [dependencies.log] version = "0.4" default-features = false diff --git a/third_party/rust/neqo-http3/.cargo-checksum.json b/third_party/rust/neqo-http3/.cargo-checksum.json index a495308c75..39cc687340 100644 --- a/third_party/rust/neqo-http3/.cargo-checksum.json +++ b/third_party/rust/neqo-http3/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"d1a77c96f99b33741e667343b225c969c746e9e093173bea6514515398ae68ad","src/buffered_send_stream.rs":"dfb248c66ea65418b0c7798c2ecaa3ed70ef1af818ef58d53ef742b3445077b7","src/client_events.rs":"77fedca72ce54956eaba3fb7103085d196a631b764662584ea2629224c5c234e","src/conn_params.rs":"7f0df52bceda1923aef2b7c5c64a532f49ea083ea45e3dcd5bd4b03031b89643","src/connection.rs":"0d7b2e529839fe6c6f7bcb6117dc8734f0dc5cce1dfb3e2541c9710488e1b753","src/connection_client.rs":"8d6d1518bee62519911dd2571e97d463d9e05cb13ec55bc1cf6f6712c920972e","src/connection_server.rs":"02fda7595a33c57d0b3ccede51a1e7a8c9073e1ec107ca1b56c56f1728db2318","src/control_stream_local.rs":"20917762c7e7c1112c56abf1cbaf0ad7f0eab97d8db9a3b10ff524315a235670","src/control_stream_remote.rs":"3729f67aa0681b1dbd4147063890f8440f27d82454776500ae964a17cda4d6b5","src/features/extended_connect/mod.rs":"cbeb2294eaf34f08a2c0d0fe4d3473aea9c65df6faaec9dc3ed29dcb577b1c3f","src/features/extended_connect/tests/mod.rs":"fd6aee37243713e80fc526552f21f0222338cec9890409b6575a2a637b17ec1f","src/features/extended_connect/tests/webtransport/datagrams.rs":"51d6f3828c44b438eb1776e8dcce531af520f28bc0d715807d3f53a0eaa071d1","src/features/extended_connect/tests/webtransport/mod.rs":"27f77213414089148e94067bfc54133945a971fd7ddd6936bbfeabb9badc7e67","src/features/extended_connect/tests/webtransport/negotiation.rs":"a22094dbaf0754d39ac8ac08fce1ae34ace108220b696c7d618567df56cddeec","src/features/extended_connect/tests/webtransport/sessions.rs":"cf8aa14087cc3ff42657d86ecacbd51bc182357fdcbd10f57d32784abb415a12","src/features/extended_connect/tests/webtransport/streams.rs":"4c136855292d5ba5169f41c18beea13e7f1e014a0acb13c565c872d3a80d6377","src/features/extended_connect/webtransport_session.rs":"da0b99092d8af8d4f7699c8d45e2e4057f4de38d6fa99e27e3a7feffa569374f","src/features/extended_connect/webtransport_streams.rs":"9855d77705acb7d21566333c4b297816e363be2ade14b8685fd1df4a4861cf74","src/features/mod.rs":"89056df3a868cb0037963c942fc27093cc16d84538ffca2d4759f9a6a6c74c7f","src/frames/hframe.rs":"72349bf4e9dd5c57dc5443bb9aa079887e2742dc08d77ea55567e3b09e0de4d8","src/frames/mod.rs":"0e6d49888d723b2c2c73df11020ceb88d9f062e9d4dc436eb38173e0b772d905","src/frames/reader.rs":"8c7ea836a466410bd3c98848b4852945ae30e1306f73290c401c686998bde16d","src/frames/tests/hframe.rs":"53941fd7656f5e424d499278e6d9ba93ce716f219e86fe6fa08c058ea92f8d7b","src/frames/tests/mod.rs":"c6bbf85fbc6cb9adf6115d315f0564317eefd83ff3177c93050844ad77f6e694","src/frames/tests/reader.rs":"9ee0d9cdd87b98da2b94e577bbcc2bfde6d72be5177bf02364188935f79cb36a","src/frames/tests/wtframe.rs":"c6598d24f5e12972f02de6e1394362671633982db637a07e1c0bb9b56d93ea2a","src/frames/wtframe.rs":"ad6dd63c54a0305c045cd983d5889ae86a5a1afe1e7c13e1c169de9af440759e","src/headers_checks.rs":"69964deb121721be01df7174c177543c161389295ce1450d348369279e312ba4","src/lib.rs":"3fb980eee46bee8dcb97ad9d55014555d8994a7a2d040ca223f2d28fe7d923ef","src/priority.rs":"946307329f31819d969093406ae5448f7923343ccc112221ea6eedf86cf447dc","src/push_controller.rs":"53f72e8043505f85cba0f9c16b4a5ce14d6668b030d773067bc88b2a10bdd25b","src/qlog.rs":"db5f2dd6566d44b4f0541f75266b417b558c09e62141f056885cb8c66478a932","src/qpack_decoder_receiver.rs":"eb06c4be59da567fef70c20daa2c0f165c768131165479a210e69659f168b88f","src/qpack_encoder_receiver.rs":"831f3da9ec17966286786ba3f2c723395a132e65d6a33b4ec341fe7640c1a53d","src/recv_message.rs":"c3acf0544680f88ccd3500e6bea949c1bb43e2fb0a8922edc8f837d0166c89f8","src/request_target.rs":"9720b9f87d66a7c2301bba7de5a5a9300f547613a63153a4d35c7a7506a59b31","src/send_message.rs":"be4e9f64db2c25eb7176b84695e608e768115d62e615d389a33d26f7cd5b0c6c","src/server.rs":"8d48376abf36d036f51a84cddcc3d5acd56786b181fba0e24449e1417b030d63","src/server_connection_events.rs":"1396baab265a814045ccfe63d637a4fdc32a667b5eb2925fa4951f5c3078fb20","src/server_events.rs":"02fc8c0711efd758fb1ddee27d257c12ed35e2a989e7bf3de44bd662dc8234e3","src/settings.rs":"d0f8c546e70161422a029a40564b9e9b953fe671c60835196b16f3364779eaf9","src/stream_type_reader.rs":"0bc91ee4c2a516053cd2b55a60f9bd8e62008cde94274e281224cdffe352a907","tests/httpconn.rs":"87c32197258711d916cace23ed850c5bf0198f5e32756c68a32d91206b6e6db8","tests/priority.rs":"364754507873298612ad12e8d1d106d26d993712142d0be4cbf056da5338854c","tests/send_message.rs":"cdf7028eb64f8f3778c3bbb2a10e9482c4e995e9e1813143ccd83ec96b2d4b6a","tests/webtransport.rs":"02b81be0a20252a8bb0796b5287e426c1af5ddaf5a47d68aa9165393cba83c45"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"db789a718ec09df778191371010b6530ac9ff3107454e88ef09300e02505adc9","src/buffered_send_stream.rs":"dfb248c66ea65418b0c7798c2ecaa3ed70ef1af818ef58d53ef742b3445077b7","src/client_events.rs":"77fedca72ce54956eaba3fb7103085d196a631b764662584ea2629224c5c234e","src/conn_params.rs":"7f0df52bceda1923aef2b7c5c64a532f49ea083ea45e3dcd5bd4b03031b89643","src/connection.rs":"0d7b2e529839fe6c6f7bcb6117dc8734f0dc5cce1dfb3e2541c9710488e1b753","src/connection_client.rs":"8d6d1518bee62519911dd2571e97d463d9e05cb13ec55bc1cf6f6712c920972e","src/connection_server.rs":"02fda7595a33c57d0b3ccede51a1e7a8c9073e1ec107ca1b56c56f1728db2318","src/control_stream_local.rs":"20917762c7e7c1112c56abf1cbaf0ad7f0eab97d8db9a3b10ff524315a235670","src/control_stream_remote.rs":"3729f67aa0681b1dbd4147063890f8440f27d82454776500ae964a17cda4d6b5","src/features/extended_connect/mod.rs":"cbeb2294eaf34f08a2c0d0fe4d3473aea9c65df6faaec9dc3ed29dcb577b1c3f","src/features/extended_connect/tests/mod.rs":"fd6aee37243713e80fc526552f21f0222338cec9890409b6575a2a637b17ec1f","src/features/extended_connect/tests/webtransport/datagrams.rs":"51d6f3828c44b438eb1776e8dcce531af520f28bc0d715807d3f53a0eaa071d1","src/features/extended_connect/tests/webtransport/mod.rs":"27f77213414089148e94067bfc54133945a971fd7ddd6936bbfeabb9badc7e67","src/features/extended_connect/tests/webtransport/negotiation.rs":"a22094dbaf0754d39ac8ac08fce1ae34ace108220b696c7d618567df56cddeec","src/features/extended_connect/tests/webtransport/sessions.rs":"cf8aa14087cc3ff42657d86ecacbd51bc182357fdcbd10f57d32784abb415a12","src/features/extended_connect/tests/webtransport/streams.rs":"4c136855292d5ba5169f41c18beea13e7f1e014a0acb13c565c872d3a80d6377","src/features/extended_connect/webtransport_session.rs":"da0b99092d8af8d4f7699c8d45e2e4057f4de38d6fa99e27e3a7feffa569374f","src/features/extended_connect/webtransport_streams.rs":"9855d77705acb7d21566333c4b297816e363be2ade14b8685fd1df4a4861cf74","src/features/mod.rs":"89056df3a868cb0037963c942fc27093cc16d84538ffca2d4759f9a6a6c74c7f","src/frames/hframe.rs":"72349bf4e9dd5c57dc5443bb9aa079887e2742dc08d77ea55567e3b09e0de4d8","src/frames/mod.rs":"0e6d49888d723b2c2c73df11020ceb88d9f062e9d4dc436eb38173e0b772d905","src/frames/reader.rs":"8c7ea836a466410bd3c98848b4852945ae30e1306f73290c401c686998bde16d","src/frames/tests/hframe.rs":"53941fd7656f5e424d499278e6d9ba93ce716f219e86fe6fa08c058ea92f8d7b","src/frames/tests/mod.rs":"c6bbf85fbc6cb9adf6115d315f0564317eefd83ff3177c93050844ad77f6e694","src/frames/tests/reader.rs":"9ee0d9cdd87b98da2b94e577bbcc2bfde6d72be5177bf02364188935f79cb36a","src/frames/tests/wtframe.rs":"c6598d24f5e12972f02de6e1394362671633982db637a07e1c0bb9b56d93ea2a","src/frames/wtframe.rs":"ad6dd63c54a0305c045cd983d5889ae86a5a1afe1e7c13e1c169de9af440759e","src/headers_checks.rs":"69964deb121721be01df7174c177543c161389295ce1450d348369279e312ba4","src/lib.rs":"3fb980eee46bee8dcb97ad9d55014555d8994a7a2d040ca223f2d28fe7d923ef","src/priority.rs":"946307329f31819d969093406ae5448f7923343ccc112221ea6eedf86cf447dc","src/push_controller.rs":"53f72e8043505f85cba0f9c16b4a5ce14d6668b030d773067bc88b2a10bdd25b","src/qlog.rs":"db5f2dd6566d44b4f0541f75266b417b558c09e62141f056885cb8c66478a932","src/qpack_decoder_receiver.rs":"eb06c4be59da567fef70c20daa2c0f165c768131165479a210e69659f168b88f","src/qpack_encoder_receiver.rs":"831f3da9ec17966286786ba3f2c723395a132e65d6a33b4ec341fe7640c1a53d","src/recv_message.rs":"c3acf0544680f88ccd3500e6bea949c1bb43e2fb0a8922edc8f837d0166c89f8","src/request_target.rs":"9720b9f87d66a7c2301bba7de5a5a9300f547613a63153a4d35c7a7506a59b31","src/send_message.rs":"be4e9f64db2c25eb7176b84695e608e768115d62e615d389a33d26f7cd5b0c6c","src/server.rs":"8d48376abf36d036f51a84cddcc3d5acd56786b181fba0e24449e1417b030d63","src/server_connection_events.rs":"1396baab265a814045ccfe63d637a4fdc32a667b5eb2925fa4951f5c3078fb20","src/server_events.rs":"02fc8c0711efd758fb1ddee27d257c12ed35e2a989e7bf3de44bd662dc8234e3","src/settings.rs":"d0f8c546e70161422a029a40564b9e9b953fe671c60835196b16f3364779eaf9","src/stream_type_reader.rs":"0bc91ee4c2a516053cd2b55a60f9bd8e62008cde94274e281224cdffe352a907","tests/httpconn.rs":"87c32197258711d916cace23ed850c5bf0198f5e32756c68a32d91206b6e6db8","tests/priority.rs":"364754507873298612ad12e8d1d106d26d993712142d0be4cbf056da5338854c","tests/send_message.rs":"cdf7028eb64f8f3778c3bbb2a10e9482c4e995e9e1813143ccd83ec96b2d4b6a","tests/webtransport.rs":"02b81be0a20252a8bb0796b5287e426c1af5ddaf5a47d68aa9165393cba83c45"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-http3/Cargo.toml b/third_party/rust/neqo-http3/Cargo.toml index 276713164c..b732c6488d 100644 --- a/third_party/rust/neqo-http3/Cargo.toml +++ b/third_party/rust/neqo-http3/Cargo.toml @@ -9,12 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +bench = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-http3" version = "0.8.2" authors = ["The Neqo Authors "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -34,8 +43,26 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/mozilla/neqo/" [lib] +name = "neqo_http3" +path = "src/lib.rs" bench = false +[[test]] +name = "httpconn" +path = "tests/httpconn.rs" + +[[test]] +name = "priority" +path = "tests/priority.rs" + +[[test]] +name = "send_message" +path = "tests/send_message.rs" + +[[test]] +name = "webtransport" +path = "tests/webtransport.rs" + [dependencies.enumset] version = "1.1" default-features = false diff --git a/third_party/rust/neqo-qpack/.cargo-checksum.json b/third_party/rust/neqo-qpack/.cargo-checksum.json index 76e92256ec..eb92ce0e15 100644 --- a/third_party/rust/neqo-qpack/.cargo-checksum.json +++ b/third_party/rust/neqo-qpack/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"1eb162284c8ff5989adbd8dc2cb5e740163af130288c09471406549861b67703","src/decoder.rs":"ed2d6fa29e8726429aabb84e65f5d8025b320c0219b442b47c38903728ba3b2d","src/decoder_instructions.rs":"7e23ad00bcc6a1f0ee9af6c3d7f5ec5fcf11e9bc6cd895e125e3392c34b309e0","src/encoder.rs":"ebc9e82e5ad6b31be46ab876965d0e9dc710c4c5db084a631f384185b56cab36","src/encoder_instructions.rs":"5afc60ecc5b65f5b1908cff7eb3b7394c5c36cebe8ebfcdefbf792c827799390","src/header_block.rs":"1ea71fe2f588a0f96e39fd3a3157c66cc0ed2794f14c6f01b4a3069a43f7997b","src/huffman.rs":"6976f1b4d3e5ef849a6b080cfb2e8804bf01cfe3b9bd9e3994a319d5405cd8f3","src/huffman_decode_helper.rs":"9ce470e318b3664f58aa109bed483ab15bfd9e0b17d261ea2b609668a42a9d80","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"f9bad0fe7643c618d034c4941ebd30ad5f6015b8b87b484b0ea79681d13d8b49","src/prefix.rs":"d9ad12838d61b38dc2300948e3da01fd65371215edde1c370cf54ccd87d64d46","src/qlog.rs":"fbd96ef7d21db2bae19b8e379995544e8cf123e8e5129c1500ace2773acf5649","src/qpack_send_buf.rs":"48f8d0e011e0fb8e4bd0774279d3465e2be01fd9480eaf374ae2adada6be430d","src/reader.rs":"c23214ba190c7a59e416eaffac612ff8c2043c3a84e884fb10ae3bc112d884a5","src/static_table.rs":"6e5ec26e2b6bd63375d2d77e72748151d430d1629a8e497ec0d0ea21c078524a","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"2d2c9e6070a1e90048a4ad7c8279f9e1ce7615b44d7d8145fb0f140e554f5ca2"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"65733e28fe0e6be1fbffa77fea4ed32f38ffab469763a577434e003d05c74786","src/decoder.rs":"ed2d6fa29e8726429aabb84e65f5d8025b320c0219b442b47c38903728ba3b2d","src/decoder_instructions.rs":"7e23ad00bcc6a1f0ee9af6c3d7f5ec5fcf11e9bc6cd895e125e3392c34b309e0","src/encoder.rs":"ebc9e82e5ad6b31be46ab876965d0e9dc710c4c5db084a631f384185b56cab36","src/encoder_instructions.rs":"5afc60ecc5b65f5b1908cff7eb3b7394c5c36cebe8ebfcdefbf792c827799390","src/header_block.rs":"1ea71fe2f588a0f96e39fd3a3157c66cc0ed2794f14c6f01b4a3069a43f7997b","src/huffman.rs":"6976f1b4d3e5ef849a6b080cfb2e8804bf01cfe3b9bd9e3994a319d5405cd8f3","src/huffman_decode_helper.rs":"9ce470e318b3664f58aa109bed483ab15bfd9e0b17d261ea2b609668a42a9d80","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"f9bad0fe7643c618d034c4941ebd30ad5f6015b8b87b484b0ea79681d13d8b49","src/prefix.rs":"d9ad12838d61b38dc2300948e3da01fd65371215edde1c370cf54ccd87d64d46","src/qlog.rs":"fbd96ef7d21db2bae19b8e379995544e8cf123e8e5129c1500ace2773acf5649","src/qpack_send_buf.rs":"48f8d0e011e0fb8e4bd0774279d3465e2be01fd9480eaf374ae2adada6be430d","src/reader.rs":"c23214ba190c7a59e416eaffac612ff8c2043c3a84e884fb10ae3bc112d884a5","src/static_table.rs":"6e5ec26e2b6bd63375d2d77e72748151d430d1629a8e497ec0d0ea21c078524a","src/stats.rs":"624dfa3b40858c304097bb0ce5b1be1bb4d7916b1abfc222f1aa705907009730","src/table.rs":"2d2c9e6070a1e90048a4ad7c8279f9e1ce7615b44d7d8145fb0f140e554f5ca2"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-qpack/Cargo.toml b/third_party/rust/neqo-qpack/Cargo.toml index c0a442a520..05125f1843 100644 --- a/third_party/rust/neqo-qpack/Cargo.toml +++ b/third_party/rust/neqo-qpack/Cargo.toml @@ -9,12 +9,22 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-qpack" version = "0.8.2" authors = ["The Neqo Authors "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -37,6 +47,8 @@ repository = "https://github.com/mozilla/neqo/" ignored = ["log"] [lib] +name = "neqo_qpack" +path = "src/lib.rs" bench = false [dependencies.log] diff --git a/third_party/rust/neqo-transport/.cargo-checksum.json b/third_party/rust/neqo-transport/.cargo-checksum.json index b42660ac44..8841fd920b 100644 --- a/third_party/rust/neqo-transport/.cargo-checksum.json +++ b/third_party/rust/neqo-transport/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"366439f1df79904f7df071ccb2d257377a157e751943697087066ce1cbae81d6","benches/range_tracker.rs":"590dd1f81c92e89ce28af1efdda583d85240438bd9c4c68767286d22a299ad4b","benches/rx_stream_orderer.rs":"53a008357703251a18100521a12d8fa9443c5601ddc3cbd1b3c2899074da4c4f","benches/transfer.rs":"115c9c83700e934b27d7045b3b40ad574265aad93f7c52f446a815dafbb6c4ac","build.rs":"78ec79c93bf13c3a40ceef8bba1ea2eada61c8f2dfc15ea7bf117958d367949c","src/ackrate.rs":"a863ed4fe1cb5b8c7ebe687b5fb840ab1de1fc6b23e6f274e6b1335f1ba27386","src/addr_valid.rs":"db90730ae9db2c2004f125ffc4339acd7123637e90a5c6a171a107a8bc7e12f5","src/cc/classic_cc.rs":"a11b755fa615ee14a137ad5a75ec509507e85088f244d73f879b429b8992a0b1","src/cc/cubic.rs":"ffa8a6647a11ad6496d8a62de1affeccc0e2bae3f5b4e94b9385ca5cf4342c9c","src/cc/mod.rs":"1848991e5ccaaf4aede250f27c3d057c9a40386607fdfd77701f6908a4ffa27d","src/cc/new_reno.rs":"f438b5ab39413f8a9dad3575c6229bbae12140a316d8da34b5dcd9397551d5f7","src/cc/tests/cubic.rs":"47001e66071830c8ed8564d62cfb0cf76b7bcac53da1cc4f6487da21d4c0b2d6","src/cc/tests/mod.rs":"44f8df551e742ae1037cd1cdb85b2c1334c2e5ab3c23ed63d856dbc6b8743afc","src/cc/tests/new_reno.rs":"78fdeb60dd2ab34d5a1b8341e8adf5212d8dd9c589d9555e7e0263aefd481de6","src/cid.rs":"a0ee275ee0a29e12fe746725ed261abe7b60a8c2d4e9e1450fa545787110fe55","src/connection/dump.rs":"93184eb3b246ae42145fac4f3f925aa68800e4759470aeb35015ad7d3b6e041b","src/connection/idle.rs":"c240b966a5918689bbd85afac45803f5ae8d05bb5bc5c09775377a759bfcbd0c","src/connection/mod.rs":"ee1d7ad627873457c9610a5ccbe1238b6c0f67e6aa80bfcfbb170b0c5df53ace","src/connection/params.rs":"5323655e4cbc04be8187a9eeecb964968da3a6e38cd81c6cc443c98f2a1296c4","src/connection/saved.rs":"90201b1df2af9f9e2fd4f7b41e094e88c1aa67ff2983c371d54cc933d104c20f","src/connection/state.rs":"7cfc597f7f2cece945aa3a4056ca521921599516814e0bde080ccf84e7d27f23","src/connection/test_internal.rs":"f3ebfe97b25c9c716d41406066295e5aff4e96a3051ef4e2b5fb258282bbc14c","src/connection/tests/ackrate.rs":"4a2b835575850ae4a14209d3e51883ecb1e69afb44ef91b5e13a5e6cb7174fab","src/connection/tests/cc.rs":"2c8d31887c4523fdaf784df24c5367ee1287ffbee1ec88e64cf976c5d48b0587","src/connection/tests/close.rs":"5f245fd134bc0759ef0c83a6d53e0a8d5a8e58dcdf203c750ec9121940272461","src/connection/tests/datagram.rs":"6973fe4eecba79d88a3fe123ec773a29ee1a552a1262ff24b299aadd752f1814","src/connection/tests/ecn.rs":"4a9af2cd82b05217a9be496db163c7583f509a8e3a6020f705c1e9b49a80a487","src/connection/tests/handshake.rs":"fce8e2e6ac5d44a93c2ed62c7784f5e53fe1da8f201b05eeb0efba13431dec77","src/connection/tests/idle.rs":"2d588bd6570172ca08974931273b6c4645af3edca9ccac78499d7d2d5ecec86c","src/connection/tests/keys.rs":"e3e94f27b955934a501f3d7b3fd540d103507fe7e12400967a4880232e7bc561","src/connection/tests/migration.rs":"713ea55e21c006ca9202cdfcb043b8713888be504bfae4556843ac1abad298b3","src/connection/tests/mod.rs":"4c4246011aa191e0812613388d4bd9154c51c81a112a255c43d3fc9575f8000e","src/connection/tests/null.rs":"38f76a4ea15e6b11634d4374cb0f2a68bd250e5d35831edfce0fa48deeaa420d","src/connection/tests/priority.rs":"dc670911fa76784ecd946e4a2d95af769f3ff36a3607e4226eff8c5470f4c9e7","src/connection/tests/recovery.rs":"545d2c66697d9494a12acd09411d342c7ce035494a31a23ce8f54929085e95f2","src/connection/tests/resumption.rs":"1a0de0993cd325224fc79a3c094d22636d5b122ab1123d16265d4fafb23574bd","src/connection/tests/stream.rs":"3a6b23be63e1901ea479749d8132db86959279329121fe5d51b34c3fef4d4d05","src/connection/tests/vn.rs":"92f61cfe4ccbb88f4f7c14f0e791bdece5368012922714d3dbd6a75bedb1b5a1","src/connection/tests/zerortt.rs":"139f25b992ee6f7e3cc31448f81e511386bb3b0e6691180c7f616b70c4864883","src/crypto.rs":"2858eeba207612e2c3b91409b6ee540983b639d4a1afc2fa1ce1968abe144265","src/ecn.rs":"6012918ebd261eea0c51de0e82f772fd40db92c48468af8546fa1c85e5047787","src/events.rs":"3cdd7d5496b2745626db4ceb863b5a91ae943090a43a5816a1f9bcf873fba2be","src/fc.rs":"da0f04b327e6b4ff900bd1fd8c817c27a5a9f3b94c1f45840e96a3d1fd1e057f","src/frame.rs":"370b4655a5b9bc584470e4cbbe843f144c289c2e6dfe213eac484be6e71f40bd","src/lib.rs":"aad180ec0268e7269c935255bb6dd8dd794ec2415346f5466793eda055d20b83","src/pace.rs":"354bf09c0a88863af13fcfbb3381db4e780a983a3a967e97e1899e32d6e6250c","src/packet/mod.rs":"c7c9047c47b74cf48f9ff94c6635666ecefc5a32c746ee40a05e55b112a00919","src/packet/retry.rs":"4b515f6c04a5ce563494b592bdccf92bf31e9c361955279a66fb59908d0405fa","src/path.rs":"d6e687566d489d9b1fe5c079fde87822a02c02f0343dc911eac68b7afa195220","src/pmtud.rs":"bc99c308b6e3565ef16bf6cfe47fba5ecadec411806652ec32a5e0031571bd2e","src/qlog.rs":"bebd2ecb297be854d3350212a27f23a15d3645ace85928b1ea40bd12ae70ceee","src/quic_datagrams.rs":"501963dd367ff7b108ffa954287ea8a8dd5f140864034ef83b7048d8e7564c39","src/recovery/mod.rs":"384b42582a5045656f3c307e071db3ad18d2d311564e82104253ed5783956e5a","src/recovery/sent.rs":"a3e0ad13c468d93d1fc57e77928d02b6922dcdb3118d00c14acc0cea24d949a4","src/recovery/token.rs":"c1e4190c6733afd2bf5e60060d8ba3ab9fb136e02252e2480b281871a54d6066","src/recv_stream.rs":"b7c47bd3a3d950289cda48105f74079a1a951ef22d27f5d44613f9b3289d1bbb","src/rtt.rs":"465efa9d934ee8f4b512db27a7526dc5c329fc6d5ed98dad4b8f53e4c1dd39e7","src/send_stream.rs":"19a5b65bac4e56eb73ce705a854a48ae1f1e0ce75fa495c2d9995dc49bb625d8","src/sender.rs":"cdcbbf247c235f0bdb75686fa4bcf17a764cb1ab9aaa577e8997c36b4d2baada","src/server.rs":"2dc37e47ecd615ca8d6593313a176ceab6bfbc55602e8358bcd3dcd130ba0ce2","src/stats.rs":"196c936df3fad722295562ba190e5e5b0eb0da7118fdc17259d6a984ee961687","src/stream_id.rs":"f11a2a92a9620da288ae049fb14fe978a46554c90ed6fda66163f0565e5b3623","src/streams.rs":"3384df5bcfac64ea9f1e394d27aaa9e56dcccc5d446c6c69d28bb71847853592","src/tparams.rs":"da5392ca16f3e62d70760b8c4d9ee4bda782d62bdb6cda516f7b7b8765b195dd","src/tracking.rs":"2a919b0aa37ec639630efba28fedd8efc405c773a1c89f7cc8e900f875938bac","src/version.rs":"9147a7b83fac986f921b09f84222bbd6eec2c12daeed9270ba30d843a3c3dcc1","tests/common/mod.rs":"7e0d07c5e4a4214c172fb7e93123a6089f40f246d81fa69edee510e3af4d7f2a","tests/conn_vectors.rs":"997702f4d8b8fa3b987b33077a0eb325e968b25b61fb4703532f8d97e1d4c98c","tests/connection.rs":"9f85d2902e408d7b1a6387d704d5ecb8b8299d173f2b74ad6a612456c1dab875","tests/network.rs":"04921aa5af583e842e6d2176a898fbfea747e831bbe292b5ef8441eaf546b93a","tests/retry.rs":"0dfc9d0a07ea638f8d84aaf1ba766a0d26adea313a43068445988949990c9f98","tests/server.rs":"7f9c8f093a26ae61e2114688ddd10793ab0a1928d1a4eb1ad21c8648fd236b86"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"b31454a245d5ca4c2babd399e1af8c8da8d4b6aaa6ca964881f066d5658073de","benches/range_tracker.rs":"590dd1f81c92e89ce28af1efdda583d85240438bd9c4c68767286d22a299ad4b","benches/rx_stream_orderer.rs":"53a008357703251a18100521a12d8fa9443c5601ddc3cbd1b3c2899074da4c4f","benches/transfer.rs":"115c9c83700e934b27d7045b3b40ad574265aad93f7c52f446a815dafbb6c4ac","build.rs":"78ec79c93bf13c3a40ceef8bba1ea2eada61c8f2dfc15ea7bf117958d367949c","src/ackrate.rs":"a863ed4fe1cb5b8c7ebe687b5fb840ab1de1fc6b23e6f274e6b1335f1ba27386","src/addr_valid.rs":"db90730ae9db2c2004f125ffc4339acd7123637e90a5c6a171a107a8bc7e12f5","src/cc/classic_cc.rs":"a11b755fa615ee14a137ad5a75ec509507e85088f244d73f879b429b8992a0b1","src/cc/cubic.rs":"ffa8a6647a11ad6496d8a62de1affeccc0e2bae3f5b4e94b9385ca5cf4342c9c","src/cc/mod.rs":"1848991e5ccaaf4aede250f27c3d057c9a40386607fdfd77701f6908a4ffa27d","src/cc/new_reno.rs":"f438b5ab39413f8a9dad3575c6229bbae12140a316d8da34b5dcd9397551d5f7","src/cc/tests/cubic.rs":"47001e66071830c8ed8564d62cfb0cf76b7bcac53da1cc4f6487da21d4c0b2d6","src/cc/tests/mod.rs":"44f8df551e742ae1037cd1cdb85b2c1334c2e5ab3c23ed63d856dbc6b8743afc","src/cc/tests/new_reno.rs":"78fdeb60dd2ab34d5a1b8341e8adf5212d8dd9c589d9555e7e0263aefd481de6","src/cid.rs":"a0ee275ee0a29e12fe746725ed261abe7b60a8c2d4e9e1450fa545787110fe55","src/connection/dump.rs":"93184eb3b246ae42145fac4f3f925aa68800e4759470aeb35015ad7d3b6e041b","src/connection/idle.rs":"c240b966a5918689bbd85afac45803f5ae8d05bb5bc5c09775377a759bfcbd0c","src/connection/mod.rs":"ee1d7ad627873457c9610a5ccbe1238b6c0f67e6aa80bfcfbb170b0c5df53ace","src/connection/params.rs":"5323655e4cbc04be8187a9eeecb964968da3a6e38cd81c6cc443c98f2a1296c4","src/connection/saved.rs":"90201b1df2af9f9e2fd4f7b41e094e88c1aa67ff2983c371d54cc933d104c20f","src/connection/state.rs":"7cfc597f7f2cece945aa3a4056ca521921599516814e0bde080ccf84e7d27f23","src/connection/test_internal.rs":"f3ebfe97b25c9c716d41406066295e5aff4e96a3051ef4e2b5fb258282bbc14c","src/connection/tests/ackrate.rs":"4a2b835575850ae4a14209d3e51883ecb1e69afb44ef91b5e13a5e6cb7174fab","src/connection/tests/cc.rs":"2c8d31887c4523fdaf784df24c5367ee1287ffbee1ec88e64cf976c5d48b0587","src/connection/tests/close.rs":"5f245fd134bc0759ef0c83a6d53e0a8d5a8e58dcdf203c750ec9121940272461","src/connection/tests/datagram.rs":"6973fe4eecba79d88a3fe123ec773a29ee1a552a1262ff24b299aadd752f1814","src/connection/tests/ecn.rs":"4a9af2cd82b05217a9be496db163c7583f509a8e3a6020f705c1e9b49a80a487","src/connection/tests/handshake.rs":"fce8e2e6ac5d44a93c2ed62c7784f5e53fe1da8f201b05eeb0efba13431dec77","src/connection/tests/idle.rs":"2d588bd6570172ca08974931273b6c4645af3edca9ccac78499d7d2d5ecec86c","src/connection/tests/keys.rs":"e3e94f27b955934a501f3d7b3fd540d103507fe7e12400967a4880232e7bc561","src/connection/tests/migration.rs":"713ea55e21c006ca9202cdfcb043b8713888be504bfae4556843ac1abad298b3","src/connection/tests/mod.rs":"4c4246011aa191e0812613388d4bd9154c51c81a112a255c43d3fc9575f8000e","src/connection/tests/null.rs":"38f76a4ea15e6b11634d4374cb0f2a68bd250e5d35831edfce0fa48deeaa420d","src/connection/tests/priority.rs":"dc670911fa76784ecd946e4a2d95af769f3ff36a3607e4226eff8c5470f4c9e7","src/connection/tests/recovery.rs":"545d2c66697d9494a12acd09411d342c7ce035494a31a23ce8f54929085e95f2","src/connection/tests/resumption.rs":"1a0de0993cd325224fc79a3c094d22636d5b122ab1123d16265d4fafb23574bd","src/connection/tests/stream.rs":"3a6b23be63e1901ea479749d8132db86959279329121fe5d51b34c3fef4d4d05","src/connection/tests/vn.rs":"92f61cfe4ccbb88f4f7c14f0e791bdece5368012922714d3dbd6a75bedb1b5a1","src/connection/tests/zerortt.rs":"139f25b992ee6f7e3cc31448f81e511386bb3b0e6691180c7f616b70c4864883","src/crypto.rs":"2858eeba207612e2c3b91409b6ee540983b639d4a1afc2fa1ce1968abe144265","src/ecn.rs":"6012918ebd261eea0c51de0e82f772fd40db92c48468af8546fa1c85e5047787","src/events.rs":"3cdd7d5496b2745626db4ceb863b5a91ae943090a43a5816a1f9bcf873fba2be","src/fc.rs":"da0f04b327e6b4ff900bd1fd8c817c27a5a9f3b94c1f45840e96a3d1fd1e057f","src/frame.rs":"370b4655a5b9bc584470e4cbbe843f144c289c2e6dfe213eac484be6e71f40bd","src/lib.rs":"aad180ec0268e7269c935255bb6dd8dd794ec2415346f5466793eda055d20b83","src/pace.rs":"354bf09c0a88863af13fcfbb3381db4e780a983a3a967e97e1899e32d6e6250c","src/packet/mod.rs":"c7c9047c47b74cf48f9ff94c6635666ecefc5a32c746ee40a05e55b112a00919","src/packet/retry.rs":"4b515f6c04a5ce563494b592bdccf92bf31e9c361955279a66fb59908d0405fa","src/path.rs":"d6e687566d489d9b1fe5c079fde87822a02c02f0343dc911eac68b7afa195220","src/pmtud.rs":"bc99c308b6e3565ef16bf6cfe47fba5ecadec411806652ec32a5e0031571bd2e","src/qlog.rs":"bebd2ecb297be854d3350212a27f23a15d3645ace85928b1ea40bd12ae70ceee","src/quic_datagrams.rs":"501963dd367ff7b108ffa954287ea8a8dd5f140864034ef83b7048d8e7564c39","src/recovery/mod.rs":"384b42582a5045656f3c307e071db3ad18d2d311564e82104253ed5783956e5a","src/recovery/sent.rs":"a3e0ad13c468d93d1fc57e77928d02b6922dcdb3118d00c14acc0cea24d949a4","src/recovery/token.rs":"c1e4190c6733afd2bf5e60060d8ba3ab9fb136e02252e2480b281871a54d6066","src/recv_stream.rs":"b7c47bd3a3d950289cda48105f74079a1a951ef22d27f5d44613f9b3289d1bbb","src/rtt.rs":"465efa9d934ee8f4b512db27a7526dc5c329fc6d5ed98dad4b8f53e4c1dd39e7","src/send_stream.rs":"19a5b65bac4e56eb73ce705a854a48ae1f1e0ce75fa495c2d9995dc49bb625d8","src/sender.rs":"cdcbbf247c235f0bdb75686fa4bcf17a764cb1ab9aaa577e8997c36b4d2baada","src/server.rs":"2dc37e47ecd615ca8d6593313a176ceab6bfbc55602e8358bcd3dcd130ba0ce2","src/stats.rs":"196c936df3fad722295562ba190e5e5b0eb0da7118fdc17259d6a984ee961687","src/stream_id.rs":"f11a2a92a9620da288ae049fb14fe978a46554c90ed6fda66163f0565e5b3623","src/streams.rs":"3384df5bcfac64ea9f1e394d27aaa9e56dcccc5d446c6c69d28bb71847853592","src/tparams.rs":"da5392ca16f3e62d70760b8c4d9ee4bda782d62bdb6cda516f7b7b8765b195dd","src/tracking.rs":"2a919b0aa37ec639630efba28fedd8efc405c773a1c89f7cc8e900f875938bac","src/version.rs":"9147a7b83fac986f921b09f84222bbd6eec2c12daeed9270ba30d843a3c3dcc1","tests/common/mod.rs":"7e0d07c5e4a4214c172fb7e93123a6089f40f246d81fa69edee510e3af4d7f2a","tests/conn_vectors.rs":"997702f4d8b8fa3b987b33077a0eb325e968b25b61fb4703532f8d97e1d4c98c","tests/connection.rs":"9f85d2902e408d7b1a6387d704d5ecb8b8299d173f2b74ad6a612456c1dab875","tests/network.rs":"04921aa5af583e842e6d2176a898fbfea747e831bbe292b5ef8441eaf546b93a","tests/retry.rs":"0dfc9d0a07ea638f8d84aaf1ba766a0d26adea313a43068445988949990c9f98","tests/server.rs":"7f9c8f093a26ae61e2114688ddd10793ab0a1928d1a4eb1ad21c8648fd236b86"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-transport/Cargo.toml b/third_party/rust/neqo-transport/Cargo.toml index 28f4a77139..faa2736d9c 100644 --- a/third_party/rust/neqo-transport/Cargo.toml +++ b/third_party/rust/neqo-transport/Cargo.toml @@ -9,12 +9,20 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-transport" version = "0.8.2" authors = ["The Neqo Authors "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -34,20 +42,45 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/mozilla/neqo/" [lib] +name = "neqo_transport" +path = "src/lib.rs" bench = false +[[test]] +name = "conn_vectors" +path = "tests/conn_vectors.rs" + +[[test]] +name = "connection" +path = "tests/connection.rs" + +[[test]] +name = "network" +path = "tests/network.rs" + +[[test]] +name = "retry" +path = "tests/retry.rs" + +[[test]] +name = "server" +path = "tests/server.rs" + [[bench]] -name = "transfer" +name = "range_tracker" +path = "benches/range_tracker.rs" harness = false required-features = ["bench"] [[bench]] name = "rx_stream_orderer" +path = "benches/rx_stream_orderer.rs" harness = false required-features = ["bench"] [[bench]] -name = "range_tracker" +name = "transfer" +path = "benches/transfer.rs" harness = false required-features = ["bench"] diff --git a/third_party/rust/neqo-udp/.cargo-checksum.json b/third_party/rust/neqo-udp/.cargo-checksum.json index 84f2bcddf9..193cdbb121 100644 --- a/third_party/rust/neqo-udp/.cargo-checksum.json +++ b/third_party/rust/neqo-udp/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"9f2c2dd38c3b49a54b3551b3d27b69118dee1478ea4cf95d323519dfe5068321","src/lib.rs":"bf3bc79b1d799a42b73e64d2b203ce688cc0859d7afa6c66eec429ec36199ba6"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"2a0119d7971850169f74f1229c8cc2d9a0f69f6384ea4a1a0da4f1449574a5f2","src/lib.rs":"bf3bc79b1d799a42b73e64d2b203ce688cc0859d7afa6c66eec429ec36199ba6"},"package":null} \ No newline at end of file diff --git a/third_party/rust/neqo-udp/Cargo.toml b/third_party/rust/neqo-udp/Cargo.toml index 0efd021aef..82fb27e92f 100644 --- a/third_party/rust/neqo-udp/Cargo.toml +++ b/third_party/rust/neqo-udp/Cargo.toml @@ -9,12 +9,22 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" rust-version = "1.76.0" name = "neqo-udp" version = "0.8.2" authors = ["The Neqo Authors "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Neqo, the Mozilla implementation of QUIC in Rust." homepage = "https://github.com/mozilla/neqo/" readme = "../README.md" @@ -37,6 +47,8 @@ repository = "https://github.com/mozilla/neqo/" ignored = ["log"] [lib] +name = "neqo_udp" +path = "src/lib.rs" bench = false [dependencies.log] diff --git a/third_party/rust/nss_build_common/.cargo-checksum.json b/third_party/rust/nss_build_common/.cargo-checksum.json index 0905eb055a..9a9048be13 100644 --- a/third_party/rust/nss_build_common/.cargo-checksum.json +++ b/third_party/rust/nss_build_common/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"6597b6d5217376ab747534364a58958ddbb23ffda52045e68b610cd8f2dcdfd1","src/lib.rs":"cb149b57b95a240499decf1afbfa4e7854645f8729079f936a5e00dcc94edf24"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"b558dcc14ac2d6e25d669e6700f77a8d9e9b30d8fefecea01a703458273a4658","src/lib.rs":"cb149b57b95a240499decf1afbfa4e7854645f8729079f936a5e00dcc94edf24"},"package":null} \ No newline at end of file diff --git a/third_party/rust/nss_build_common/Cargo.toml b/third_party/rust/nss_build_common/Cargo.toml index d0c8163496..286c4f9337 100644 --- a/third_party/rust/nss_build_common/Cargo.toml +++ b/third_party/rust/nss_build_common/Cargo.toml @@ -9,11 +9,26 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "nss_build_common" version = "0.1.0" authors = ["Thom Chiovoloni "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" +[lib] +name = "nss_build_common" +path = "src/lib.rs" + [dependencies] diff --git a/third_party/rust/payload-support/.cargo-checksum.json b/third_party/rust/payload-support/.cargo-checksum.json index 9c866d3a62..644ce833df 100644 --- a/third_party/rust/payload-support/.cargo-checksum.json +++ b/third_party/rust/payload-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"93e4aa75876fdbc1bb2e3db74a7723e5bdedcf55a11501105dae1ceb3b644b11","src/lib.rs":"79dc9e049ea9a09ab811869dcca06b396ffd6c349f6d3f726811ffda58070c5e"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"bae819bed31efd22e8c13b36381d60a7bdc2d1386f0552453277210232f0104c","src/lib.rs":"79dc9e049ea9a09ab811869dcca06b396ffd6c349f6d3f726811ffda58070c5e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/payload-support/Cargo.toml b/third_party/rust/payload-support/Cargo.toml index aba1471ff1..50fe79fd62 100644 --- a/third_party/rust/payload-support/Cargo.toml +++ b/third_party/rust/payload-support/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "payload-support" version = "0.1.0" authors = ["Sync Team "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" +[lib] +name = "payload_support" +path = "src/lib.rs" + [dependencies] serde = "1" serde_derive = "1" diff --git a/third_party/rust/pulse-ffi/.cargo-checksum.json b/third_party/rust/pulse-ffi/.cargo-checksum.json index 983fc390eb..c500a03da9 100644 --- a/third_party/rust/pulse-ffi/.cargo-checksum.json +++ b/third_party/rust/pulse-ffi/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"96983752046f2988087a836546a02aba746cdd1fc3ccd16f4170460465de5e63","src/ffi_funcs.rs":"a16646c5e7c49e94b907a7a404cfcadf3007688005c689cca936f0c2ee2e28e6","src/ffi_types.rs":"2ca56bc3638a40d331e53117a5dd175d0a6e102b1e0eccb9c2adc565c6861a33","src/lib.rs":"6aff308de11954a067d0f6ef95bf3126aabb6d928a5191e91d9a38ebadba91c2"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"316a9caaafc5301e57495e98660ca59050fc451250f8089f38fa588ac344c34c","src/ffi_funcs.rs":"a16646c5e7c49e94b907a7a404cfcadf3007688005c689cca936f0c2ee2e28e6","src/ffi_types.rs":"2ca56bc3638a40d331e53117a5dd175d0a6e102b1e0eccb9c2adc565c6861a33","src/lib.rs":"6aff308de11954a067d0f6ef95bf3126aabb6d928a5191e91d9a38ebadba91c2"},"package":null} \ No newline at end of file diff --git a/third_party/rust/pulse-ffi/Cargo.toml b/third_party/rust/pulse-ffi/Cargo.toml index 6f84948b42..4a41c99ad7 100644 --- a/third_party/rust/pulse-ffi/Cargo.toml +++ b/third_party/rust/pulse-ffi/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] name = "pulse-ffi" version = "0.1.0" authors = ["Dan Glastonbury "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "FFI for libpulse.so supporting static linking and dynamic loading." +readme = false license = "ISC" +[lib] +name = "pulse_ffi" +path = "src/lib.rs" + [dependencies] libc = "^0.2.20" diff --git a/third_party/rust/pulse/.cargo-checksum.json b/third_party/rust/pulse/.cargo-checksum.json index bb4198b1fd..5fb80d16b4 100644 --- a/third_party/rust/pulse/.cargo-checksum.json +++ b/third_party/rust/pulse/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"630a54435ea8717b2e6ede25b38c97d1dc86b7c0b70e7e14adf9cb392b41e3b1","src/context.rs":"849333d1d3b443700ea13e07696c68b3fe7ad3c4ee136b17ea888c494e871812","src/error.rs":"7cca3f0b0a238743db01d707881eee0c7b5b2ba530d579b6a2bd82bc8dd7dd30","src/lib.rs":"37edfc5ddfaf0a9442f69ca0139a652627f88f7ce68f245ae7f967ce2ba66dc1","src/mainloop_api.rs":"6374f8f62233277f4cf460b9978db0347a8829eb04f62101eaaa5533b6aca769","src/operation.rs":"c0d3e28ef7db52d60b19f931fe7bb44271127009b2e82693da2b7e342e804022","src/proplist.rs":"ce53f1e92fae51727aa564d371b1e0d59078f5cbbd655b39bc1c7741c8ba2f87","src/stream.rs":"ba14551ff34f6b23e94e450384487b3c35be75ac4456c22c14b36ade23282978","src/threaded_mainloop.rs":"057928b5b84b1ea8c839150840ccd88cb944b60ca0aa2ec5389aaa6676c8e505","src/util.rs":"1613909f460eb008b282801ac803dd28b4bfe59926c14fe030da6482fdacd70f"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"ddfbc40844852a4db3e6ee6b4e95cfcf5dc129a66ae8c7d3ab81365d99d701b5","src/context.rs":"849333d1d3b443700ea13e07696c68b3fe7ad3c4ee136b17ea888c494e871812","src/error.rs":"7cca3f0b0a238743db01d707881eee0c7b5b2ba530d579b6a2bd82bc8dd7dd30","src/lib.rs":"37edfc5ddfaf0a9442f69ca0139a652627f88f7ce68f245ae7f967ce2ba66dc1","src/mainloop_api.rs":"6374f8f62233277f4cf460b9978db0347a8829eb04f62101eaaa5533b6aca769","src/operation.rs":"c0d3e28ef7db52d60b19f931fe7bb44271127009b2e82693da2b7e342e804022","src/proplist.rs":"ce53f1e92fae51727aa564d371b1e0d59078f5cbbd655b39bc1c7741c8ba2f87","src/stream.rs":"ba14551ff34f6b23e94e450384487b3c35be75ac4456c22c14b36ade23282978","src/threaded_mainloop.rs":"057928b5b84b1ea8c839150840ccd88cb944b60ca0aa2ec5389aaa6676c8e505","src/util.rs":"1613909f460eb008b282801ac803dd28b4bfe59926c14fe030da6482fdacd70f"},"package":null} \ No newline at end of file diff --git a/third_party/rust/pulse/Cargo.toml b/third_party/rust/pulse/Cargo.toml index 230b838fde..62284f4641 100644 --- a/third_party/rust/pulse/Cargo.toml +++ b/third_party/rust/pulse/Cargo.toml @@ -9,12 +9,27 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] name = "pulse" version = "0.3.0" authors = ["Dan Glastonbury "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "ISC" +[lib] +name = "pulse" +path = "src/lib.rs" + [dependencies] bitflags = "2" diff --git a/third_party/rust/relevancy/.cargo-checksum.json b/third_party/rust/relevancy/.cargo-checksum.json index 2bf0156606..88f839ffb1 100644 --- a/third_party/rust/relevancy/.cargo-checksum.json +++ b/third_party/rust/relevancy/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"970c64cc4ed32fddac6b8cc2a83e7eb4e57aa249b8034d2d67cb56efa8475522","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"84fa47dc54f113769ce9ec6f827c8813abed61d5e5fc82404816266703a5c668","src/error.rs":"bda332098f9759e4250c725b09d82704ba03c9ad87dc761414fa21f40220acf5","src/ingest.rs":"58bb3ed984aa5a9becb405793832e578586be744d3c4a1c411fdfb7ff48c55dd","src/interest.rs":"73baa578b40b96d13899016b14087c9ac37b754c1311e2798b1d09c719447751","src/lib.rs":"214fdbeb25e0753ef132245e6892d77cad0ddd87c96d9bdd7f3427bc5d11091e","src/relevancy.udl":"9f463bbc2a7ef28358ffbfe832e62ddd6127888c484576466c759b127a55c4b2","src/rs.rs":"cff2351c9e1b45bb67ee945650fd74b45ed48815851e58b8dbf39e66a30c10a3","src/schema.rs":"919f4d1d3654bad966c5ce93ac157dc17cac2f35e7b8c2efc471b9af562555db","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"836ed62b1d856eb26b77f53d493585c7db861a12ba77eb481591c332cb9e8c18","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"84fa47dc54f113769ce9ec6f827c8813abed61d5e5fc82404816266703a5c668","src/error.rs":"bda332098f9759e4250c725b09d82704ba03c9ad87dc761414fa21f40220acf5","src/ingest.rs":"58bb3ed984aa5a9becb405793832e578586be744d3c4a1c411fdfb7ff48c55dd","src/interest.rs":"73baa578b40b96d13899016b14087c9ac37b754c1311e2798b1d09c719447751","src/lib.rs":"214fdbeb25e0753ef132245e6892d77cad0ddd87c96d9bdd7f3427bc5d11091e","src/relevancy.udl":"9f463bbc2a7ef28358ffbfe832e62ddd6127888c484576466c759b127a55c4b2","src/rs.rs":"cff2351c9e1b45bb67ee945650fd74b45ed48815851e58b8dbf39e66a30c10a3","src/schema.rs":"919f4d1d3654bad966c5ce93ac157dc17cac2f35e7b8c2efc471b9af562555db","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null} \ No newline at end of file diff --git a/third_party/rust/relevancy/Cargo.toml b/third_party/rust/relevancy/Cargo.toml index 46966beb19..cae166b377 100644 --- a/third_party/rust/relevancy/Cargo.toml +++ b/third_party/rust/relevancy/Cargo.toml @@ -9,20 +9,33 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "relevancy" version = "0.1.0" +build = "build.rs" exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" [lib] +name = "relevancy" +path = "src/lib.rs" [[bin]] name = "generate-test-data" +path = "src/bin/generate-test-data.rs" [dependencies] anyhow = "1.0" @@ -33,7 +46,6 @@ parking_lot = ">=0.11,<=0.12" serde_json = "1" serde_path_to_error = "0.1" thiserror = "1.0" -uniffi = "0.27.1" url = "2.5" [dependencies.error-support] @@ -56,6 +68,9 @@ features = ["derive"] [dependencies.sql-support] path = "../support/sql" +[dependencies.uniffi] +version = "0.27.1" + [build-dependencies.uniffi] version = "0.27.1" features = ["build"] diff --git a/third_party/rust/remote_settings/.cargo-checksum.json b/third_party/rust/remote_settings/.cargo-checksum.json index 77a9c784a4..dd17c17d5a 100644 --- a/third_party/rust/remote_settings/.cargo-checksum.json +++ b/third_party/rust/remote_settings/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"15a6e0298dd7d708f4aa8514e218925c1f013c66cb117b12e19148d051fd5de5","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/cache.rs":"9c16f17353730103d57132a0f055863b085d2d3eb3a78f6a6f8d095f897d0c0d","src/client.rs":"1c589317907d21745e945dfd992c11535aaafcaca9a6ebe33a5a7c2e2cb93997","src/config.rs":"52a209256acd8b1fada2b91e9d9f669df0ee6e9609baad7ec34a2111ed2a6541","src/error.rs":"4bb15cd7f6ebc438119f36291ab0eb951fe2fb05e166445817cb05aa89397000","src/lib.rs":"ff1b9f66ae6069005d36c84b296f22424b4305a5873353e351fbe057f126e140","src/remote_settings.udl":"1ffeb10385e4db63606cda79bb59e77170af1d2ca0028da8ab2c4d7622969734","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"fc7859a498493f1ede9c5c62b857ec76e3e9e8097cfd8c4f3d779f268b250303","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/cache.rs":"9c16f17353730103d57132a0f055863b085d2d3eb3a78f6a6f8d095f897d0c0d","src/client.rs":"1c589317907d21745e945dfd992c11535aaafcaca9a6ebe33a5a7c2e2cb93997","src/config.rs":"52a209256acd8b1fada2b91e9d9f669df0ee6e9609baad7ec34a2111ed2a6541","src/error.rs":"4bb15cd7f6ebc438119f36291ab0eb951fe2fb05e166445817cb05aa89397000","src/lib.rs":"ff1b9f66ae6069005d36c84b296f22424b4305a5873353e351fbe057f126e140","src/remote_settings.udl":"1ffeb10385e4db63606cda79bb59e77170af1d2ca0028da8ab2c4d7622969734","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null} \ No newline at end of file diff --git a/third_party/rust/remote_settings/Cargo.toml b/third_party/rust/remote_settings/Cargo.toml index 105cc298cc..87cd8467cf 100644 --- a/third_party/rust/remote_settings/Cargo.toml +++ b/third_party/rust/remote_settings/Cargo.toml @@ -9,6 +9,11 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "remote_settings" @@ -17,25 +22,37 @@ authors = [ "The Android Mobile Team ", "The Glean Team ", ] +build = "build.rs" exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "A Remote Settings client intended for application layer platforms." +readme = false license = "MPL-2.0" +[lib] +name = "remote_settings" +path = "src/lib.rs" + [dependencies] log = "0.4" parking_lot = "0.12" serde_json = "1" thiserror = "1.0" -uniffi = "0.27.1" url = "2.1" [dependencies.serde] version = "1" features = ["derive"] +[dependencies.uniffi] +version = "0.27.1" + [dependencies.viaduct] path = "../viaduct" diff --git a/third_party/rust/sql-support/.cargo-checksum.json b/third_party/rust/sql-support/.cargo-checksum.json index fe493e9e4c..e7dcefbefb 100644 --- a/third_party/rust/sql-support/.cargo-checksum.json +++ b/third_party/rust/sql-support/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"6765229acc1f06326b3ede93379d78d119aa78679567baf0bf7bdb5ec310522f","src/conn_ext.rs":"7c4ea787532733772cc840ecab47153d14533279351d9aa16cb5becec8b2345b","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"e900a4ebadad31b0a87cb8d7c3ed5aeb7325d4d380ae1d9174eff62c78facdcc","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"b2c120db4928c3e4abdd96405fd4c1016255699bdbc38c8cd60dbd3431fc0a12","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"b0f748ae88739db9e706a1f7f3d5b02769e689df59ff8ef2e894f2b503f80c70","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"9d67163fec61fa4d37207e55ab0119370005a3c2272e66d4e534ece5f4ecdda8","src/conn_ext.rs":"7c4ea787532733772cc840ecab47153d14533279351d9aa16cb5becec8b2345b","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"e900a4ebadad31b0a87cb8d7c3ed5aeb7325d4d380ae1d9174eff62c78facdcc","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"b2c120db4928c3e4abdd96405fd4c1016255699bdbc38c8cd60dbd3431fc0a12","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"b0f748ae88739db9e706a1f7f3d5b02769e689df59ff8ef2e894f2b503f80c70","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null} \ No newline at end of file diff --git a/third_party/rust/sql-support/Cargo.toml b/third_party/rust/sql-support/Cargo.toml index b4b674e89a..9da2f3b035 100644 --- a/third_party/rust/sql-support/Cargo.toml +++ b/third_party/rust/sql-support/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "sql-support" version = "0.1.0" authors = ["Thom Chiovoloni "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" +[lib] +name = "sql_support" +path = "src/lib.rs" + [dependencies] ffi-support = "0.4" lazy_static = "1.4" diff --git a/third_party/rust/suggest/.cargo-checksum.json b/third_party/rust/suggest/.cargo-checksum.json index 9bf1f95bec..13b82eaa2c 100644 --- a/third_party/rust/suggest/.cargo-checksum.json +++ b/third_party/rust/suggest/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"2f909cd4eaff25732d1a7c9193d4f8f98348c6933da521c69c34de7bb3a48dff","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"3582f21af9758766ff32ed95f90b69984b32091b1e31e0c0bef307c22fd82f18","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"3b92c350ad396b0e0b5438c7b7b94b08b322702f419ca9b815e6732bd174f8a1","src/benchmarks/ingest.rs":"ca368573591519e6b777d659d5615718bedb6eee1734e25242627f8116b10881","src/benchmarks/mod.rs":"2d7c20d47d6c7e17bc738255a31119bd0c4a4e495419a00c7b10b251ace9ef6b","src/benchmarks/query.rs":"0cac34ce895dd810513b30113b2608fecaece560c74a3286af55e3554f7a7b5a","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"d40c6e83d8b5faa32c66110803ca9e78611d43507e9d3f1e191a93a7773c37b3","src/db.rs":"1fbcdcc2e99692024fcb8a85aafa9dacb35d83703ce509bea1d0c694d379ceb2","src/error.rs":"183a92511565439915275e0705e6740ff513c2549f2ef78fd3055d8aaaf81021","src/fakespot.rs":"03d3aac07b3a3a9ceb8d2c452d4a122bfebf04579829e62e83487877055312d4","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"455e7ca3cf1c95e04ac567e147a906a07df3e7d548546db399370e3fac3f94c9","src/metrics.rs":"b3b9816b8eda366f808b56e242ac6aa43a5b141ad01d43420fdfcbfca13e1cfc","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"922ff68a4a49da637982d7b480651acf507197f62e0c0a04fce7237c243dc5e2","src/query.rs":"d9a26c024b8ac19ba0dbd6068a3bab881fa60928ecbac080bae80b8cbd2d5320","src/rs.rs":"81c11647b9ee4e52925b98e21adfd7c5c053846918500927502c41850f8f8a09","src/schema.rs":"2f4b0fbf0fd931c1cafa3be8dbddb9791c402125807b687d0bcf4d23b52743fc","src/store.rs":"a848bfbe254e83a6bb9a958a25984357ddb02d679af010cf170cb2498b3c1cd7","src/suggest.udl":"5eedf30402ed121e7f5b052782a55f64d7ca7a690901cd87f657a48f5206228b","src/suggestion.rs":"e24d951b564905f5bcd9b230a28fec78cbd4c29f8ef46bec014b06219902e3f3","src/testing/client.rs":"f059e844f336fd45fe4a335c67779558a98796d86f9ec0f43f96e6a0a6309f69","src/testing/data.rs":"d4fc5227996a8b115d93243fdbd83bc57d73a8c2d4c0b20dffa15bbec27925cb","src/testing/mod.rs":"b6ad90bb951fe0233493a7a1625f9979b6b8a946c5e027342ec25caeb5d1fed9","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"b6f48d7892872e05decf3ce4e4198f4481c753fbb74384d9cbc18b4fe1affd12","README.md":"5e28baf874b643d756228bdab345e287bf107d3182dfe6a18aafadcc4b9a3fc9","benches/benchmark_all.rs":"3582f21af9758766ff32ed95f90b69984b32091b1e31e0c0bef307c22fd82f18","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","metrics.yaml":"0540ab2271aeab7f07335c7ceec12acde942995f9dcb3c29070489aa61899d56","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"3b92c350ad396b0e0b5438c7b7b94b08b322702f419ca9b815e6732bd174f8a1","src/benchmarks/ingest.rs":"ca368573591519e6b777d659d5615718bedb6eee1734e25242627f8116b10881","src/benchmarks/mod.rs":"2d7c20d47d6c7e17bc738255a31119bd0c4a4e495419a00c7b10b251ace9ef6b","src/benchmarks/query.rs":"0cac34ce895dd810513b30113b2608fecaece560c74a3286af55e3554f7a7b5a","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"d40c6e83d8b5faa32c66110803ca9e78611d43507e9d3f1e191a93a7773c37b3","src/db.rs":"1fbcdcc2e99692024fcb8a85aafa9dacb35d83703ce509bea1d0c694d379ceb2","src/error.rs":"183a92511565439915275e0705e6740ff513c2549f2ef78fd3055d8aaaf81021","src/fakespot.rs":"03d3aac07b3a3a9ceb8d2c452d4a122bfebf04579829e62e83487877055312d4","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"455e7ca3cf1c95e04ac567e147a906a07df3e7d548546db399370e3fac3f94c9","src/metrics.rs":"b3b9816b8eda366f808b56e242ac6aa43a5b141ad01d43420fdfcbfca13e1cfc","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"922ff68a4a49da637982d7b480651acf507197f62e0c0a04fce7237c243dc5e2","src/query.rs":"d9a26c024b8ac19ba0dbd6068a3bab881fa60928ecbac080bae80b8cbd2d5320","src/rs.rs":"81c11647b9ee4e52925b98e21adfd7c5c053846918500927502c41850f8f8a09","src/schema.rs":"2f4b0fbf0fd931c1cafa3be8dbddb9791c402125807b687d0bcf4d23b52743fc","src/store.rs":"a848bfbe254e83a6bb9a958a25984357ddb02d679af010cf170cb2498b3c1cd7","src/suggest.udl":"5eedf30402ed121e7f5b052782a55f64d7ca7a690901cd87f657a48f5206228b","src/suggestion.rs":"e24d951b564905f5bcd9b230a28fec78cbd4c29f8ef46bec014b06219902e3f3","src/testing/client.rs":"f059e844f336fd45fe4a335c67779558a98796d86f9ec0f43f96e6a0a6309f69","src/testing/data.rs":"d4fc5227996a8b115d93243fdbd83bc57d73a8c2d4c0b20dffa15bbec27925cb","src/testing/mod.rs":"b6ad90bb951fe0233493a7a1625f9979b6b8a946c5e027342ec25caeb5d1fed9","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null} \ No newline at end of file diff --git a/third_party/rust/suggest/Cargo.toml b/third_party/rust/suggest/Cargo.toml index bac8ef4441..3097d8bed7 100644 --- a/third_party/rust/suggest/Cargo.toml +++ b/third_party/rust/suggest/Cargo.toml @@ -9,28 +9,40 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +example = [] +test = [] + [package] edition = "2021" name = "suggest" version = "0.1.0" +build = "build.rs" exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Manages sponsored and web suggestions for Firefox Suggest" readme = "README.md" license = "MPL-2.0" [lib] +name = "suggest" +path = "src/lib.rs" bench = false [[bin]] name = "debug_ingestion_sizes" +path = "src/bin/debug_ingestion_sizes.rs" bench = false required-features = ["benchmark_api"] [[bench]] name = "benchmark_all" +path = "benches/benchmark_all.rs" harness = false required-features = ["benchmark_api"] @@ -44,7 +56,6 @@ parking_lot = ">=0.11,<=0.12" rmp-serde = "1.3" serde_json = "1" thiserror = "1" -uniffi = "0.27.1" [dependencies.error-support] path = "../support/error" @@ -74,6 +85,9 @@ path = "../support/sql" version = "3.2.0" optional = true +[dependencies.uniffi] +version = "0.27.1" + [dependencies.url] version = "2.1" features = ["serde"] diff --git a/third_party/rust/sync-guid/.cargo-checksum.json b/third_party/rust/sync-guid/.cargo-checksum.json index c7d6321a7c..5e6ba76fff 100644 --- a/third_party/rust/sync-guid/.cargo-checksum.json +++ b/third_party/rust/sync-guid/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f64f49761ff16c3504292455d4a94f34456ce1605a545a7e8d53bddb12f581e4","src/lib.rs":"a112b66270feba587d0b09e64b4197af01f981675a23f76649a7d948f85c2bd9","src/rusqlite_support.rs":"c6791f103c286858a1a6e2c7e106b177ed8d9196b73ed100a8bb0aec1b1f957f","src/serde_support.rs":"99668580adb3c28ee7d3ae00ad4cf52e297aec3eeeaed11b200fa8c7e17319f1"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"0a80200ef5a1a1a15f0b1dfd424c6ab3ace7cc226bb0d31e5c3f05ba828c94db","src/lib.rs":"a112b66270feba587d0b09e64b4197af01f981675a23f76649a7d948f85c2bd9","src/rusqlite_support.rs":"c6791f103c286858a1a6e2c7e106b177ed8d9196b73ed100a8bb0aec1b1f957f","src/serde_support.rs":"99668580adb3c28ee7d3ae00ad4cf52e297aec3eeeaed11b200fa8c7e17319f1"},"package":null} \ No newline at end of file diff --git a/third_party/rust/sync-guid/Cargo.toml b/third_party/rust/sync-guid/Cargo.toml index d9302be079..d03b757f04 100644 --- a/third_party/rust/sync-guid/Cargo.toml +++ b/third_party/rust/sync-guid/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "sync-guid" version = "0.1.0" authors = ["Thom Chiovoloni "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" +[lib] +name = "sync_guid" +path = "src/lib.rs" + [dependencies.base64] version = "0.21" optional = true diff --git a/third_party/rust/sync15/.cargo-checksum.json b/third_party/rust/sync15/.cargo-checksum.json index 7a5e913cc9..fa8171bc74 100644 --- a/third_party/rust/sync15/.cargo-checksum.json +++ b/third_party/rust/sync15/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"a80fd7eab7dfcb3767d8f959fa6e10cdb109d3bfa9634902617e783ca02b02ef","README.md":"6d4ff5b079ac5340d18fa127f583e7ad793c5a2328b8ecd12c3fc723939804f2","build.rs":"aa971160d67ce8626b26e15c04c34b730f594c45c817aae34cfc9f3ea14ae284","src/bso/content.rs":"92935258745bdf0c3915a555cb6884a7fa69faa1290ec2c1815f6e2f3c0f0562","src/bso/crypto.rs":"27602dcccb37d3a55620ee4e16b705da455d49af575de115c7c79c0178eb1d6d","src/bso/mod.rs":"09e723dc7e99295ecafdcadffaf604d66ea27cf2b7f1fd9ab3cac4f4698ff6a7","src/bso/test_utils.rs":"4ec5a2df5e1c0ec14dc770681e959bdcef6ef04f6fde435999197f46a8ae4831","src/client/coll_state.rs":"13e6ef55273baf5536acc369be522e34a803a32cabf19cce43e426aea9b6223e","src/client/coll_update.rs":"dac04a90c29dd969f8b4250414609c9b6d61daf2dfa4ae77d1c4a165ba970b05","src/client/collection_keys.rs":"c27b2277a3a52033b58ab01490fc2ea7007494195dd5e6dc2c6931a4ca96795a","src/client/mod.rs":"8f588d4a035cf79d96f2500f06d5651c1a7c566127c456ffa5429811ddce3fd6","src/client/request.rs":"e878c5b43298b6eb682748474963f9fb8d053b4dc690bbb27107f5fa0ee74e01","src/client/state.rs":"4e31193ef2471c1dfabf1c6a391bcb95e14ddb45855786a4194ff187d5c9347c","src/client/status.rs":"f445a8765dac9789444e23b5145148413407bb1d18a15ef56682243997f591bf","src/client/storage_client.rs":"cc4a3219f342f8665399734902f68a2ddf12ed7e3726033ed10084bcefb66ffd","src/client/sync.rs":"b29abb512ec9d163f7883b71f78c9202802dcb17cad1fc5dc08087fb0bb66704","src/client/sync_multiple.rs":"6e92571132f89744b553190c596be8aff9b2d031d8f79d82c94cdf78b1683f4a","src/client/token.rs":"13729c693c8be72bcafc816c97e2a35932d008b4f2ccda6a5f8cdb8b2c99a293","src/client/util.rs":"71cc70ee41f821f53078675e636e9fad9c6046fa1a989e37f5487e340a2277d6","src/client_types.rs":"3c3cac1540b92482f43660d9e43bdde8481c4cc1a98253a68c80e791231f5976","src/clients_engine/engine.rs":"9e11b47be81fc63214f31879af74075674aa50a8f8989afe20fefa7990fa99b9","src/clients_engine/mod.rs":"461729e6f89b66b2cbd89b041a03d4d6a8ba582284ed4f3015cb13e1a0c6da97","src/clients_engine/record.rs":"b0d84bf420743d7638a45e4836633a45e50257d5548fe7ecd04bff4d724439b8","src/clients_engine/ser.rs":"be6a19c45eb8002ff8e7cf746d2f97d9cecd1740f9817a8f1d624825475fd777","src/device_type.rs":"dc2d4296d25e31471c8e68488f1043ff239b902036cd6aea8a686cf79b4ed335","src/enc_payload.rs":"aa3eea7df49b24cd59831680a47c417b73a3e36e6b0f3f4baf14ca66bd68be6b","src/engine/bridged_engine.rs":"b4e3071a0259ac55303364e57f9cd685916b80dc302030bba07790e55ceecb66","src/engine/mod.rs":"90f1f9760f5f712a337aebb04e59c736e4b6fbd89d6a188d969210c7f3f321ae","src/engine/request.rs":"5923025fb9550178339f880a1bf8526d8e853e7a0b2bce6d9d687cc808ac0085","src/engine/sync_engine.rs":"531b35d72ce9e04c3e543c0468c1e450fba2c0dc3d33d68d9b1c0a5c1ad7dd34","src/error.rs":"a45cfe02e6301f473c34678b694943c1a04308b8c292c6e0448bf495194c3b5e","src/key_bundle.rs":"abd0781f3be8c8e7c691f18bb71f3433b633803c48da9794e15ac6301ed60d6c","src/lib.rs":"f59f8817978d943518dfa03ab31fc0f6b1fc72ee9943a97aef1537e2769649f5","src/record_types.rs":"02bb3d352fb808131d298f9b90d9c95b7e9e0138b97c5401f3b9fdacc5562f44","src/server_timestamp.rs":"63916817796e83fe31fbd598bac025dfa71ec9e1808d09073db258c78a3331cd","src/sync15.udl":"005b2b056b93c959a04670f6f489afecb8e17093d8e4be34765a3a4cc0faeb8c","src/telemetry.rs":"1d06433aafe05b8d0c403ff6cb3bb35eec292f2cd6273d321eaa196fb6584dd6","uniffi.toml":"34488f947497a9b05007445dd816024ef02e6b1696f1056ee868f039722828ee"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"3cacaf0a05825c2bc79d3ea3b12580301ef056d40d2bc5b2546de99d306ef242","README.md":"6d4ff5b079ac5340d18fa127f583e7ad793c5a2328b8ecd12c3fc723939804f2","build.rs":"aa971160d67ce8626b26e15c04c34b730f594c45c817aae34cfc9f3ea14ae284","src/bso/content.rs":"92935258745bdf0c3915a555cb6884a7fa69faa1290ec2c1815f6e2f3c0f0562","src/bso/crypto.rs":"27602dcccb37d3a55620ee4e16b705da455d49af575de115c7c79c0178eb1d6d","src/bso/mod.rs":"09e723dc7e99295ecafdcadffaf604d66ea27cf2b7f1fd9ab3cac4f4698ff6a7","src/bso/test_utils.rs":"4ec5a2df5e1c0ec14dc770681e959bdcef6ef04f6fde435999197f46a8ae4831","src/client/coll_state.rs":"13e6ef55273baf5536acc369be522e34a803a32cabf19cce43e426aea9b6223e","src/client/coll_update.rs":"dac04a90c29dd969f8b4250414609c9b6d61daf2dfa4ae77d1c4a165ba970b05","src/client/collection_keys.rs":"c27b2277a3a52033b58ab01490fc2ea7007494195dd5e6dc2c6931a4ca96795a","src/client/mod.rs":"8f588d4a035cf79d96f2500f06d5651c1a7c566127c456ffa5429811ddce3fd6","src/client/request.rs":"e878c5b43298b6eb682748474963f9fb8d053b4dc690bbb27107f5fa0ee74e01","src/client/state.rs":"4e31193ef2471c1dfabf1c6a391bcb95e14ddb45855786a4194ff187d5c9347c","src/client/status.rs":"f445a8765dac9789444e23b5145148413407bb1d18a15ef56682243997f591bf","src/client/storage_client.rs":"cc4a3219f342f8665399734902f68a2ddf12ed7e3726033ed10084bcefb66ffd","src/client/sync.rs":"b29abb512ec9d163f7883b71f78c9202802dcb17cad1fc5dc08087fb0bb66704","src/client/sync_multiple.rs":"6e92571132f89744b553190c596be8aff9b2d031d8f79d82c94cdf78b1683f4a","src/client/token.rs":"13729c693c8be72bcafc816c97e2a35932d008b4f2ccda6a5f8cdb8b2c99a293","src/client/util.rs":"71cc70ee41f821f53078675e636e9fad9c6046fa1a989e37f5487e340a2277d6","src/client_types.rs":"3c3cac1540b92482f43660d9e43bdde8481c4cc1a98253a68c80e791231f5976","src/clients_engine/engine.rs":"9e11b47be81fc63214f31879af74075674aa50a8f8989afe20fefa7990fa99b9","src/clients_engine/mod.rs":"461729e6f89b66b2cbd89b041a03d4d6a8ba582284ed4f3015cb13e1a0c6da97","src/clients_engine/record.rs":"b0d84bf420743d7638a45e4836633a45e50257d5548fe7ecd04bff4d724439b8","src/clients_engine/ser.rs":"be6a19c45eb8002ff8e7cf746d2f97d9cecd1740f9817a8f1d624825475fd777","src/device_type.rs":"dc2d4296d25e31471c8e68488f1043ff239b902036cd6aea8a686cf79b4ed335","src/enc_payload.rs":"aa3eea7df49b24cd59831680a47c417b73a3e36e6b0f3f4baf14ca66bd68be6b","src/engine/bridged_engine.rs":"b4e3071a0259ac55303364e57f9cd685916b80dc302030bba07790e55ceecb66","src/engine/mod.rs":"90f1f9760f5f712a337aebb04e59c736e4b6fbd89d6a188d969210c7f3f321ae","src/engine/request.rs":"5923025fb9550178339f880a1bf8526d8e853e7a0b2bce6d9d687cc808ac0085","src/engine/sync_engine.rs":"531b35d72ce9e04c3e543c0468c1e450fba2c0dc3d33d68d9b1c0a5c1ad7dd34","src/error.rs":"a45cfe02e6301f473c34678b694943c1a04308b8c292c6e0448bf495194c3b5e","src/key_bundle.rs":"abd0781f3be8c8e7c691f18bb71f3433b633803c48da9794e15ac6301ed60d6c","src/lib.rs":"f59f8817978d943518dfa03ab31fc0f6b1fc72ee9943a97aef1537e2769649f5","src/record_types.rs":"02bb3d352fb808131d298f9b90d9c95b7e9e0138b97c5401f3b9fdacc5562f44","src/server_timestamp.rs":"63916817796e83fe31fbd598bac025dfa71ec9e1808d09073db258c78a3331cd","src/sync15.udl":"005b2b056b93c959a04670f6f489afecb8e17093d8e4be34765a3a4cc0faeb8c","src/telemetry.rs":"1d06433aafe05b8d0c403ff6cb3bb35eec292f2cd6273d321eaa196fb6584dd6","uniffi.toml":"34488f947497a9b05007445dd816024ef02e6b1696f1056ee868f039722828ee"},"package":null} \ No newline at end of file diff --git a/third_party/rust/sync15/Cargo.toml b/third_party/rust/sync15/Cargo.toml index d073610067..06f5dfda92 100644 --- a/third_party/rust/sync15/Cargo.toml +++ b/third_party/rust/sync15/Cargo.toml @@ -9,18 +9,32 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "sync15" version = "0.1.0" authors = ["Sync Team "] +build = "build.rs" exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" +[lib] +name = "sync15" +path = "src/lib.rs" + [dependencies] anyhow = "1.0" ffi-support = "0.4" @@ -30,7 +44,6 @@ serde_derive = "1" serde_json = "1" serde_path_to_error = "0.1" thiserror = "1.0" -uniffi = "0.27.1" [dependencies.base16] version = "0.2" @@ -62,6 +75,9 @@ features = ["derive"] path = "../support/guid" features = ["random"] +[dependencies.uniffi] +version = "0.27.1" + [dependencies.url] version = "2.1" optional = true diff --git a/third_party/rust/tabs/.cargo-checksum.json b/third_party/rust/tabs/.cargo-checksum.json index 3c7a379baf..e8e4f8b716 100644 --- a/third_party/rust/tabs/.cargo-checksum.json +++ b/third_party/rust/tabs/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"a613b43ebf9e388395b51cc026dd08f0b6fdf04404eeaf3d8efcc1f59c9072bc","README.md":"c48b8f391ef822c4f3971b5f453a1e7b43bea232752d520460d2f04803aead1a","build.rs":"33e61b811b19ed2b58e319cc65d5988bed258d2c4fea2d706301184c59847a0f","src/error.rs":"2694657aeb12f99c4b2fe102ad2b08b79955d209201831b3e071129f0b7d7eda","src/lib.rs":"5789fc7107c76168c331c175aff4f0b2ac2ba3d65cfa0df0e1d4f8ef0c6eb80c","src/schema.rs":"510218d465c7d26d6b9f342cc33c14ab83044a67561ef924c33dadb060761972","src/storage.rs":"99f14f989a04a73bf794863786370fe7fdc89061eddc381ff82ae067297fd92b","src/store.rs":"95ed09a93bc72327811f9c5826779ef4fe96d7f2c04a2382a96557746bf7b2f9","src/sync/bridge.rs":"18d3a7913a030b598d4b6cbd5b7e2ab4cef4cc7ea964f5bc84d7fb2f28787529","src/sync/engine.rs":"73007423f2a22314a034ac660aa65bd9c50e8aa850c445a66604486280067843","src/sync/mod.rs":"09ba3c87f1174a243bf5aaa481effd18929d54359ceb9b23ccb2c32ee3482f34","src/sync/record.rs":"eef6751c209d039958afbe245ddb006cfdf6b8b6b47f925f69c552b832b87922","src/tabs.udl":"b2918b26c982c3420346bad4c8de83fa039afcee5ab838c71048eae27240af8f","uniffi.toml":"f9125e8d55b109e86076ee88bfd640372f06b142b7db557e41816c7227dd445c"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"916ac811a7f5fab127228d1d8b5bf2b5eee6884a3f5b7ef87e1e2d6008ad8e4a","README.md":"c48b8f391ef822c4f3971b5f453a1e7b43bea232752d520460d2f04803aead1a","build.rs":"33e61b811b19ed2b58e319cc65d5988bed258d2c4fea2d706301184c59847a0f","src/error.rs":"2694657aeb12f99c4b2fe102ad2b08b79955d209201831b3e071129f0b7d7eda","src/lib.rs":"5789fc7107c76168c331c175aff4f0b2ac2ba3d65cfa0df0e1d4f8ef0c6eb80c","src/schema.rs":"510218d465c7d26d6b9f342cc33c14ab83044a67561ef924c33dadb060761972","src/storage.rs":"99f14f989a04a73bf794863786370fe7fdc89061eddc381ff82ae067297fd92b","src/store.rs":"95ed09a93bc72327811f9c5826779ef4fe96d7f2c04a2382a96557746bf7b2f9","src/sync/bridge.rs":"18d3a7913a030b598d4b6cbd5b7e2ab4cef4cc7ea964f5bc84d7fb2f28787529","src/sync/engine.rs":"73007423f2a22314a034ac660aa65bd9c50e8aa850c445a66604486280067843","src/sync/mod.rs":"09ba3c87f1174a243bf5aaa481effd18929d54359ceb9b23ccb2c32ee3482f34","src/sync/record.rs":"eef6751c209d039958afbe245ddb006cfdf6b8b6b47f925f69c552b832b87922","src/tabs.udl":"b2918b26c982c3420346bad4c8de83fa039afcee5ab838c71048eae27240af8f","uniffi.toml":"f9125e8d55b109e86076ee88bfd640372f06b142b7db557e41816c7227dd445c"},"package":null} \ No newline at end of file diff --git a/third_party/rust/tabs/Cargo.toml b/third_party/rust/tabs/Cargo.toml index c8bcd8d72b..e9da5e091c 100644 --- a/third_party/rust/tabs/Cargo.toml +++ b/third_party/rust/tabs/Cargo.toml @@ -9,18 +9,32 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "tabs" version = "0.1.0" authors = ["Sync Team "] +build = "build.rs" exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" +[lib] +name = "tabs" +path = "src/lib.rs" + [dependencies] anyhow = "1.0" lazy_static = "1.4" @@ -29,7 +43,6 @@ serde = "1" serde_derive = "1" serde_json = "1" thiserror = "1.0" -uniffi = "0.27.1" url = "2.1" [dependencies.error-support] @@ -62,6 +75,9 @@ features = ["sync-engine"] [dependencies.types] path = "../support/types" +[dependencies.uniffi] +version = "0.27.1" + [dev-dependencies] tempfile = "3.1" diff --git a/third_party/rust/types/.cargo-checksum.json b/third_party/rust/types/.cargo-checksum.json index f60ceb5732..c57a1cf2a6 100644 --- a/third_party/rust/types/.cargo-checksum.json +++ b/third_party/rust/types/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"2f27d63e4c01b357abd1a53a6ebd4e6f5ea861c01fb93f61547f6a0f802c0599","src/lib.rs":"0ce1fe3683f2285fea2d67975e53d121b69c23bf901a5b1d428919e5ce67a7ba"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"c29588990e069841a7cd2ecc31a8f0159e75166933ea0a4553f071a4c1f34768","src/lib.rs":"0ce1fe3683f2285fea2d67975e53d121b69c23bf901a5b1d428919e5ce67a7ba"},"package":null} \ No newline at end of file diff --git a/third_party/rust/types/Cargo.toml b/third_party/rust/types/Cargo.toml index 783b170ffe..184fccbe5f 100644 --- a/third_party/rust/types/Cargo.toml +++ b/third_party/rust/types/Cargo.toml @@ -9,13 +9,28 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "types" version = "0.1.0" authors = ["Sync Team "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false license = "MPL-2.0" +[lib] +name = "types" +path = "src/lib.rs" + [dependencies] serde = "1" serde_derive = "1" diff --git a/third_party/rust/unicode-bidi/.cargo-checksum.json b/third_party/rust/unicode-bidi/.cargo-checksum.json index fa0b5995c0..c6a85bea08 100644 --- a/third_party/rust/unicode-bidi/.cargo-checksum.json +++ b/third_party/rust/unicode-bidi/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".appveyor.yml":"15bdeea0e836ac2ccbb259cde1509a0673a73300e90e970f3e533b189234b6fd",".github/workflows/main.yml":"e0bee93284a8b39c9d419038bfa72a6389ebdae39ce55c40624e764ac1c98a9e",".rustfmt.toml":"168c973274f3f5946e90cac6ae0f017d0832a5c830872d9d3b9b387ad6c1a81e","AUTHORS":"1ff3a7c8519b29544bb28ba9b1e7502df0cb764051fb9a1172e60006aa2b8dcc","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.lock":"8842f03d0fcea88aa1546244d0455834732603175b293218f8e9a9f44c297b7c","Cargo.toml":"099454ebee9b081080e1521eccbe447db30b17ac36e9e655ed1d0d1e20e657fb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"81d3dc6d894a68894d982760b0a907f9dcbb0da179a8063ed9de1d2257518957","src/char_data/mod.rs":"8cbdcaacddb3dd9b70d615693fa73d0e7dca6332102a95f0d3ce447df7645284","src/char_data/tables.rs":"8adf126131f573a3b6d2c35849c1cc13c831c9b55c4d3fcb5a3961d8ed7a0d44","src/data_source.rs":"36fa0785e51c549c1f72f09040cfe515b848d1b23fb30d469770a6b4b17b49df","src/deprecated.rs":"f94c0e75dec7e70cb9802e26b7f82fe618dcdd50e9973927bacd4eccc6899c62","src/explicit.rs":"86c3c55bf2cc90aab1411aac6cf05de505ca74e44a76fe829572dd7dc4dd2aa3","src/format_chars.rs":"678399fec3f4bfaf4093f38cfdb8956288313386dc3511dab9fb58164e8dc01b","src/implicit.rs":"8d5b003464aee3f333785c6170a884945251f39601e4ea658e669a2ad575d588","src/level.rs":"ce1eaa9940f1b90bc59aba296488b8cd128aefeb4b6b2e3ecc34da26c569150b","src/lib.rs":"9dff9c105f481a03823de6ad9a0a11733af019649ae211644061d5a525670244","src/prepare.rs":"aeb8b88cfb2d2e6b74473f5903205dd3683d57abcc8801de7b9fdea6a432a0fe","src/utf16.rs":"12ee177127a0b5b0350a1fcc1edf7387c26b51ec5654f724629aab723881c313"},"package":null} \ No newline at end of file +{"files":{".appveyor.yml":"15bdeea0e836ac2ccbb259cde1509a0673a73300e90e970f3e533b189234b6fd",".github/workflows/main.yml":"e0bee93284a8b39c9d419038bfa72a6389ebdae39ce55c40624e764ac1c98a9e",".rustfmt.toml":"168c973274f3f5946e90cac6ae0f017d0832a5c830872d9d3b9b387ad6c1a81e","AUTHORS":"1ff3a7c8519b29544bb28ba9b1e7502df0cb764051fb9a1172e60006aa2b8dcc","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.lock":"8842f03d0fcea88aa1546244d0455834732603175b293218f8e9a9f44c297b7c","Cargo.toml":"c65f47c45c08130abfef7b32ed530e6eeb51329d58984fb5a450771a151b24a8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"81d3dc6d894a68894d982760b0a907f9dcbb0da179a8063ed9de1d2257518957","src/char_data/mod.rs":"8cbdcaacddb3dd9b70d615693fa73d0e7dca6332102a95f0d3ce447df7645284","src/char_data/tables.rs":"8adf126131f573a3b6d2c35849c1cc13c831c9b55c4d3fcb5a3961d8ed7a0d44","src/data_source.rs":"36fa0785e51c549c1f72f09040cfe515b848d1b23fb30d469770a6b4b17b49df","src/deprecated.rs":"f94c0e75dec7e70cb9802e26b7f82fe618dcdd50e9973927bacd4eccc6899c62","src/explicit.rs":"86c3c55bf2cc90aab1411aac6cf05de505ca74e44a76fe829572dd7dc4dd2aa3","src/format_chars.rs":"678399fec3f4bfaf4093f38cfdb8956288313386dc3511dab9fb58164e8dc01b","src/implicit.rs":"8d5b003464aee3f333785c6170a884945251f39601e4ea658e669a2ad575d588","src/level.rs":"ce1eaa9940f1b90bc59aba296488b8cd128aefeb4b6b2e3ecc34da26c569150b","src/lib.rs":"9dff9c105f481a03823de6ad9a0a11733af019649ae211644061d5a525670244","src/prepare.rs":"aeb8b88cfb2d2e6b74473f5903205dd3683d57abcc8801de7b9fdea6a432a0fe","src/utf16.rs":"12ee177127a0b5b0350a1fcc1edf7387c26b51ec5654f724629aab723881c313"},"package":null} \ No newline at end of file diff --git a/third_party/rust/unicode-bidi/Cargo.toml b/third_party/rust/unicode-bidi/Cargo.toml index 584d471c8a..ff8a97d633 100644 --- a/third_party/rust/unicode-bidi/Cargo.toml +++ b/third_party/rust/unicode-bidi/Cargo.toml @@ -9,12 +9,15 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] + [package] edition = "2018" rust-version = "1.47.0" name = "unicode-bidi" version = "0.3.15" authors = ["The Servo Project Developers"] +build = false exclude = [ "benches/**", "data/**", @@ -22,6 +25,10 @@ exclude = [ "tests/**", "tools/**", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "Implementation of the Unicode Bidirectional Algorithm" documentation = "https://docs.rs/unicode-bidi/" readme = "README.md" @@ -42,12 +49,25 @@ repository = "https://github.com/servo/unicode-bidi" [lib] name = "unicode_bidi" +path = "src/lib.rs" + +[[example]] +name = "flame_udhr" +path = "examples/flame_udhr.rs" [[test]] name = "conformance_tests" path = "tests/conformance_tests.rs" required-features = ["hardcoded-data"] +[[bench]] +name = "basic" +path = "benches/basic.rs" + +[[bench]] +name = "udhr" +path = "benches/udhr.rs" + [dependencies.flame] version = "0.2" optional = true diff --git a/third_party/rust/viaduct/.cargo-checksum.json b/third_party/rust/viaduct/.cargo-checksum.json index 50f4841a85..c904d64831 100644 --- a/third_party/rust/viaduct/.cargo-checksum.json +++ b/third_party/rust/viaduct/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f82da27595f8b63e143ea2a7dab3215d0084b16177c69a0664ea195b63990ab5","README.md":"7507842687c0a9f7146318fe1541183a2fdca65ec86aafb12207c994012ab15a","src/backend.rs":"22c313dd0ecbe92803219d3770bb97b3f876ed2fdc4ac8b5ac8dbea92b563e9f","src/backend/ffi.rs":"a1ccc25c3f52cc94718624d39c082c9c7e34082804bb12f0b96f5d3a064e0c54","src/error.rs":"98ca92b58bd8b4f3c9d4c6d03ed235609d486fe8121277004283b9cfda6e3260","src/fetch_msg_types.proto":"de8a46a4947a140783a4d714364f18ccf02c4759d6ab5ace9da0b1c058efa6c3","src/headers.rs":"bf3cd6b717dfb337c64ce0bc6d275364181884378fc47afed7c80c435ce0733f","src/headers/name.rs":"dcfd4d42326724f822893cf6ac90f1e14734dba178150dcb606f4b19de5e66d7","src/lib.rs":"abddea31021b5743e4cc6d20c0bd89dc59b248a15405bf9717c79ed732950a35","src/mozilla.appservices.httpconfig.protobuf.rs":"9ede762489a0c07bc08a5b852b33013a410cb41b44b92a44555f85bb2db91412","src/settings.rs":"f62d0779d7b86af5daad0c23fb61a5982c11520e6fa528ebe2e2d6ad76e70afd"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"27b6408a4dc5179358f55709ec319852bd884efa395844ecf927432c14d7fb2d","README.md":"7507842687c0a9f7146318fe1541183a2fdca65ec86aafb12207c994012ab15a","src/backend.rs":"22c313dd0ecbe92803219d3770bb97b3f876ed2fdc4ac8b5ac8dbea92b563e9f","src/backend/ffi.rs":"a1ccc25c3f52cc94718624d39c082c9c7e34082804bb12f0b96f5d3a064e0c54","src/error.rs":"98ca92b58bd8b4f3c9d4c6d03ed235609d486fe8121277004283b9cfda6e3260","src/fetch_msg_types.proto":"de8a46a4947a140783a4d714364f18ccf02c4759d6ab5ace9da0b1c058efa6c3","src/headers.rs":"bf3cd6b717dfb337c64ce0bc6d275364181884378fc47afed7c80c435ce0733f","src/headers/name.rs":"dcfd4d42326724f822893cf6ac90f1e14734dba178150dcb606f4b19de5e66d7","src/lib.rs":"abddea31021b5743e4cc6d20c0bd89dc59b248a15405bf9717c79ed732950a35","src/mozilla.appservices.httpconfig.protobuf.rs":"9ede762489a0c07bc08a5b852b33013a410cb41b44b92a44555f85bb2db91412","src/settings.rs":"f62d0779d7b86af5daad0c23fb61a5982c11520e6fa528ebe2e2d6ad76e70afd"},"package":null} \ No newline at end of file diff --git a/third_party/rust/viaduct/Cargo.toml b/third_party/rust/viaduct/Cargo.toml index 74a1db66b8..5911e504be 100644 --- a/third_party/rust/viaduct/Cargo.toml +++ b/third_party/rust/viaduct/Cargo.toml @@ -9,20 +9,32 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "viaduct" version = "0.1.0" authors = ["Thom Chiovoloni "] +build = false exclude = [ "/android", "/ios", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" [lib] +name = "viaduct" crate-type = ["lib"] +path = "src/lib.rs" [dependencies] ffi-support = "0.4" diff --git a/third_party/rust/webext-storage/.cargo-checksum.json b/third_party/rust/webext-storage/.cargo-checksum.json index c33901ae27..cbfa3c5424 100644 --- a/third_party/rust/webext-storage/.cargo-checksum.json +++ b/third_party/rust/webext-storage/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"14914aa0f47377f379f26cde5111d13620ac6ce588285e9791b14b196e0e408b","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"92f7d380f3d8fab1e6d80276915af57192e276321d132a5f800ea4520e9cb469","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"b3f0ff950178d006e443ddbeec4513e0acaa8894211053cfdfc1de104b9fb6ab","src/db.rs":"04ef67021b6aad7552a268397c7323302c4f619b3fb07fb140132beb8b37f8b5","src/error.rs":"8587813be8e2a7f5efad4216a5c4686554ed44e98cf94bfd9c2f2c9adc8e9a11","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"ab25e7c6ea67fb905fe6dad866c0d2c462b1e93bcff283db947513aeabbb2d73","src/migration.rs":"8d92f82b2ba38e1039fd054c8c75078a6b896a0d3cdc1a52571456b25a32c9c3","src/schema.rs":"d8dd8f66cad71e3e369722734e0d5d16fd9423d5f6a5abba1854a27e1e814724","src/store.rs":"d208689c46fb97cd2c60a0c610ba1998a7132fb50fffa2eefa1d6b169b7c34f0","src/sync/bridge.rs":"996de05beb2904f84b3cbfc9ef85c4844078fdb4867d9068390d496156bee614","src/sync/incoming.rs":"dd77c64e2ade4f39cba258decab6d3db8ad0b5f513aa018efbd56b9869a021d9","src/sync/mod.rs":"05da064e1bc2cc449c806a534842da92d8d4b24a919f2dff2e88dc69f3e926a5","src/sync/outgoing.rs":"dacb77b956f2546fd60a89367927a199d9b662b17201d0781145f7405b61fdce","src/sync/sync_tests.rs":"bc9845312c7b08c5efd892979f61e9385b553f872a6c5d78600f4587b14421f5","src/webext-storage.udl":"0341d431ba837cf64ea210ef6157010c6664a0b5a194e89acb0414938636b391","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"81b4e03b6df32859fabe75be2a86051e4646b2eac61d610323beb780b7f7574b","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"92f7d380f3d8fab1e6d80276915af57192e276321d132a5f800ea4520e9cb469","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"b3f0ff950178d006e443ddbeec4513e0acaa8894211053cfdfc1de104b9fb6ab","src/db.rs":"04ef67021b6aad7552a268397c7323302c4f619b3fb07fb140132beb8b37f8b5","src/error.rs":"8587813be8e2a7f5efad4216a5c4686554ed44e98cf94bfd9c2f2c9adc8e9a11","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"ab25e7c6ea67fb905fe6dad866c0d2c462b1e93bcff283db947513aeabbb2d73","src/migration.rs":"8d92f82b2ba38e1039fd054c8c75078a6b896a0d3cdc1a52571456b25a32c9c3","src/schema.rs":"d8dd8f66cad71e3e369722734e0d5d16fd9423d5f6a5abba1854a27e1e814724","src/store.rs":"d208689c46fb97cd2c60a0c610ba1998a7132fb50fffa2eefa1d6b169b7c34f0","src/sync/bridge.rs":"996de05beb2904f84b3cbfc9ef85c4844078fdb4867d9068390d496156bee614","src/sync/incoming.rs":"dd77c64e2ade4f39cba258decab6d3db8ad0b5f513aa018efbd56b9869a021d9","src/sync/mod.rs":"05da064e1bc2cc449c806a534842da92d8d4b24a919f2dff2e88dc69f3e926a5","src/sync/outgoing.rs":"dacb77b956f2546fd60a89367927a199d9b662b17201d0781145f7405b61fdce","src/sync/sync_tests.rs":"bc9845312c7b08c5efd892979f61e9385b553f872a6c5d78600f4587b14421f5","src/webext-storage.udl":"0341d431ba837cf64ea210ef6157010c6664a0b5a194e89acb0414938636b391","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null} \ No newline at end of file diff --git a/third_party/rust/webext-storage/Cargo.toml b/third_party/rust/webext-storage/Cargo.toml index 89d35fdcf9..fcca3f82f8 100644 --- a/third_party/rust/webext-storage/Cargo.toml +++ b/third_party/rust/webext-storage/Cargo.toml @@ -9,15 +9,29 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "webext-storage" version = "0.1.0" authors = ["sync-team@mozilla.com"] +build = "build.rs" exclude = ["/android"] +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MPL-2.0" +[lib] +name = "webext_storage" +path = "src/lib.rs" + [dependencies] anyhow = "1.0" ffi-support = "0.4" @@ -28,7 +42,6 @@ serde = "1" serde_derive = "1" serde_json = "1" thiserror = "1.0" -uniffi = "0.27.1" [dependencies.error-support] path = "../support/error" @@ -59,18 +72,23 @@ features = [ path = "../../components/sync15" features = ["sync-engine"] +[dependencies.uniffi] +version = "0.27.1" + [dependencies.url] version = "2.1" features = ["serde"] [dev-dependencies] -libsqlite3-sys = "0.28.0" tempfile = "3" [dev-dependencies.env_logger] version = "0.10" default-features = false +[dev-dependencies.libsqlite3-sys] +version = "0.28.0" + [dev-dependencies.serde_json] version = "1" features = ["preserve_order"] diff --git a/third_party/rust/wgpu-core/.cargo-checksum.json b/third_party/rust/wgpu-core/.cargo-checksum.json index 895dc71983..bc78558311 100644 --- a/third_party/rust/wgpu-core/.cargo-checksum.json +++ b/third_party/rust/wgpu-core/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"1e374f1f9d3e0a99aa87801fe7b7e5218e582b1d9eae8a9ee011dc305ea2b8a7","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/binding_model.rs":"6d3b0babc8a09218ef8cbb43f6a5e9d273ceb6fffc86e71fd2d6a6ad39b19655","src/command/allocator.rs":"882d780e5d58b7a60370b58fffd7f35ffd4c087cf2ff2536267fcd57071b5f68","src/command/bind.rs":"e6a50b50daf7d75a51498b37269d9fc2cb0174c7fb91a5292e68bfd531f13e65","src/command/bundle.rs":"1ee0f49da1f45e3514491842b36966de18606426b16838e6a52048b2491fc17d","src/command/clear.rs":"af1667085d1f83d70206db90f1dca9935a9aa7c2dda5945a7bf34695e4f73260","src/command/compute.rs":"3eecbca9f169ecbdacbc80ac6624868662d71f0f16e6cbceac5f9a9042a80044","src/command/compute_command.rs":"9ef10ab26d2a457ea1a53ac5af1c69905e1a39e5f0b14f9df427a86c03192bcf","src/command/draw.rs":"1f028fd72e17e3c48b5854ee635167198829d78b5ad1bea5130d8e9708a3921e","src/command/memory_init.rs":"fadd17881d35ea5b2918de48ae9d631e16d6c49aba744d334e3edee64c0e839d","src/command/mod.rs":"dcd79aca340054a3028e625849b7fdcea1545029a2579c9e347f1de38f659640","src/command/query.rs":"93c0285cebee0cd301fcd7541ba48fc56ad7c745dff6393271d97235a845d5da","src/command/render.rs":"f11ae17ef1d6e6a0e1636972a6a6b282cda9242c7543fc83d81785b4ba11c7b5","src/command/render_command.rs":"2becc9aea7a2fdfca79562ba0369ce83b59ed9e79fa923e73e1356f91410f088","src/command/timestamp_writes.rs":"38d3a48ec70043c0cbf4113a8751a3bf267c31c3c8328dcfd9d86bacbc800dc3","src/command/transfer.rs":"b3a971ae18d34cf2cc29af2c9c4db1b4a0bcbd98b1155c3dbb47ad071fd188b0","src/conv.rs":"9bbcd0660741a808d29788266bbac34af54c58e8db8ed856082f8d2d1dfb792d","src/device/bgl.rs":"1198f47a486d4cad4c03b49c98d690bac039a7b370cc241a5f279c6767e0b010","src/device/global.rs":"3b51c5c3f926e36f2099529acd0569309b6901936c967dfce4c776f94bef7f6b","src/device/life.rs":"5a6267bb36278c806905919cc016569bc13d1d7ab4afef10366890a32dd0fe79","src/device/mod.rs":"a2b1bae5c839d924e4555bd91aa29621d09ab9384ea718d014a301a275ad3658","src/device/queue.rs":"e04c4090ebdecce8a2e1287ef469425ceec79c7db4cc6463306be25fc92ea1e0","src/device/resource.rs":"fbf38af8fe49e119a41e76f48623473f2ae83a6250b3c38ebf8a3a173faa1861","src/device/trace.rs":"0e38395e0f41b763975d94d0b538ccbb926a3d784d4bfc78048884789c5b9d09","src/error.rs":"f509aa8a57c04e1aea9ba1b4a1589d007666018cd619db3f822c37082a76b871","src/global.rs":"601a8160b5b7afa44a633ced0e87e73cb8fa298c8ff3e29b6dfe5f50c83df04f","src/hal_api.rs":"29377c036d3eaaa05d83b87644a9a33916824eb51aa2d005704cde97e77925cb","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"d357d4d52ca62211ab80e57c4781489add8ee52ff684a81aa616a6d35e444c1c","src/id.rs":"36f578a7f1c56d1ae8d5f6c7f2ab3594c26b69ca050b1fa727e2ab1dc2465c1e","src/identity.rs":"b27d4e06b1f6c25ca2f4ad276fdf8c09a5d71f890b06cbabef7ef62369cb4df6","src/init_tracker/buffer.rs":"85e7c942b0acc1b2f724bb63ca015389c8a9a853198c37108a162326a2b5e70b","src/init_tracker/mod.rs":"a0f64730cc025113b656b4690f9dcb0ec18b8770bc7ef24c7b4ad8bebae03d24","src/init_tracker/texture.rs":"8e69fa256bf7cf7ce7bcbe28991e12990bf199ddb359b7a2bd40eee950a0fea9","src/instance.rs":"bde36d69f73b055b58edcad8da07d98debbcf918863eaee42633f63678af58ac","src/lib.rs":"f23f4b83d75846ecbcecd894ca430d01c13b065193cbc74a0261599c0f7cc1ec","src/lock/mod.rs":"c58ae08a8e6108432d9e14e7d8b7bd15af7bb5e98bf700d6bd9a469b80a38b11","src/lock/observing.rs":"0ef28b269d2ecbd3c46e25e5921b657a2e3d35622c154b2850690dd4d117d47e","src/lock/rank.rs":"e6eebdb0fe0bf5e6ef7f8b522b1d83957643d244f84e1523a1e96f8f0a8d8126","src/lock/ranked.rs":"bafe6f295b4cade449cc41491c0dcd1497a6e04c5d902124040ac2056996a44d","src/lock/vanilla.rs":"a6cd5cc3c1900271783ba146adf07e28424f6fecc5466d54624dbda237770fb4","src/pipeline.rs":"1f530314b3c19d06cfdbcafb8627d8be7267584ce2ee4382590bf19fa7e90367","src/pipeline_cache.rs":"dbb6b93562a15c9b27acc006545449a6c033280433c1950806243fcfe0850c3e","src/pool.rs":"7899e74874da17c83ec39a88b360de12f564ef4bee2bb1240c37becdaeb57a86","src/present.rs":"4de7942bcee2fea830a7d7101bf59c2a1fb41b835a3963e9a56b8a0b843cbc02","src/registry.rs":"b9cd3ec0c1bda659f91e78c372ec0f58786caf24e5f2ff62f49ca5b7e07f097d","src/resource.rs":"6602249ed3ce9d04ffd7eb64aacf8741ace436665d50031772c54ba87f97ec99","src/snatch.rs":"c16e3d21547198b4b7d22a10d115376d2d6f5fa0a62d51ced2dd6a4f934d7ef7","src/storage.rs":"531eeda868cdfef205d48d0c9d3d7f3f0d22968491b6c4f15d0510b9faf86ff1","src/track/buffer.rs":"dc671db7ab4b8378af0e4a0f7dab181d86708922f942e3b01f7fc5d48507c509","src/track/metadata.rs":"44b3a8361780e8c8b2bd8910355e0ce89e2b04d921a97da4b1857a599bd6f5a4","src/track/mod.rs":"7e80349251c0874ed1d50847beee61e193ae706b9161405061e35c26d389c1f2","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"e404d58dbe2644bed4a9fcdc2c01a699322d669aaa4e6619750347519fb56625","src/track/texture.rs":"33959d21380105de4a2bafa70d323281263a2b21a5464bc5b239d46e8246e88a","src/validation.rs":"7709f256515812e7f0261dc4e3cd36f006e914084005affd795dda2c05c2ed50"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"eb416772aa8ed73f10e3fbc7b36f11066a1fff7a16d4f33321103f472536fa8e","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/binding_model.rs":"6d3b0babc8a09218ef8cbb43f6a5e9d273ceb6fffc86e71fd2d6a6ad39b19655","src/command/allocator.rs":"882d780e5d58b7a60370b58fffd7f35ffd4c087cf2ff2536267fcd57071b5f68","src/command/bind.rs":"e6a50b50daf7d75a51498b37269d9fc2cb0174c7fb91a5292e68bfd531f13e65","src/command/bundle.rs":"1ee0f49da1f45e3514491842b36966de18606426b16838e6a52048b2491fc17d","src/command/clear.rs":"af1667085d1f83d70206db90f1dca9935a9aa7c2dda5945a7bf34695e4f73260","src/command/compute.rs":"3eecbca9f169ecbdacbc80ac6624868662d71f0f16e6cbceac5f9a9042a80044","src/command/compute_command.rs":"9ef10ab26d2a457ea1a53ac5af1c69905e1a39e5f0b14f9df427a86c03192bcf","src/command/draw.rs":"1f028fd72e17e3c48b5854ee635167198829d78b5ad1bea5130d8e9708a3921e","src/command/memory_init.rs":"fadd17881d35ea5b2918de48ae9d631e16d6c49aba744d334e3edee64c0e839d","src/command/mod.rs":"dcd79aca340054a3028e625849b7fdcea1545029a2579c9e347f1de38f659640","src/command/query.rs":"93c0285cebee0cd301fcd7541ba48fc56ad7c745dff6393271d97235a845d5da","src/command/render.rs":"f11ae17ef1d6e6a0e1636972a6a6b282cda9242c7543fc83d81785b4ba11c7b5","src/command/render_command.rs":"2becc9aea7a2fdfca79562ba0369ce83b59ed9e79fa923e73e1356f91410f088","src/command/timestamp_writes.rs":"38d3a48ec70043c0cbf4113a8751a3bf267c31c3c8328dcfd9d86bacbc800dc3","src/command/transfer.rs":"b3a971ae18d34cf2cc29af2c9c4db1b4a0bcbd98b1155c3dbb47ad071fd188b0","src/conv.rs":"9bbcd0660741a808d29788266bbac34af54c58e8db8ed856082f8d2d1dfb792d","src/device/bgl.rs":"1198f47a486d4cad4c03b49c98d690bac039a7b370cc241a5f279c6767e0b010","src/device/global.rs":"3b51c5c3f926e36f2099529acd0569309b6901936c967dfce4c776f94bef7f6b","src/device/life.rs":"5a6267bb36278c806905919cc016569bc13d1d7ab4afef10366890a32dd0fe79","src/device/mod.rs":"a2b1bae5c839d924e4555bd91aa29621d09ab9384ea718d014a301a275ad3658","src/device/queue.rs":"e04c4090ebdecce8a2e1287ef469425ceec79c7db4cc6463306be25fc92ea1e0","src/device/resource.rs":"fbf38af8fe49e119a41e76f48623473f2ae83a6250b3c38ebf8a3a173faa1861","src/device/trace.rs":"0e38395e0f41b763975d94d0b538ccbb926a3d784d4bfc78048884789c5b9d09","src/error.rs":"f509aa8a57c04e1aea9ba1b4a1589d007666018cd619db3f822c37082a76b871","src/global.rs":"601a8160b5b7afa44a633ced0e87e73cb8fa298c8ff3e29b6dfe5f50c83df04f","src/hal_api.rs":"29377c036d3eaaa05d83b87644a9a33916824eb51aa2d005704cde97e77925cb","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"d357d4d52ca62211ab80e57c4781489add8ee52ff684a81aa616a6d35e444c1c","src/id.rs":"36f578a7f1c56d1ae8d5f6c7f2ab3594c26b69ca050b1fa727e2ab1dc2465c1e","src/identity.rs":"b27d4e06b1f6c25ca2f4ad276fdf8c09a5d71f890b06cbabef7ef62369cb4df6","src/init_tracker/buffer.rs":"85e7c942b0acc1b2f724bb63ca015389c8a9a853198c37108a162326a2b5e70b","src/init_tracker/mod.rs":"a0f64730cc025113b656b4690f9dcb0ec18b8770bc7ef24c7b4ad8bebae03d24","src/init_tracker/texture.rs":"8e69fa256bf7cf7ce7bcbe28991e12990bf199ddb359b7a2bd40eee950a0fea9","src/instance.rs":"bde36d69f73b055b58edcad8da07d98debbcf918863eaee42633f63678af58ac","src/lib.rs":"f23f4b83d75846ecbcecd894ca430d01c13b065193cbc74a0261599c0f7cc1ec","src/lock/mod.rs":"c58ae08a8e6108432d9e14e7d8b7bd15af7bb5e98bf700d6bd9a469b80a38b11","src/lock/observing.rs":"0ef28b269d2ecbd3c46e25e5921b657a2e3d35622c154b2850690dd4d117d47e","src/lock/rank.rs":"e6eebdb0fe0bf5e6ef7f8b522b1d83957643d244f84e1523a1e96f8f0a8d8126","src/lock/ranked.rs":"bafe6f295b4cade449cc41491c0dcd1497a6e04c5d902124040ac2056996a44d","src/lock/vanilla.rs":"a6cd5cc3c1900271783ba146adf07e28424f6fecc5466d54624dbda237770fb4","src/pipeline.rs":"1f530314b3c19d06cfdbcafb8627d8be7267584ce2ee4382590bf19fa7e90367","src/pipeline_cache.rs":"dbb6b93562a15c9b27acc006545449a6c033280433c1950806243fcfe0850c3e","src/pool.rs":"7899e74874da17c83ec39a88b360de12f564ef4bee2bb1240c37becdaeb57a86","src/present.rs":"4de7942bcee2fea830a7d7101bf59c2a1fb41b835a3963e9a56b8a0b843cbc02","src/registry.rs":"b9cd3ec0c1bda659f91e78c372ec0f58786caf24e5f2ff62f49ca5b7e07f097d","src/resource.rs":"6602249ed3ce9d04ffd7eb64aacf8741ace436665d50031772c54ba87f97ec99","src/snatch.rs":"c16e3d21547198b4b7d22a10d115376d2d6f5fa0a62d51ced2dd6a4f934d7ef7","src/storage.rs":"531eeda868cdfef205d48d0c9d3d7f3f0d22968491b6c4f15d0510b9faf86ff1","src/track/buffer.rs":"dc671db7ab4b8378af0e4a0f7dab181d86708922f942e3b01f7fc5d48507c509","src/track/metadata.rs":"44b3a8361780e8c8b2bd8910355e0ce89e2b04d921a97da4b1857a599bd6f5a4","src/track/mod.rs":"7e80349251c0874ed1d50847beee61e193ae706b9161405061e35c26d389c1f2","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"e404d58dbe2644bed4a9fcdc2c01a699322d669aaa4e6619750347519fb56625","src/track/texture.rs":"33959d21380105de4a2bafa70d323281263a2b21a5464bc5b239d46e8246e88a","src/validation.rs":"7709f256515812e7f0261dc4e3cd36f006e914084005affd795dda2c05c2ed50"},"package":null} \ No newline at end of file diff --git a/third_party/rust/wgpu-core/Cargo.toml b/third_party/rust/wgpu-core/Cargo.toml index facdcc5746..79f99e49ef 100644 --- a/third_party/rust/wgpu-core/Cargo.toml +++ b/third_party/rust/wgpu-core/Cargo.toml @@ -9,14 +9,25 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" rust-version = "1.76" name = "wgpu-core" version = "22.0.0" authors = ["gfx-rs developers"] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "WebGPU core logic on wgpu-hal" homepage = "https://wgpu.rs/" +readme = false keywords = ["graphics"] license = "MIT OR Apache-2.0" repository = "https://github.com/gfx-rs/wgpu" @@ -38,35 +49,48 @@ targets = [ ] [lib] +name = "wgpu_core" +path = "src/lib.rs" -[dependencies] -arrayvec = "0.7" -bit-vec = "0.8" -bitflags = "2.6" -document-features = "0.2.10" -indexmap = "2" -log = "0.4" -once_cell = "1.19.0" -parking_lot = ">=0.11, <0.13" -rustc-hash = "1.1.0" -smallvec = "1" -thiserror = "1.0.63" +[dependencies.arrayvec] +version = "0.7" + +[dependencies.bit-vec] +version = "0.8" + +[dependencies.bitflags] +version = "2.6" [dependencies.bytemuck] version = "1.17" features = ["derive"] optional = true +[dependencies.document-features] +version = "0.2.10" + [dependencies.hal] version = "22.0.0" path = "../wgpu-hal" default-features = false package = "wgpu-hal" +[dependencies.indexmap] +version = "2" + +[dependencies.log] +version = "0.4" + [dependencies.naga] version = "22.0.0" path = "../naga" +[dependencies.once_cell] +version = "1.19.0" + +[dependencies.parking_lot] +version = ">=0.11, <0.13" + [dependencies.profiling] version = "1" default-features = false @@ -79,18 +103,27 @@ optional = true version = "0.8" optional = true +[dependencies.rustc-hash] +version = "1.1.0" + [dependencies.serde] version = "1" features = ["derive"] optional = true +[dependencies.smallvec] +version = "1" + +[dependencies.thiserror] +version = "1.0.63" + [dependencies.wgt] version = "22.0.0" path = "../wgpu-types" package = "wgpu-types" -[build-dependencies] -cfg_aliases = "0.1" +[build-dependencies.cfg_aliases] +version = "0.1" [features] api_log_info = [] diff --git a/third_party/rust/wgpu-hal/.cargo-checksum.json b/third_party/rust/wgpu-hal/.cargo-checksum.json index b4666a13d4..30a40204aa 100644 --- a/third_party/rust/wgpu-hal/.cargo-checksum.json +++ b/third_party/rust/wgpu-hal/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"990dbdfee98bd873e9d74b2ad43adbe78cab8888ab706a47b1e8c4576cff5b60","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","README.md":"8930213345c3edb1273533f22d2c44bd8a7c6c4fe2510d71852a7e2d27116c6e","build.rs":"c80bdc0152a00471eec6ed0dd0f7d55d0b975498a00ba05e94100c84ad639a49","examples/halmark/main.rs":"e3b3a94ec643f13d0047786a1d4e8d03d076d6df28f987d36f31e6df4533cffb","examples/halmark/shader.wgsl":"26c256ec36d6f0e9a1647431ca772766bee4382d64eaa718ba7b488dcfb6bcca","examples/raw-gles.em.html":"70fbe68394a1a4522192de1dcfaf7d399f60d7bdf5de70b708f9bb0417427546","examples/raw-gles.rs":"faefa9b8dda46cc83eea26d4f0eade4790c2922569e0d2beab06d340b61886c6","examples/ray-traced-triangle/main.rs":"53cc5515b94f8cf57b0c709d69328f1d10112963b70ddb26799d2c858bcb1635","examples/ray-traced-triangle/shader.wgsl":"cc10caf92746724a71f6dd0dbc3a71e57b37c7d1d83278556805a535c0728a9d","src/auxil/dxgi/conv.rs":"06dae4417e804d7a15421e116df9aa6cf05d0471bec77a5f881e0f7dd7c5b731","src/auxil/dxgi/exception.rs":"fd9ca0a9bdfe028ee9d41d149f91351de7563c23864757fd4e6f3e046192f65f","src/auxil/dxgi/factory.rs":"eaddd1a85f803367d4a2729f5775f96d672a2f7675b6ee6ad1d4b2ccd3c1989a","src/auxil/dxgi/mod.rs":"a202564d9ac97530b16a234b87d180cd345aae705e082a9b1177dcde813645f9","src/auxil/dxgi/result.rs":"773b1afddb262ec416b6166506eb748a33bfdaee4bcad1f95839ac2858e73b06","src/auxil/dxgi/time.rs":"9b0fa8af0f7d284c7f18e37d1d15749230dca87b39bc4c205a0c4d358fb16336","src/auxil/mod.rs":"b07c43813541136786f06b8a0c11a8b89157932dde14c0f7a4ead1ba1ee401cc","src/auxil/renderdoc.rs":"be2a012b7f326173cdeeccc0925bc26c64e3439c974338f5d5836f20afcf0022","src/dx12/adapter.rs":"cf1c3e6dca9244fc74b5cc02f9c1e3db25029a93884e2b28d57befcd1699dca2","src/dx12/command.rs":"36ce2fb1edc56f4a10cf9f18dcb357ad03a2b3be878108a447efcac3432a47c4","src/dx12/conv.rs":"14d74445762d000f88067670118a4a259e37e94002904879fbdc56a965236955","src/dx12/descriptor.rs":"a32fe353ec0ac35e55499de437d58599f88675f118f333c201978dacd70380be","src/dx12/device.rs":"b9bceff605f8c2a2c97cae2c40ca0d58c804aae2aaf3995cd0f5f1778930dd59","src/dx12/instance.rs":"92441550e669d8a954c26de8d818f99a0b907297454efa4667f80d0bc4b13051","src/dx12/mod.rs":"6a1b3d1b8778ed933badcf7283f60174669176eab8f5eb7551f935a1bcf52a6b","src/dx12/shader_compilation.rs":"6ddb7ea2d5da783a49642463815de5426cfb18107379cb898834a51413b9758f","src/dx12/suballocation.rs":"b2b0ad99abcd429a61dfb7b68b33d81520b562d3ce1c5150f3dc95b6ec8a5752","src/dx12/types.rs":"3fc7619fc09303eb3c936d4ded6889f94ce9e8b9aa62742ce900baa1b1e1cca7","src/dx12/view.rs":"1b10cee262487ca0466d07c4f994ff6b1ff95178bd037d1c8a1cf1a74cea0581","src/dynamic/adapter.rs":"ea69fd063e4f0492e7927bcca64501640daa53af9b2d81b8948ac7c5836d0910","src/dynamic/command.rs":"ba32bd046f0cd52f7a041bbd51254aedbd21b39db4bc920f96a9adfe7fda0466","src/dynamic/device.rs":"0d30b790224a6d5884f0089303b64546e317b0d0d7c7327aaa9582ed08297889","src/dynamic/instance.rs":"6c1f3b325a8059ae4717e016d03d3c1f6074c98422f787f776aeb6d46a828c26","src/dynamic/mod.rs":"c8f25c902c35306a15cdbe47d8c3877968d9ca6586c5b2c3db1f9e45d7f536fb","src/dynamic/queue.rs":"23367e59dbf97cbaf5363cc68c00b0d2096a296f79ec5f636479f2132ab9a39c","src/dynamic/surface.rs":"c07327f244687c4a700390d3a8f0a443e4fff2a9192bf026962687bad945ccd2","src/empty.rs":"070521690d8846a02859727df817267027ae00bd98a8eb3820620a47dff551c8","src/gles/adapter.rs":"890cd5a93a9dfbff073e1a16c90cc181cfb60beab123787abb224e4d1f86e83f","src/gles/command.rs":"470347bb905f702dd3b9e6cf80f1e5bf0ee53b069f4b347bb4d49216c548d901","src/gles/conv.rs":"9b82ee6b549a4db25a20a9337d30ff9a78443acdb87b820a77f1ad72ab32b3ec","src/gles/device.rs":"322cd233f87e11d314124078610126f7730e54f5fa4d3e58c76828b6eab8d190","src/gles/egl.rs":"eaa90401ecf9027d837c53a6420891c6b3ea1c54d4d7a6b2924a64f753792fd3","src/gles/emscripten.rs":"d225171b044a949bb4ebc295d975f73cca85440e8f892605bf5ef42373e6772d","src/gles/mod.rs":"ce951bd0030a0a4e42e1fac233618fb59410a3bd70935ceca0136774fe903473","src/gles/queue.rs":"36fc2318e37f6eb5e98b01f12c9903f2877075301ddc1f3f75d8c76c839541b4","src/gles/shaders/clear.frag":"9133ed8ed97d3641fbb6b5f5ea894a3554c629ccc1b80a5fc9221d7293aa1954","src/gles/shaders/clear.vert":"a543768725f4121ff2e9e1fb5b00644931e9d6f2f946c0ef01968afb5a135abd","src/gles/shaders/srgb_present.frag":"dd9a43c339a2fa4ccf7f6a1854c6f400cabf271a7d5e9230768e9f39d47f3ff5","src/gles/shaders/srgb_present.vert":"6e85d489403d80b81cc94790730bb53b309dfc5eeede8f1ea3412a660f31d357","src/gles/web.rs":"2c7bd33d66bc41f9fc63226fe92b995b2d9dbfef7ffa4c7930d5133182b5aa87","src/gles/wgl.rs":"7031dd0d6668f4f7e31c46a55afdb69ebc183b3b9ad88218064548555522222e","src/lib.rs":"52e1bd4674c11c1af858628ed3d5e45689e99d47d76347347ccd2e5782d6ce6f","src/metal/adapter.rs":"cdaa1af796641281482981b33d73fde06d97a671b96c3560cf40883709ecbe8d","src/metal/command.rs":"a09cabb0a4aac05ef853d17c4979cf4144f83ebfd153d4f548469f0c79494a17","src/metal/conv.rs":"a34a44e6affb594f3285f8d585b0fb33132aa7dc6a612f7c1aecaa400fe43265","src/metal/device.rs":"2e921cfcb636977273e219b3d0fb6574eceb58471f3bb3327bca986567902cbf","src/metal/mod.rs":"05b9a3bf2e0dc065da880c7ca718d86fdbc416e292e066cc97bfd6c0314ece2a","src/metal/surface.rs":"a2332b8577411a79ecb6aaf1e2089b5b4313e2724c70df49227d11e649e4a721","src/metal/time.rs":"c32d69f30e846dfcc0e39e01097fb80df63b2bebb6586143bb62494999850246","src/vulkan/adapter.rs":"d9870072838a1a221d47223e2894910e626ebc4d0e6c08f4d9197d354dd8ba05","src/vulkan/command.rs":"133192c9d113a5f3bcdddebbf43a91c4204353632045255939e6e3b1b46d1ff5","src/vulkan/conv.rs":"086bd08d19dc6829bdd926e5b495278e721c432b7b7475a50f09281812f5e5d6","src/vulkan/device.rs":"2534fe30ba4da9418a7cf64b4ad01f751ef132b35497cb187254104d2aea5721","src/vulkan/instance.rs":"034f51659ae3caf85b6cc2249165900763ae7dcea128c1d62caca0a0f1cacee5","src/vulkan/mod.rs":"168cc2acb8fecfb9dc7932c7104e4c529bdc9cd8bd02f8328fdd69690c67c6dd"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"0656d8a5016d0afc11412729a35be8fd3e917933b2680c84cf162c66e74cfcaf","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","README.md":"8930213345c3edb1273533f22d2c44bd8a7c6c4fe2510d71852a7e2d27116c6e","build.rs":"c80bdc0152a00471eec6ed0dd0f7d55d0b975498a00ba05e94100c84ad639a49","examples/halmark/main.rs":"e3b3a94ec643f13d0047786a1d4e8d03d076d6df28f987d36f31e6df4533cffb","examples/halmark/shader.wgsl":"26c256ec36d6f0e9a1647431ca772766bee4382d64eaa718ba7b488dcfb6bcca","examples/raw-gles.em.html":"70fbe68394a1a4522192de1dcfaf7d399f60d7bdf5de70b708f9bb0417427546","examples/raw-gles.rs":"faefa9b8dda46cc83eea26d4f0eade4790c2922569e0d2beab06d340b61886c6","examples/ray-traced-triangle/main.rs":"53cc5515b94f8cf57b0c709d69328f1d10112963b70ddb26799d2c858bcb1635","examples/ray-traced-triangle/shader.wgsl":"cc10caf92746724a71f6dd0dbc3a71e57b37c7d1d83278556805a535c0728a9d","src/auxil/dxgi/conv.rs":"06dae4417e804d7a15421e116df9aa6cf05d0471bec77a5f881e0f7dd7c5b731","src/auxil/dxgi/exception.rs":"fd9ca0a9bdfe028ee9d41d149f91351de7563c23864757fd4e6f3e046192f65f","src/auxil/dxgi/factory.rs":"eaddd1a85f803367d4a2729f5775f96d672a2f7675b6ee6ad1d4b2ccd3c1989a","src/auxil/dxgi/mod.rs":"a202564d9ac97530b16a234b87d180cd345aae705e082a9b1177dcde813645f9","src/auxil/dxgi/result.rs":"773b1afddb262ec416b6166506eb748a33bfdaee4bcad1f95839ac2858e73b06","src/auxil/dxgi/time.rs":"9b0fa8af0f7d284c7f18e37d1d15749230dca87b39bc4c205a0c4d358fb16336","src/auxil/mod.rs":"b07c43813541136786f06b8a0c11a8b89157932dde14c0f7a4ead1ba1ee401cc","src/auxil/renderdoc.rs":"be2a012b7f326173cdeeccc0925bc26c64e3439c974338f5d5836f20afcf0022","src/dx12/adapter.rs":"cf1c3e6dca9244fc74b5cc02f9c1e3db25029a93884e2b28d57befcd1699dca2","src/dx12/command.rs":"36ce2fb1edc56f4a10cf9f18dcb357ad03a2b3be878108a447efcac3432a47c4","src/dx12/conv.rs":"14d74445762d000f88067670118a4a259e37e94002904879fbdc56a965236955","src/dx12/descriptor.rs":"a32fe353ec0ac35e55499de437d58599f88675f118f333c201978dacd70380be","src/dx12/device.rs":"b9bceff605f8c2a2c97cae2c40ca0d58c804aae2aaf3995cd0f5f1778930dd59","src/dx12/instance.rs":"92441550e669d8a954c26de8d818f99a0b907297454efa4667f80d0bc4b13051","src/dx12/mod.rs":"6a1b3d1b8778ed933badcf7283f60174669176eab8f5eb7551f935a1bcf52a6b","src/dx12/shader_compilation.rs":"6ddb7ea2d5da783a49642463815de5426cfb18107379cb898834a51413b9758f","src/dx12/suballocation.rs":"b2b0ad99abcd429a61dfb7b68b33d81520b562d3ce1c5150f3dc95b6ec8a5752","src/dx12/types.rs":"3fc7619fc09303eb3c936d4ded6889f94ce9e8b9aa62742ce900baa1b1e1cca7","src/dx12/view.rs":"1b10cee262487ca0466d07c4f994ff6b1ff95178bd037d1c8a1cf1a74cea0581","src/dynamic/adapter.rs":"ea69fd063e4f0492e7927bcca64501640daa53af9b2d81b8948ac7c5836d0910","src/dynamic/command.rs":"ba32bd046f0cd52f7a041bbd51254aedbd21b39db4bc920f96a9adfe7fda0466","src/dynamic/device.rs":"0d30b790224a6d5884f0089303b64546e317b0d0d7c7327aaa9582ed08297889","src/dynamic/instance.rs":"6c1f3b325a8059ae4717e016d03d3c1f6074c98422f787f776aeb6d46a828c26","src/dynamic/mod.rs":"c8f25c902c35306a15cdbe47d8c3877968d9ca6586c5b2c3db1f9e45d7f536fb","src/dynamic/queue.rs":"23367e59dbf97cbaf5363cc68c00b0d2096a296f79ec5f636479f2132ab9a39c","src/dynamic/surface.rs":"c07327f244687c4a700390d3a8f0a443e4fff2a9192bf026962687bad945ccd2","src/empty.rs":"070521690d8846a02859727df817267027ae00bd98a8eb3820620a47dff551c8","src/gles/adapter.rs":"890cd5a93a9dfbff073e1a16c90cc181cfb60beab123787abb224e4d1f86e83f","src/gles/command.rs":"470347bb905f702dd3b9e6cf80f1e5bf0ee53b069f4b347bb4d49216c548d901","src/gles/conv.rs":"9b82ee6b549a4db25a20a9337d30ff9a78443acdb87b820a77f1ad72ab32b3ec","src/gles/device.rs":"322cd233f87e11d314124078610126f7730e54f5fa4d3e58c76828b6eab8d190","src/gles/egl.rs":"eaa90401ecf9027d837c53a6420891c6b3ea1c54d4d7a6b2924a64f753792fd3","src/gles/emscripten.rs":"d225171b044a949bb4ebc295d975f73cca85440e8f892605bf5ef42373e6772d","src/gles/mod.rs":"ce951bd0030a0a4e42e1fac233618fb59410a3bd70935ceca0136774fe903473","src/gles/queue.rs":"36fc2318e37f6eb5e98b01f12c9903f2877075301ddc1f3f75d8c76c839541b4","src/gles/shaders/clear.frag":"9133ed8ed97d3641fbb6b5f5ea894a3554c629ccc1b80a5fc9221d7293aa1954","src/gles/shaders/clear.vert":"a543768725f4121ff2e9e1fb5b00644931e9d6f2f946c0ef01968afb5a135abd","src/gles/shaders/srgb_present.frag":"dd9a43c339a2fa4ccf7f6a1854c6f400cabf271a7d5e9230768e9f39d47f3ff5","src/gles/shaders/srgb_present.vert":"6e85d489403d80b81cc94790730bb53b309dfc5eeede8f1ea3412a660f31d357","src/gles/web.rs":"2c7bd33d66bc41f9fc63226fe92b995b2d9dbfef7ffa4c7930d5133182b5aa87","src/gles/wgl.rs":"7031dd0d6668f4f7e31c46a55afdb69ebc183b3b9ad88218064548555522222e","src/lib.rs":"52e1bd4674c11c1af858628ed3d5e45689e99d47d76347347ccd2e5782d6ce6f","src/metal/adapter.rs":"cdaa1af796641281482981b33d73fde06d97a671b96c3560cf40883709ecbe8d","src/metal/command.rs":"a09cabb0a4aac05ef853d17c4979cf4144f83ebfd153d4f548469f0c79494a17","src/metal/conv.rs":"a34a44e6affb594f3285f8d585b0fb33132aa7dc6a612f7c1aecaa400fe43265","src/metal/device.rs":"2e921cfcb636977273e219b3d0fb6574eceb58471f3bb3327bca986567902cbf","src/metal/mod.rs":"05b9a3bf2e0dc065da880c7ca718d86fdbc416e292e066cc97bfd6c0314ece2a","src/metal/surface.rs":"a2332b8577411a79ecb6aaf1e2089b5b4313e2724c70df49227d11e649e4a721","src/metal/time.rs":"c32d69f30e846dfcc0e39e01097fb80df63b2bebb6586143bb62494999850246","src/vulkan/adapter.rs":"d9870072838a1a221d47223e2894910e626ebc4d0e6c08f4d9197d354dd8ba05","src/vulkan/command.rs":"133192c9d113a5f3bcdddebbf43a91c4204353632045255939e6e3b1b46d1ff5","src/vulkan/conv.rs":"086bd08d19dc6829bdd926e5b495278e721c432b7b7475a50f09281812f5e5d6","src/vulkan/device.rs":"2534fe30ba4da9418a7cf64b4ad01f751ef132b35497cb187254104d2aea5721","src/vulkan/instance.rs":"034f51659ae3caf85b6cc2249165900763ae7dcea128c1d62caca0a0f1cacee5","src/vulkan/mod.rs":"168cc2acb8fecfb9dc7932c7104e4c529bdc9cd8bd02f8328fdd69690c67c6dd"},"package":null} \ No newline at end of file diff --git a/third_party/rust/wgpu-hal/Cargo.toml b/third_party/rust/wgpu-hal/Cargo.toml index dda3d0145c..9cb5faeffc 100644 --- a/third_party/rust/wgpu-hal/Cargo.toml +++ b/third_party/rust/wgpu-hal/Cargo.toml @@ -9,12 +9,21 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +test = [] +bench = [] + [package] edition = "2021" rust-version = "1.76" name = "wgpu-hal" version = "22.0.0" authors = ["gfx-rs developers"] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "WebGPU hardware abstraction layer" homepage = "https://wgpu.rs/" readme = "README.md" @@ -43,45 +52,71 @@ targets = [ ] [lib] +name = "wgpu_hal" +path = "src/lib.rs" [[example]] name = "halmark" +path = "examples/halmark/main.rs" [[example]] name = "raw-gles" +path = "examples/raw-gles.rs" required-features = ["gles"] -[dependencies] -arrayvec = "0.7" -bitflags = "2.6" -log = "0.4" -once_cell = "1.19.0" -parking_lot = ">=0.11, <0.13" -raw-window-handle = "0.6" -rustc-hash = "1.1.0" -thiserror = "1.0.63" +[[example]] +name = "ray-traced-triangle" +path = "examples/ray-traced-triangle/main.rs" + +[dependencies.arrayvec] +version = "0.7" + +[dependencies.bitflags] +version = "2.6" [dependencies.glow] version = "0.14.0" optional = true +[dependencies.log] +version = "0.4" + [dependencies.naga] version = "22.0.0" path = "../naga" +[dependencies.once_cell] +version = "1.19.0" + +[dependencies.parking_lot] +version = ">=0.11, <0.13" + [dependencies.profiling] version = "1" default-features = false +[dependencies.raw-window-handle] +version = "0.6" + +[dependencies.rustc-hash] +version = "1.1.0" + +[dependencies.thiserror] +version = "1.0.63" + [dependencies.wgt] version = "22.0.0" path = "../wgpu-types" package = "wgpu-types" -[dev-dependencies] -cfg-if = "1" -env_logger = "0.11" -glam = "0.28" +[dev-dependencies.cfg-if] +version = "1" + +[dev-dependencies.env_logger] +version = "0.11" + +[dev-dependencies.glam] +version = "0.28" [dev-dependencies.naga] version = "22.0.0" @@ -92,8 +127,8 @@ features = ["wgsl-in"] version = "0.29" features = ["android-native-activity"] -[build-dependencies] -cfg_aliases = "0.1" +[build-dependencies.cfg_aliases] +version = "0.1" [features] device_lost_panic = [] @@ -150,11 +185,13 @@ vulkan = [ "dep:android_system_properties", ] -[target."cfg(all(target_arch = \"wasm32\", not(target_os = \"emscripten\")))".dependencies] -js-sys = "0.3.70" -wasm-bindgen = "0.2.87" +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies.js-sys] +version = "0.3.70" -[target."cfg(all(target_arch = \"wasm32\", not(target_os = \"emscripten\")))".dependencies.web-sys] +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies.wasm-bindgen] +version = "0.2.87" + +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies.web-sys] version = "0.3.70" features = [ "Window", @@ -163,18 +200,20 @@ features = [ "OffscreenCanvas", ] -[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies] -core-graphics-types = "0.1" -objc = "0.2.5" - -[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies.block] +[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies.block] version = "0.1" optional = true -[target."cfg(any(target_os=\"macos\", target_os=\"ios\"))".dependencies.metal] +[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies.core-graphics-types] +version = "0.1" + +[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies.metal] version = "0.29.0" -[target."cfg(not(any(target_arch = \"wasm32\", windows, target_os = \"ios\")))".dev-dependencies.glutin] +[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies.objc] +version = "0.2.5" + +[target.'cfg(not(any(target_arch = "wasm32", windows, target_os = "ios")))'.dev-dependencies.glutin] version = "0.31" features = [ "egl", @@ -183,7 +222,7 @@ features = [ ] default-features = false -[target."cfg(not(any(target_arch = \"wasm32\", windows, target_os = \"ios\")))".dev-dependencies.glutin-winit] +[target.'cfg(not(any(target_arch = "wasm32", windows, target_os = "ios")))'.dev-dependencies.glutin-winit] version = "0.4" features = [ "egl", @@ -192,68 +231,68 @@ features = [ ] default-features = false -[target."cfg(not(any(target_arch = \"wasm32\", windows, target_os = \"ios\")))".dev-dependencies.rwh_05] +[target.'cfg(not(any(target_arch = "wasm32", windows, target_os = "ios")))'.dev-dependencies.rwh_05] version = "0.5" package = "raw-window-handle" -[target."cfg(not(any(target_arch = \"wasm32\", windows, target_os = \"ios\")))".dev-dependencies.winit] +[target.'cfg(not(any(target_arch = "wasm32", windows, target_os = "ios")))'.dev-dependencies.winit] version = "0.29" features = [ "android-native-activity", "rwh_05", ] -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.ash] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.ash] version = "0.38.0" optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.gpu-alloc] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.gpu-alloc] version = "0.6" optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.gpu-descriptor] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.gpu-descriptor] version = "0.3" optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.khronos-egl] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.khronos-egl] version = "6" features = ["dynamic"] optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.libloading] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.libloading] version = "0.8" optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.renderdoc-sys] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.renderdoc-sys] version = "1.1.0" optional = true -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.smallvec] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.smallvec] version = "1" features = ["union"] optional = true -[target."cfg(target_os = \"android\")".dependencies.android_system_properties] +[target.'cfg(target_os = "android")'.dependencies.android_system_properties] version = "0.1.1" optional = true -[target."cfg(target_os = \"android\")".dependencies.ndk-sys] +[target.'cfg(target_os = "android")'.dependencies.ndk-sys] version = "0.5.0" optional = true -[target."cfg(target_os = \"emscripten\")".dependencies.khronos-egl] +[target.'cfg(target_os = "emscripten")'.dependencies.khronos-egl] version = "6" features = [ "static", "no-pkg-config", ] -[target."cfg(target_os = \"emscripten\")".dependencies.libloading] +[target.'cfg(target_os = "emscripten")'.dependencies.libloading] version = "0.8" optional = true -[target."cfg(unix)".dependencies] -libc = "0.2" +[target."cfg(unix)".dependencies.libc] +version = "0.2" [target."cfg(windows)".dependencies.bit-set] version = "0.8" diff --git a/third_party/rust/wgpu-types/.cargo-checksum.json b/third_party/rust/wgpu-types/.cargo-checksum.json index 6da31fb351..d095033778 100644 --- a/third_party/rust/wgpu-types/.cargo-checksum.json +++ b/third_party/rust/wgpu-types/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"d56f85319fdf62c9a430fc2ee6c5c5cb36d5d9f66e374e4cf99da892e159dc2f","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"d22aa7ddb95d3ae129ff9848fd45913bab41bd354b6f1c1f6c38a86f9d1abbc6","src/counters.rs":"599e9c033c4f8fcc95113bf730191d80f51b3276b3ee8fd03bbc1c27d24bf76d","src/lib.rs":"f3434598049500d0bc2c1d1e047de091c6d8728d5d0ecae22651f97889f5cce0","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"e23d8d5f33e2bc96270c9c839e3e8038095ce1ffd5cca66129766c2879a7e350","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"d22aa7ddb95d3ae129ff9848fd45913bab41bd354b6f1c1f6c38a86f9d1abbc6","src/counters.rs":"599e9c033c4f8fcc95113bf730191d80f51b3276b3ee8fd03bbc1c27d24bf76d","src/lib.rs":"f3434598049500d0bc2c1d1e047de091c6d8728d5d0ecae22651f97889f5cce0","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null} \ No newline at end of file diff --git a/third_party/rust/wgpu-types/Cargo.toml b/third_party/rust/wgpu-types/Cargo.toml index 0c662b8bc3..e823d55e1a 100644 --- a/third_party/rust/wgpu-types/Cargo.toml +++ b/third_party/rust/wgpu-types/Cargo.toml @@ -9,14 +9,25 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" rust-version = "1.76" name = "wgpu-types" version = "22.0.0" authors = ["gfx-rs developers"] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false description = "WebGPU types" homepage = "https://wgpu.rs/" +readme = false keywords = ["graphics"] license = "MIT OR Apache-2.0" repository = "https://github.com/gfx-rs/wgpu" @@ -35,32 +46,34 @@ targets = [ ] [lib] +name = "wgpu_types" +path = "src/lib.rs" -[dependencies] -bitflags = "2.6" +[dependencies.bitflags] +version = "2.6" [dependencies.serde] version = "1" features = ["derive"] optional = true -[dev-dependencies] -serde_json = "1.0.125" - [dev-dependencies.serde] version = "1" features = ["derive"] +[dev-dependencies.serde_json] +version = "1.0.125" + [features] counters = [] fragile-send-sync-non-atomic-wasm = [] serde = ["dep:serde"] strict_asserts = [] -[target."cfg(target_arch = \"wasm32\")".dependencies] -js-sys = "0.3.70" +[target.'cfg(target_arch = "wasm32")'.dependencies.js-sys] +version = "0.3.70" -[target."cfg(target_arch = \"wasm32\")".dependencies.web-sys] +[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] version = "0.3.70" features = [ "ImageBitmap", diff --git a/third_party/rust/wpf-gpu-raster/.cargo-checksum.json b/third_party/rust/wpf-gpu-raster/.cargo-checksum.json index 9bc1e8eb39..61411746de 100644 --- a/third_party/rust/wpf-gpu-raster/.cargo-checksum.json +++ b/third_party/rust/wpf-gpu-raster/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"16a2fc5b725d83b7a3547d0eab6df5ec5a710a9f87fca37ae473eab210b13113","LICENSE":"ae48df11a335dc1a615f4f938b69cba73bcf4485c4f97af49b38efb0f216353b","README.md":"e14b7ddbd29b6f87d956921999da1cf7bc3add0166cacf21e8b1ac1d9092a90d","src/aacoverage.rs":"fdadadd208caa986cc386797f937a976b5a315174c7c0782b87c0334d6474a97","src/aarasterizer.rs":"283bed1e22917118f332b24731cb6bd11334a4f0ba0d88821cfeb6b607de12da","src/bezier.rs":"f089ab04e30077ce4e0fe59dfa602948b989aa53d51ad207fbc30c1edd24086b","src/c_bindings.rs":"deac1f9eac8e77d1b26bb3e8348fed97bb02e5bfedb8c1dede408e51126ba63d","src/fix.rs":"7ccf63db5bab4ab0135d92691f7c2272a27866b9792dd55ec98b2d1c1b7c0358","src/geometry_sink.rs":"9025569f77f475a1e47fd470e8f53dcdf88ef57e3a5b8a51268fff892da8b1a7","src/helpers.rs":"220294dac335943518f249c4a27ad803f8226ed62cd780f517e95be6343a1f2f","src/hwrasterizer.rs":"82b2d6d35488a6ad7de4d82f3ee38c6f09f4b6de06b4f98eea61b3abdd72eb62","src/hwvertexbuffer.rs":"f3dd54f17570eb530c9c827b24a53b755a2dfa6028e9b83f9d7a4ba9945c2ecf","src/lib.rs":"9a09fd5f6a1ba9469c3ddfd38493e315ef94f0bc0a4e58724d146c3658d9ab1d","src/matrix.rs":"1ac44bc5d073f96ab64b1b5c6077fd0d47fe61db8243bd9a55fc91d8eae1dd92","src/notes":"d50d49e0b5660bc6350d8055f25f26700c937558de0af690e1fc4f50ed7e05c9","src/nullable_ref.rs":"789fe0e59b7d4a925faecbf2362be93643ea8382b4424ca0e60866f9bf83c3cd","src/real.rs":"73a2d1a77613364e9514fd7ead4d708a554d2b7343645cdb4cb8a2b3b640e057","src/tri_rasterize.rs":"30821a3465cea3c5ac578590013b530c03ea3010225f580d6cf609e39910c412","src/types.rs":"b840212a99a212ef38211aaf1bd801ec83416569541941d15fd95285d1342b99"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"60b7cb0b395bc7c5351952b11d9d722fa7dd36c989195bc58721518040d8b461","LICENSE":"ae48df11a335dc1a615f4f938b69cba73bcf4485c4f97af49b38efb0f216353b","README.md":"e14b7ddbd29b6f87d956921999da1cf7bc3add0166cacf21e8b1ac1d9092a90d","src/aacoverage.rs":"fdadadd208caa986cc386797f937a976b5a315174c7c0782b87c0334d6474a97","src/aarasterizer.rs":"283bed1e22917118f332b24731cb6bd11334a4f0ba0d88821cfeb6b607de12da","src/bezier.rs":"f089ab04e30077ce4e0fe59dfa602948b989aa53d51ad207fbc30c1edd24086b","src/c_bindings.rs":"deac1f9eac8e77d1b26bb3e8348fed97bb02e5bfedb8c1dede408e51126ba63d","src/fix.rs":"7ccf63db5bab4ab0135d92691f7c2272a27866b9792dd55ec98b2d1c1b7c0358","src/geometry_sink.rs":"9025569f77f475a1e47fd470e8f53dcdf88ef57e3a5b8a51268fff892da8b1a7","src/helpers.rs":"220294dac335943518f249c4a27ad803f8226ed62cd780f517e95be6343a1f2f","src/hwrasterizer.rs":"82b2d6d35488a6ad7de4d82f3ee38c6f09f4b6de06b4f98eea61b3abdd72eb62","src/hwvertexbuffer.rs":"f3dd54f17570eb530c9c827b24a53b755a2dfa6028e9b83f9d7a4ba9945c2ecf","src/lib.rs":"9a09fd5f6a1ba9469c3ddfd38493e315ef94f0bc0a4e58724d146c3658d9ab1d","src/matrix.rs":"1ac44bc5d073f96ab64b1b5c6077fd0d47fe61db8243bd9a55fc91d8eae1dd92","src/notes":"d50d49e0b5660bc6350d8055f25f26700c937558de0af690e1fc4f50ed7e05c9","src/nullable_ref.rs":"789fe0e59b7d4a925faecbf2362be93643ea8382b4424ca0e60866f9bf83c3cd","src/real.rs":"73a2d1a77613364e9514fd7ead4d708a554d2b7343645cdb4cb8a2b3b640e057","src/tri_rasterize.rs":"30821a3465cea3c5ac578590013b530c03ea3010225f580d6cf609e39910c412","src/types.rs":"b840212a99a212ef38211aaf1bd801ec83416569541941d15fd95285d1342b99"},"package":null} \ No newline at end of file diff --git a/third_party/rust/wpf-gpu-raster/Cargo.toml b/third_party/rust/wpf-gpu-raster/Cargo.toml index 9c7f4cdfb6..a7a8f6c92a 100644 --- a/third_party/rust/wpf-gpu-raster/Cargo.toml +++ b/third_party/rust/wpf-gpu-raster/Cargo.toml @@ -9,21 +9,46 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +test = [] +bench = [] + [package] edition = "2021" name = "wpf-gpu-raster" version = "0.1.0" +build = false include = [ "src/**/*", "LICENSE", "README.md", ] +autobins = false +autoexamples = false +autotests = false +autobenches = false readme = "README.md" license = "MIT" [profile.release] debug = 2 +[lib] +name = "wpf_gpu_raster" +path = "src/lib.rs" + +[[example]] +name = "draw" +path = "examples/draw.rs" + +[[example]] +name = "obj-output" +path = "examples/obj-output.rs" + +[[example]] +name = "simple" +path = "examples/simple.rs" + [dependencies] typed-arena-nomut = "0.1.0" diff --git a/third_party/rust/xml_struct/.cargo-checksum.json b/third_party/rust/xml_struct/.cargo-checksum.json index 0574935a1a..e2d6a69cff 100644 --- a/third_party/rust/xml_struct/.cargo-checksum.json +++ b/third_party/rust/xml_struct/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"3e10c126973fc3638dd8d3bef72f2f8ff128589c9f27c0fa7a41f86c266e2342","src/impls.rs":"a99488ab36106830e9769e92f60cf09f8ecc0b0f31564e999cfddb80967a8d14","src/lib.rs":"6c15f1b236d3ccb045ecf9b2968cb0cfcfc134f5127726362642370b62514312","src/tests.rs":"720028fb6a732356021e9a6edd6fb8dae4a9eba6360e64640f6dbe4cffb53c8d"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"941d8d9c5c1daf189b68f9cd0425b414c73938aaf59a2ba052ace0801c1225aa","src/impls.rs":"a99488ab36106830e9769e92f60cf09f8ecc0b0f31564e999cfddb80967a8d14","src/lib.rs":"6c15f1b236d3ccb045ecf9b2968cb0cfcfc134f5127726362642370b62514312","src/tests.rs":"720028fb6a732356021e9a6edd6fb8dae4a9eba6360e64640f6dbe4cffb53c8d"},"package":null} \ No newline at end of file diff --git a/third_party/rust/xml_struct/Cargo.toml b/third_party/rust/xml_struct/Cargo.toml index 6654db5ac0..2530a7b5a8 100644 --- a/third_party/rust/xml_struct/Cargo.toml +++ b/third_party/rust/xml_struct/Cargo.toml @@ -9,10 +9,25 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "xml_struct" version = "0.1.0" +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false + +[lib] +name = "xml_struct" +path = "src/lib.rs" [dependencies] anyhow = "1.0.69" diff --git a/third_party/rust/xml_struct_derive/.cargo-checksum.json b/third_party/rust/xml_struct_derive/.cargo-checksum.json index ca0f304077..93bb06b46b 100644 --- a/third_party/rust/xml_struct_derive/.cargo-checksum.json +++ b/third_party/rust/xml_struct_derive/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"f880f790b7ad87b155402c1522d56e50baf045305e124c00cccfb29da409b257","src/lib.rs":"4c9d1f5f553e2d2dce2f2d33f7ea129eccbe92520a897a7f9d40c04738ab1397","src/properties.rs":"e16d997368fafb5a612d858900b9f0b49d7dbd685f8ca8048b2eb542f20dad91","src/serialize.rs":"f2b09ae462823d0b891815e8a33562a3ef2c845e7ab7b0bc67b44c52450d8bdf","src/serialize/codegen.rs":"9889a8aa5173bf6933b096304b22489e903f3d782fbed6d50a6d0df2c5bdfbee"},"package":null} \ No newline at end of file +{"files":{"Cargo.toml":"25ad245a94ae47e308b8c01fe7adddf1445a0f1f7ef870f32aa03c129b26314d","src/lib.rs":"4c9d1f5f553e2d2dce2f2d33f7ea129eccbe92520a897a7f9d40c04738ab1397","src/properties.rs":"e16d997368fafb5a612d858900b9f0b49d7dbd685f8ca8048b2eb542f20dad91","src/serialize.rs":"f2b09ae462823d0b891815e8a33562a3ef2c845e7ab7b0bc67b44c52450d8bdf","src/serialize/codegen.rs":"9889a8aa5173bf6933b096304b22489e903f3d782fbed6d50a6d0df2c5bdfbee"},"package":null} \ No newline at end of file diff --git a/third_party/rust/xml_struct_derive/Cargo.toml b/third_party/rust/xml_struct_derive/Cargo.toml index dbb1a394d8..51fa6fb509 100644 --- a/third_party/rust/xml_struct_derive/Cargo.toml +++ b/third_party/rust/xml_struct_derive/Cargo.toml @@ -9,12 +9,25 @@ # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. +bin = [] +example = [] +test = [] +bench = [] + [package] edition = "2021" name = "xml_struct_derive" version = "0.1.0" +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false [lib] +name = "xml_struct_derive" +path = "src/lib.rs" proc-macro = true [dependencies] diff --git a/third_party/rust/zlib-rs/.cargo-checksum.json b/third_party/rust/zlib-rs/.cargo-checksum.json new file mode 100644 index 0000000000..3a86fe16cd --- /dev/null +++ b/third_party/rust/zlib-rs/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"b2dd882f23a8d8edd2285b9a97cc63f1d8ae2fa9b6c29d6c6739e4a1befc9e18","LICENSE":"7d60612df8fcd9d3714871a95b4d3012563246fdea8f6710b7567f83cfa3c8ef","README.md":"9938581c82330440be5f3b6b9125cc02c0874b250dc62093f167bf2158dbe29a","src/adler32.rs":"daa45aa1c83096e8962c5d687da1d99f57eecfa15380084d2634c775bf628a9b","src/adler32/avx2.rs":"7383b4dd559cc946b966240971fb0fc4aa94eecc3f870c277f238c60c7541c71","src/adler32/generic.rs":"cfe8da0e145faac42ed31e9de1ccb718e389265517a007533b8c997cae68f1a7","src/adler32/neon.rs":"1d77a00d009c659cf6113eb661d8e974568077031a6b548a31159cfc3da22c7e","src/allocate.rs":"e0c181e6e052f609d5024abaf327fbe8a6e9c0d7aacdce1ba7c8aae35e6265b4","src/c_api.rs":"8328f52b477beecfc7f68240c40e775516cb773dad8c46cf24aad178c4ea0f6c","src/cpu_features.rs":"e283f3e65ea9bde9fa85fb3e83ba17b8bdf1b32d24e5cff51b15ea34f15847f3","src/crc32.rs":"ef2799e93378aa32d81a146dc5671cbc00b0664b330bdf338456f982e4c92c82","src/crc32/acle.rs":"3b4a7b7101f1c2b3ef531b732d466de4b11a6ce9c86646bac9ed38dd90d25f79","src/crc32/braid.rs":"9911138a714353708b6f9945e2b0debf86ed6879db7497d1c9ecb308eb29def9","src/crc32/combine.rs":"a1aded8c5f1886f60daad9765886299c65feb5240f24f8e9f67ebced14e267f0","src/crc32/pclmulqdq.rs":"891a57eea0e8d5ca4b5d5ee0dd69c62d0c9ecaa741c26ba09abedefe53fd446b","src/deflate.rs":"5e02de2d90106cf966b4613971da4ebe14f04d819fac1e8119b6a3da9e28f70d","src/deflate/algorithm/fast.rs":"686c0a35c1baff2d842287354f919e166fe5eca1748ad46ed14d6127611bffa0","src/deflate/algorithm/huff.rs":"2ed0a098571d4e056bb4e1d8655ec8d37e6d291ba3e2d5d7c581c2486e6abbce","src/deflate/algorithm/medium.rs":"6b3b3e99ad870a6c35921b0abb4b10569e49bf3d5f57a8af2179c886a94e54b6","src/deflate/algorithm/mod.rs":"184151cde5952a4ff0029c6647705be5f884d558bd8552a3d29f9c7a16598c93","src/deflate/algorithm/quick.rs":"3b981d8b80b6e593b21fdf3c73f47e3b3a8b912d5cd803d6752f26b2aef278e1","src/deflate/algorithm/rle.rs":"549427a5a8a69610afd612f89a9cbde97fe78c38c85442083b5dde10e8be4d73","src/deflate/algorithm/slow.rs":"2fa351c77604fad7d5e113ed3b90ba2abc83be0ff589a0e367d012aee5ce967b","src/deflate/algorithm/stored.rs":"0ab4c6e1d901a7460edf3d7e760bf633122b4016d1c0535f31738ac8d0d9b2d8","src/deflate/compare256.rs":"2d476ae9363cdf9f0b06aafd5bcb7899fc66b18cd4802b19a2f4c2adad86af99","src/deflate/hash_calc.rs":"4b9e9629593b27c4331e3d4adab54d262ec8e07af0c37f6ca2f5b578e1ed54a0","src/deflate/longest_match.rs":"176babeb518323f587995de932c623d099444d7565682a0838669159b8213fd8","src/deflate/pending.rs":"84f0860b650570e824607e3ceb53dcc9fbb91a667ba110728cc9d4c995f1bb05","src/deflate/slide_hash.rs":"0b279c4e6d84fb713516772209ff5224fef6072a517f7983d749717d1ff2a2f5","src/deflate/test-data/inflate_buf_error.dat":"254f280f8f1e8914bd12d8bcd3813e5c08083b1b46d8d643c8e2ebe109e75cb8","src/deflate/test-data/paper-100k.pdf":"60f73a051b7ca35bfec44734b2eed7736cb5c0b7f728beb7b97ade6c5e44849b","src/deflate/trees_tbl.rs":"503c65c7648405619a95dc9f5a52ecd558e439e870c116f61ef94128c6a4c52e","src/deflate/window.rs":"317cc28e690710a5905fcda2dbddfa91e27bd8f44380b1d923519c40dc0399e5","src/inflate.rs":"a528850e11437d7e923a5ca193957859c4171963532481232ded2c857df5d05f","src/inflate/bitreader.rs":"09d1844933d044e7a758ad2d68d2ab421b5003881f509b58be611faba6e86295","src/inflate/inffixed_tbl.rs":"eb1ed1927ca07b61fe30ae8461ce62e7da28c595416e687a26db57c8eac8f4a1","src/inflate/inftrees.rs":"44efb568c9cc2dbbc6c51e50f3cc38d6c8e896b93936f47b3879396fc814abfe","src/inflate/window.rs":"8b175bdba8c7f7cd346a4ab408f0218c84ae177f32f2ac581872064269677423","src/lib.rs":"94a27cad5bb21f60b2a49c5bdfcafeef43c643a20ecbce7392e1bda7047e484f","src/read_buf.rs":"1c34709d582568e46223f7f3b116956af314f07238b8105724ed21c1b23ac23c"},"package":null} \ No newline at end of file diff --git a/third_party/rust/zlib-rs/Cargo.toml b/third_party/rust/zlib-rs/Cargo.toml new file mode 100644 index 0000000000..a797764a91 --- /dev/null +++ b/third_party/rust/zlib-rs/Cargo.toml @@ -0,0 +1,73 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +bin = [] +example = [] +test = [] +bench = [] + +[package] +edition = "2021" +rust-version = "1.75" +name = "zlib-rs" +version = "0.2.1" +build = false +publish = true +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A memory-safe zlib implementation written in rust" +homepage = "https://github.com/memorysafety/zlib-rs" +readme = "README.md" +license = "Zlib" +repository = "https://github.com/memorysafety/zlib-rs" + +[lib] +name = "zlib_rs" +path = "src/lib.rs" + +[dependencies.arbitrary] +version = "1.0" +features = ["derive"] +optional = true + +[dependencies.libz-sys] +version = "1.1.19" +features = ["zlib-ng"] +optional = true +default-features = false + +[dependencies.quickcheck] +version = "1.0.3" +features = [] +optional = true +default-features = false + +[dev-dependencies] +crc32fast = "1.3.2" + +[dev-dependencies.quickcheck] +version = "1.0.3" +features = [] +default-features = false + +[features] +ZLIB_DEBUG = [] +__internal-fuzz = ["arbitrary"] +__internal-test = ["quickcheck"] +c-allocator = [] +default = [ + "std", + "c-allocator", +] +rust-allocator = [] +std = ["rust-allocator"] diff --git a/third_party/rust/zlib-rs/LICENSE b/third_party/rust/zlib-rs/LICENSE new file mode 100644 index 0000000000..8079b948a6 --- /dev/null +++ b/third_party/rust/zlib-rs/LICENSE @@ -0,0 +1,19 @@ +(C) 2024 Internet Security Research Group + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/third_party/rust/zlib-rs/README.md b/third_party/rust/zlib-rs/README.md new file mode 100644 index 0000000000..7710c6d5c1 --- /dev/null +++ b/third_party/rust/zlib-rs/README.md @@ -0,0 +1,6 @@ +# âš ï¸ UNSTABLEâš ï¸ +_the public interface of this crate is unstable!_ + +A pure-rust implementation of [zlib](https://www.zlib.net/manual.html). + +For a [zlib](https://www.zlib.net/manual.html) -compatible rust api of this crate, see [`libz-rs-sys`](https://crates.io/crates/libz-rs-sys). For a more high-level interface, use [`flate2`](https://crates.io/crates/flate2). diff --git a/third_party/rust/zlib-rs/src/adler32.rs b/third_party/rust/zlib-rs/src/adler32.rs new file mode 100644 index 0000000000..ca78898b51 --- /dev/null +++ b/third_party/rust/zlib-rs/src/adler32.rs @@ -0,0 +1,133 @@ +use core::mem::MaybeUninit; + +#[cfg(target_arch = "x86_64")] +mod avx2; +mod generic; +#[cfg(target_arch = "aarch64")] +mod neon; + +pub fn adler32(start_checksum: u32, data: &[u8]) -> u32 { + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx2() { + return avx2::adler32_avx2(start_checksum, data); + } + + #[cfg(target_arch = "aarch64")] + if crate::cpu_features::is_enabled_neon() { + return self::neon::adler32_neon(start_checksum, data); + } + + generic::adler32_rust(start_checksum, data) +} + +pub fn adler32_fold_copy(start_checksum: u32, dst: &mut [MaybeUninit], src: &[u8]) -> u32 { + debug_assert!(dst.len() >= src.len(), "{} < {}", dst.len(), src.len()); + + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx2() { + return avx2::adler32_fold_copy_avx2(start_checksum, dst, src); + } + + let adler = adler32(start_checksum, src); + dst[..src.len()].copy_from_slice(slice_to_uninit(src)); + adler +} + +pub fn adler32_combine(adler1: u32, adler2: u32, len2: u64) -> u32 { + const BASE: u64 = self::BASE as u64; + + let rem = len2 % BASE; + + let adler1 = adler1 as u64; + let adler2 = adler2 as u64; + + /* the derivation of this formula is left as an exercise for the reader */ + let mut sum1 = adler1 & 0xffff; + let mut sum2 = rem * sum1; + sum2 %= BASE; + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + + if sum1 >= BASE { + sum1 -= BASE; + } + if sum1 >= BASE { + sum1 -= BASE; + } + if sum2 >= (BASE << 1) { + sum2 -= BASE << 1; + } + if sum2 >= BASE { + sum2 -= BASE; + } + + (sum1 | (sum2 << 16)) as u32 +} + +// when stable, use MaybeUninit::write_slice +fn slice_to_uninit(slice: &[u8]) -> &[MaybeUninit] { + // safety: &[T] and &[MaybeUninit] have the same layout + unsafe { &*(slice as *const [u8] as *const [MaybeUninit]) } +} + +// inefficient but correct, useful for testing +#[cfg(test)] +fn naive_adler32(start_checksum: u32, data: &[u8]) -> u32 { + const MOD_ADLER: u32 = 65521; // Largest prime smaller than 2^16 + + let mut a = start_checksum & 0xFFFF; + let mut b = (start_checksum >> 16) & 0xFFFF; + + for &byte in data { + a = (a + byte as u32) % MOD_ADLER; + b = (b + a) % MOD_ADLER; + } + + (b << 16) | a +} + +const BASE: u32 = 65521; /* largest prime smaller than 65536 */ +const NMAX: u32 = 5552; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn naive_is_fancy_small_inputs() { + for i in 0..128 { + let v = (0u8..i).collect::>(); + assert_eq!(naive_adler32(1, &v), generic::adler32_rust(1, &v)); + } + } + + #[test] + fn test_adler32_combine() { + ::quickcheck::quickcheck(test as fn(_) -> _); + + fn test(data: Vec) -> bool { + let Some(buf_len) = data.first().copied() else { + return true; + }; + + let buf_size = Ord::max(buf_len, 1) as usize; + + let mut adler1 = 1; + let mut adler2 = 1; + + for chunk in data.chunks(buf_size) { + adler1 = adler32(adler1, chunk); + } + + adler2 = adler32(adler2, &data); + + assert_eq!(adler1, adler2); + + let combine1 = adler32_combine(adler1, adler2, data.len() as _); + let combine2 = adler32_combine(adler1, adler1, data.len() as _); + assert_eq!(combine1, combine2); + + true + } + } +} diff --git a/third_party/rust/zlib-rs/src/adler32/avx2.rs b/third_party/rust/zlib-rs/src/adler32/avx2.rs new file mode 100644 index 0000000000..6bcf5a889a --- /dev/null +++ b/third_party/rust/zlib-rs/src/adler32/avx2.rs @@ -0,0 +1,257 @@ +use core::{ + arch::x86_64::{ + __m256i, _mm256_add_epi32, _mm256_castsi256_si128, _mm256_extracti128_si256, + _mm256_madd_epi16, _mm256_maddubs_epi16, _mm256_permutevar8x32_epi32, _mm256_sad_epu8, + _mm256_slli_epi32, _mm256_storeu_si256, _mm256_zextsi128_si256, _mm_add_epi32, + _mm_cvtsi128_si32, _mm_cvtsi32_si128, _mm_shuffle_epi32, _mm_unpackhi_epi64, + }, + mem::MaybeUninit, +}; + +use crate::adler32::{ + generic::{adler32_copy_len_16, adler32_len_16, adler32_len_64}, + BASE, NMAX, +}; + +const fn __m256i_literal(bytes: [u8; 32]) -> __m256i { + unsafe { core::mem::transmute(bytes) } +} + +const DOT2V: __m256i = __m256i_literal([ + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1, +]); + +const DOT3V: __m256i = __m256i_literal([ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, +]); + +const ZERO: __m256i = __m256i_literal([0; 32]); + +// 32 bit horizontal sum, adapted from Agner Fog's vector library. +#[target_feature(enable = "avx2")] +unsafe fn hsum256(x: __m256i) -> u32 { + unsafe { + let sum1 = _mm_add_epi32(_mm256_extracti128_si256(x, 1), _mm256_castsi256_si128(x)); + let sum2 = _mm_add_epi32(sum1, _mm_unpackhi_epi64(sum1, sum1)); + let sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + _mm_cvtsi128_si32(sum3) as u32 + } +} + +#[target_feature(enable = "avx2")] +unsafe fn partial_hsum256(x: __m256i) -> u32 { + const PERM_VEC: __m256i = __m256i_literal([ + 0, 0, 0, 0, // + 2, 0, 0, 0, // + 4, 0, 0, 0, // + 6, 0, 0, 0, // + 1, 0, 0, 0, // + 1, 0, 0, 0, // + 1, 0, 0, 0, // + 1, 0, 0, 0, // + ]); + + unsafe { + let non_zero = _mm256_permutevar8x32_epi32(x, PERM_VEC); + let non_zero_sse = _mm256_castsi256_si128(non_zero); + let sum2 = _mm_add_epi32(non_zero_sse, _mm_unpackhi_epi64(non_zero_sse, non_zero_sse)); + let sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + _mm_cvtsi128_si32(sum3) as u32 + } +} + +pub fn adler32_avx2(adler: u32, src: &[u8]) -> u32 { + assert!(crate::cpu_features::is_enabled_avx2()); + unsafe { adler32_avx2_help::(adler, &mut [], src) } +} + +pub fn adler32_fold_copy_avx2(adler: u32, dst: &mut [MaybeUninit], src: &[u8]) -> u32 { + assert!(crate::cpu_features::is_enabled_avx2()); + unsafe { adler32_avx2_help::(adler, dst, src) } +} + +#[target_feature(enable = "avx2")] +unsafe fn adler32_avx2_help( + adler: u32, + mut dst: &mut [MaybeUninit], + src: &[u8], +) -> u32 { + if src.is_empty() { + return adler; + } + + let (before, middle, after) = unsafe { src.align_to::<__m256i>() }; + + let mut adler1 = (adler >> 16) & 0xffff; + let mut adler0 = adler & 0xffff; + + let adler = if before.len() < 16 { + if COPY { + let adler = adler32_copy_len_16(adler0, dst, before, adler1); + dst = &mut dst[before.len()..]; + adler + } else { + adler32_len_16(adler0, before, adler1) + } + } else if before.len() < 32 { + if COPY { + let adler = adler32_copy_len_16(adler0, dst, before, adler1); + dst = &mut dst[before.len()..]; + adler + } else { + adler32_len_64(adler0, before, adler1) + } + } else { + adler + }; + + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + + // use largest step possible (without causing overflow) + for chunk in middle.chunks(NMAX as usize / 32) { + (adler0, adler1) = unsafe { helper_32_bytes::(adler0, adler1, dst, chunk) }; + if COPY { + dst = &mut dst[32 * chunk.len()..]; + } + } + + if !after.is_empty() { + if after.len() < 16 { + if COPY { + return adler32_copy_len_16(adler0, dst, after, adler1); + } else { + return adler32_len_16(adler0, after, adler1); + } + } else if after.len() < 32 { + if COPY { + return adler32_copy_len_16(adler0, dst, after, adler1); + } else { + return adler32_len_64(adler0, after, adler1); + } + } else { + unreachable!() + } + } + + adler0 | (adler1 << 16) +} + +#[target_feature(enable = "avx2")] +unsafe fn helper_32_bytes( + mut adler0: u32, + mut adler1: u32, + dst: &mut [MaybeUninit], + src: &[__m256i], +) -> (u32, u32) { + let mut vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0 as i32)); + let mut vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1 as i32)); + + let mut vs1_0 = vs1; + let mut vs3 = ZERO; + + let mut out_chunks = dst.chunks_exact_mut(32); + + for vbuf in src.iter().copied() { + if COPY { + let out_chunk = out_chunks.next().unwrap(); + _mm256_storeu_si256(out_chunk.as_mut_ptr() as *mut __m256i, vbuf); + } + + let vs1_sad = _mm256_sad_epu8(vbuf, ZERO); // Sum of abs diff, resulting in 2 x int32's + + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + let v_short_sum2 = _mm256_maddubs_epi16(vbuf, DOT2V); // sum 32 uint8s to 16 shorts + let vsum2 = _mm256_madd_epi16(v_short_sum2, DOT3V); // sum 16 shorts to 8 uint32s + vs2 = _mm256_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + /* Defer the multiplication with 32 to outside of the loop */ + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + + (adler0, adler1) +} + +#[cfg(test)] +#[cfg(target_feature = "avx2")] +mod test { + use super::*; + + #[test] + fn empty_input() { + let avx2 = adler32_avx2(0, &[]); + let rust = crate::adler32::generic::adler32_rust(0, &[]); + + assert_eq!(rust, avx2); + } + + quickcheck::quickcheck! { + fn adler32_avx2_is_adler32_rust(v: Vec, start: u32) -> bool { + let avx2 = adler32_avx2(start, &v); + let rust = crate::adler32::generic::adler32_rust(start, &v); + + rust == avx2 + } + } + + const INPUT: [u8; 1024] = { + let mut array = [0; 1024]; + let mut i = 0; + while i < array.len() { + array[i] = i as u8; + i += 1; + } + + array + }; + + #[test] + fn start_alignment() { + // SIMD algorithm is sensitive to alignment; + for i in 0..16 { + for start in [crate::ADLER32_INITIAL_VALUE as u32, 42] { + let avx2 = adler32_avx2(start, &INPUT[i..]); + let rust = crate::adler32::generic::adler32_rust(start, &INPUT[i..]); + + assert_eq!(avx2, rust, "offset = {i}, start = {start}"); + } + } + } + + #[test] + #[cfg_attr(miri, ignore)] + fn large_input() { + const DEFAULT: &[u8] = include_bytes!("../deflate/test-data/paper-100k.pdf"); + + let avx2 = adler32_avx2(42, DEFAULT); + let rust = crate::adler32::generic::adler32_rust(42, DEFAULT); + + assert_eq!(avx2, rust); + } + + // TODO: This could use `MaybeUninit::slice_assume_init` when it is stable. + unsafe fn slice_assume_init(slice: &[MaybeUninit]) -> &[u8] { + &*(slice as *const [MaybeUninit] as *const [u8]) + } + + #[test] + fn fold_copy_copies() { + let src: Vec<_> = (0..128).map(|x| x as u8).collect(); + let mut dst = [MaybeUninit::new(0); 128]; + + for (i, _) in src.iter().enumerate() { + dst.fill(MaybeUninit::new(0)); + + adler32_fold_copy_avx2(1, &mut dst[..i], &src[..i]); + + assert_eq!(&src[..i], unsafe { slice_assume_init(&dst[..i]) }) + } + } +} diff --git a/third_party/rust/zlib-rs/src/adler32/generic.rs b/third_party/rust/zlib-rs/src/adler32/generic.rs new file mode 100644 index 0000000000..2500c38f61 --- /dev/null +++ b/third_party/rust/zlib-rs/src/adler32/generic.rs @@ -0,0 +1,136 @@ +use core::mem::MaybeUninit; + +use super::{BASE, NMAX}; + +const UNROLL_MORE: bool = true; + +// macros for loop unrolling +macro_rules! do1 { + ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => { + $sum1 += unsafe { *$chunk.get_unchecked($i) } as u32; + $sum2 += $sum1; + }; +} + +macro_rules! do2 { + ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => { + do1!($sum1, $sum2, $chunk, $i); + do1!($sum1, $sum2, $chunk, $i + 1); + }; +} + +macro_rules! do4 { + ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => { + do2!($sum1, $sum2, $chunk, $i); + do2!($sum1, $sum2, $chunk, $i + 2); + }; +} + +macro_rules! do8 { + ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => { + do4!($sum1, $sum2, $chunk, $i); + do4!($sum1, $sum2, $chunk, $i + 4); + }; +} + +macro_rules! do16 { + ($sum1:expr, $sum2:expr, $chunk:expr) => { + do8!($sum1, $sum2, $chunk, 0); + do8!($sum1, $sum2, $chunk, 8); + }; +} + +pub fn adler32_rust(mut adler: u32, buf: &[u8]) -> u32 { + /* split Adler-32 into component sums */ + let mut sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if buf.len() == 1 { + return adler32_len_1(adler, buf, sum2); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if buf.is_empty() { + return adler | (sum2 << 16); + } + + /* in case short lengths are provided, keep it somewhat fast */ + if buf.len() < 16 { + return adler32_len_16(adler, buf, sum2); + } + + let mut it = buf.chunks_exact(NMAX as usize); + for big_chunk in it.by_ref() { + const N: usize = if UNROLL_MORE { 16 } else { 8 } as usize; + let it = big_chunk.chunks_exact(N); + for chunk in it { + if N == 16 { + do16!(adler, sum2, chunk); + } else { + do8!(adler, sum2, chunk, 0); + } + } + + adler %= BASE; + sum2 %= BASE; + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + return adler32_len_64(adler, it.remainder(), sum2); +} + +pub(crate) fn adler32_len_1(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 { + adler += buf[0] as u32; + adler %= BASE; + sum2 += adler; + sum2 %= BASE; + adler | (sum2 << 16) +} + +pub(crate) fn adler32_len_16(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 { + for b in buf { + adler += (*b) as u32; + sum2 += adler; + } + + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + adler | (sum2 << 16) +} + +#[cfg_attr(not(target_arch = "x86_64"), allow(unused))] +pub(crate) fn adler32_copy_len_16( + mut adler: u32, + dst: &mut [MaybeUninit], + src: &[u8], + mut sum2: u32, +) -> u32 { + for (source, destination) in src.iter().zip(dst.iter_mut()) { + let v = *source; + *destination = MaybeUninit::new(v); + adler += v as u32; + sum2 += adler; + } + + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + adler | (sum2 << 16) +} + +pub(crate) fn adler32_len_64(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 { + const N: usize = if UNROLL_MORE { 16 } else { 8 }; + let mut it = buf.chunks_exact(N); + for chunk in it.by_ref() { + if N == 16 { + do16!(adler, sum2, chunk); + } else { + do8!(adler, sum2, chunk, 0); + } + } + + /* Process tail (len < 16). */ + adler32_len_16(adler, it.remainder(), sum2) +} diff --git a/third_party/rust/zlib-rs/src/adler32/neon.rs b/third_party/rust/zlib-rs/src/adler32/neon.rs new file mode 100644 index 0000000000..d256512e26 --- /dev/null +++ b/third_party/rust/zlib-rs/src/adler32/neon.rs @@ -0,0 +1,242 @@ +use core::arch::aarch64::{ + uint16x8_t, uint16x8x2_t, uint16x8x4_t, uint8x16_t, vaddq_u32, vaddw_high_u8, vaddw_u8, + vdupq_n_u16, vdupq_n_u32, vget_high_u32, vget_lane_u32, vget_low_u16, vget_low_u32, + vget_low_u8, vld1q_u8_x4, vmlal_high_u16, vmlal_u16, vpadalq_u16, vpadalq_u8, vpadd_u32, + vpaddlq_u8, vsetq_lane_u32, vshlq_n_u32, +}; + +use crate::adler32::{ + generic::{adler32_len_1, adler32_len_16}, + BASE, NMAX, +}; + +const TAPS: [uint16x8x4_t; 2] = unsafe { + core::mem::transmute::<[u16; 64], [uint16x8x4_t; 2]>([ + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, + 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + ]) +}; + +pub fn adler32_neon(adler: u32, buf: &[u8]) -> u32 { + assert!(crate::cpu_features::is_enabled_neon()); + unsafe { adler32_neon_internal(adler, buf) } +} + +#[target_feature(enable = "neon")] +unsafe fn adler32_neon_internal(mut adler: u32, buf: &[u8]) -> u32 { + /* split Adler-32 into component sums */ + let sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if buf.len() == 1 { + return adler32_len_1(adler, buf, sum2); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if buf.is_empty() { + return adler | (sum2 << 16); + } + + /* in case short lengths are provided, keep it somewhat fast */ + if buf.len() < 16 { + return adler32_len_16(adler, buf, sum2); + } + + // Split Adler-32 into component sums, it can be supplied by the caller sites (e.g. in a PNG file). + let mut pair = (adler, sum2); + + // If memory is not SIMD aligned, do scalar sums to an aligned + // offset, provided that doing so doesn't completely eliminate + // SIMD operation. Aligned loads are still faster on ARM, even + // though there's no explicit aligned load instruction + const _: () = assert!(core::mem::align_of::() == 16); + let (before, middle, after) = unsafe { buf.align_to::() }; + + pair = handle_tail(pair, before); + + for chunk in middle.chunks(NMAX as usize / core::mem::size_of::()) { + pair = unsafe { accum32(pair, chunk) }; + pair.0 %= BASE; + pair.1 %= BASE; + } + + if !after.is_empty() { + pair = handle_tail(pair, after); + pair.0 %= BASE; + pair.1 %= BASE; + } + + // D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. + (pair.1 << 16) | pair.0 +} + +fn handle_tail(mut pair: (u32, u32), buf: &[u8]) -> (u32, u32) { + for x in buf { + pair.0 += *x as u32; + pair.1 += pair.0; + } + + pair +} + +#[target_feature(enable = "neon")] +unsafe fn accum32(s: (u32, u32), buf: &[uint8x16_t]) -> (u32, u32) { + let mut adacc = vdupq_n_u32(0); + let mut s2acc = vdupq_n_u32(0); + + adacc = vsetq_lane_u32(s.0, adacc, 0); + s2acc = vsetq_lane_u32(s.1, s2acc, 0); + + let mut s3acc = vdupq_n_u32(0); + let mut adacc_prev = adacc; + + let mut s2_0 = vdupq_n_u16(0); + let mut s2_1 = vdupq_n_u16(0); + let mut s2_2 = vdupq_n_u16(0); + let mut s2_3 = vdupq_n_u16(0); + + let mut s2_4 = vdupq_n_u16(0); + let mut s2_5 = vdupq_n_u16(0); + let mut s2_6 = vdupq_n_u16(0); + let mut s2_7 = vdupq_n_u16(0); + + let mut it = buf.chunks_exact(4); + + for chunk in &mut it { + let d0_d3 = vld1q_u8_x4(chunk.as_ptr() as *const u8); + + // Unfortunately it doesn't look like there's a direct sum 8 bit to 32 + // bit instruction, we'll have to make due summing to 16 bits first + let hsum = uint16x8x2_t(vpaddlq_u8(d0_d3.0), vpaddlq_u8(d0_d3.1)); + + let hsum_fold = uint16x8x2_t(vpadalq_u8(hsum.0, d0_d3.2), vpadalq_u8(hsum.1, d0_d3.3)); + + adacc = vpadalq_u16(adacc, hsum_fold.0); + s3acc = vaddq_u32(s3acc, adacc_prev); + adacc = vpadalq_u16(adacc, hsum_fold.1); + + // If we do straight widening additions to the 16 bit values, we don't incur + // the usual penalties of a pairwise add. We can defer the multiplications + // until the very end. These will not overflow because we are incurring at + // most 408 loop iterations (NMAX / 64), and a given lane is only going to be + // summed into once. This means for the maximum input size, the largest value + // we will see is 255 * 102 = 26010, safely under uint16 max + s2_0 = vaddw_u8(s2_0, vget_low_u8(d0_d3.0)); + s2_1 = vaddw_high_u8(s2_1, d0_d3.0); + s2_2 = vaddw_u8(s2_2, vget_low_u8(d0_d3.1)); + s2_3 = vaddw_high_u8(s2_3, d0_d3.1); + s2_4 = vaddw_u8(s2_4, vget_low_u8(d0_d3.2)); + s2_5 = vaddw_high_u8(s2_5, d0_d3.2); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0_d3.3)); + s2_7 = vaddw_high_u8(s2_7, d0_d3.3); + + adacc_prev = adacc; + } + + s3acc = vshlq_n_u32(s3acc, 6); + + let remainder = it.remainder(); + + if !remainder.is_empty() { + let mut s3acc_0 = vdupq_n_u32(0); + for d0 in remainder.iter().copied() { + let adler: uint16x8_t = vpaddlq_u8(d0); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0)); + s2_7 = vaddw_high_u8(s2_7, d0); + adacc = vpadalq_u16(adacc, adler); + s3acc_0 = vaddq_u32(s3acc_0, adacc_prev); + adacc_prev = adacc; + } + + s3acc_0 = vshlq_n_u32(s3acc_0, 4); + s3acc = vaddq_u32(s3acc_0, s3acc); + } + + let t0_t3 = TAPS[0]; + let t4_t7 = TAPS[1]; + + let mut s2acc_0 = vdupq_n_u32(0); + let mut s2acc_1 = vdupq_n_u32(0); + let mut s2acc_2 = vdupq_n_u32(0); + + s2acc = vmlal_high_u16(s2acc, t0_t3.0, s2_0); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.0), vget_low_u16(s2_0)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.1, s2_1); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.1), vget_low_u16(s2_1)); + + s2acc = vmlal_high_u16(s2acc, t0_t3.2, s2_2); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.2), vget_low_u16(s2_2)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.3, s2_3); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.3), vget_low_u16(s2_3)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.0, s2_4); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.0), vget_low_u16(s2_4)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.1, s2_5); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.1), vget_low_u16(s2_5)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.2, s2_6); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.2), vget_low_u16(s2_6)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.3, s2_7); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.3), vget_low_u16(s2_7)); + + s2acc = vaddq_u32(s2acc_0, s2acc); + s2acc_2 = vaddq_u32(s2acc_1, s2acc_2); + s2acc = vaddq_u32(s2acc, s2acc_2); + + let s2acc = vaddq_u32(s2acc, s3acc); + let adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc)); + let s2acc2 = vpadd_u32(vget_low_u32(s2acc), vget_high_u32(s2acc)); + let as_ = vpadd_u32(adacc2, s2acc2); + + (vget_lane_u32(as_, 0), vget_lane_u32(as_, 1)) +} + +#[cfg(test)] +mod tests { + use super::*; + + quickcheck::quickcheck! { + fn adler32_neon_is_adler32_rust(v: Vec, start: u32) -> bool { + let neon = adler32_neon(start, &v); + let rust = crate::adler32::generic::adler32_rust(start, &v); + + rust == neon + } + } + + const INPUT: [u8; 1024] = { + let mut array = [0; 1024]; + let mut i = 0; + while i < array.len() { + array[i] = i as u8; + i += 1; + } + + array + }; + + #[test] + fn start_alignment() { + // SIMD algorithm is sensitive to alignment; + for i in 0..16 { + for start in [crate::ADLER32_INITIAL_VALUE as u32, 42] { + let neon = adler32_neon(start, &INPUT[i..]); + let rust = crate::adler32::generic::adler32_rust(start, &INPUT[i..]); + + assert_eq!(neon, rust, "offset = {i}, start = {start}"); + } + } + } + + #[test] + fn large_input() { + const DEFAULT: &[u8] = include_bytes!("../deflate/test-data/paper-100k.pdf"); + + let neon = adler32_neon(42, &DEFAULT); + let rust = crate::adler32::generic::adler32_rust(42, &DEFAULT); + + assert_eq!(neon, rust); + } +} diff --git a/third_party/rust/zlib-rs/src/allocate.rs b/third_party/rust/zlib-rs/src/allocate.rs new file mode 100644 index 0000000000..e4c8def122 --- /dev/null +++ b/third_party/rust/zlib-rs/src/allocate.rs @@ -0,0 +1,353 @@ +use core::ffi::c_int; +use core::{ + alloc::Layout, + ffi::{c_uint, c_void}, + marker::PhantomData, + mem::MaybeUninit, +}; + +#[cfg(feature = "rust-allocator")] +use alloc::alloc::GlobalAlloc; + +#[allow(non_camel_case_types)] +type size_t = usize; + +/// # Safety +/// +/// This function is safe, but must have this type signature to be used elsewhere in the library +#[cfg(unix)] +unsafe extern "C" fn zalloc_c(opaque: *mut c_void, items: c_uint, size: c_uint) -> *mut c_void { + let _ = opaque; + + extern "C" { + fn posix_memalign(memptr: *mut *mut c_void, align: size_t, size: size_t) -> c_int; + } + + let mut ptr = core::ptr::null_mut(); + match posix_memalign(&mut ptr, 64, items as size_t * size as size_t) { + 0 => ptr, + _ => core::ptr::null_mut(), + } +} + +/// # Safety +/// +/// This function is safe, but must have this type signature to be used elsewhere in the library +#[cfg(not(unix))] +unsafe extern "C" fn zalloc_c(opaque: *mut c_void, items: c_uint, size: c_uint) -> *mut c_void { + let _ = opaque; + + extern "C" { + fn malloc(size: size_t) -> *mut c_void; + } + + malloc(items as size_t * size as size_t) +} + +/// # Safety +/// +/// The `ptr` must be allocated with the allocator that is used internally by `zcfree` +unsafe extern "C" fn zfree_c(opaque: *mut c_void, ptr: *mut c_void) { + let _ = opaque; + + extern "C" { + fn free(p: *mut c_void); + } + + unsafe { free(ptr) } +} + +/// # Safety +/// +/// This function is safe to call. +#[cfg(feature = "rust-allocator")] +unsafe extern "C" fn zalloc_rust(_opaque: *mut c_void, count: c_uint, size: c_uint) -> *mut c_void { + let align = 64; + let size = count as usize * size as usize; + + // internally, we want to align allocations to 64 bytes (in part for SIMD reasons) + let layout = Layout::from_size_align(size, align).unwrap(); + + let ptr = std::alloc::System.alloc(layout); + + ptr as *mut c_void +} + +/// # Safety +/// +/// - `ptr` must be allocated with the rust `alloc::System` allocator +/// - `opaque` is a `&usize` that represents the size of the allocation +#[cfg(feature = "rust-allocator")] +unsafe extern "C" fn zfree_rust(opaque: *mut c_void, ptr: *mut c_void) { + if ptr.is_null() { + return; + } + + // we can't really do much else. Deallocating with an invalid layout is UB. + debug_assert!(!opaque.is_null()); + if opaque.is_null() { + return; + } + + let size = *(opaque as *mut usize); + let align = 64; + + let layout = Layout::from_size_align(size, align); + let layout = layout.unwrap(); + + std::alloc::System.dealloc(ptr.cast(), layout); +} + +#[derive(Clone, Copy)] +#[repr(C)] +pub struct Allocator<'a> { + pub zalloc: crate::c_api::alloc_func, + pub zfree: crate::c_api::free_func, + pub opaque: crate::c_api::voidpf, + pub _marker: PhantomData<&'a ()>, +} + +impl Allocator<'static> { + #[cfg(feature = "rust-allocator")] + pub const RUST: Self = Self { + zalloc: zalloc_rust, + zfree: zfree_rust, + opaque: core::ptr::null_mut(), + _marker: PhantomData, + }; + + #[cfg(feature = "c-allocator")] + pub const C: Self = Self { + zalloc: zalloc_c, + zfree: zfree_c, + opaque: core::ptr::null_mut(), + _marker: PhantomData, + }; +} + +impl<'a> Allocator<'a> { + pub fn allocate_layout(&self, layout: Layout) -> *mut c_void { + // Special case for the Rust `alloc` backed allocator + #[cfg(feature = "rust-allocator")] + if self.zalloc == Allocator::RUST.zalloc { + let ptr = unsafe { (Allocator::RUST.zalloc)(self.opaque, layout.size() as _, 1) }; + + debug_assert_eq!(ptr as usize % layout.align(), 0); + + return ptr; + } + + // General case for c-style allocation + + // We cannot rely on the allocator giving properly aligned allocations and have to fix that ourselves. + // + // The general approach is to allocate a bit more than the layout needs, so that we can + // give the application a properly aligned address and also store the real allocation + // pointer in the allocation so that `free` can free the real allocation pointer. + // + // + // Example: The layout represents `(u32, u32)`, with an alignment of 4 bytes and a + // total size of 8 bytes. + // + // Assume that the allocator will give us address `0x07`. We need that to be a multiple + // of the alignment, so that shifts the starting position to `0x08`. Then we also need + // to store the pointer to the start of the allocation so that `free` can free that + // pointer, bumping to `0x10`. The `0x10` pointer is then the pointer that the application + // deals with. When free'ing, the original allocation pointer can be read from `0x10 - size_of::<*const c_void>()`. + // + // Of course there does need to be enough space in the allocation such that when we + // shift the start forwards, the end is still within the allocation. Hence we allocate + // `extra_space` bytes: enough for a full alignment plus a pointer. + + // we need at least + // + // - `align` extra space so that no matter what pointer we get from zalloc, we can shift the start of the + // allocation by at most `align - 1` so that `ptr as usize % align == 0 + // - `size_of::<*mut _>` extra space so that after aligning to `align`, + // there is `size_of::<*mut _>` space to store the pointer to the allocation. + // This pointer is then retrieved in `free` + let extra_space = core::mem::size_of::<*mut c_void>() + layout.align(); + + // Safety: we assume allocating works correctly in the safety assumptions on + // `DeflateStream` and `InflateStream`. + let ptr = unsafe { (self.zalloc)(self.opaque, (layout.size() + extra_space) as _, 1) }; + + if ptr.is_null() { + return ptr; + } + + // Calculate return pointer address with space enough to store original pointer + let align_diff = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize); + + // Safety: offset is smaller than 64, and we allocated 64 extra bytes in the allocation + let mut return_ptr = unsafe { ptr.cast::().add(align_diff) }; + + // if there is not enough space to store a pointer we need to make more + if align_diff < core::mem::size_of::<*mut c_void>() { + // # Safety + // + // - `return_ptr` is well-aligned, therefore `return_ptr + align` is also well-aligned + // - we reserve `size_of::<*mut _> + align` extra space in the allocation, so + // `ptr + align_diff + align` is still valid for (at least) `layout.size` bytes + let offset = Ord::max(core::mem::size_of::<*mut c_void>(), layout.align()); + return_ptr = unsafe { return_ptr.add(offset) }; + } + + // Store the original pointer for free() + // + // Safety: `align >= size_of::<*mut _>`, so there is now space for a pointer before `return_ptr` + // in the allocation + unsafe { + let original_ptr = return_ptr.sub(core::mem::size_of::<*mut c_void>()); + core::ptr::write_unaligned(original_ptr.cast::<*mut c_void>(), ptr); + }; + + // Return properly aligned pointer in allocation + let ptr = return_ptr.cast::(); + + debug_assert_eq!(ptr as usize % layout.align(), 0); + + ptr + } + + pub fn allocate(&self) -> Option<&'a mut MaybeUninit> { + let ptr = self.allocate_layout(Layout::new::()); + + if ptr.is_null() { + None + } else { + Some(unsafe { &mut *(ptr as *mut MaybeUninit) }) + } + } + + pub fn allocate_slice(&self, len: usize) -> Option<&'a mut [MaybeUninit]> { + let ptr = self.allocate_layout(Layout::array::(len).ok()?); + + if ptr.is_null() { + None + } else { + Some(unsafe { core::slice::from_raw_parts_mut(ptr.cast(), len) }) + } + } + + /// # Panics + /// + /// - when `len` is 0 + /// + /// # Safety + /// + /// - `ptr` must be allocated with this allocator + /// - `len` must be the number of `T`s that are in this allocation + #[allow(unused)] // Rust needs `len` for deallocation + pub unsafe fn deallocate(&self, ptr: *mut T, len: usize) { + if !ptr.is_null() { + // Special case for the Rust `alloc` backed allocator + #[cfg(feature = "rust-allocator")] + if self.zfree == Allocator::RUST.zfree { + assert_ne!(len, 0, "invalid size for {:?}", ptr); + let mut size = core::mem::size_of::() * len; + return (Allocator::RUST.zfree)(&mut size as *mut usize as *mut c_void, ptr.cast()); + } + + // General case for c-style allocation + let original_ptr = (ptr as *mut u8).sub(core::mem::size_of::<*const c_void>()); + let free_ptr = core::ptr::read_unaligned(original_ptr as *mut *mut c_void); + + (self.zfree)(self.opaque, free_ptr) + } + } +} + +#[cfg(test)] +mod tests { + use core::sync::atomic::{AtomicPtr, Ordering}; + use std::sync::Mutex; + + use super::*; + + static PTR: AtomicPtr = AtomicPtr::new(core::ptr::null_mut()); + static MUTEX: Mutex<()> = Mutex::new(()); + + unsafe extern "C" fn unaligned_alloc( + _opaque: *mut c_void, + _items: c_uint, + _size: c_uint, + ) -> *mut c_void { + PTR.load(Ordering::Relaxed) + } + + unsafe extern "C" fn unaligned_free(_opaque: *mut c_void, ptr: *mut c_void) { + let expected = PTR.load(Ordering::Relaxed); + assert_eq!(expected, ptr) + } + + fn unaligned_allocator_help() { + let mut buf = [0u8; 1024]; + + // we don't want anyone else messing with the PTR static + let _guard = MUTEX.lock().unwrap(); + + for i in 0..64 { + let ptr = unsafe { buf.as_mut_ptr().add(i).cast() }; + PTR.store(ptr, Ordering::Relaxed); + + let allocator = Allocator { + zalloc: unaligned_alloc, + zfree: unaligned_free, + opaque: core::ptr::null_mut(), + _marker: PhantomData, + }; + + let ptr = allocator.allocate::().unwrap(); + assert_eq!(ptr.as_ptr() as usize % core::mem::align_of::(), 0); + unsafe { allocator.deallocate(ptr, 1) } + + let ptr = allocator.allocate_slice::(10).unwrap(); + assert_eq!(ptr.as_ptr() as usize % core::mem::align_of::(), 0); + unsafe { allocator.deallocate(ptr.as_mut_ptr(), 10) } + } + } + + #[test] + fn unaligned_allocator_0() { + unaligned_allocator_help::<()>() + } + + #[test] + fn unaligned_allocator_1() { + unaligned_allocator_help::() + } + + #[test] + fn unaligned_allocator_2() { + unaligned_allocator_help::() + } + #[test] + fn unaligned_allocator_4() { + unaligned_allocator_help::() + } + #[test] + fn unaligned_allocator_8() { + unaligned_allocator_help::() + } + #[test] + fn unaligned_allocator_16() { + unaligned_allocator_help::() + } + + #[test] + fn unaligned_allocator_32() { + #[repr(C, align(32))] + struct Align32(u8); + + unaligned_allocator_help::() + } + + #[test] + fn unaligned_allocator_64() { + #[repr(C, align(64))] + struct Align64(u8); + + unaligned_allocator_help::() + } +} diff --git a/third_party/rust/zlib-rs/src/c_api.rs b/third_party/rust/zlib-rs/src/c_api.rs new file mode 100644 index 0000000000..abee846ecf --- /dev/null +++ b/third_party/rust/zlib-rs/src/c_api.rs @@ -0,0 +1,228 @@ +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use core::ffi::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void}; + +use crate::allocate::Allocator; + +pub type alloc_func = unsafe extern "C" fn(voidpf, uInt, uInt) -> voidpf; +pub type free_func = unsafe extern "C" fn(voidpf, voidpf); + +pub type Bytef = u8; +pub type in_func = unsafe extern "C" fn(*mut c_void, *mut *const c_uchar) -> c_uint; +pub type out_func = unsafe extern "C" fn(*mut c_void, *mut c_uchar, c_uint) -> c_int; +pub type uInt = c_uint; +pub type uLong = c_ulong; +pub type uLongf = c_ulong; +pub type voidp = *mut c_void; +pub type voidpc = *const c_void; +pub type voidpf = *mut c_void; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct z_stream { + pub next_in: *const Bytef, + pub avail_in: uInt, + pub total_in: z_size, + pub next_out: *mut Bytef, + pub avail_out: uInt, + pub total_out: z_size, + pub msg: *mut c_char, + pub state: *mut internal_state, + pub zalloc: Option, + pub zfree: Option, + pub opaque: voidpf, + pub data_type: c_int, + pub adler: z_checksum, + pub reserved: uLong, +} +pub type z_streamp = *mut z_stream; + +impl Default for z_stream { + fn default() -> Self { + let mut stream = Self { + next_in: core::ptr::null_mut(), + avail_in: 0, + total_in: 0, + next_out: core::ptr::null_mut(), + avail_out: 0, + total_out: 0, + msg: core::ptr::null_mut(), + state: core::ptr::null_mut(), + zalloc: None, + zfree: None, + opaque: core::ptr::null_mut(), + data_type: 0, + adler: 0, + reserved: 0, + }; + + #[cfg(feature = "rust-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_rust_allocator() + } + + #[cfg(feature = "c-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_c_allocator() + } + + stream + } +} + +impl z_stream { + fn configure_allocator(&mut self, alloc: Allocator) { + self.zalloc = Some(alloc.zalloc); + self.zfree = Some(alloc.zfree); + self.opaque = alloc.opaque; + } + + #[cfg(feature = "rust-allocator")] + pub fn configure_default_rust_allocator(&mut self) { + self.configure_allocator(Allocator::RUST) + } + + #[cfg(feature = "c-allocator")] + pub fn configure_default_c_allocator(&mut self) { + self.configure_allocator(Allocator::C) + } +} + +// // zlib stores Adler-32 and CRC-32 checksums in unsigned long; zlib-ng uses uint32_t. +pub(crate) type z_size = c_ulong; +pub(crate) type z_checksum = c_ulong; + +// opaque to the user +pub enum internal_state {} + +pub const Z_NO_FLUSH: c_int = 0; +pub const Z_PARTIAL_FLUSH: c_int = 1; +pub const Z_SYNC_FLUSH: c_int = 2; +pub const Z_FULL_FLUSH: c_int = 3; +pub const Z_FINISH: c_int = 4; +pub const Z_BLOCK: c_int = 5; +pub const Z_TREES: c_int = 6; + +pub const Z_OK: c_int = 0; +pub const Z_STREAM_END: c_int = 1; +pub const Z_NEED_DICT: c_int = 2; +pub const Z_ERRNO: c_int = -1; +pub const Z_STREAM_ERROR: c_int = -2; +pub const Z_DATA_ERROR: c_int = -3; +pub const Z_MEM_ERROR: c_int = -4; +pub const Z_BUF_ERROR: c_int = -5; +pub const Z_VERSION_ERROR: c_int = -6; + +pub const Z_NO_COMPRESSION: c_int = 0; +pub const Z_BEST_SPEED: c_int = 1; +pub const Z_BEST_COMPRESSION: c_int = 9; +pub const Z_DEFAULT_COMPRESSION: c_int = -1; + +pub const Z_DEFLATED: c_int = 8; + +pub const Z_BINARY: c_int = 0; +pub const Z_TEXT: c_int = 1; +pub const Z_ASCII: c_int = Z_TEXT; /* for compatibility with 1.2.2 and earlier */ +pub const Z_UNKNOWN: c_int = 2; + +pub const Z_FILTERED: c_int = 1; +pub const Z_HUFFMAN_ONLY: c_int = 2; +pub const Z_RLE: c_int = 3; +pub const Z_FIXED: c_int = 4; +pub const Z_DEFAULT_STRATEGY: c_int = 0; + +pub type gz_headerp = *mut gz_header; + +/// gzip header information passed to and from zlib routines. +/// See RFC 1952 for more details on the meanings of these fields. +#[derive(Debug)] +#[repr(C)] +pub struct gz_header { + /// true if compressed data believed to be text + pub text: i32, + /// modification time + pub time: c_ulong, + /// extra flags (not used when writing a gzip file) + pub xflags: i32, + /// operating system + pub os: i32, + /// pointer to extra field or NULL if none + pub extra: *mut u8, + /// extra field length (valid if extra != NULL) + pub extra_len: u32, + /// space at extra (only when reading header) + pub extra_max: u32, + /// pointer to zero-terminated file name or NULL + pub name: *mut u8, + /// space at name (only when reading header) + pub name_max: u32, + /// pointer to zero-terminated comment or NULL + pub comment: *mut u8, + /// space at comment (only when reading header) + pub comm_max: u32, + /// true if there was or will be a header crc + pub hcrc: i32, + /// true when done reading gzip header (not used when writing a gzip file) + pub done: i32, +} + +impl Default for gz_header { + fn default() -> Self { + Self { + text: 0, + time: 0, + xflags: 0, + os: 0, + extra: core::ptr::null_mut(), + extra_len: 0, + extra_max: 0, + name: core::ptr::null_mut(), + name_max: 0, + comment: core::ptr::null_mut(), + comm_max: 0, + hcrc: 0, + done: 0, + } + } +} + +impl gz_header { + // based on the spec https://www.ietf.org/rfc/rfc1952.txt + // + // 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + // 1 - Amiga + // 2 - VMS (or OpenVMS) + // 3 - Unix + // 4 - VM/CMS + // 5 - Atari TOS + // 6 - HPFS filesystem (OS/2, NT) + // 7 - Macintosh + // 8 - Z-System + // 9 - CP/M + // 10 - TOPS-20 + // 11 - NTFS filesystem (NT) + // 12 - QDOS + // 13 - Acorn RISCOS + // 255 - unknown + #[allow(clippy::if_same_then_else)] + pub const OS_CODE: u8 = { + if cfg!(windows) { + 10 + } else if cfg!(target_os = "macos") { + 19 + } else if cfg!(unix) { + 3 + } else { + 3 // assume unix + } + }; + + pub(crate) fn flags(&self) -> u8 { + (if self.text > 0 { 1 } else { 0 }) + + (if self.hcrc > 0 { 2 } else { 0 }) + + (if self.extra.is_null() { 0 } else { 4 }) + + (if self.name.is_null() { 0 } else { 8 }) + + (if self.comment.is_null() { 0 } else { 16 }) + } +} diff --git a/third_party/rust/zlib-rs/src/cpu_features.rs b/third_party/rust/zlib-rs/src/cpu_features.rs new file mode 100644 index 0000000000..5978d78284 --- /dev/null +++ b/third_party/rust/zlib-rs/src/cpu_features.rs @@ -0,0 +1,67 @@ +#![allow(dead_code)] +#![allow(unreachable_code)] + +#[inline(always)] +pub fn is_enabled_sse() -> bool { + #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(feature = "std")] + return std::is_x86_feature_detected!("sse"); + + false +} + +#[inline(always)] +pub fn is_enabled_sse42() -> bool { + #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(feature = "std")] + return std::is_x86_feature_detected!("sse4.2"); + + false +} + +#[inline(always)] +pub fn is_enabled_avx2() -> bool { + #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(feature = "std")] + return std::is_x86_feature_detected!("avx2"); + + false +} + +#[inline(always)] +pub fn is_enabled_avx512() -> bool { + #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] + #[cfg(feature = "std")] + return std::is_x86_feature_detected!("avx512f"); + + false +} + +#[inline(always)] +pub fn is_enabled_pclmulqdq() -> bool { + #[cfg(target_arch = "x86_64")] + #[cfg(feature = "std")] + return std::is_x86_feature_detected!("pclmulqdq") + && std::is_x86_feature_detected!("sse2") + && std::is_x86_feature_detected!("sse4.1"); + + false +} + +#[inline(always)] +pub fn is_enabled_neon() -> bool { + #[cfg(target_arch = "aarch64")] + #[cfg(feature = "std")] + return std::arch::is_aarch64_feature_detected!("neon"); + + false +} + +#[inline(always)] +pub fn is_enabled_crc() -> bool { + #[cfg(target_arch = "aarch64")] + #[cfg(feature = "std")] + return std::arch::is_aarch64_feature_detected!("crc"); + + false +} diff --git a/third_party/rust/zlib-rs/src/crc32.rs b/third_party/rust/zlib-rs/src/crc32.rs new file mode 100644 index 0000000000..51e00fa2b9 --- /dev/null +++ b/third_party/rust/zlib-rs/src/crc32.rs @@ -0,0 +1,262 @@ +use core::mem::MaybeUninit; + +use crate::{read_buf::ReadBuf, CRC32_INITIAL_VALUE}; + +#[cfg(target_arch = "aarch64")] +pub(crate) mod acle; +mod braid; +mod combine; +#[cfg(target_arch = "x86_64")] +mod pclmulqdq; + +pub use combine::crc32_combine; + +pub fn crc32(start: u32, buf: &[u8]) -> u32 { + /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for + * these short lengths might also prove to be effective */ + if buf.len() < 64 { + return crc32_braid(start, buf); + } + + let mut crc_state = Crc32Fold::new_with_initial(start); + crc_state.fold(buf, start); + crc_state.finish() +} + +pub fn crc32_braid(start: u32, buf: &[u8]) -> u32 { + braid::crc32_braid::<5>(start, buf) +} + +#[allow(unused)] +pub fn crc32_copy(dst: &mut ReadBuf, buf: &[u8]) -> u32 { + /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for + * these short lengths might also prove to be effective */ + if buf.len() < 64 { + dst.extend(buf); + return braid::crc32_braid::<5>(CRC32_INITIAL_VALUE, buf); + } + + let mut crc_state = Crc32Fold::new(); + + crc_state.fold_copy(unsafe { dst.inner_mut() }, buf); + unsafe { dst.assume_init(buf.len()) }; + dst.set_filled(buf.len()); + + crc_state.finish() +} + +#[derive(Debug, Clone, Copy)] +pub struct Crc32Fold { + #[cfg(target_arch = "x86_64")] + fold: pclmulqdq::Accumulator, + value: u32, +} + +impl Default for Crc32Fold { + fn default() -> Self { + Self::new() + } +} + +impl Crc32Fold { + pub const fn new() -> Self { + Self::new_with_initial(CRC32_INITIAL_VALUE) + } + + pub const fn new_with_initial(initial: u32) -> Self { + Self { + #[cfg(target_arch = "x86_64")] + fold: pclmulqdq::Accumulator::new(), + value: initial, + } + } + + #[cfg_attr(not(target_arch = "x86_64"), allow(unused))] + pub(crate) fn is_pclmulqdq_enabled() -> bool { + crate::cpu_features::is_enabled_pclmulqdq() + } + + #[cfg_attr(not(target_arch = "aarch64"), allow(unused))] + pub(crate) fn is_crc_enabled() -> bool { + crate::cpu_features::is_enabled_crc() + } + + pub fn fold(&mut self, src: &[u8], _start: u32) { + #[cfg(target_arch = "x86_64")] + if Self::is_pclmulqdq_enabled() { + return self.fold.fold(src, _start); + } + + #[cfg(target_arch = "aarch64")] + if Self::is_crc_enabled() { + self.value = self::acle::crc32_acle_aarch64(self.value, src); + return; + } + + // in this case the start value is ignored + self.value = braid::crc32_braid::<5>(self.value, src); + } + + pub fn fold_copy(&mut self, dst: &mut [MaybeUninit], src: &[u8]) { + #[cfg(target_arch = "x86_64")] + if Self::is_pclmulqdq_enabled() { + return self.fold.fold_copy(dst, src); + } + + self.fold(src, 0); + dst[..src.len()].copy_from_slice(slice_to_uninit(src)); + } + + pub fn finish(self) -> u32 { + #[cfg(target_arch = "x86_64")] + if Self::is_pclmulqdq_enabled() { + return unsafe { self.fold.finish() }; + } + + self.value + } +} + +// when stable, use MaybeUninit::write_slice +fn slice_to_uninit(slice: &[u8]) -> &[MaybeUninit] { + // safety: &[T] and &[MaybeUninit] have the same layout + unsafe { &*(slice as *const [u8] as *const [MaybeUninit]) } +} + +#[cfg(test)] +mod test { + use test::braid::crc32_braid; + + use super::*; + + const INPUT: [u8; 1024] = { + let mut array = [0; 1024]; + let mut i = 0; + while i < array.len() { + array[i] = i as u8; + i += 1; + } + + array + }; + + #[test] + fn test_crc32_fold() { + // input large enough to trigger the SIMD + let mut h = crc32fast::Hasher::new_with_initial(CRC32_INITIAL_VALUE); + h.update(&INPUT); + assert_eq!(crc32(CRC32_INITIAL_VALUE, &INPUT), h.finalize()); + } + + #[test] + fn test_crc32_fold_align() { + // SIMD algorithm is sensitive to alignment; + for i in 0..16 { + for start in [CRC32_INITIAL_VALUE, 42] { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&INPUT[i..]); + assert_eq!( + crc32(start, &INPUT[i..]), + h.finalize(), + "offset = {i}, start = {start}" + ); + } + } + } + + #[test] + fn test_crc32_fold_copy() { + // input large enough to trigger the SIMD + let mut h = crc32fast::Hasher::new_with_initial(CRC32_INITIAL_VALUE); + h.update(&INPUT); + let mut dst = [0; INPUT.len()]; + let mut dst = ReadBuf::new(&mut dst); + + assert_eq!(crc32_copy(&mut dst, &INPUT), h.finalize()); + + assert_eq!(INPUT, dst.filled()); + } + + quickcheck::quickcheck! { + fn crc_fold_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v); + + let a = crc32(start, &v) ; + let b = h.finalize(); + + a == b + } + + fn crc_fold_copy_is_crc32fast(v: Vec) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(CRC32_INITIAL_VALUE); + h.update(&v); + + let mut dst = vec![0; v.len()]; + let mut dst = ReadBuf::new(&mut dst); + + let a = crc32_copy(&mut dst, &v) ; + let b = h.finalize(); + + assert_eq!(a,b); + + v == dst.filled() + } + } + + #[test] + fn chunked() { + const INPUT: &[&[u8]] = &[ + &[116], + &[111, 107, 105, 111, 44, 32, 97, 115], + &[121, 110, 99, 45, 115, 116, 100, 44], + &[32, 97, 110, 100, 32, 115, 109, 111], + &[108, 46, 32, 89, 111, 117, 226, 128], + &[153, 118, 101, 32, 112, 114, 111, 98], + &[97, 98, 108, 121, 32, 117, 115, 101], + &[100, 32, 116, 104, 101, 109, 32, 97], + &[116, 32, 115, 111, 109, 101, 32, 112], + &[111, 105, 110, 116, 44, 32, 101, 105], + &[116, 104, 101, 114, 32, 100, 105, 114], + &[101, 99, 116, 108, 121, 32, 111, 114], + &[0], + ]; + + const START: u32 = 2380683574; + + let mut in_chunks = START; + for chunk in INPUT { + in_chunks = crc32(in_chunks, chunk); + } + + let flattened: Vec<_> = INPUT.iter().copied().flatten().copied().collect(); + let flat = crc32(START, &flattened); + + assert_eq!(in_chunks, flat); + } + + #[test] + fn nasty_alignment() { + const START: u32 = 2380683574; + + const FLAT: &[u8] = &[ + 116, 111, 107, 105, 111, 44, 32, 97, 115, 121, 110, 99, 45, 115, 116, 100, 44, 32, 97, + 110, 100, 32, 115, 109, 111, 108, 46, 32, 89, 111, 117, 226, 128, 153, 118, 101, 32, + 112, 114, 111, 98, 97, 98, 108, 121, 32, 117, 115, 101, 100, 32, 116, 104, 101, 109, + 32, 97, 116, 32, 115, 111, 109, 101, 32, 112, 111, 105, 110, 116, 44, 32, 101, 105, + 116, 104, 101, 114, 32, 100, 105, 114, 101, 99, 116, 108, 121, 32, 111, 114, 0, + ]; + + let mut i = 0; + let mut flat = FLAT.to_vec(); + while flat[i..].as_ptr() as usize % 16 != 15 { + flat.insert(0, 0); + i += 1; + } + + let flat = &flat[i..]; + + assert_eq!(crc32_braid::<5>(START, flat), crc32(START, flat)); + assert_eq!(crc32(2380683574, flat), 1175758345); + } +} diff --git a/third_party/rust/zlib-rs/src/crc32/acle.rs b/third_party/rust/zlib-rs/src/crc32/acle.rs new file mode 100644 index 0000000000..b85ddc1067 --- /dev/null +++ b/third_party/rust/zlib-rs/src/crc32/acle.rs @@ -0,0 +1,201 @@ +#[cfg_attr(not(target_arch = "aarch64"), allow(unused))] +pub fn crc32_acle_aarch64(crc: u32, buf: &[u8]) -> u32 { + let mut c = !crc; + + let (before, middle, after) = unsafe { buf.align_to::() }; + + c = remainder(c, before); + + if middle.is_empty() && after.is_empty() { + return !c; + } + + for d in middle { + c = unsafe { __crc32d(c, *d) }; + } + + c = remainder(c, after); + + !c +} + +#[cfg_attr(not(target_arch = "arm"), allow(unused))] +pub fn crc32_acle_arm(crc: u32, buf: &[u8]) -> u32 { + let mut c = !crc; + + let (before, middle, after) = unsafe { buf.align_to::() }; + + c = remainder(c, before); + + if middle.is_empty() && after.is_empty() { + return !c; + } + + for w in middle { + c = unsafe { __crc32w(c, *w) }; + } + + c = remainder(c, after); + + !c +} + +fn remainder(mut c: u32, mut buf: &[u8]) -> u32 { + if let [b0, b1, b2, b3, rest @ ..] = buf { + c = unsafe { __crc32w(c, u32::from_le_bytes([*b0, *b1, *b2, *b3])) }; + buf = rest; + } + + if let [b0, b1, rest @ ..] = buf { + c = unsafe { __crc32h(c, u16::from_le_bytes([*b0, *b1])) }; + buf = rest; + } + + if let [b0, rest @ ..] = buf { + c = unsafe { __crc32b(c, *b0) }; + buf = rest; + } + + debug_assert!(buf.is_empty()); + + c +} + +/// CRC32 single round checksum for bytes (8 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32b) +#[target_feature(enable = "crc")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +unsafe fn __crc32b(mut crc: u32, data: u8) -> u32 { + core::arch::asm!("crc32b {crc:w}, {crc:w}, {data:w}", crc = inout(reg) crc, data = in(reg) data); + crc +} + +/// CRC32 single round checksum for half words (16 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32h) +#[target_feature(enable = "crc")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +unsafe fn __crc32h(mut crc: u32, data: u16) -> u32 { + core::arch::asm!("crc32h {crc:w}, {crc:w}, {data:w}", crc = inout(reg) crc, data = in(reg) data); + crc +} + +/// CRC32 single round checksum for words (32 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32w) +#[target_feature(enable = "crc")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +pub unsafe fn __crc32w(mut crc: u32, data: u32) -> u32 { + core::arch::asm!("crc32w {crc:w}, {crc:w}, {data:w}", crc = inout(reg) crc, data = in(reg) data); + crc +} + +/// CRC32 single round checksum for double words (64 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d) +#[cfg(target_arch = "aarch64")] +#[target_feature(enable = "crc")] +unsafe fn __crc32d(mut crc: u32, data: u64) -> u32 { + core::arch::asm!("crc32x {crc:w}, {crc:w}, {data:x}", crc = inout(reg) crc, data = in(reg) data); + crc +} + +/// CRC32-C single round checksum for words (32 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cw) +#[target_feature(enable = "crc")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +pub unsafe fn __crc32cw(mut crc: u32, data: u32) -> u32 { + core::arch::asm!("crc32cw {crc:w}, {crc:w}, {data:w}", crc = inout(reg) crc, data = in(reg) data); + crc +} + +#[cfg(test)] +mod tests { + use super::*; + + quickcheck::quickcheck! { + #[cfg(target_arch = "aarch64")] + fn crc32_acle_aarch64_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v); + + let a = crc32_acle_aarch64(start, &v) ; + let b = h.finalize(); + + a == b + } + + fn crc32_acle_arm_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v); + + let a = crc32_acle_arm(start, &v) ; + let b = h.finalize(); + + a == b + } + } + + #[test] + fn test_crc32b() { + if !crate::crc32::Crc32Fold::is_crc_enabled() { + return; + } + + unsafe { + assert_eq!(__crc32b(0, 0), 0); + assert_eq!(__crc32b(0, 255), 755167117); + } + } + + #[test] + fn test_crc32h() { + if !crate::crc32::Crc32Fold::is_crc_enabled() { + return; + } + + unsafe { + assert_eq!(__crc32h(0, 0), 0); + assert_eq!(__crc32h(0, 16384), 1994146192); + } + } + + #[test] + fn test_crc32w() { + if !crate::crc32::Crc32Fold::is_crc_enabled() { + return; + } + + unsafe { + assert_eq!(__crc32w(0, 0), 0); + assert_eq!(__crc32w(0, 4294967295), 3736805603); + } + } + + #[test] + #[cfg(target_arch = "aarch64")] + fn test_crc32d() { + if !crate::crc32::Crc32Fold::is_crc_enabled() { + return; + } + + unsafe { + assert_eq!(__crc32d(0, 0), 0); + assert_eq!(__crc32d(0, 18446744073709551615), 1147535477); + } + } + + #[test] + fn test_crc32cw() { + if !crate::crc32::Crc32Fold::is_crc_enabled() { + return; + } + + unsafe { + assert_eq!(__crc32cw(0, 0), 0); + assert_eq!(__crc32cw(0, 4294967295), 3080238136); + } + } +} diff --git a/third_party/rust/zlib-rs/src/crc32/braid.rs b/third_party/rust/zlib-rs/src/crc32/braid.rs new file mode 100644 index 0000000000..dc3b744f91 --- /dev/null +++ b/third_party/rust/zlib-rs/src/crc32/braid.rs @@ -0,0 +1,202 @@ +// Several implementations of CRC-32: +// * A naive byte-granularity approach +// * A word-sized approach that processes a usize word at a time +// * A "braid" implementation that processes a block of N words +// at a time, based on the algorithm in section 4.11 from +// https://github.com/zlib-ng/zlib-ng/blob/develop/doc/crc-doc.1.0.pdf. + +// The binary encoding of the CRC-32 polynomial. +// We are assuming little-endianness so we process the input +// LSB-first. We need to use the "reversed" value from e.g +// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Polynomial_representations. +pub(crate) const CRC32_LSB_POLY: usize = 0xedb8_8320usize; + +const W: usize = core::mem::size_of::(); + +// The logic assumes that W >= sizeof(u32). +// In Rust, this is generally true. +const _: () = assert!(W >= core::mem::size_of::()); + +// Pre-computed tables for the CRC32 algorithm. +// CRC32_BYTE_TABLE corresponds to MulByXPowD from the paper. +static CRC32_BYTE_TABLE: [[u32; 256]; 1] = build_crc32_table::<256, 1, 1>(); +// CRC32_WORD_TABLE is MulWordByXpowD. +static CRC32_WORD_TABLE: [[u32; 256]; W] = build_crc32_table::<256, W, 1>(); + +// Work-around for not being able to define generic consts or statics +// Crc32BraidTable::::TABLE is the generic table for any braid size N. +struct Crc32BraidTable; + +impl Crc32BraidTable { + const TABLE: [[u32; 256]; W] = build_crc32_table::<256, W, N>(); +} + +// Build the CRC32 tables using a more efficient and simpler approach +// than the combination of Multiply and XpowN (which implement polynomial +// multiplication and exponentiation, respectively) from the paper, +// but with identical results. This function is const, so it should be +// fully evaluated at compile time. +const fn build_crc32_table() -> [[u32; A]; W] { + let mut arr = [[0u32; A]; W]; + let mut i = 0; + while i < W { + let mut j = 0; + while j < A { + let mut c = j; + let mut k = 0; + while k < 8 * (W * N - i) { + if c & 1 != 0 { + c = CRC32_LSB_POLY ^ (c >> 1); + } else { + c >>= 1; + } + k += 1; + } + arr[i][j] = c as u32; + j += 1; + } + i += 1; + } + arr +} + +fn crc32_naive_inner(data: &[u8], start: u32) -> u32 { + data.iter().fold(start, |crc, val| { + let crc32_lsb = crc.to_le_bytes()[0]; + CRC32_BYTE_TABLE[0][usize::from(crc32_lsb ^ *val)] ^ (crc >> 8) + }) +} + +fn crc32_words_inner(words: &[usize], start: u32, per_word_crcs: &[u32]) -> u32 { + words.iter().enumerate().fold(start, |crc, (i, word)| { + let value = word.to_le() ^ (crc ^ per_word_crcs.get(i).unwrap_or(&0)) as usize; + value + .to_le_bytes() + .into_iter() + .zip(CRC32_WORD_TABLE) + .fold(0u32, |crc, (b, tab)| crc ^ tab[usize::from(b)]) + }) +} + +pub fn crc32_braid(start: u32, data: &[u8]) -> u32 { + // Get a word-aligned sub-slice of the input data + let (prefix, words, suffix) = unsafe { data.align_to::() }; + let crc = !start; + let crc = crc32_naive_inner(prefix, crc); + + let mut crcs = [0u32; N]; + crcs[0] = crc; + + // TODO: this would normally use words.chunks_exact(N), but + // we need to pass the last full block to crc32_words_inner + // because we accumulate partial crcs in the array and we + // need to roll those into the final value. The last call to + // crc32_words_inner does that for us with its per_word_crcs + // argument. + let blocks = words.len() / N; + let blocks = blocks.saturating_sub(1); + for i in 0..blocks { + // Load the next N words. + let mut buffer: [usize; N] = + core::array::from_fn(|j| usize::to_le(words[i * N + j]) ^ (crcs[j] as usize)); + + crcs.fill(0); + for j in 0..W { + for k in 0..N { + crcs[k] ^= Crc32BraidTable::::TABLE[j][buffer[k] & 0xff]; + buffer[k] >>= 8; + } + } + } + + let crc = core::mem::take(&mut crcs[0]); + let crc = crc32_words_inner(&words[blocks * N..], crc, &crcs); + let crc = crc32_naive_inner(suffix, crc); + !crc +} + +#[cfg(test)] +mod test { + use super::*; + + fn crc32_naive(data: &[u8], start: u32) -> u32 { + let crc = !start; + let crc = crc32_naive_inner(data, crc); + !crc + } + + fn crc32_words(data: &[u8], start: u32) -> u32 { + // Get a word-aligned sub-slice of the input data + let (prefix, words, suffix) = unsafe { data.align_to::() }; + let crc = !start; + let crc = crc32_naive_inner(prefix, crc); + let crc = crc32_words_inner(words, crc, &[]); + let crc = crc32_naive_inner(suffix, crc); + !crc + } + + #[test] + fn empty_is_identity() { + assert_eq!(crc32_naive(&[], 32), 32); + } + + #[test] + fn words_endianness() { + let v = [0, 0, 0, 0, 0, 16, 0, 1]; + let start = 1534327806; + + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + assert_eq!(crc32_words(&v[..], start), h.finalize()); + } + + #[test] + fn crc32_naive_inner_endianness_and_alignment() { + assert_eq!(crc32_naive_inner(&[0, 1], 0), 1996959894); + + let v: Vec<_> = (0..1024).map(|i| i as u8).collect(); + let start = 0; + + // test alignment + for i in 0..8 { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[i..]); + assert_eq!(crc32_braid::<5>(start, &v[i..]), h.finalize()); + } + } + + quickcheck::quickcheck! { + fn naive_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + crc32_naive(&v[..], start) == h.finalize() + } + + fn words_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + crc32_words(&v[..], start) == h.finalize() + } + + #[cfg_attr(miri, ignore)] + fn braid_4_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + crc32_braid::<4>(start, &v[..]) == h.finalize() + } + + #[cfg_attr(miri, ignore)] + fn braid_5_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + crc32_braid::<5>(start, &v[..]) == h.finalize() + } + + #[cfg_attr(miri, ignore)] + fn braid_6_is_crc32fast(v: Vec, start: u32) -> bool { + let mut h = crc32fast::Hasher::new_with_initial(start); + h.update(&v[..]); + crc32_braid::<6>(start, &v[..]) == h.finalize() + } + } +} diff --git a/third_party/rust/zlib-rs/src/crc32/combine.rs b/third_party/rust/zlib-rs/src/crc32/combine.rs new file mode 100644 index 0000000000..40e3745dd2 --- /dev/null +++ b/third_party/rust/zlib-rs/src/crc32/combine.rs @@ -0,0 +1,115 @@ +use super::braid::CRC32_LSB_POLY; + +pub const fn crc32_combine(crc1: u32, crc2: u32, len2: u64) -> u32 { + crc32_combine_op(crc1, crc2, crc32_combine_gen(len2)) +} + +#[inline(always)] +const fn crc32_combine_gen(len2: u64) -> u32 { + x2nmodp(len2, 3) +} + +#[inline(always)] +const fn crc32_combine_op(crc1: u32, crc2: u32, op: u32) -> u32 { + multmodp(op, crc1) ^ crc2 +} + +const X2N_TABLE: [u32; 32] = [ + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, 0xedb88320, 0xb1e6b092, 0xa06a2517, + 0xed627dae, 0x88d14467, 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, 0x09fe548f, + 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, + 0xbad90e37, 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, 0xc40ba6d0, 0xc4e22c3c, +]; + +// Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, +// reflected. For speed, this requires that a not be zero. +const fn multmodp(a: u32, mut b: u32) -> u32 { + let mut m = 1 << 31; + let mut p = 0; + + loop { + if (a & m) != 0 { + p ^= b; + if (a & (m - 1)) == 0 { + break; + } + } + m >>= 1; + b = if (b & 1) != 0 { + (b >> 1) ^ CRC32_LSB_POLY as u32 + } else { + b >> 1 + }; + } + + p +} + +// Return x^(n * 2^k) modulo p(x). +const fn x2nmodp(mut n: u64, mut k: u32) -> u32 { + let mut p: u32 = 1 << 31; /* x^0 == 1 */ + + while n > 0 { + if (n & 1) != 0 { + p = multmodp(X2N_TABLE[k as usize & 31], p); + } + n >>= 1; + k += 1; + } + + p +} + +#[cfg(test)] +mod test { + use super::*; + + use crate::crc32; + + #[test] + fn test_crc32_combine() { + ::quickcheck::quickcheck(test as fn(_) -> _); + + fn test(data: Vec) -> bool { + let Some(buf_len) = data.first().copied() else { + return true; + }; + + let buf_size = Ord::max(buf_len, 1) as usize; + + let crc0 = 0; + let mut crc1 = crc0; + let mut crc2 = crc0; + + /* CRC32 */ + for chunk in data.chunks(buf_size) { + let crc3 = crc32(crc0, chunk); + let op = crc32_combine_gen(chunk.len() as _); + let crc4 = crc32_combine_op(crc1, crc3, op); + crc1 = crc32(crc1, chunk); + + assert_eq!(crc1, crc4); + } + + crc2 = crc32(crc2, &data); + + assert_eq!(crc1, crc2); + + let combine1 = crc32_combine(crc1, crc2, data.len() as _); + let combine2 = crc32_combine(crc1, crc1, data.len() as _); + assert_eq!(combine1, combine2); + + // Fast CRC32 combine. + let op = crc32_combine_gen(data.len() as _); + let combine1 = crc32_combine_op(crc1, crc2, op); + let combine2 = crc32_combine_op(crc2, crc1, op); + assert_eq!(combine1, combine2); + + let combine1 = crc32_combine(crc1, crc2, data.len() as _); + let combine2 = crc32_combine_op(crc2, crc1, op); + assert_eq!(combine1, combine2); + + true + } + } +} diff --git a/third_party/rust/zlib-rs/src/crc32/pclmulqdq.rs b/third_party/rust/zlib-rs/src/crc32/pclmulqdq.rs new file mode 100644 index 0000000000..9eb2761830 --- /dev/null +++ b/third_party/rust/zlib-rs/src/crc32/pclmulqdq.rs @@ -0,0 +1,342 @@ +use core::arch::x86_64::__m128i; +use core::{ + arch::x86_64::{ + _mm_and_si128, _mm_clmulepi64_si128, _mm_extract_epi32, _mm_load_si128, _mm_loadu_si128, + _mm_or_si128, _mm_shuffle_epi8, _mm_slli_si128, _mm_srli_si128, _mm_storeu_si128, + _mm_xor_si128, + }, + mem::MaybeUninit, +}; + +use crate::{crc32::slice_to_uninit, CRC32_INITIAL_VALUE}; + +#[derive(Debug)] +#[repr(C, align(16))] +struct Align16(T); + +#[cfg(target_arch = "x86_64")] +const fn reg(input: [u32; 4]) -> __m128i { + // safety: any valid [u32; 4] represents a valid __m128i + unsafe { core::mem::transmute(input) } +} + +#[derive(Debug, Clone, Copy)] +#[cfg(target_arch = "x86_64")] +pub(crate) struct Accumulator { + fold: [__m128i; 4], +} + +#[cfg(target_arch = "x86_64")] +impl Accumulator { + const XMM_FOLD4: __m128i = reg([0xc6e41596u32, 0x00000001u32, 0x54442bd4u32, 0x00000001u32]); + + pub const fn new() -> Self { + let xmm_crc0 = reg([0x9db42487, 0, 0, 0]); + let xmm_zero = reg([0, 0, 0, 0]); + + Self { + fold: [xmm_crc0, xmm_zero, xmm_zero, xmm_zero], + } + } + + pub fn fold(&mut self, src: &[u8], start: u32) { + unsafe { self.fold_help::(&mut [], src, start) } + } + + pub fn fold_copy(&mut self, dst: &mut [MaybeUninit], src: &[u8]) { + unsafe { self.fold_help::(dst, src, 0) } + } + + #[target_feature(enable = "pclmulqdq", enable = "sse2", enable = "sse4.1")] + pub unsafe fn finish(self) -> u32 { + const CRC_MASK1: __m128i = + reg([0xFFFFFFFFu32, 0xFFFFFFFFu32, 0x00000000u32, 0x00000000u32]); + + const CRC_MASK2: __m128i = + reg([0x00000000u32, 0xFFFFFFFFu32, 0xFFFFFFFFu32, 0xFFFFFFFFu32]); + + const RK1_RK2: __m128i = reg([ + 0xccaa009e, 0x00000000, /* rk1 */ + 0x751997d0, 0x00000001, /* rk2 */ + ]); + + const RK5_RK6: __m128i = reg([ + 0xccaa009e, 0x00000000, /* rk5 */ + 0x63cd6124, 0x00000001, /* rk6 */ + ]); + + const RK7_RK8: __m128i = reg([ + 0xf7011640, 0x00000001, /* rk7 */ + 0xdb710640, 0x00000001, /* rk8 */ + ]); + + let [mut xmm_crc0, mut xmm_crc1, mut xmm_crc2, mut xmm_crc3] = self.fold; + + /* + * k1 + */ + let mut crc_fold = RK1_RK2; + + let x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); + xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); + xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); + + let x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); + xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); + xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); + + let x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); + xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); + xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + + /* + * k5 + */ + crc_fold = RK5_RK6; + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + xmm_crc3 = _mm_and_si128(xmm_crc3, CRC_MASK2); + + /* + * k7 + */ + xmm_crc1 = xmm_crc3; + xmm_crc2 = xmm_crc3; + crc_fold = RK7_RK8; + + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_and_si128(xmm_crc3, CRC_MASK1); + + xmm_crc2 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); + + !(_mm_extract_epi32(xmm_crc3, 2) as u32) + } + + fn fold_step(&mut self) { + self.fold = core::array::from_fn(|i| match self.fold.get(i + N) { + Some(v) => *v, + None => unsafe { Self::step(self.fold[(i + N) - 4]) }, + }); + } + + #[inline(always)] + unsafe fn step(input: __m128i) -> __m128i { + _mm_xor_si128( + _mm_clmulepi64_si128(input, Self::XMM_FOLD4, 0x01), + _mm_clmulepi64_si128(input, Self::XMM_FOLD4, 0x10), + ) + } + + unsafe fn partial_fold(&mut self, xmm_crc_part: __m128i, len: usize) { + const PSHUFB_SHF_TABLE: [__m128i; 15] = [ + reg([0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d]), /* shl 15 (16 - 1)/shr1 */ + reg([0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e]), /* shl 14 (16 - 3)/shr2 */ + reg([0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f]), /* shl 13 (16 - 4)/shr3 */ + reg([0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100]), /* shl 12 (16 - 4)/shr4 */ + reg([0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201]), /* shl 11 (16 - 5)/shr5 */ + reg([0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302]), /* shl 10 (16 - 6)/shr6 */ + reg([0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403]), /* shl 9 (16 - 7)/shr7 */ + reg([0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504]), /* shl 8 (16 - 8)/shr8 */ + reg([0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605]), /* shl 7 (16 - 9)/shr9 */ + reg([0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706]), /* shl 6 (16 -10)/shr10*/ + reg([0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807]), /* shl 5 (16 -11)/shr11*/ + reg([0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908]), /* shl 4 (16 -12)/shr12*/ + reg([0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09]), /* shl 3 (16 -13)/shr13*/ + reg([0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a]), /* shl 2 (16 -14)/shr14*/ + reg([0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b]), /* shl 1 (16 -15)/shr15*/ + ]; + + let xmm_shl = PSHUFB_SHF_TABLE[len - 1]; + let xmm_shr = _mm_xor_si128(xmm_shl, reg([0x80808080u32; 4])); + + let xmm_a0 = Self::step(_mm_shuffle_epi8(self.fold[0], xmm_shl)); + + self.fold[0] = _mm_shuffle_epi8(self.fold[0], xmm_shr); + let xmm_tmp1 = _mm_shuffle_epi8(self.fold[1], xmm_shl); + self.fold[0] = _mm_or_si128(self.fold[0], xmm_tmp1); + + self.fold[1] = _mm_shuffle_epi8(self.fold[1], xmm_shr); + let xmm_tmp2 = _mm_shuffle_epi8(self.fold[2], xmm_shl); + self.fold[1] = _mm_or_si128(self.fold[1], xmm_tmp2); + + self.fold[2] = _mm_shuffle_epi8(self.fold[2], xmm_shr); + let xmm_tmp3 = _mm_shuffle_epi8(self.fold[3], xmm_shl); + self.fold[2] = _mm_or_si128(self.fold[2], xmm_tmp3); + + self.fold[3] = _mm_shuffle_epi8(self.fold[3], xmm_shr); + let xmm_crc_part = _mm_shuffle_epi8(xmm_crc_part, xmm_shl); + self.fold[3] = _mm_or_si128(self.fold[3], xmm_crc_part); + + // zlib-ng uses casts and a floating-point xor instruction here. There is a theory that + // this breaks dependency chains on some CPUs and gives better throughput. Other sources + // claim that casting between integer and float has a cost and should be avoided. We can't + // measure the difference, and choose the shorter code. + self.fold[3] = _mm_xor_si128(self.fold[3], xmm_a0) + } + + #[allow(clippy::needless_range_loop)] + fn progress( + &mut self, + dst: &mut [MaybeUninit], + src: &mut &[u8], + init_crc: &mut u32, + ) -> usize { + let mut it = src.chunks_exact(16); + let mut input: [_; N] = core::array::from_fn(|_| unsafe { + _mm_load_si128(it.next().unwrap().as_ptr() as *const __m128i) + }); + + *src = &src[N * 16..]; + + if COPY { + for (s, d) in input[..N].iter().zip(dst.chunks_exact_mut(16)) { + unsafe { _mm_storeu_si128(d.as_mut_ptr() as *mut __m128i, *s) }; + } + } else if *init_crc != CRC32_INITIAL_VALUE { + let xmm_initial = reg([*init_crc, 0, 0, 0]); + input[0] = unsafe { _mm_xor_si128(input[0], xmm_initial) }; + *init_crc = CRC32_INITIAL_VALUE; + } + + self.fold_step::(); + + for i in 0..N { + self.fold[i + (4 - N)] = unsafe { _mm_xor_si128(self.fold[i + (4 - N)], input[i]) }; + } + + if COPY { + N * 16 + } else { + 0 + } + } + + #[target_feature(enable = "pclmulqdq", enable = "sse2", enable = "sse4.1")] + unsafe fn fold_help( + &mut self, + mut dst: &mut [MaybeUninit], + mut src: &[u8], + mut init_crc: u32, + ) { + let mut xmm_crc_part = reg([0; 4]); + + let mut partial_buf = Align16([0u8; 16]); + + // Technically the CRC functions don't even call this for input < 64, but a bare minimum of 31 + // bytes of input is needed for the aligning load that occurs. If there's an initial CRC, to + // carry it forward through the folded CRC there must be 16 - src % 16 + 16 bytes available, which + // by definition can be up to 15 bytes + one full vector load. */ + assert!(src.len() >= 31 || init_crc == CRC32_INITIAL_VALUE); + + if COPY { + assert_eq!(dst.len(), src.len(), "dst and src must be the same length") + } + + if src.len() < 16 { + if COPY { + if src.is_empty() { + return; + } + + partial_buf.0[..src.len()].copy_from_slice(src); + xmm_crc_part = _mm_load_si128(partial_buf.0.as_mut_ptr() as *mut __m128i); + dst[..src.len()].copy_from_slice(slice_to_uninit(&partial_buf.0[..src.len()])); + } + } else { + let (before, _, _) = unsafe { src.align_to::<__m128i>() }; + + if !before.is_empty() { + xmm_crc_part = _mm_loadu_si128(src.as_ptr() as *const __m128i); + if COPY { + _mm_storeu_si128(dst.as_mut_ptr() as *mut __m128i, xmm_crc_part); + dst = &mut dst[before.len()..]; + } else { + let is_initial = init_crc == CRC32_INITIAL_VALUE; + + if !is_initial { + let xmm_initial = reg([init_crc, 0, 0, 0]); + xmm_crc_part = _mm_xor_si128(xmm_crc_part, xmm_initial); + init_crc = CRC32_INITIAL_VALUE; + } + + if before.len() < 4 && !is_initial { + let xmm_t0 = xmm_crc_part; + xmm_crc_part = _mm_loadu_si128((src.as_ptr() as *const __m128i).add(1)); + + self.fold_step::<1>(); + + self.fold[3] = _mm_xor_si128(self.fold[3], xmm_t0); + src = &src[16..]; + } + } + + self.partial_fold(xmm_crc_part, before.len()); + + src = &src[before.len()..]; + } + + // if is_x86_feature_detected!("vpclmulqdq") { + // if src.len() >= 256 { + // if COPY { + // // size_t n = fold_16_vpclmulqdq_copy(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, dst, src, len); + // // dst += n; + // } else { + // // size_t n = fold_16_vpclmulqdq(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, src, len, xmm_initial, first); + // // first = false; + // } + // // len -= n; + // // src += n; + // } + // } + + while src.len() >= 64 { + let n = self.progress::<4, COPY>(dst, &mut src, &mut init_crc); + dst = &mut dst[n..]; + } + + if src.len() >= 48 { + let n = self.progress::<3, COPY>(dst, &mut src, &mut init_crc); + dst = &mut dst[n..]; + } else if src.len() >= 32 { + let n = self.progress::<2, COPY>(dst, &mut src, &mut init_crc); + dst = &mut dst[n..]; + } else if src.len() >= 16 { + let n = self.progress::<1, COPY>(dst, &mut src, &mut init_crc); + dst = &mut dst[n..]; + } + } + + if !src.is_empty() { + core::ptr::copy_nonoverlapping( + src.as_ptr(), + &mut xmm_crc_part as *mut _ as *mut u8, + src.len(), + ); + if COPY { + _mm_storeu_si128(partial_buf.0.as_mut_ptr() as *mut __m128i, xmm_crc_part); + core::ptr::copy_nonoverlapping( + partial_buf.0.as_ptr() as *const MaybeUninit, + dst.as_mut_ptr(), + src.len(), + ); + } + + self.partial_fold(xmm_crc_part, src.len()); + } + } +} diff --git a/third_party/rust/zlib-rs/src/deflate.rs b/third_party/rust/zlib-rs/src/deflate.rs new file mode 100644 index 0000000000..f47ce2309a --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate.rs @@ -0,0 +1,4146 @@ +use core::{ffi::CStr, marker::PhantomData, mem::MaybeUninit, ops::ControlFlow}; + +use crate::{ + adler32::adler32, + allocate::Allocator, + c_api::{gz_header, internal_state, z_checksum, z_stream}, + crc32::{crc32, Crc32Fold}, + read_buf::ReadBuf, + trace, DeflateFlush, ReturnCode, ADLER32_INITIAL_VALUE, CRC32_INITIAL_VALUE, MAX_WBITS, + MIN_WBITS, +}; + +use self::{ + algorithm::CONFIGURATION_TABLE, + hash_calc::{Crc32HashCalc, HashCalcVariant, RollHashCalc, StandardHashCalc}, + pending::Pending, + trees_tbl::STATIC_LTREE, + window::Window, +}; + +mod algorithm; +mod compare256; +mod hash_calc; +mod longest_match; +mod pending; +mod slide_hash; +mod trees_tbl; +mod window; + +#[repr(C)] +pub struct DeflateStream<'a> { + pub(crate) next_in: *mut crate::c_api::Bytef, + pub(crate) avail_in: crate::c_api::uInt, + pub(crate) total_in: crate::c_api::z_size, + pub(crate) next_out: *mut crate::c_api::Bytef, + pub(crate) avail_out: crate::c_api::uInt, + pub(crate) total_out: crate::c_api::z_size, + pub(crate) msg: *const core::ffi::c_char, + pub(crate) state: &'a mut State<'a>, + pub(crate) alloc: Allocator<'a>, + pub(crate) data_type: core::ffi::c_int, + pub(crate) adler: crate::c_api::z_checksum, + pub(crate) reserved: crate::c_api::uLong, +} + +impl<'a> DeflateStream<'a> { + const _S: () = assert!(core::mem::size_of::() == core::mem::size_of::()); + const _A: () = assert!(core::mem::align_of::() == core::mem::align_of::()); + + /// # Safety + /// + /// Behavior is undefined if any of the following conditions are violated: + /// + /// - `strm` satisfies the conditions of [`pointer::as_mut`] + /// - if not `NULL`, `strm` as initialized using [`init`] or similar + /// + /// [`pointer::as_mut`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_mut + #[inline(always)] + pub unsafe fn from_stream_mut(strm: *mut z_stream) -> Option<&'a mut Self> { + { + // Safety: ptr points to a valid value of type z_stream (if non-null) + let stream = unsafe { strm.as_ref() }?; + + if stream.zalloc.is_none() || stream.zfree.is_none() { + return None; + } + + if stream.state.is_null() { + return None; + } + } + + // Safety: DeflateStream has an equivalent layout as z_stream + unsafe { strm.cast::().as_mut() } + } + + fn as_z_stream_mut(&mut self) -> &mut z_stream { + // safety: a valid &mut DeflateStream is also a valid &mut z_stream + unsafe { &mut *(self as *mut DeflateStream as *mut z_stream) } + } + + pub fn pending(&self) -> (usize, u8) { + ( + self.state.bit_writer.pending.pending, + self.state.bit_writer.bits_used, + ) + } +} + +/// number of elements in hash table +pub(crate) const HASH_SIZE: usize = 65536; +/// log2(HASH_SIZE) +const HASH_BITS: usize = 16; + +/// Maximum value for memLevel in deflateInit2 +const MAX_MEM_LEVEL: i32 = 9; +const DEF_MEM_LEVEL: i32 = if MAX_MEM_LEVEL > 8 { 8 } else { MAX_MEM_LEVEL }; + +#[repr(i32)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +#[cfg_attr(feature = "__internal-fuzz", derive(arbitrary::Arbitrary))] +pub enum Method { + #[default] + Deflated = 8, +} + +impl TryFrom for Method { + type Error = (); + + fn try_from(value: i32) -> Result { + match value { + 8 => Ok(Self::Deflated), + _ => Err(()), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "__internal-fuzz", derive(arbitrary::Arbitrary))] +pub struct DeflateConfig { + pub level: i32, + pub method: Method, + pub window_bits: i32, + pub mem_level: i32, + pub strategy: Strategy, +} + +#[cfg(any(test, feature = "__internal-test"))] +impl quickcheck::Arbitrary for DeflateConfig { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + let mem_levels: Vec<_> = (1..=9).collect(); + let levels: Vec<_> = (0..=9).collect(); + + let mut window_bits = Vec::new(); + window_bits.extend(9..=15); // zlib + window_bits.extend(9 + 16..=15 + 16); // gzip + window_bits.extend(-15..=-9); // raw + + Self { + level: *g.choose(&levels).unwrap(), + method: Method::Deflated, + window_bits: *g.choose(&window_bits).unwrap(), + mem_level: *g.choose(&mem_levels).unwrap(), + strategy: *g + .choose(&[ + Strategy::Default, + Strategy::Filtered, + Strategy::HuffmanOnly, + Strategy::Rle, + Strategy::Fixed, + ]) + .unwrap(), + } + } +} + +impl DeflateConfig { + pub fn new(level: i32) -> Self { + Self { + level, + ..Self::default() + } + } +} + +impl Default for DeflateConfig { + fn default() -> Self { + Self { + level: crate::c_api::Z_DEFAULT_COMPRESSION, + method: Method::Deflated, + window_bits: MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::Default, + } + } +} + +// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable. +unsafe fn slice_assume_init_mut(slice: &mut [MaybeUninit]) -> &mut [T] { + &mut *(slice as *mut [MaybeUninit] as *mut [T]) +} + +// when stable, use MaybeUninit::write_slice +fn slice_to_uninit(slice: &[T]) -> &[MaybeUninit] { + // safety: &[T] and &[MaybeUninit] have the same layout + unsafe { &*(slice as *const [T] as *const [MaybeUninit]) } +} + +pub fn init(stream: &mut z_stream, config: DeflateConfig) -> ReturnCode { + let DeflateConfig { + mut level, + method: _, + mut window_bits, + mem_level, + strategy, + } = config; + + /* Todo: ignore strm->next_in if we use it as window */ + stream.msg = core::ptr::null_mut(); + + // for safety we must really make sure that alloc and free are consistent + // this is a (slight) deviation from stock zlib. In this crate we pick the rust + // allocator as the default, but `libz-rs-sys` always explicitly sets an allocator, + // and can configure the C allocator + #[cfg(feature = "rust-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_rust_allocator() + } + + #[cfg(feature = "c-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_c_allocator() + } + + if stream.zalloc.is_none() || stream.zfree.is_none() { + return ReturnCode::StreamError; + } + + if level == crate::c_api::Z_DEFAULT_COMPRESSION { + level = 6; + } + + let wrap = if window_bits < 0 { + if window_bits < -MAX_WBITS { + return ReturnCode::StreamError; + } + window_bits = -window_bits; + + 0 + } else if window_bits > MAX_WBITS { + window_bits -= 16; + 2 + } else { + 1 + }; + + if (!(1..=MAX_MEM_LEVEL).contains(&mem_level)) + || !(MIN_WBITS..=MAX_WBITS).contains(&window_bits) + || !(0..=9).contains(&level) + || (window_bits == 8 && wrap != 1) + { + return ReturnCode::StreamError; + } + + let window_bits = if window_bits == 8 { + 9 /* until 256-byte window bug fixed */ + } else { + window_bits as usize + }; + + let alloc = Allocator { + zalloc: stream.zalloc.unwrap(), + zfree: stream.zfree.unwrap(), + opaque: stream.opaque, + _marker: PhantomData, + }; + + // allocated here to have the same order as zlib + let Some(state_allocation) = alloc.allocate::() else { + return ReturnCode::MemError; + }; + + let w_size = 1 << window_bits; + let window = Window::new_in(&alloc, window_bits); + + let prev = alloc.allocate_slice::(w_size); + let head = alloc.allocate::<[u16; HASH_SIZE]>(); + + let lit_bufsize = 1 << (mem_level + 6); // 16K elements by default + let pending = Pending::new_in(&alloc, 4 * lit_bufsize); + + // zlib-ng overlays the pending_buf and sym_buf. We cannot really do that safely + let sym_buf = ReadBuf::new_in(&alloc, 3 * lit_bufsize); + + // if any allocation failed, clean up allocations that did succeed + let (window, prev, head, pending, sym_buf) = match (window, prev, head, pending, sym_buf) { + (Some(window), Some(prev), Some(head), Some(pending), Some(sym_buf)) => { + (window, prev, head, pending, sym_buf) + } + (window, prev, head, pending, sym_buf) => { + unsafe { + if let Some(mut sym_buf) = sym_buf { + alloc.deallocate(sym_buf.as_mut_ptr(), sym_buf.capacity()) + } + if let Some(pending) = pending { + pending.drop_in(&alloc); + } + if let Some(head) = head { + alloc.deallocate(head.as_mut_ptr(), 1) + } + if let Some(prev) = prev { + alloc.deallocate(prev.as_mut_ptr(), prev.len()) + } + if let Some(mut window) = window { + window.drop_in(&alloc); + } + + alloc.deallocate(state_allocation.as_mut_ptr(), 1); + } + + return ReturnCode::MemError; + } + }; + + prev.fill(MaybeUninit::zeroed()); + let prev = unsafe { slice_assume_init_mut(prev) }; + + *head = MaybeUninit::zeroed(); + let head = unsafe { head.assume_init_mut() }; + + let state = State { + status: Status::Init, + + // window + w_bits: window_bits, + w_size, + w_mask: w_size - 1, + + // allocated values + window, + prev, + head, + bit_writer: BitWriter::from_pending(pending), + + // + lit_bufsize, + + // + sym_buf, + + // + level: level as i8, // set to zero again for testing? + strategy, + + // these fields are not set explicitly at this point + last_flush: 0, + wrap, + strstart: 0, + block_start: 0, + block_open: 0, + window_size: 0, + insert: 0, + matches: 0, + opt_len: 0, + static_len: 0, + lookahead: 0, + ins_h: 0, + max_chain_length: 0, + max_lazy_match: 0, + good_match: 0, + nice_match: 0, + + // + l_desc: TreeDesc::EMPTY, + d_desc: TreeDesc::EMPTY, + bl_desc: TreeDesc::EMPTY, + + bl_count: [0u16; MAX_BITS + 1], + + // + heap: Heap::new(), + + // + crc_fold: Crc32Fold::new(), + gzhead: None, + gzindex: 0, + + // + match_start: 0, + match_length: 0, + prev_match: 0, + match_available: false, + prev_length: 0, + + // just provide a valid default; gets set properly later + hash_calc_variant: HashCalcVariant::Standard, + }; + + let state = state_allocation.write(state); + stream.state = state as *mut _ as *mut internal_state; + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(stream) }) else { + if cfg!(debug_assertions) { + unreachable!("we should have initialized the stream properly"); + } + return ReturnCode::StreamError; + }; + + reset(stream) +} + +pub fn params(stream: &mut DeflateStream, level: i32, strategy: Strategy) -> ReturnCode { + let level = if level == crate::c_api::Z_DEFAULT_COMPRESSION { + 6 + } else { + level + }; + + if !(0..=9).contains(&level) { + return ReturnCode::StreamError; + } + + let level = level as i8; + + let func = CONFIGURATION_TABLE[stream.state.level as usize].func; + + let state = &mut stream.state; + + if (strategy != state.strategy || func != CONFIGURATION_TABLE[level as usize].func) + && state.last_flush != -2 + { + // Flush the last buffer. + let err = deflate(stream, DeflateFlush::Block); + if err == ReturnCode::StreamError { + return err; + } + + let state = &mut stream.state; + + if stream.avail_in != 0 + || ((state.strstart as isize - state.block_start) + state.lookahead as isize) != 0 + { + return ReturnCode::BufError; + } + } + + let state = &mut stream.state; + + if state.level != level { + if state.level == 0 && state.matches != 0 { + if state.matches == 1 { + self::slide_hash::slide_hash(state); + } else { + state.head.fill(0); + } + state.matches = 0; + } + + lm_set_level(state, level); + } + + state.strategy = strategy; + + ReturnCode::Ok +} + +pub fn set_dictionary(stream: &mut DeflateStream, mut dictionary: &[u8]) -> ReturnCode { + let state = &mut stream.state; + + let wrap = state.wrap; + + if wrap == 2 || (wrap == 1 && state.status != Status::Init) || state.lookahead != 0 { + return ReturnCode::StreamError; + } + + // when using zlib wrappers, compute Adler-32 for provided dictionary + if wrap == 1 { + stream.adler = adler32(stream.adler as u32, dictionary) as z_checksum; + } + + // avoid computing Adler-32 in read_buf + state.wrap = 0; + + // if dictionary would fill window, just replace the history + if dictionary.len() >= state.window.capacity() { + if wrap == 0 { + // clear the hash table + state.head.fill(0); + + state.strstart = 0; + state.block_start = 0; + state.insert = 0; + } else { + /* already empty otherwise */ + } + + // use the tail + dictionary = &dictionary[dictionary.len() - state.w_size..]; + } + + // insert dictionary into window and hash + let avail = stream.avail_in; + let next = stream.next_in; + stream.avail_in = dictionary.len() as _; + stream.next_in = dictionary.as_ptr() as *mut u8; + fill_window(stream); + + while stream.state.lookahead >= STD_MIN_MATCH { + let str = stream.state.strstart; + let n = stream.state.lookahead - (STD_MIN_MATCH - 1); + stream.state.insert_string(str, n); + stream.state.strstart = str + n; + stream.state.lookahead = STD_MIN_MATCH - 1; + fill_window(stream); + } + + let state = &mut stream.state; + + state.strstart += state.lookahead; + state.block_start = state.strstart as _; + state.insert = state.lookahead; + state.lookahead = 0; + state.prev_length = 0; + state.match_available = false; + + // restore the state + stream.next_in = next; + stream.avail_in = avail; + state.wrap = wrap; + + ReturnCode::Ok +} + +pub fn prime(stream: &mut DeflateStream, mut bits: i32, value: i32) -> ReturnCode { + // our logic actually supports up to 32 bits. + debug_assert!(bits <= 16, "zlib only supports up to 16 bits here"); + + let mut value64 = value as u64; + + let state = &mut stream.state; + + if bits < 0 + || bits > BitWriter::BIT_BUF_SIZE as i32 + || bits > (core::mem::size_of_val(&value) << 3) as i32 + { + return ReturnCode::BufError; + } + + let mut put; + + loop { + put = BitWriter::BIT_BUF_SIZE - state.bit_writer.bits_used; + let put = Ord::min(put as i32, bits); + + if state.bit_writer.bits_used == 0 { + state.bit_writer.bit_buffer = value64; + } else { + state.bit_writer.bit_buffer |= + (value64 & ((1 << put) - 1)) << state.bit_writer.bits_used; + } + + state.bit_writer.bits_used += put as u8; + state.bit_writer.flush_bits(); + value64 >>= put; + bits -= put; + + if bits == 0 { + break; + } + } + + ReturnCode::Ok +} + +pub fn copy<'a>( + dest: &mut MaybeUninit>, + source: &mut DeflateStream<'a>, +) -> ReturnCode { + // Safety: source and dest are both mutable references, so guaranteed not to overlap. + // dest being a reference to maybe uninitialized memory makes a copy of 1 DeflateStream valid. + unsafe { + core::ptr::copy_nonoverlapping(source, dest.as_mut_ptr(), 1); + } + + let alloc = &source.alloc; + + // allocated here to have the same order as zlib + let Some(state_allocation) = alloc.allocate::() else { + return ReturnCode::MemError; + }; + + let source_state = &source.state; + + let window = source_state.window.clone_in(alloc); + + let prev = alloc.allocate_slice::(source_state.w_size); + let head = alloc.allocate::<[u16; HASH_SIZE]>(); + + let pending = source_state.bit_writer.pending.clone_in(alloc); + let sym_buf = source_state.sym_buf.clone_in(alloc); + + // if any allocation failed, clean up allocations that did succeed + let (window, prev, head, pending, sym_buf) = match (window, prev, head, pending, sym_buf) { + (Some(window), Some(prev), Some(head), Some(pending), Some(sym_buf)) => { + (window, prev, head, pending, sym_buf) + } + (window, prev, head, pending, sym_buf) => { + // Safety: this access is in-bounds + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state) }; + unsafe { core::ptr::write(field_ptr as *mut *mut State, core::ptr::null_mut()) }; + + // Safety: it is an assumpion on DeflateStream that (de)allocation does not cause UB. + unsafe { + if let Some(mut sym_buf) = sym_buf { + alloc.deallocate(sym_buf.as_mut_ptr(), sym_buf.capacity()) + } + if let Some(pending) = pending { + pending.drop_in(alloc); + } + if let Some(head) = head { + alloc.deallocate(head.as_mut_ptr(), HASH_SIZE) + } + if let Some(prev) = prev { + alloc.deallocate(prev.as_mut_ptr(), prev.len()) + } + if let Some(mut window) = window { + window.drop_in(alloc); + } + + alloc.deallocate(state_allocation.as_mut_ptr(), 1); + } + + return ReturnCode::MemError; + } + }; + + prev.copy_from_slice(slice_to_uninit(source_state.prev)); + let prev = unsafe { core::slice::from_raw_parts_mut(prev.as_mut_ptr().cast(), prev.len()) }; + let head = head.write(*source_state.head); + + let mut bit_writer = BitWriter::from_pending(pending); + bit_writer.bits_used = source_state.bit_writer.bits_used; + bit_writer.bit_buffer = source_state.bit_writer.bit_buffer; + + let dest_state = State { + status: source_state.status, + bit_writer, + last_flush: source_state.last_flush, + wrap: source_state.wrap, + strategy: source_state.strategy, + level: source_state.level, + good_match: source_state.good_match, + nice_match: source_state.nice_match, + l_desc: source_state.l_desc.clone(), + d_desc: source_state.d_desc.clone(), + bl_desc: source_state.bl_desc.clone(), + bl_count: source_state.bl_count, + match_length: source_state.match_length, + prev_match: source_state.prev_match, + match_available: source_state.match_available, + strstart: source_state.strstart, + match_start: source_state.match_start, + prev_length: source_state.prev_length, + max_chain_length: source_state.max_chain_length, + max_lazy_match: source_state.max_lazy_match, + block_start: source_state.block_start, + block_open: source_state.block_open, + window, + sym_buf, + lit_bufsize: source_state.lit_bufsize, + window_size: source_state.window_size, + matches: source_state.matches, + opt_len: source_state.opt_len, + static_len: source_state.static_len, + insert: source_state.insert, + w_size: source_state.w_size, + w_bits: source_state.w_bits, + w_mask: source_state.w_mask, + lookahead: source_state.lookahead, + prev, + head, + ins_h: source_state.ins_h, + heap: source_state.heap.clone(), + hash_calc_variant: source_state.hash_calc_variant, + crc_fold: source_state.crc_fold, + gzhead: None, + gzindex: source_state.gzindex, + }; + + // write the cloned state into state_ptr + let state_ptr = state_allocation.write(dest_state); + + // insert the state_ptr into `dest` + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state) }; + unsafe { core::ptr::write(field_ptr as *mut *mut State, state_ptr) }; + + // update the gzhead field (it contains a mutable reference so we need to be careful + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state.gzhead) }; + unsafe { core::ptr::copy(&source_state.gzhead, field_ptr, 1) }; + + ReturnCode::Ok +} + +/// # Returns +/// +/// - Err when deflate is not done. A common cause is insufficient output space +/// - Ok otherwise +pub fn end<'a>(stream: &'a mut DeflateStream) -> Result<&'a mut z_stream, &'a mut z_stream> { + let status = stream.state.status; + + let alloc = stream.alloc; + + // deallocate in reverse order of allocations + unsafe { + // safety: we make sure that these fields are not used (by invalidating the state pointer) + stream.state.sym_buf.drop_in(&alloc); + stream.state.bit_writer.pending.drop_in(&alloc); + alloc.deallocate(stream.state.head, 1); + if !stream.state.prev.is_empty() { + alloc.deallocate(stream.state.prev.as_mut_ptr(), stream.state.prev.len()); + } + stream.state.window.drop_in(&alloc); + } + + let state = stream.state as *mut State; + let stream = stream.as_z_stream_mut(); + stream.state = core::ptr::null_mut(); + + // safety: `state` is not used later + unsafe { + alloc.deallocate(state, 1); + } + + match status { + Status::Busy => Err(stream), + _ => Ok(stream), + } +} + +pub fn reset(stream: &mut DeflateStream) -> ReturnCode { + let ret = reset_keep(stream); + + if ret == ReturnCode::Ok { + lm_init(stream.state); + } + + ret +} + +fn reset_keep(stream: &mut DeflateStream) -> ReturnCode { + stream.total_in = 0; + stream.total_out = 0; + stream.msg = core::ptr::null_mut(); + stream.data_type = crate::c_api::Z_UNKNOWN; + + let state = &mut stream.state; + + state.bit_writer.pending.reset_keep(); + + // can be made negative by deflate(..., Z_FINISH); + state.wrap = state.wrap.abs(); + + state.status = match state.wrap { + 2 => Status::GZip, + _ => Status::Init, + }; + + stream.adler = match state.wrap { + 2 => { + state.crc_fold = Crc32Fold::new(); + CRC32_INITIAL_VALUE as _ + } + _ => ADLER32_INITIAL_VALUE as _, + }; + + state.last_flush = -2; + + state.zng_tr_init(); + + ReturnCode::Ok +} + +fn lm_init(state: &mut State) { + state.window_size = 2 * state.w_size; + + // zlib uses CLEAR_HASH here + state.head.fill(0); + + // Set the default configuration parameters: + lm_set_level(state, state.level); + + state.strstart = 0; + state.block_start = 0; + state.lookahead = 0; + state.insert = 0; + state.prev_length = 0; + state.match_available = false; + state.match_start = 0; + state.ins_h = 0; +} + +fn lm_set_level(state: &mut State, level: i8) { + state.max_lazy_match = CONFIGURATION_TABLE[level as usize].max_lazy as usize; + state.good_match = CONFIGURATION_TABLE[level as usize].good_length as usize; + state.nice_match = CONFIGURATION_TABLE[level as usize].nice_length as usize; + state.max_chain_length = CONFIGURATION_TABLE[level as usize].max_chain as usize; + + state.hash_calc_variant = HashCalcVariant::for_max_chain_length(state.max_chain_length); + state.level = level; +} + +pub fn tune( + stream: &mut DeflateStream, + good_length: usize, + max_lazy: usize, + nice_length: usize, + max_chain: usize, +) -> ReturnCode { + stream.state.good_match = good_length; + stream.state.max_lazy_match = max_lazy; + stream.state.nice_match = nice_length; + stream.state.max_chain_length = max_chain; + + ReturnCode::Ok +} + +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct Value { + a: u16, + b: u16, +} + +impl Value { + pub(crate) const fn new(a: u16, b: u16) -> Self { + Self { a, b } + } + + pub(crate) fn freq_mut(&mut self) -> &mut u16 { + &mut self.a + } + + pub(crate) fn code_mut(&mut self) -> &mut u16 { + &mut self.a + } + + pub(crate) fn dad_mut(&mut self) -> &mut u16 { + &mut self.b + } + + pub(crate) fn len_mut(&mut self) -> &mut u16 { + &mut self.b + } + + #[inline(always)] + pub(crate) const fn freq(self) -> u16 { + self.a + } + + pub(crate) fn code(self) -> u16 { + self.a + } + + pub(crate) fn dad(self) -> u16 { + self.b + } + + pub(crate) fn len(self) -> u16 { + self.b + } +} + +/// number of length codes, not counting the special END_BLOCK code +pub(crate) const LENGTH_CODES: usize = 29; + +/// number of literal bytes 0..255 +const LITERALS: usize = 256; + +/// number of Literal or Length codes, including the END_BLOCK code +pub(crate) const L_CODES: usize = LITERALS + 1 + LENGTH_CODES; + +/// number of distance codes +pub(crate) const D_CODES: usize = 30; + +/// number of codes used to transfer the bit lengths +const BL_CODES: usize = 19; + +/// maximum heap size +const HEAP_SIZE: usize = 2 * L_CODES + 1; + +/// all codes must not exceed MAX_BITS bits +const MAX_BITS: usize = 15; + +/// Bit length codes must not exceed MAX_BL_BITS bits +const MAX_BL_BITS: usize = 7; + +pub(crate) const DIST_CODE_LEN: usize = 512; + +struct BitWriter<'a> { + pub(crate) pending: Pending<'a>, // output still pending + pub(crate) bit_buffer: u64, + pub(crate) bits_used: u8, + + /// total bit length of compressed file (NOTE: zlib-ng uses a 32-bit integer here) + #[cfg(feature = "ZLIB_DEBUG")] + compressed_len: usize, + /// bit length of compressed data sent (NOTE: zlib-ng uses a 32-bit integer here) + #[cfg(feature = "ZLIB_DEBUG")] + bits_sent: usize, +} + +impl<'a> BitWriter<'a> { + pub(crate) const BIT_BUF_SIZE: u8 = 64; + + fn from_pending(pending: Pending<'a>) -> Self { + Self { + pending, + bit_buffer: 0, + bits_used: 0, + + #[cfg(feature = "ZLIB_DEBUG")] + compressed_len: 0, + #[cfg(feature = "ZLIB_DEBUG")] + bits_sent: 0, + } + } + + fn flush_bits(&mut self) { + debug_assert!(self.bits_used <= 64); + let removed = self.bits_used.saturating_sub(7).next_multiple_of(8); + let keep_bytes = self.bits_used / 8; // can never divide by zero + + let src = &self.bit_buffer.to_le_bytes(); + self.pending.extend(&src[..keep_bytes as usize]); + + self.bits_used -= removed; + self.bit_buffer = self.bit_buffer.checked_shr(removed as u32).unwrap_or(0); + } + + fn emit_align(&mut self) { + debug_assert!(self.bits_used <= 64); + let keep_bytes = self.bits_used.div_ceil(8); + let src = &self.bit_buffer.to_le_bytes(); + self.pending.extend(&src[..keep_bytes as usize]); + + self.bits_used = 0; + self.bit_buffer = 0; + + self.sent_bits_align(); + } + + fn send_bits_trace(&self, _value: u64, _len: u8) { + trace!(" l {:>2} v {:>4x} ", _len, _value); + } + + fn cmpr_bits_add(&mut self, _len: usize) { + #[cfg(feature = "ZLIB_DEBUG")] + { + self.compressed_len += _len; + } + } + + fn cmpr_bits_align(&mut self) { + #[cfg(feature = "ZLIB_DEBUG")] + { + self.compressed_len = self.compressed_len.next_multiple_of(8); + } + } + + fn sent_bits_add(&mut self, _len: usize) { + #[cfg(feature = "ZLIB_DEBUG")] + { + self.bits_sent += _len; + } + } + + fn sent_bits_align(&mut self) { + #[cfg(feature = "ZLIB_DEBUG")] + { + self.bits_sent = self.bits_sent.next_multiple_of(8); + } + } + + fn send_bits(&mut self, val: u64, len: u8) { + debug_assert!(len <= 64); + debug_assert!(self.bits_used <= 64); + + let total_bits = len + self.bits_used; + + self.send_bits_trace(val, len); + self.sent_bits_add(len as usize); + + if total_bits < Self::BIT_BUF_SIZE { + self.bit_buffer |= val << self.bits_used; + self.bits_used = total_bits; + } else if self.bits_used == Self::BIT_BUF_SIZE { + // with how send_bits is called, this is unreachable in practice + self.pending.extend(&self.bit_buffer.to_le_bytes()); + self.bit_buffer = val; + self.bits_used = len; + } else { + self.bit_buffer |= val << self.bits_used; + self.pending.extend(&self.bit_buffer.to_le_bytes()); + self.bit_buffer = val >> (Self::BIT_BUF_SIZE - self.bits_used); + self.bits_used = total_bits - Self::BIT_BUF_SIZE; + } + } + + fn send_code(&mut self, code: usize, tree: &[Value]) { + let node = tree[code]; + self.send_bits(node.code() as u64, node.len() as u8) + } + + /// Send one empty static block to give enough lookahead for inflate. + /// This takes 10 bits, of which 7 may remain in the bit buffer. + pub fn align(&mut self) { + self.emit_tree(BlockType::StaticTrees, false); + self.emit_end_block(&STATIC_LTREE, false); + self.flush_bits(); + } + + pub(crate) fn emit_tree(&mut self, block_type: BlockType, is_last_block: bool) { + let header_bits = (block_type as u64) << 1 | (is_last_block as u64); + self.send_bits(header_bits, 3); + trace!("\n--- Emit Tree: Last: {}\n", is_last_block as u8); + } + + pub(crate) fn emit_end_block_and_align(&mut self, ltree: &[Value], is_last_block: bool) { + self.emit_end_block(ltree, is_last_block); + + if is_last_block { + self.emit_align(); + } + } + + fn emit_end_block(&mut self, ltree: &[Value], _is_last_block: bool) { + const END_BLOCK: usize = 256; + self.send_code(END_BLOCK, ltree); + + trace!( + "\n+++ Emit End Block: Last: {} Pending: {} Total Out: {}\n", + _is_last_block as u8, + self.pending.pending().len(), + "" + ); + } + + pub(crate) fn emit_lit(&mut self, ltree: &[Value], c: u8) -> u16 { + self.send_code(c as usize, ltree); + + #[cfg(feature = "ZLIB_DEBUG")] + if let Some(c) = char::from_u32(c as u32) { + if isgraph(c as u8) { + trace!(" '{}' ", c); + } + } + + ltree[c as usize].len() + } + + pub(crate) fn emit_dist( + &mut self, + ltree: &[Value], + dtree: &[Value], + lc: u8, + mut dist: usize, + ) -> usize { + let mut lc = lc as usize; + + /* Send the length code, len is the match length - STD_MIN_MATCH */ + let mut code = self::trees_tbl::LENGTH_CODE[lc] as usize; + let c = code + LITERALS + 1; + assert!(c < L_CODES, "bad l_code"); + // send_code_trace(s, c); + + let lnode = ltree[c]; + let mut match_bits: u64 = lnode.code() as u64; + let mut match_bits_len = lnode.len() as usize; + let mut extra = StaticTreeDesc::EXTRA_LBITS[code] as usize; + if extra != 0 { + lc -= self::trees_tbl::BASE_LENGTH[code] as usize; + match_bits |= (lc as u64) << match_bits_len; + match_bits_len += extra; + } + + dist -= 1; /* dist is now the match distance - 1 */ + code = State::d_code(dist) as usize; + assert!(code < D_CODES, "bad d_code"); + // send_code_trace(s, code); + + /* Send the distance code */ + let dnode = dtree[code]; + match_bits |= (dnode.code() as u64) << match_bits_len; + match_bits_len += dnode.len() as usize; + extra = StaticTreeDesc::EXTRA_DBITS[code] as usize; + if extra != 0 { + dist -= self::trees_tbl::BASE_DIST[code] as usize; + match_bits |= (dist as u64) << match_bits_len; + match_bits_len += extra; + } + + self.send_bits(match_bits, match_bits_len as u8); + + match_bits_len + } + + fn compress_block_help(&mut self, sym_buf: &[u8], ltree: &[Value], dtree: &[Value]) { + for chunk in sym_buf.chunks_exact(3) { + let [dist_low, dist_high, lc] = *chunk else { + unreachable!("out of bound access on the symbol buffer"); + }; + + match u16::from_be_bytes([dist_high, dist_low]) as usize { + 0 => self.emit_lit(ltree, lc) as usize, + dist => self.emit_dist(ltree, dtree, lc, dist), + }; + } + + self.emit_end_block(ltree, false) + } + + fn send_tree(&mut self, tree: &[Value], bl_tree: &[Value], max_code: usize) { + /* tree: the tree to be scanned */ + /* max_code and its largest code of non zero frequency */ + let mut prevlen: isize = -1; /* last emitted length */ + let mut curlen; /* length of current code */ + let mut nextlen = tree[0].len(); /* length of next code */ + let mut count = 0; /* repeat count of the current code */ + let mut max_count = 7; /* max repeat count */ + let mut min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ + /* guard already set */ + if nextlen == 0 { + max_count = 138; + min_count = 3; + } + + for n in 0..=max_code { + curlen = nextlen; + nextlen = tree[n + 1].len(); + count += 1; + if count < max_count && curlen == nextlen { + continue; + } else if count < min_count { + loop { + self.send_code(curlen as usize, bl_tree); + + count -= 1; + if count == 0 { + break; + } + } + } else if curlen != 0 { + if curlen as isize != prevlen { + self.send_code(curlen as usize, bl_tree); + count -= 1; + } + assert!((3..=6).contains(&count), " 3_6?"); + self.send_code(REP_3_6, bl_tree); + self.send_bits(count - 3, 2); + } else if count <= 10 { + self.send_code(REPZ_3_10, bl_tree); + self.send_bits(count - 3, 3); + } else { + self.send_code(REPZ_11_138, bl_tree); + self.send_bits(count - 11, 7); + } + + count = 0; + prevlen = curlen as isize; + + if nextlen == 0 { + max_count = 138; + min_count = 3; + } else if curlen == nextlen { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } +} + +#[repr(C)] +pub(crate) struct State<'a> { + status: Status, + + last_flush: i32, /* value of flush param for previous deflate call */ + + bit_writer: BitWriter<'a>, + + pub(crate) wrap: i8, /* bit 0 true for zlib, bit 1 true for gzip */ + + pub(crate) strategy: Strategy, + pub(crate) level: i8, + + /// Use a faster search when the previous match is longer than this + pub(crate) good_match: usize, + + /// Stop searching when current match exceeds this + pub(crate) nice_match: usize, + + // part of the fields below + // dyn_ltree: [Value; ], + // dyn_dtree: [Value; ], + // bl_tree: [Value; ], + l_desc: TreeDesc, /* literal and length tree */ + d_desc: TreeDesc<{ 2 * D_CODES + 1 }>, /* distance tree */ + bl_desc: TreeDesc<{ 2 * BL_CODES + 1 }>, /* Huffman tree for bit lengths */ + + pub(crate) bl_count: [u16; MAX_BITS + 1], + + pub(crate) match_length: usize, /* length of best match */ + pub(crate) prev_match: u16, /* previous match */ + pub(crate) match_available: bool, /* set if previous match exists */ + pub(crate) strstart: usize, /* start of string to insert */ + pub(crate) match_start: usize, /* start of matching string */ + + /// Length of the best match at previous step. Matches not greater than this + /// are discarded. This is used in the lazy match evaluation. + pub(crate) prev_length: usize, + + /// To speed up deflation, hash chains are never searched beyond this length. + /// A higher limit improves compression ratio but degrades the speed. + pub(crate) max_chain_length: usize, + + // TODO untangle this mess! zlib uses the same field differently based on compression level + // we should just have 2 fields for clarity! + // + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + // define max_insert_length max_lazy_match + /// Attempt to find a better match only when the current match is strictly smaller + /// than this value. This mechanism is used only for compression levels >= 4. + pub(crate) max_lazy_match: usize, + + /// Window position at the beginning of the current output block. Gets + /// negative when the window is moved backwards. + pub(crate) block_start: isize, + + /// Whether or not a block is currently open for the QUICK deflation scheme. + /// true if there is an active block, or false if the block was just closed + pub(crate) block_open: u8, + + pub(crate) window: Window<'a>, + + pub(crate) sym_buf: ReadBuf<'a>, + + /// Size of match buffer for literals/lengths. There are 4 reasons for + /// limiting lit_bufsize to 64K: + /// - frequencies can be kept in 16 bit counters + /// - if compression is not successful for the first block, all input + /// data is still in the window so we can still emit a stored block even + /// when input comes from standard input. (This can also be done for + /// all blocks if lit_bufsize is not greater than 32K.) + /// - if compression is not successful for a file smaller than 64K, we can + /// even emit a stored file instead of a stored block (saving 5 bytes). + /// This is applicable only for zip (not gzip or zlib). + /// - creating new Huffman trees less frequently may not provide fast + /// adaptation to changes in the input data statistics. (Take for + /// example a binary file with poorly compressible code followed by + /// a highly compressible string table.) Smaller buffer sizes give + /// fast adaptation but have of course the overhead of transmitting + /// trees more frequently. + /// - I can't count above 4 + lit_bufsize: usize, + + /// Actual size of window: 2*wSize, except when the user input buffer is directly used as sliding window. + pub(crate) window_size: usize, + + /// number of string matches in current block + pub(crate) matches: usize, + + /// bit length of current block with optimal trees + opt_len: usize, + /// bit length of current block with static trees + static_len: usize, + + /// bytes at end of window left to insert + pub(crate) insert: usize, + + pub(crate) w_size: usize, /* LZ77 window size (32K by default) */ + pub(crate) w_bits: usize, /* log2(w_size) (8..16) */ + pub(crate) w_mask: usize, /* w_size - 1 */ + pub(crate) lookahead: usize, /* number of valid bytes ahead in window */ + + pub(crate) prev: &'a mut [u16], + pub(crate) head: &'a mut [u16; HASH_SIZE], + + /// hash index of string to be inserted + pub(crate) ins_h: usize, + + heap: Heap, + + pub(crate) hash_calc_variant: HashCalcVariant, + + crc_fold: crate::crc32::Crc32Fold, + gzhead: Option<&'a mut gz_header>, + gzindex: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +#[cfg_attr(feature = "__internal-fuzz", derive(arbitrary::Arbitrary))] +pub enum Strategy { + #[default] + Default = 0, + Filtered = 1, + HuffmanOnly = 2, + Rle = 3, + Fixed = 4, +} + +impl TryFrom for Strategy { + type Error = (); + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Strategy::Default), + 1 => Ok(Strategy::Filtered), + 2 => Ok(Strategy::HuffmanOnly), + 3 => Ok(Strategy::Rle), + 4 => Ok(Strategy::Fixed), + _ => Err(()), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +enum DataType { + Binary = 0, + Text = 1, + Unknown = 2, +} + +impl<'a> State<'a> { + pub const BIT_BUF_SIZE: u8 = BitWriter::BIT_BUF_SIZE; + + pub(crate) fn max_dist(&self) -> usize { + self.w_size - MIN_LOOKAHEAD + } + + // TODO untangle this mess! zlib uses the same field differently based on compression level + // we should just have 2 fields for clarity! + pub(crate) fn max_insert_length(&self) -> usize { + self.max_lazy_match + } + + /// Total size of the pending buf. But because `pending` shares memory with `sym_buf`, this is + /// not the number of bytes that are actually in `pending`! + pub(crate) fn pending_buf_size(&self) -> usize { + self.lit_bufsize * 4 + } + + pub(crate) fn update_hash(&self, h: u32, val: u32) -> u32 { + match self.hash_calc_variant { + HashCalcVariant::Standard => StandardHashCalc::update_hash(h, val), + HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::update_hash(h, val) }, + HashCalcVariant::Roll => RollHashCalc::update_hash(h, val), + } + } + + pub(crate) fn quick_insert_string(&mut self, string: usize) -> u16 { + match self.hash_calc_variant { + HashCalcVariant::Standard => StandardHashCalc::quick_insert_string(self, string), + HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::quick_insert_string(self, string) }, + HashCalcVariant::Roll => RollHashCalc::quick_insert_string(self, string), + } + } + + pub(crate) fn insert_string(&mut self, string: usize, count: usize) { + match self.hash_calc_variant { + HashCalcVariant::Standard => StandardHashCalc::insert_string(self, string, count), + HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::insert_string(self, string, count) }, + HashCalcVariant::Roll => RollHashCalc::insert_string(self, string, count), + } + } + + pub(crate) fn tally_lit(&mut self, unmatched: u8) -> bool { + self.sym_buf.push(0); + self.sym_buf.push(0); + self.sym_buf.push(unmatched); + + *self.l_desc.dyn_tree[unmatched as usize].freq_mut() += 1; + + assert!( + unmatched as usize <= STD_MAX_MATCH - STD_MIN_MATCH, + "zng_tr_tally: bad literal" + ); + + // signal that the current block should be flushed + self.sym_buf.len() == self.sym_buf.capacity() - 3 + } + + const fn d_code(dist: usize) -> u8 { + let index = if dist < 256 { dist } else { 256 + (dist >> 7) }; + self::trees_tbl::DIST_CODE[index] + } + + pub(crate) fn tally_dist(&mut self, mut dist: usize, len: usize) -> bool { + let symbols = [dist as u8, (dist >> 8) as u8, len as u8]; + self.sym_buf.extend(&symbols); + + self.matches += 1; + dist -= 1; + + assert!( + dist < self.max_dist() && Self::d_code(dist) < D_CODES as u8, + "tally_dist: bad match" + ); + + let index = self::trees_tbl::LENGTH_CODE[len] as usize + LITERALS + 1; + *self.l_desc.dyn_tree[index].freq_mut() += 1; + + *self.d_desc.dyn_tree[Self::d_code(dist) as usize].freq_mut() += 1; + + // signal that the current block should be flushed + self.sym_buf.len() == self.sym_buf.capacity() - 3 + } + + fn detect_data_type(dyn_tree: &[Value]) -> DataType { + // set bits 0..6, 14..25, and 28..31 + // 0xf3ffc07f = binary 11110011111111111100000001111111 + const NON_TEXT: u64 = 0xf3ffc07f; + let mut mask = NON_TEXT; + + /* Check for non-textual bytes. */ + for value in &dyn_tree[0..32] { + if (mask & 1) != 0 && value.freq() != 0 { + return DataType::Binary; + } + + mask >>= 1; + } + + /* Check for textual bytes. */ + if dyn_tree[9].freq() != 0 || dyn_tree[10].freq() != 0 || dyn_tree[13].freq() != 0 { + return DataType::Text; + } + + if dyn_tree[32..LITERALS].iter().any(|v| v.freq() != 0) { + return DataType::Text; + } + + // there are no explicit text or non-text bytes. The stream is either empty or has only + // tolerated bytes + DataType::Binary + } + + fn compress_block_static_trees(&mut self) { + self.bit_writer.compress_block_help( + self.sym_buf.filled(), + self::trees_tbl::STATIC_LTREE.as_slice(), + self::trees_tbl::STATIC_DTREE.as_slice(), + ) + } + + fn compress_block_dynamic_trees(&mut self) { + self.bit_writer.compress_block_help( + self.sym_buf.filled(), + &self.l_desc.dyn_tree, + &self.d_desc.dyn_tree, + ); + } + + fn header(&self) -> u16 { + // preset dictionary flag in zlib header + const PRESET_DICT: u16 = 0x20; + + // The deflate compression method (the only one supported in this version) + const Z_DEFLATED: u16 = 8; + + let dict = match self.strstart { + 0 => 0, + _ => PRESET_DICT, + }; + + let h = + (Z_DEFLATED + ((self.w_bits as u16 - 8) << 4)) << 8 | (self.level_flags() << 6) | dict; + + h + 31 - (h % 31) + } + + fn level_flags(&self) -> u16 { + if self.strategy >= Strategy::HuffmanOnly || self.level < 2 { + 0 + } else if self.level < 6 { + 1 + } else if self.level == 6 { + 2 + } else { + 3 + } + } + + fn zng_tr_init(&mut self) { + self.l_desc.stat_desc = &StaticTreeDesc::L; + + self.d_desc.stat_desc = &StaticTreeDesc::D; + + self.bl_desc.stat_desc = &StaticTreeDesc::BL; + + self.bit_writer.bit_buffer = 0; + self.bit_writer.bits_used = 0; + + #[cfg(feature = "ZLIB_DEBUG")] + { + self.bit_writer.compressed_len = 0; + self.bit_writer.bits_sent = 0; + } + + // Initialize the first block of the first file: + self.init_block(); + } + + /// initializes a new block + fn init_block(&mut self) { + // Initialize the trees. + // TODO would a memset also work here? + + for value in &mut self.l_desc.dyn_tree[..L_CODES] { + *value.freq_mut() = 0; + } + + for value in &mut self.d_desc.dyn_tree[..D_CODES] { + *value.freq_mut() = 0; + } + + for value in &mut self.bl_desc.dyn_tree[..BL_CODES] { + *value.freq_mut() = 0; + } + + // end of block literal code + const END_BLOCK: usize = 256; + + *self.l_desc.dyn_tree[END_BLOCK].freq_mut() = 1; + self.opt_len = 0; + self.static_len = 0; + self.sym_buf.clear(); + self.matches = 0; + } +} + +#[repr(u8)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Status { + Init = 1, + + GZip = 4, + Extra = 5, + Name = 6, + Comment = 7, + Hcrc = 8, + + Busy = 2, + Finish = 3, +} + +const fn rank_flush(f: i32) -> i32 { + // rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH + ((f) * 2) - (if (f) > 4 { 9 } else { 0 }) +} + +#[derive(Debug)] +pub(crate) enum BlockState { + /// block not completed, need more input or more output + NeedMore = 0, + /// block flush performed + BlockDone = 1, + /// finish started, need only more output at next deflate + FinishStarted = 2, + /// finish done, accept no more input or output + FinishDone = 3, +} + +// Maximum stored block length in deflate format (not including header). +pub(crate) const MAX_STORED: usize = 65535; // so u16::max + +pub(crate) fn read_buf_window(stream: &mut DeflateStream, offset: usize, size: usize) -> usize { + let len = Ord::min(stream.avail_in as usize, size); + + if len == 0 { + return 0; + } + + stream.avail_in -= len as u32; + + if stream.state.wrap == 2 { + // we likely cannot fuse the crc32 and the copy here because the input can be changed by + // a concurrent thread. Therefore it cannot be converted into a slice! + let window = &mut stream.state.window; + window.initialize_at_least(offset + len); + unsafe { window.copy_and_initialize(offset..offset + len, stream.next_in) }; + + let data = &stream.state.window.filled()[offset..][..len]; + stream.state.crc_fold.fold(data, CRC32_INITIAL_VALUE); + } else if stream.state.wrap == 1 { + // we likely cannot fuse the adler32 and the copy here because the input can be changed by + // a concurrent thread. Therefore it cannot be converted into a slice! + let window = &mut stream.state.window; + window.initialize_at_least(offset + len); + unsafe { window.copy_and_initialize(offset..offset + len, stream.next_in) }; + + let data = &stream.state.window.filled()[offset..][..len]; + stream.adler = adler32(stream.adler as u32, data) as _; + } else { + let window = &mut stream.state.window; + window.initialize_at_least(offset + len); + unsafe { window.copy_and_initialize(offset..offset + len, stream.next_in) }; + } + + stream.next_in = stream.next_in.wrapping_add(len); + stream.total_in += len as crate::c_api::z_size; + + len +} + +pub(crate) enum BlockType { + StoredBlock = 0, + StaticTrees = 1, + DynamicTrees = 2, +} + +pub(crate) fn zng_tr_stored_block( + state: &mut State, + window_range: core::ops::Range, + is_last: bool, +) { + // send block type + state.bit_writer.emit_tree(BlockType::StoredBlock, is_last); + + // align on byte boundary + state.bit_writer.emit_align(); + + state.bit_writer.cmpr_bits_align(); + + let input_block: &[u8] = &state.window.filled()[window_range]; + let stored_len = input_block.len() as u16; + + state.bit_writer.pending.extend(&stored_len.to_le_bytes()); + state + .bit_writer + .pending + .extend(&(!stored_len).to_le_bytes()); + + state.bit_writer.cmpr_bits_add(32); + state.bit_writer.sent_bits_add(32); + if stored_len > 0 { + state.bit_writer.pending.extend(input_block); + state.bit_writer.cmpr_bits_add((stored_len << 3) as usize); + state.bit_writer.sent_bits_add((stored_len << 3) as usize); + } +} + +/// The minimum match length mandated by the deflate standard +pub(crate) const STD_MIN_MATCH: usize = 3; +/// The maximum match length mandated by the deflate standard +pub(crate) const STD_MAX_MATCH: usize = 258; + +/// The minimum wanted match length, affects deflate_quick, deflate_fast, deflate_medium and deflate_slow +pub(crate) const WANT_MIN_MATCH: usize = 4; + +pub(crate) const MIN_LOOKAHEAD: usize = STD_MAX_MATCH + STD_MIN_MATCH + 1; + +pub(crate) fn fill_window(stream: &mut DeflateStream) { + debug_assert!(stream.state.lookahead < MIN_LOOKAHEAD); + + let wsize = stream.state.w_size; + + loop { + let state = &mut stream.state; + let mut more = state.window_size - state.lookahead - state.strstart; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + if state.strstart >= wsize + state.max_dist() { + // in some cases zlib-ng copies uninitialized bytes here. We cannot have that, so + // explicitly initialize them with zeros. + // + // see also the "fill_window_out_of_bounds" test. + state.window.initialize_at_least(2 * wsize); + state.window.filled_mut().copy_within(wsize..2 * wsize, 0); + + if state.match_start >= wsize { + state.match_start -= wsize; + } else { + state.match_start = 0; + state.prev_length = 0; + } + state.strstart -= wsize; /* we now have strstart >= MAX_DIST */ + state.block_start -= wsize as isize; + if state.insert > state.strstart { + state.insert = state.strstart; + } + + self::slide_hash::slide_hash(state); + + more += wsize; + } + + if stream.avail_in == 0 { + break; + } + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + assert!(more >= 2, "more < 2"); + + let n = read_buf_window(stream, stream.state.strstart + stream.state.lookahead, more); + + let state = &mut stream.state; + state.lookahead += n; + + // Initialize the hash value now that we have some input: + if state.lookahead + state.insert >= STD_MIN_MATCH { + let string = state.strstart - state.insert; + if state.max_chain_length > 1024 { + let v0 = state.window.filled()[string] as u32; + let v1 = state.window.filled()[string + 1] as u32; + state.ins_h = state.update_hash(v0, v1) as usize; + } else if string >= 1 { + state.quick_insert_string(string + 2 - STD_MIN_MATCH); + } + let mut count = state.insert; + if state.lookahead == 1 { + count -= 1; + } + if count > 0 { + state.insert_string(string, count); + state.insert -= count; + } + } + + // If the whole input has less than STD_MIN_MATCH bytes, ins_h is garbage, + // but this is not important since only literal bytes will be emitted. + + if !(stream.state.lookahead < MIN_LOOKAHEAD && stream.avail_in != 0) { + break; + } + } + + // initialize some memory at the end of the (filled) window, so SIMD operations can go "out of + // bounds" without violating any requirements. The window allocation is already slightly bigger + // to allow for this. + stream.state.window.initialize_out_of_bounds(); + + assert!( + stream.state.strstart <= stream.state.window_size - MIN_LOOKAHEAD, + "not enough room for search" + ); +} + +pub(crate) struct StaticTreeDesc { + /// static tree or NULL + pub(crate) static_tree: &'static [Value], + /// extra bits for each code or NULL + extra_bits: &'static [u8], + /// base index for extra_bits + extra_base: usize, + /// max number of elements in the tree + elems: usize, + /// max bit length for the codes + max_length: u16, +} + +impl StaticTreeDesc { + const EMPTY: Self = Self { + static_tree: &[], + extra_bits: &[], + extra_base: 0, + elems: 0, + max_length: 0, + }; + + /// extra bits for each length code + const EXTRA_LBITS: [u8; LENGTH_CODES] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, + ]; + + /// extra bits for each distance code + const EXTRA_DBITS: [u8; D_CODES] = [ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, + 13, 13, + ]; + + /// extra bits for each bit length code + const EXTRA_BLBITS: [u8; BL_CODES] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]; + + /// The lengths of the bit length codes are sent in order of decreasing + /// probability, to avoid transmitting the lengths for unused bit length codes. + const BL_ORDER: [u8; BL_CODES] = [ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, + ]; + + pub(crate) const L: Self = Self { + static_tree: &self::trees_tbl::STATIC_LTREE, + extra_bits: &Self::EXTRA_LBITS, + extra_base: LITERALS + 1, + elems: L_CODES, + max_length: MAX_BITS as u16, + }; + + pub(crate) const D: Self = Self { + static_tree: &self::trees_tbl::STATIC_DTREE, + extra_bits: &Self::EXTRA_DBITS, + extra_base: 0, + elems: D_CODES, + max_length: MAX_BITS as u16, + }; + + pub(crate) const BL: Self = Self { + static_tree: &[], + extra_bits: &Self::EXTRA_BLBITS, + extra_base: 0, + elems: BL_CODES, + max_length: MAX_BL_BITS as u16, + }; +} + +#[derive(Clone)] +struct TreeDesc { + dyn_tree: [Value; N], + max_code: usize, + stat_desc: &'static StaticTreeDesc, +} + +impl TreeDesc { + const EMPTY: Self = Self { + dyn_tree: [Value::new(0, 0); N], + max_code: 0, + stat_desc: &StaticTreeDesc::EMPTY, + }; +} + +fn build_tree(state: &mut State, desc: &mut TreeDesc) { + let tree = &mut desc.dyn_tree; + let stree = desc.stat_desc.static_tree; + let elements = desc.stat_desc.elems; + + let mut max_code = state.heap.initialize(&mut tree[..elements]); + + // The pkzip format requires that at least one distance code exists, + // and that at least one bit should be sent even if there is only one + // possible code. So to avoid special checks later on we force at least + // two codes of non zero frequency. + while state.heap.heap_len < 2 { + state.heap.heap_len += 1; + let node = if max_code < 2 { + max_code += 1; + max_code + } else { + 0 + }; + + debug_assert!(node >= 0); + let node = node as usize; + + state.heap.heap[state.heap.heap_len] = node as u32; + *tree[node].freq_mut() = 1; + state.heap.depth[node] = 0; + state.opt_len -= 1; + if !stree.is_empty() { + state.static_len -= stree[node].len() as usize; + } + /* node is 0 or 1 so it does not have extra bits */ + } + + debug_assert!(max_code >= 0); + let max_code = max_code as usize; + desc.max_code = max_code; + + // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + // establish sub-heaps of increasing lengths: + let mut n = state.heap.heap_len / 2; + while n >= 1 { + state.heap.pqdownheap(tree, n); + n -= 1; + } + + state.heap.construct_huffman_tree(tree, elements); + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + gen_bitlen(state, desc); + + // The field len is now set, we can generate the bit codes + gen_codes(&mut desc.dyn_tree, max_code, &state.bl_count); +} + +fn gen_bitlen(state: &mut State, desc: &mut TreeDesc) { + let heap = &mut state.heap; + + let tree = &mut desc.dyn_tree; + let max_code = desc.max_code; + let stree = desc.stat_desc.static_tree; + let extra = desc.stat_desc.extra_bits; + let base = desc.stat_desc.extra_base; + let max_length = desc.stat_desc.max_length; + + state.bl_count.fill(0); + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + *tree[heap.heap[heap.heap_max] as usize].len_mut() = 0; /* root of the heap */ + + // number of elements with bit length too large + let mut overflow: i32 = 0; + + for h in heap.heap_max + 1..HEAP_SIZE { + let n = heap.heap[h] as usize; + let mut bits = tree[tree[n].dad() as usize].len() + 1; + + if bits > max_length { + bits = max_length; + overflow += 1; + } + + // We overwrite tree[n].Dad which is no longer needed + *tree[n].len_mut() = bits; + + // not a leaf node + if n > max_code { + continue; + } + + state.bl_count[bits as usize] += 1; + let mut xbits = 0; + if n >= base { + xbits = extra[n - base] as usize; + } + + let f = tree[n].freq() as usize; + state.opt_len += f * (bits as usize + xbits); + + if !stree.is_empty() { + state.static_len += f * (stree[n].len() as usize + xbits); + } + } + + if overflow == 0 { + return; + } + + /* Find the first bit length which could increase: */ + loop { + let mut bits = max_length as usize - 1; + while state.bl_count[bits] == 0 { + bits -= 1; + } + state.bl_count[bits] -= 1; /* move one leaf down the tree */ + state.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + state.bl_count[max_length as usize] -= 1; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + + if overflow <= 0 { + break; + } + } + + // Now recompute all bit lengths, scanning in increasing frequency. + // h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + // lengths instead of fixing only the wrong ones. This idea is taken + // from 'ar' written by Haruhiko Okumura.) + let mut h = HEAP_SIZE; + for bits in (1..=max_length).rev() { + let mut n = state.bl_count[bits as usize]; + while n != 0 { + h -= 1; + let m = heap.heap[h] as usize; + if m > max_code { + continue; + } + + if tree[m].len() != bits { + // Tracev((stderr, "code %d bits %d->%u\n", m, tree[m].Len, bits)); + state.opt_len += (bits * tree[m].freq()) as usize; + state.opt_len -= (tree[m].len() * tree[m].freq()) as usize; + *tree[m].len_mut() = bits; + } + + n -= 1; + } + } +} + +/// Checks that symbol is a printing character (excluding space) +#[allow(unused)] +fn isgraph(c: u8) -> bool { + (c > 0x20) && (c <= 0x7E) +} + +fn gen_codes(tree: &mut [Value], max_code: usize, bl_count: &[u16]) { + /* tree: the tree to decorate */ + /* max_code: largest code with non zero frequency */ + /* bl_count: number of codes at each bit length */ + let mut next_code = [0; MAX_BITS + 1]; /* next code value for each bit length */ + let mut code = 0; /* running code value */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for bits in 1..=MAX_BITS { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = code; + } + + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + assert!( + code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts" + ); + + trace!("\ngen_codes: max_code {max_code} "); + + for n in 0..=max_code { + let len = tree[n].len(); + if len == 0 { + continue; + } + + /* Now reverse the bits */ + assert!((1..=15).contains(&len), "code length must be 1-15"); + *tree[n].code_mut() = next_code[len as usize].reverse_bits() >> (16 - len); + next_code[len as usize] += 1; + + if tree != self::trees_tbl::STATIC_LTREE.as_slice() { + trace!( + "\nn {:>3} {} l {:>2} c {:>4x} ({:x}) ", + n, + if isgraph(n as u8) { + char::from_u32(n as u32).unwrap() + } else { + ' ' + }, + len, + tree[n].code(), + next_code[len as usize] - 1 + ); + } + } +} + +/// repeat previous bit length 3-6 times (2 bits of repeat count) +const REP_3_6: usize = 16; + +/// repeat a zero length 3-10 times (3 bits of repeat count) +const REPZ_3_10: usize = 17; + +/// repeat a zero length 11-138 times (7 bits of repeat count) +const REPZ_11_138: usize = 18; + +fn scan_tree(bl_desc: &mut TreeDesc<{ 2 * BL_CODES + 1 }>, tree: &mut [Value], max_code: usize) { + /* tree: the tree to be scanned */ + /* max_code: and its largest code of non zero frequency */ + let mut prevlen = -1isize; /* last emitted length */ + let mut curlen: isize; /* length of current code */ + let mut nextlen = tree[0].len(); /* length of next code */ + let mut count = 0; /* repeat count of the current code */ + let mut max_count = 7; /* max repeat count */ + let mut min_count = 4; /* min repeat count */ + + if nextlen == 0 { + max_count = 138; + min_count = 3; + } + + *tree[max_code + 1].len_mut() = 0xffff; /* guard */ + + let bl_tree = &mut bl_desc.dyn_tree; + + for n in 0..=max_code { + curlen = nextlen as isize; + nextlen = tree[n + 1].len(); + count += 1; + if count < max_count && curlen == nextlen as isize { + continue; + } else if count < min_count { + *bl_tree[curlen as usize].freq_mut() += count; + } else if curlen != 0 { + if curlen != prevlen { + *bl_tree[curlen as usize].freq_mut() += 1; + } + *bl_tree[REP_3_6].freq_mut() += 1; + } else if count <= 10 { + *bl_tree[REPZ_3_10].freq_mut() += 1; + } else { + *bl_tree[REPZ_11_138].freq_mut() += 1; + } + + count = 0; + prevlen = curlen; + + if nextlen == 0 { + max_count = 138; + min_count = 3; + } else if curlen == nextlen as isize { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } +} + +fn send_all_trees(state: &mut State, lcodes: usize, dcodes: usize, blcodes: usize) { + assert!( + lcodes >= 257 && dcodes >= 1 && blcodes >= 4, + "not enough codes" + ); + assert!( + lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes" + ); + + trace!("\nbl counts: "); + state.bit_writer.send_bits(lcodes as u64 - 257, 5); /* not +255 as stated in appnote.txt */ + state.bit_writer.send_bits(dcodes as u64 - 1, 5); + state.bit_writer.send_bits(blcodes as u64 - 4, 4); /* not -3 as stated in appnote.txt */ + + for rank in 0..blcodes { + trace!("\nbl code {:>2} ", StaticTreeDesc::BL_ORDER[rank]); + state.bit_writer.send_bits( + state.bl_desc.dyn_tree[StaticTreeDesc::BL_ORDER[rank] as usize].len() as u64, + 3, + ); + } + trace!("\nbl tree: sent {}", state.bit_writer.bits_sent); + + // literal tree + state + .bit_writer + .send_tree(&state.l_desc.dyn_tree, &state.bl_desc.dyn_tree, lcodes - 1); + trace!("\nlit tree: sent {}", state.bit_writer.bits_sent); + + // distance tree + state + .bit_writer + .send_tree(&state.d_desc.dyn_tree, &state.bl_desc.dyn_tree, dcodes - 1); + trace!("\ndist tree: sent {}", state.bit_writer.bits_sent); +} + +/// Construct the Huffman tree for the bit lengths and return the index in +/// bl_order of the last bit length code to send. +fn build_bl_tree(state: &mut State) -> usize { + /* Determine the bit length frequencies for literal and distance trees */ + + scan_tree( + &mut state.bl_desc, + &mut state.l_desc.dyn_tree, + state.l_desc.max_code, + ); + + scan_tree( + &mut state.bl_desc, + &mut state.d_desc.dyn_tree, + state.d_desc.max_code, + ); + + /* Build the bit length tree: */ + { + let mut tmp = TreeDesc::EMPTY; + core::mem::swap(&mut tmp, &mut state.bl_desc); + build_tree(state, &mut tmp); + core::mem::swap(&mut tmp, &mut state.bl_desc); + } + + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + let mut max_blindex = BL_CODES - 1; + while max_blindex >= 3 { + let index = StaticTreeDesc::BL_ORDER[max_blindex] as usize; + if state.bl_desc.dyn_tree[index].len() != 0 { + break; + } + + max_blindex -= 1; + } + + /* Update opt_len to include the bit length tree and counts */ + state.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + trace!( + "\ndyn trees: dyn {}, stat {}", + state.opt_len, + state.static_len + ); + + max_blindex +} + +fn zng_tr_flush_block( + stream: &mut DeflateStream, + window_offset: Option, + stored_len: u32, + last: bool, +) { + /* window_offset: offset of the input block into the window */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + + let mut opt_lenb; + let static_lenb; + let mut max_blindex = 0; + + let state = &mut stream.state; + + if state.sym_buf.is_empty() { + opt_lenb = 0; + static_lenb = 0; + state.static_len = 7; + } else if state.level > 0 { + if stream.data_type == DataType::Unknown as i32 { + stream.data_type = State::detect_data_type(&state.l_desc.dyn_tree) as i32; + } + + { + let mut tmp = TreeDesc::EMPTY; + core::mem::swap(&mut tmp, &mut state.l_desc); + + build_tree(state, &mut tmp); + core::mem::swap(&mut tmp, &mut state.l_desc); + + trace!( + "\nlit data: dyn {}, stat {}", + state.opt_len, + state.static_len + ); + } + + { + let mut tmp = TreeDesc::EMPTY; + core::mem::swap(&mut tmp, &mut state.d_desc); + build_tree(state, &mut tmp); + core::mem::swap(&mut tmp, &mut state.d_desc); + + trace!( + "\ndist data: dyn {}, stat {}", + state.opt_len, + state.static_len + ); + } + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex = build_bl_tree(state); + + // Determine the best encoding. Compute the block lengths in bytes. + opt_lenb = (state.opt_len + 3 + 7) >> 3; + static_lenb = (state.static_len + 3 + 7) >> 3; + + trace!( + "\nopt {}({}) stat {}({}) stored {} lit {} ", + opt_lenb, + state.opt_len, + static_lenb, + state.static_len, + stored_len, + state.sym_buf.len() / 3 + ); + + if static_lenb <= opt_lenb || state.strategy == Strategy::Fixed { + opt_lenb = static_lenb; + } + } else { + assert!(window_offset.is_some(), "lost buf"); + /* force a stored block */ + opt_lenb = stored_len as usize + 5; + static_lenb = stored_len as usize + 5; + } + + if stored_len as usize + 4 <= opt_lenb && window_offset.is_some() { + /* 4: two words for the lengths + * The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + let window_offset = window_offset.unwrap(); + let range = window_offset..window_offset + stored_len as usize; + zng_tr_stored_block(state, range, last); + } else if static_lenb == opt_lenb { + state.bit_writer.emit_tree(BlockType::StaticTrees, last); + state.compress_block_static_trees(); + // cmpr_bits_add(s, s.static_len); + } else { + state.bit_writer.emit_tree(BlockType::DynamicTrees, last); + send_all_trees( + state, + state.l_desc.max_code + 1, + state.d_desc.max_code + 1, + max_blindex + 1, + ); + + state.compress_block_dynamic_trees(); + } + + // TODO + // This check is made mod 2^32, for files larger than 512 MB and unsigned long implemented on 32 bits. + // assert_eq!(state.compressed_len, state.bits_sent, "bad compressed size"); + + state.init_block(); + if last { + state.bit_writer.emit_align(); + } + + // Tracev((stderr, "\ncomprlen {}(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); +} + +pub(crate) fn flush_block_only(stream: &mut DeflateStream, is_last: bool) { + zng_tr_flush_block( + stream, + (stream.state.block_start >= 0).then_some(stream.state.block_start as usize), + (stream.state.strstart as isize - stream.state.block_start) as u32, + is_last, + ); + + stream.state.block_start = stream.state.strstart as isize; + flush_pending(stream) +} + +#[must_use] +fn flush_bytes(stream: &mut DeflateStream, mut bytes: &[u8]) -> ControlFlow { + let mut state = &mut stream.state; + + // we'll be using the pending buffer as temporary storage + let mut beg = state.bit_writer.pending.pending().len(); /* start of bytes to update crc */ + + while state.bit_writer.pending.remaining() < bytes.len() { + let copy = state.bit_writer.pending.remaining(); + + state.bit_writer.pending.extend(&bytes[..copy]); + + stream.adler = crc32( + stream.adler as u32, + &state.bit_writer.pending.pending()[beg..], + ) as z_checksum; + + state.gzindex += copy; + flush_pending(stream); + state = &mut stream.state; + + // could not flush all the pending output + if !state.bit_writer.pending.pending().is_empty() { + state.last_flush = -1; + return ControlFlow::Break(ReturnCode::Ok); + } + + beg = 0; + bytes = &bytes[copy..]; + } + + state.bit_writer.pending.extend(bytes); + + stream.adler = crc32( + stream.adler as u32, + &state.bit_writer.pending.pending()[beg..], + ) as z_checksum; + state.gzindex = 0; + + ControlFlow::Continue(()) +} + +pub fn deflate(stream: &mut DeflateStream, flush: DeflateFlush) -> ReturnCode { + if stream.next_out.is_null() + || (stream.avail_in != 0 && stream.next_in.is_null()) + || (stream.state.status == Status::Finish && flush != DeflateFlush::Finish) + { + let err = ReturnCode::StreamError; + stream.msg = err.error_message(); + return err; + } + + if stream.avail_out == 0 { + let err = ReturnCode::BufError; + stream.msg = err.error_message(); + return err; + } + + let old_flush = stream.state.last_flush; + stream.state.last_flush = flush as i32; + + /* Flush as much pending output as possible */ + if !stream.state.bit_writer.pending.pending().is_empty() { + flush_pending(stream); + if stream.avail_out == 0 { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + stream.state.last_flush = -1; + return ReturnCode::Ok; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if stream.avail_in == 0 + && rank_flush(flush as i32) <= rank_flush(old_flush) + && flush != DeflateFlush::Finish + { + let err = ReturnCode::BufError; + stream.msg = err.error_message(); + return err; + } + + /* User must not provide more input after the first FINISH: */ + if stream.state.status == Status::Finish && stream.avail_in != 0 { + let err = ReturnCode::BufError; + stream.msg = err.error_message(); + return err; + } + + /* Write the header */ + if stream.state.status == Status::Init && stream.state.wrap == 0 { + stream.state.status = Status::Busy; + } + + if stream.state.status == Status::Init { + let header = stream.state.header(); + stream + .state + .bit_writer + .pending + .extend(&header.to_be_bytes()); + + /* Save the adler32 of the preset dictionary: */ + if stream.state.strstart != 0 { + let adler = stream.adler as u32; + stream.state.bit_writer.pending.extend(&adler.to_be_bytes()); + } + + stream.adler = ADLER32_INITIAL_VALUE as _; + stream.state.status = Status::Busy; + + // compression must start with an empty pending buffer + flush_pending(stream); + + if !stream.state.bit_writer.pending.pending().is_empty() { + stream.state.last_flush = -1; + + return ReturnCode::Ok; + } + } + + if stream.state.status == Status::GZip { + /* gzip header */ + stream.state.crc_fold = Crc32Fold::new(); + + stream.state.bit_writer.pending.extend(&[31, 139, 8]); + + let extra_flags = if stream.state.level == 9 { + 2 + } else if stream.state.strategy >= Strategy::HuffmanOnly || stream.state.level < 2 { + 4 + } else { + 0 + }; + + match &stream.state.gzhead { + None => { + let bytes = [0, 0, 0, 0, 0, extra_flags, gz_header::OS_CODE]; + stream.state.bit_writer.pending.extend(&bytes); + stream.state.status = Status::Busy; + + /* Compression must start with an empty pending buffer */ + flush_pending(stream); + if !stream.state.bit_writer.pending.pending().is_empty() { + stream.state.last_flush = -1; + return ReturnCode::Ok; + } + } + Some(gzhead) => { + stream.state.bit_writer.pending.extend(&[gzhead.flags()]); + let bytes = (gzhead.time as u32).to_le_bytes(); + stream.state.bit_writer.pending.extend(&bytes); + stream + .state + .bit_writer + .pending + .extend(&[extra_flags, gzhead.os as u8]); + + if !gzhead.extra.is_null() { + let bytes = (gzhead.extra_len as u16).to_le_bytes(); + stream.state.bit_writer.pending.extend(&bytes); + } + + if gzhead.hcrc > 0 { + stream.adler = crc32( + stream.adler as u32, + stream.state.bit_writer.pending.pending(), + ) as z_checksum + } + + stream.state.gzindex = 0; + stream.state.status = Status::Extra; + } + } + } + + if stream.state.status == Status::Extra { + if let Some(gzhead) = stream.state.gzhead.as_ref() { + if !gzhead.extra.is_null() { + let gzhead_extra = gzhead.extra; + + let extra = unsafe { + core::slice::from_raw_parts( + gzhead_extra.add(stream.state.gzindex), + (gzhead.extra_len & 0xffff) as usize - stream.state.gzindex, + ) + }; + + if let ControlFlow::Break(err) = flush_bytes(stream, extra) { + return err; + } + } + } + stream.state.status = Status::Name; + } + + if stream.state.status == Status::Name { + if let Some(gzhead) = stream.state.gzhead.as_ref() { + if !gzhead.name.is_null() { + let gzhead_name = unsafe { CStr::from_ptr(gzhead.name.cast()) }; + let bytes = gzhead_name.to_bytes_with_nul(); + if let ControlFlow::Break(err) = flush_bytes(stream, bytes) { + return err; + } + } + stream.state.status = Status::Comment; + } + } + + if stream.state.status == Status::Comment { + if let Some(gzhead) = stream.state.gzhead.as_ref() { + if !gzhead.comment.is_null() { + let gzhead_comment = unsafe { CStr::from_ptr(gzhead.comment.cast()) }; + let bytes = gzhead_comment.to_bytes_with_nul(); + if let ControlFlow::Break(err) = flush_bytes(stream, bytes) { + return err; + } + } + stream.state.status = Status::Hcrc; + } + } + + if stream.state.status == Status::Hcrc { + if let Some(gzhead) = stream.state.gzhead.as_ref() { + if gzhead.hcrc != 0 { + let bytes = (stream.adler as u16).to_le_bytes(); + if let ControlFlow::Break(err) = flush_bytes(stream, &bytes) { + return err; + } + } + } + + stream.state.status = Status::Busy; + + // compression must start with an empty pending buffer + flush_pending(stream); + if !stream.state.bit_writer.pending.pending().is_empty() { + stream.state.last_flush = -1; + return ReturnCode::Ok; + } + } + + // Start a new block or continue the current one. + let state = &mut stream.state; + if stream.avail_in != 0 + || state.lookahead != 0 + || (flush != DeflateFlush::NoFlush && state.status != Status::Finish) + { + let bstate = self::algorithm::run(stream, flush); + + let state = &mut stream.state; + + if matches!(bstate, BlockState::FinishStarted | BlockState::FinishDone) { + state.status = Status::Finish; + } + + match bstate { + BlockState::NeedMore | BlockState::FinishStarted => { + if stream.avail_out == 0 { + state.last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return ReturnCode::Ok; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + BlockState::BlockDone => { + match flush { + DeflateFlush::NoFlush => unreachable!("condition of inner surrounding if"), + DeflateFlush::PartialFlush => { + state.bit_writer.align(); + } + DeflateFlush::SyncFlush => { + // add an empty stored block that is marked as not final. This is useful for + // parallel deflate where we want to make sure the intermediate blocks are not + // marked as "last block". + zng_tr_stored_block(state, 0..0, false); + } + DeflateFlush::FullFlush => { + // add an empty stored block that is marked as not final. This is useful for + // parallel deflate where we want to make sure the intermediate blocks are not + // marked as "last block". + zng_tr_stored_block(state, 0..0, false); + + state.head.fill(0); // forget history + + if state.lookahead == 0 { + state.strstart = 0; + state.block_start = 0; + state.insert = 0; + } + } + DeflateFlush::Block => { /* fall through */ } + DeflateFlush::Finish => unreachable!("condition of outer surrounding if"), + } + + flush_pending(stream); + + if stream.avail_out == 0 { + stream.state.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return ReturnCode::Ok; + } + } + BlockState::FinishDone => { /* do nothing */ } + } + } + + if flush != DeflateFlush::Finish { + return ReturnCode::Ok; + } + + // write the trailer + if stream.state.wrap == 2 { + let crc_fold = core::mem::take(&mut stream.state.crc_fold); + stream.adler = crc_fold.finish() as z_checksum; + + let adler = stream.adler as u32; + stream.state.bit_writer.pending.extend(&adler.to_le_bytes()); + + let total_in = stream.total_in as u32; + stream + .state + .bit_writer + .pending + .extend(&total_in.to_le_bytes()); + } else if stream.state.wrap == 1 { + let adler = stream.adler as u32; + stream.state.bit_writer.pending.extend(&adler.to_be_bytes()); + } + + flush_pending(stream); + + // If avail_out is zero, the application will call deflate again to flush the rest. + if stream.state.wrap > 0 { + stream.state.wrap = -stream.state.wrap; /* write the trailer only once! */ + } + + if stream.state.bit_writer.pending.pending().is_empty() { + assert_eq!(stream.state.bit_writer.bits_used, 0, "bi_buf not flushed"); + return ReturnCode::StreamEnd; + } + ReturnCode::Ok +} + +pub(crate) fn flush_pending(stream: &mut DeflateStream) { + let state = &mut stream.state; + + state.bit_writer.flush_bits(); + + let pending = state.bit_writer.pending.pending(); + let len = Ord::min(pending.len(), stream.avail_out as usize); + + if len == 0 { + return; + } + + trace!("\n[FLUSH {len} bytes]"); + unsafe { core::ptr::copy_nonoverlapping(pending.as_ptr(), stream.next_out, len) }; + + stream.next_out = stream.next_out.wrapping_add(len); + stream.total_out += len as crate::c_api::z_size; + stream.avail_out -= len as crate::c_api::uInt; + + state.bit_writer.pending.advance(len); +} + +pub fn compress_slice<'a>( + output: &'a mut [u8], + input: &[u8], + config: DeflateConfig, +) -> (&'a mut [u8], ReturnCode) { + let output_uninit = unsafe { + core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut MaybeUninit, output.len()) + }; + + compress(output_uninit, input, config) +} + +pub fn compress<'a>( + output: &'a mut [MaybeUninit], + input: &[u8], + config: DeflateConfig, +) -> (&'a mut [u8], ReturnCode) { + compress_with_flush(output, input, config, DeflateFlush::Finish) +} + +pub fn compress_slice_with_flush<'a>( + output: &'a mut [u8], + input: &[u8], + config: DeflateConfig, + flush: DeflateFlush, +) -> (&'a mut [u8], ReturnCode) { + let output_uninit = unsafe { + core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut MaybeUninit, output.len()) + }; + + compress_with_flush(output_uninit, input, config, flush) +} + +pub fn compress_with_flush<'a>( + output: &'a mut [MaybeUninit], + input: &[u8], + config: DeflateConfig, + final_flush: DeflateFlush, +) -> (&'a mut [u8], ReturnCode) { + let mut stream = z_stream { + next_in: input.as_ptr() as *mut u8, + avail_in: 0, // for special logic in the first iteration + total_in: 0, + next_out: output.as_mut_ptr() as *mut u8, + avail_out: 0, // for special logic on the first iteration + total_out: 0, + msg: core::ptr::null_mut(), + state: core::ptr::null_mut(), + zalloc: None, + zfree: None, + opaque: core::ptr::null_mut(), + data_type: 0, + adler: 0, + reserved: 0, + }; + + let err = init(&mut stream, config); + if err != ReturnCode::Ok { + return (&mut [], err); + } + + let max = core::ffi::c_uint::MAX as usize; + + let mut left = output.len(); + let mut source_len = input.len(); + + loop { + if stream.avail_out == 0 { + stream.avail_out = Ord::min(left, max) as _; + left -= stream.avail_out as usize; + } + + if stream.avail_in == 0 { + stream.avail_in = Ord::min(source_len, max) as _; + source_len -= stream.avail_in as usize; + } + + let flush = if source_len > 0 { + DeflateFlush::NoFlush + } else { + final_flush + }; + + let err = if let Some(stream) = unsafe { DeflateStream::from_stream_mut(&mut stream) } { + deflate(stream, flush) + } else { + ReturnCode::StreamError + }; + + if err != ReturnCode::Ok { + break; + } + } + + // SAFETY: we have now initialized these bytes + let output_slice = unsafe { + core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, stream.total_out as usize) + }; + + // may DataError if insufficient output space + let return_code = if let Some(stream) = unsafe { DeflateStream::from_stream_mut(&mut stream) } { + match end(stream) { + Ok(_) => ReturnCode::Ok, + Err(_) => ReturnCode::DataError, + } + } else { + ReturnCode::Ok + }; + + (output_slice, return_code) +} + +pub const fn compress_bound(source_len: usize) -> usize { + compress_bound_help(source_len, ZLIB_WRAPLEN) +} + +const fn compress_bound_help(source_len: usize, wrap_len: usize) -> usize { + source_len // The source size itself */ + // Always at least one byte for any input + .wrapping_add(if source_len == 0 { 1 } else { 0 }) + // One extra byte for lengths less than 9 + .wrapping_add(if source_len < 9 { 1 } else { 0 }) + // Source encoding overhead, padded to next full byte + .wrapping_add(deflate_quick_overhead(source_len)) + // Deflate block overhead bytes + .wrapping_add(DEFLATE_BLOCK_OVERHEAD) + // none, zlib or gzip wrapper + .wrapping_add(wrap_len) +} + +/// heap used to build the Huffman trees + +/// The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. +/// The same heap array is used to build all trees. +#[derive(Clone)] +struct Heap { + heap: [u32; 2 * L_CODES + 1], + + /// number of elements in the heap + heap_len: usize, + + /// element of the largest frequency + heap_max: usize, + + depth: [u8; 2 * L_CODES + 1], +} + +impl Heap { + // an empty heap + fn new() -> Self { + Self { + heap: [0; 2 * L_CODES + 1], + heap_len: 0, + heap_max: 0, + depth: [0; 2 * L_CODES + 1], + } + } + + /// Construct the initial heap, with least frequent element in + /// heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + fn initialize(&mut self, tree: &mut [Value]) -> isize { + let mut max_code = -1; + + self.heap_len = 0; + self.heap_max = HEAP_SIZE; + + for (n, node) in tree.iter_mut().enumerate() { + if node.freq() > 0 { + self.heap_len += 1; + self.heap[self.heap_len] = n as u32; + max_code = n as isize; + self.depth[n] = 0; + } else { + *node.len_mut() = 0; + } + } + + max_code + } + + /// Index within the heap array of least frequent node in the Huffman tree + const SMALLEST: usize = 1; + + fn smaller(tree: &[Value], n: u32, m: u32, depth: &[u8]) -> bool { + let (n, m) = (n as usize, m as usize); + + match Ord::cmp(&tree[n].freq(), &tree[m].freq()) { + core::cmp::Ordering::Less => true, + core::cmp::Ordering::Equal => depth[n] <= depth[m], + core::cmp::Ordering::Greater => false, + } + } + + fn pqdownheap(&mut self, tree: &[Value], mut k: usize) { + /* tree: the tree to restore */ + /* k: node to move down */ + + let v = self.heap[k]; + let mut j = k << 1; /* left son of k */ + + while j <= self.heap_len { + /* Set j to the smallest of the two sons: */ + if j < self.heap_len { + let cond = Self::smaller(tree, self.heap[j + 1], self.heap[j], &self.depth); + if cond { + j += 1; + } + } + + /* Exit if v is smaller than both sons */ + if Self::smaller(tree, v, self.heap[j], &self.depth) { + break; + } + + /* Exchange v with the smallest son */ + self.heap[k] = self.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + + self.heap[k] = v; + } + + /// Remove the smallest element from the heap and recreate the heap with + /// one less element. Updates heap and heap_len. + fn pqremove(&mut self, tree: &[Value]) -> u32 { + let top = self.heap[Self::SMALLEST]; + self.heap[Self::SMALLEST] = self.heap[self.heap_len]; + self.heap_len -= 1; + + self.pqdownheap(tree, Self::SMALLEST); + + top + } + + /// Construct the Huffman tree by repeatedly combining the least two frequent nodes. + fn construct_huffman_tree(&mut self, tree: &mut [Value], mut node: usize) { + loop { + let n = self.pqremove(tree) as usize; /* n = node of least frequency */ + let m = self.heap[Heap::SMALLEST] as usize; /* m = node of next least frequency */ + + self.heap_max -= 1; + self.heap[self.heap_max] = n as u32; /* keep the nodes sorted by frequency */ + self.heap_max -= 1; + self.heap[self.heap_max] = m as u32; + + /* Create a new node father of n and m */ + *tree[node].freq_mut() = tree[n].freq() + tree[m].freq(); + self.depth[node] = Ord::max(self.depth[n], self.depth[m]) + 1; + + *tree[n].dad_mut() = node as u16; + *tree[m].dad_mut() = node as u16; + + /* and insert the new node in the heap */ + self.heap[Heap::SMALLEST] = node as u32; + node += 1; + + self.pqdownheap(tree, Heap::SMALLEST); + + if self.heap_len < 2 { + break; + } + } + + self.heap_max -= 1; + self.heap[self.heap_max] = self.heap[Heap::SMALLEST]; + } +} + +pub fn set_header<'a>( + stream: &mut DeflateStream<'a>, + head: Option<&'a mut gz_header>, +) -> ReturnCode { + if stream.state.wrap != 2 { + ReturnCode::StreamError as _ + } else { + stream.state.gzhead = head; + ReturnCode::Ok as _ + } +} + +// zlib format overhead +const ZLIB_WRAPLEN: usize = 6; +// gzip format overhead +const GZIP_WRAPLEN: usize = 18; + +const DEFLATE_HEADER_BITS: usize = 3; +const DEFLATE_EOBS_BITS: usize = 15; +const DEFLATE_PAD_BITS: usize = 6; +const DEFLATE_BLOCK_OVERHEAD: usize = + (DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3; + +const DEFLATE_QUICK_LIT_MAX_BITS: usize = 9; +const fn deflate_quick_overhead(x: usize) -> usize { + let sum = x + .wrapping_mul(DEFLATE_QUICK_LIT_MAX_BITS - 8) + .wrapping_add(7); + + // imitate zlib-ng rounding behavior (on windows, c_ulong is 32 bits) + (sum as core::ffi::c_ulong >> 3) as usize +} + +/// For the default windowBits of 15 and memLevel of 8, this function returns +/// a close to exact, as well as small, upper bound on the compressed size. +/// They are coded as constants here for a reason--if the #define's are +/// changed, then this function needs to be changed as well. The return +/// value for 15 and 8 only works for those exact settings. +/// +/// For any setting other than those defaults for windowBits and memLevel, +/// the value returned is a conservative worst case for the maximum expansion +/// resulting from using fixed blocks instead of stored blocks, which deflate +/// can emit on compressed data for some combinations of the parameters. +/// +/// This function could be more sophisticated to provide closer upper bounds for +/// every combination of windowBits and memLevel. But even the conservative +/// upper bound of about 14% expansion does not seem onerous for output buffer +/// allocation. +pub fn bound(stream: Option<&mut DeflateStream>, source_len: usize) -> usize { + // on windows, c_ulong is only a 32-bit integer + let mask = core::ffi::c_ulong::MAX as usize; + + // conservative upper bound for compressed data + let comp_len = source_len + .wrapping_add((source_len.wrapping_add(7) & mask) >> 3) + .wrapping_add((source_len.wrapping_add(63) & mask) >> 6) + .wrapping_add(5); + + let Some(stream) = stream else { + // return conservative bound plus zlib wrapper + return comp_len.wrapping_add(6); + }; + + /* compute wrapper length */ + let wrap_len = match stream.state.wrap { + 0 => { + // raw deflate + 0 + } + 1 => { + // zlib wrapper + if stream.state.strstart != 0 { + ZLIB_WRAPLEN + 4 + } else { + ZLIB_WRAPLEN + } + } + 2 => { + // gzip wrapper + let mut gz_wrap_len = GZIP_WRAPLEN; + + if let Some(header) = &stream.state.gzhead { + if !header.extra.is_null() { + gz_wrap_len += 2 + header.extra_len as usize; + } + + let mut c_string = header.name; + if !c_string.is_null() { + loop { + gz_wrap_len += 1; + unsafe { + if *c_string == 0 { + break; + } + c_string = c_string.add(1); + } + } + } + + let mut c_string = header.comment; + if !c_string.is_null() { + loop { + gz_wrap_len += 1; + unsafe { + if *c_string == 0 { + break; + } + c_string = c_string.add(1); + } + } + } + + if header.hcrc != 0 { + gz_wrap_len += 2; + } + } + + gz_wrap_len + } + _ => { + // default + ZLIB_WRAPLEN + } + }; + + if stream.state.w_bits != MAX_WBITS as usize || HASH_BITS < 15 { + if stream.state.level == 0 { + /* upper bound for stored blocks with length 127 (memLevel == 1) ~4% overhead plus a small constant */ + source_len + .wrapping_add(source_len >> 5) + .wrapping_add(source_len >> 7) + .wrapping_add(source_len >> 11) + .wrapping_add(7) + .wrapping_add(wrap_len) + } else { + comp_len.wrapping_add(wrap_len) + } + } else { + compress_bound_help(source_len, wrap_len) + } +} + +#[cfg(test)] +mod test { + use crate::{ + inflate::{uncompress_slice, InflateConfig, InflateStream}, + InflateFlush, + }; + + use super::*; + + use core::{ffi::CStr, sync::atomic::AtomicUsize}; + + #[test] + fn detect_data_type_basic() { + let empty = || [Value::new(0, 0); LITERALS]; + + assert_eq!(State::detect_data_type(&empty()), DataType::Binary); + + let mut binary = empty(); + binary[0] = Value::new(1, 0); + assert_eq!(State::detect_data_type(&binary), DataType::Binary); + + let mut text = empty(); + text[b'\r' as usize] = Value::new(1, 0); + assert_eq!(State::detect_data_type(&text), DataType::Text); + + let mut text = empty(); + text[b'a' as usize] = Value::new(1, 0); + assert_eq!(State::detect_data_type(&text), DataType::Text); + + let mut non_text = empty(); + non_text[7] = Value::new(1, 0); + assert_eq!(State::detect_data_type(&non_text), DataType::Binary); + } + + #[test] + fn from_stream_mut() { + unsafe { + assert!(DeflateStream::from_stream_mut(core::ptr::null_mut()).is_none()); + + let mut stream = z_stream::default(); + assert!(DeflateStream::from_stream_mut(&mut stream).is_none()); + + // state is still NULL + assert!(DeflateStream::from_stream_mut(&mut stream).is_none()); + + init(&mut stream, DeflateConfig::default()); + let stream = DeflateStream::from_stream_mut(&mut stream); + assert!(stream.is_some()); + + assert!(end(stream.unwrap()).is_ok()); + } + } + + unsafe extern "C" fn fail_nth_allocation( + opaque: crate::c_api::voidpf, + items: crate::c_api::uInt, + size: crate::c_api::uInt, + ) -> crate::c_api::voidpf { + let count = unsafe { &*(opaque as *const AtomicUsize) }; + + if count.fetch_add(1, core::sync::atomic::Ordering::Relaxed) != N { + // must use the C allocator internally because (de)allocation is based on function + // pointer values and because we don't use the rust allocator directly, the allocation + // logic will store the pointer to the start at the start of the allocation. + (crate::allocate::Allocator::C.zalloc)(opaque, items, size) + } else { + core::ptr::null_mut() + } + } + + #[test] + fn init_invalid_allocator() { + { + let atomic = AtomicUsize::new(0); + let mut stream = z_stream { + zalloc: Some(fail_nth_allocation::<0>), + zfree: Some(crate::allocate::Allocator::C.zfree), + opaque: &atomic as *const _ as *const core::ffi::c_void as *mut _, + ..z_stream::default() + }; + assert_eq!( + init(&mut stream, DeflateConfig::default()), + ReturnCode::MemError + ); + } + + { + let atomic = AtomicUsize::new(0); + let mut stream = z_stream { + zalloc: Some(fail_nth_allocation::<3>), + zfree: Some(crate::allocate::Allocator::C.zfree), + opaque: &atomic as *const _ as *const core::ffi::c_void as *mut _, + ..z_stream::default() + }; + assert_eq!( + init(&mut stream, DeflateConfig::default()), + ReturnCode::MemError + ); + } + + { + let atomic = AtomicUsize::new(0); + let mut stream = z_stream { + zalloc: Some(fail_nth_allocation::<5>), + zfree: Some(crate::allocate::Allocator::C.zfree), + opaque: &atomic as *const _ as *const core::ffi::c_void as *mut _, + ..z_stream::default() + }; + assert_eq!( + init(&mut stream, DeflateConfig::default()), + ReturnCode::MemError + ); + } + } + + mod copy_invalid_allocator { + use super::*; + + #[test] + fn fail_0() { + let mut stream = z_stream::default(); + + let atomic = AtomicUsize::new(0); + stream.opaque = &atomic as *const _ as *const core::ffi::c_void as *mut _; + stream.zalloc = Some(fail_nth_allocation::<6>); + stream.zfree = Some(crate::allocate::Allocator::C.zfree); + + // init performs 6 allocations; we don't want those to fail + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(&mut stream) }) else { + unreachable!() + }; + + let mut stream_copy = MaybeUninit::::zeroed(); + + assert_eq!(copy(&mut stream_copy, stream), ReturnCode::MemError); + + assert!(end(stream).is_ok()); + } + + #[test] + fn fail_3() { + let mut stream = z_stream::default(); + + let atomic = AtomicUsize::new(0); + stream.zalloc = Some(fail_nth_allocation::<{ 6 + 3 }>); + stream.zfree = Some(crate::allocate::Allocator::C.zfree); + stream.opaque = &atomic as *const _ as *const core::ffi::c_void as *mut _; + + // init performs 6 allocations; we don't want those to fail + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(&mut stream) }) else { + unreachable!() + }; + + let mut stream_copy = MaybeUninit::::zeroed(); + + assert_eq!(copy(&mut stream_copy, stream), ReturnCode::MemError); + + assert!(end(stream).is_ok()); + } + + #[test] + fn fail_5() { + let mut stream = z_stream::default(); + + let atomic = AtomicUsize::new(0); + stream.zalloc = Some(fail_nth_allocation::<{ 6 + 5 }>); + stream.zfree = Some(crate::allocate::Allocator::C.zfree); + stream.opaque = &atomic as *const _ as *const core::ffi::c_void as *mut _; + + // init performs 6 allocations; we don't want those to fail + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(&mut stream) }) else { + unreachable!() + }; + + let mut stream_copy = MaybeUninit::::zeroed(); + + assert_eq!(copy(&mut stream_copy, stream), ReturnCode::MemError); + + assert!(end(stream).is_ok()); + } + } + + mod invalid_deflate_config { + use super::*; + + #[test] + fn sanity_check() { + let mut stream = z_stream::default(); + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + + assert!(stream.zalloc.is_some()); + assert!(stream.zfree.is_some()); + + // this should be the default level + let stream = unsafe { DeflateStream::from_stream_mut(&mut stream) }.unwrap(); + assert_eq!(stream.state.level, 6); + + assert!(end(stream).is_ok()); + } + + #[test] + fn window_bits_correction() { + // window_bits of 8 gets turned into 9 internally + let mut stream = z_stream::default(); + let config = DeflateConfig { + window_bits: 8, + ..Default::default() + }; + assert_eq!(init(&mut stream, config), ReturnCode::Ok); + let stream = unsafe { DeflateStream::from_stream_mut(&mut stream) }.unwrap(); + assert_eq!(stream.state.w_bits, 9); + + assert!(end(stream).is_ok()); + } + + #[test] + fn window_bits_too_low() { + let mut stream = z_stream::default(); + let config = DeflateConfig { + window_bits: -16, + ..Default::default() + }; + assert_eq!(init(&mut stream, config), ReturnCode::StreamError); + } + + #[test] + fn window_bits_too_high() { + // window bits too high + let mut stream = z_stream::default(); + let config = DeflateConfig { + window_bits: 42, + ..Default::default() + }; + assert_eq!(init(&mut stream, config), ReturnCode::StreamError); + } + } + + #[test] + fn end_data_error() { + let mut stream = z_stream::default(); + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + let stream = unsafe { DeflateStream::from_stream_mut(&mut stream) }.unwrap(); + + // next deflate into too little space + let input = b"Hello World\n"; + stream.next_in = input.as_ptr() as *mut u8; + stream.avail_in = input.len() as _; + let output = &mut [0, 0, 0]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = output.len() as _; + + // the deflate is fine + assert_eq!(deflate(stream, DeflateFlush::NoFlush), ReturnCode::Ok); + + // but end is not + assert!(end(stream).is_err()); + } + + #[test] + fn test_reset_keep() { + let mut stream = z_stream::default(); + assert_eq!(init(&mut stream, DeflateConfig::default()), ReturnCode::Ok); + let stream = unsafe { DeflateStream::from_stream_mut(&mut stream) }.unwrap(); + + // next deflate into too little space + let input = b"Hello World\n"; + stream.next_in = input.as_ptr() as *mut u8; + stream.avail_in = input.len() as _; + + let output = &mut [0; 1024]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = output.len() as _; + assert_eq!(deflate(stream, DeflateFlush::Finish), ReturnCode::StreamEnd); + + assert_eq!(reset_keep(stream), ReturnCode::Ok); + + let output = &mut [0; 1024]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = output.len() as _; + assert_eq!(deflate(stream, DeflateFlush::Finish), ReturnCode::StreamEnd); + + assert!(end(stream).is_ok()); + } + + #[test] + fn hello_world_huffman_only() { + const EXPECTED: &[u8] = &[ + 0x78, 0x01, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0x08, 0xcf, 0x2f, 0xca, 0x49, 0x51, + 0xe4, 0x02, 0x00, 0x20, 0x91, 0x04, 0x48, + ]; + + let input = "Hello World!\n"; + + let mut output = vec![0; 128]; + + let config = DeflateConfig { + level: 6, + method: Method::Deflated, + window_bits: crate::MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::HuffmanOnly, + }; + + let (output, err) = compress_slice(&mut output, input.as_bytes(), config); + + assert_eq!(err, ReturnCode::Ok); + + assert_eq!(output.len(), EXPECTED.len()); + + assert_eq!(EXPECTED, output); + } + + #[test] + fn hello_world_quick() { + const EXPECTED: &[u8] = &[ + 0x78, 0x01, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0x08, 0xcf, 0x2f, 0xca, 0x49, 0x51, + 0xe4, 0x02, 0x00, 0x20, 0x91, 0x04, 0x48, + ]; + + let input = "Hello World!\n"; + + let mut output = vec![0; 128]; + + let config = DeflateConfig { + level: 1, + method: Method::Deflated, + window_bits: crate::MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::Default, + }; + + let (output, err) = compress_slice(&mut output, input.as_bytes(), config); + + assert_eq!(err, ReturnCode::Ok); + + assert_eq!(output.len(), EXPECTED.len()); + + assert_eq!(EXPECTED, output); + } + + #[test] + fn hello_world_quick_random() { + const EXPECTED: &[u8] = &[ + 0x78, 0x01, 0x53, 0xe1, 0x50, 0x51, 0xe1, 0x52, 0x51, 0x51, 0x01, 0x00, 0x03, 0xec, + 0x00, 0xeb, + ]; + + let input = "$\u{8}$$\n$$$"; + + let mut output = vec![0; 128]; + + let config = DeflateConfig { + level: 1, + method: Method::Deflated, + window_bits: crate::MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::Default, + }; + + let (output, err) = compress_slice(&mut output, input.as_bytes(), config); + + assert_eq!(err, ReturnCode::Ok); + + assert_eq!(output.len(), EXPECTED.len()); + + assert_eq!(EXPECTED, output); + } + + fn fuzz_based_test(input: &[u8], config: DeflateConfig, expected: &[u8]) { + let mut output_rs = [0; 1 << 17]; + let (output_rs, err) = compress_slice(&mut output_rs, input, config); + assert_eq!(err, ReturnCode::Ok); + + assert_eq!(output_rs, expected); + } + + #[test] + fn simple_rle() { + fuzz_based_test( + "\0\0\0\0\u{6}".as_bytes(), + DeflateConfig { + level: -1, + method: Method::Deflated, + window_bits: 11, + mem_level: 4, + strategy: Strategy::Rle, + }, + &[56, 17, 99, 0, 2, 54, 0, 0, 11, 0, 7], + ) + } + + #[test] + fn fill_window_out_of_bounds() { + const INPUT: &[u8] = &[ + 0x71, 0x71, 0x71, 0x71, 0x71, 0x6a, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x1d, 0x1d, 0x1d, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x27, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, + 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x48, 0x50, + 0x50, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x70, 0x71, 0x71, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, 0x6a, 0x0, 0x0, 0x0, 0x0, + 0x71, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x70, 0x71, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, + 0x6a, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x1d, 0x0, 0x0, 0x0, 0x0, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x50, 0x50, 0x50, 0x50, 0x48, 0x50, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, 0x3b, 0x3f, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x50, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x70, 0x71, 0x71, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x70, 0x71, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x71, 0x71, 0x71, 0x3b, 0x3f, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x3b, 0x3f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x71, 0x75, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x10, 0x0, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x3b, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x76, 0x71, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x10, 0x0, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x3b, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x76, 0x71, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x30, 0x34, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x6, + ]; + + fuzz_based_test( + INPUT, + DeflateConfig { + level: -1, + method: Method::Deflated, + window_bits: 9, + mem_level: 1, + strategy: Strategy::HuffmanOnly, + }, + &[ + 0x18, 0x19, 0x4, 0xc1, 0x21, 0x1, 0xc4, 0x0, 0x10, 0x3, 0xb0, 0x18, 0x29, 0x1e, + 0x7e, 0x17, 0x83, 0xf5, 0x70, 0x6c, 0xac, 0xfe, 0xc9, 0x27, 0xdb, 0xb6, 0x6f, 0xdb, + 0xb6, 0x6d, 0xdb, 0x80, 0x24, 0xb9, 0xbb, 0xbb, 0x24, 0x49, 0x92, 0x24, 0xf, 0x2, + 0xd8, 0x36, 0x0, 0xf0, 0x3, 0x0, 0x0, 0x24, 0xd0, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, + 0xdb, 0xbe, 0x6d, 0xf9, 0x13, 0x4, 0xc7, 0x4, 0x0, 0x80, 0x30, 0x0, 0xc3, 0x22, + 0x68, 0xf, 0x36, 0x90, 0xc2, 0xb5, 0xfa, 0x7f, 0x48, 0x80, 0x81, 0xb, 0x40, 0x55, + 0x55, 0x55, 0xd5, 0x16, 0x80, 0xaa, 0x7, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x7c, 0x82, 0xe0, 0x98, 0x0, 0x0, 0x0, 0x4, 0x60, 0x10, 0xf9, 0x8c, 0xe2, + 0xe5, 0xfa, 0x3f, 0x2, 0x54, 0x55, 0x55, 0x65, 0x0, 0xa8, 0xaa, 0xaa, 0xaa, 0xba, + 0x2, 0x50, 0xb5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x82, 0xe0, 0xd0, + 0x8a, 0x41, 0x0, 0x0, 0xa2, 0x58, 0x54, 0xb7, 0x60, 0x83, 0x9a, 0x6a, 0x4, 0x96, + 0x87, 0xba, 0x51, 0xf8, 0xfb, 0x9b, 0x26, 0xfc, 0x0, 0x1c, 0x7, 0x6c, 0xdb, 0xb6, + 0x6d, 0xdb, 0xb6, 0x6d, 0xf7, 0xa8, 0x3a, 0xaf, 0xaa, 0x6a, 0x3, 0xf8, 0xc2, 0x3, + 0x40, 0x55, 0x55, 0x55, 0xd5, 0x5b, 0xf8, 0x80, 0xaa, 0x7a, 0xb, 0x0, 0x7f, 0x82, + 0xe0, 0x98, 0x0, 0x40, 0x18, 0x0, 0x82, 0xd8, 0x49, 0x40, 0x2, 0x22, 0x7e, 0xeb, + 0x80, 0xa6, 0xc, 0xa0, 0x9f, 0xa4, 0x2a, 0x38, 0xf, 0x0, 0x0, 0xe7, 0x1, 0xdc, + 0x55, 0x95, 0x17, 0x0, 0x0, 0xae, 0x0, 0x38, 0xc0, 0x67, 0xdb, 0x36, 0x80, 0x2b, + 0x0, 0xe, 0xf0, 0xd9, 0xf6, 0x13, 0x4, 0xc7, 0x4, 0x0, 0x0, 0x30, 0xc, 0x83, 0x22, + 0x69, 0x7, 0xc6, 0xea, 0xff, 0x19, 0x0, 0x0, 0x80, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x6a, + 0xf5, 0x63, 0x60, 0x60, 0x3, 0x0, 0xee, 0x8a, 0x88, 0x67, + ], + ) + } + + #[test] + fn gzip_no_header() { + let config = DeflateConfig { + level: 9, + method: Method::Deflated, + window_bits: 31, // gzip + ..Default::default() + }; + + let input = b"Hello World!"; + let os = gz_header::OS_CODE; + + fuzz_based_test( + input, + config, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 2, os, 243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, + 81, 4, 0, 163, 28, 41, 28, 12, 0, 0, 0, + ], + ) + } + + #[test] + #[rustfmt::skip] + fn gzip_stored_block_checksum() { + fuzz_based_test( + &[ + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 0, + ], + DeflateConfig { + level: 0, + method: Method::Deflated, + window_bits: 26, + mem_level: 6, + strategy: Strategy::Default, + }, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 4, gz_header::OS_CODE, 1, 18, 0, 237, 255, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 0, 60, 101, 156, 55, 18, 0, 0, 0, + ], + ) + } + + #[test] + fn gzip_header_pending_flush() { + let extra = "aaaaaaaaaaaaaaaaaaaa\0"; + let name = "bbbbbbbbbbbbbbbbbbbb\0"; + let comment = "cccccccccccccccccccc\0"; + + let mut header = gz_header { + text: 0, + time: 0, + xflags: 0, + os: 0, + extra: extra.as_ptr() as *mut _, + extra_len: extra.len() as _, + extra_max: 0, + name: name.as_ptr() as *mut _, + name_max: 0, + comment: comment.as_ptr() as *mut _, + comm_max: 0, + hcrc: 1, + done: 0, + }; + + let config = DeflateConfig { + window_bits: 31, + mem_level: 1, + ..Default::default() + }; + + let mut stream = z_stream::default(); + assert_eq!(init(&mut stream, config), ReturnCode::Ok); + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(&mut stream) }) else { + unreachable!() + }; + + set_header(stream, Some(&mut header)); + + let input = b"Hello World\n"; + stream.next_in = input.as_ptr() as *mut _; + stream.avail_in = input.len() as _; + + let mut output = [0u8; 1024]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = 100; + + assert_eq!(stream.state.bit_writer.pending.capacity(), 512); + + // only 12 bytes remain, so to write the name the pending buffer must be flushed. + // but there is insufficient output space to flush (only 100 bytes) + stream.state.bit_writer.pending.extend(&[0; 500]); + + assert_eq!(deflate(stream, DeflateFlush::Finish), ReturnCode::Ok); + + // now try that again but with sufficient output space + stream.avail_out = output.len() as _; + assert_eq!(deflate(stream, DeflateFlush::Finish), ReturnCode::StreamEnd); + + let n = stream.total_out as usize; + + assert!(end(stream).is_ok()); + + let output_rs = &mut output[..n]; + + assert_eq!(output_rs.len(), 500 + 99); + } + + #[test] + fn gzip_with_header() { + // this test is here mostly so we get some MIRI action on the gzip header. A test that + // compares behavior with zlib-ng is in the libz-rs-sys test suite + + let extra = "some extra stuff\0"; + let name = "nomen est omen\0"; + let comment = "such comment\0"; + + let mut header = gz_header { + text: 0, + time: 0, + xflags: 0, + os: 0, + extra: extra.as_ptr() as *mut _, + extra_len: extra.len() as _, + extra_max: 0, + name: name.as_ptr() as *mut _, + name_max: 0, + comment: comment.as_ptr() as *mut _, + comm_max: 0, + hcrc: 1, + done: 0, + }; + + let config = DeflateConfig { + window_bits: 31, + ..Default::default() + }; + + let mut stream = z_stream::default(); + assert_eq!(init(&mut stream, config), ReturnCode::Ok); + + let Some(stream) = (unsafe { DeflateStream::from_stream_mut(&mut stream) }) else { + unreachable!() + }; + + set_header(stream, Some(&mut header)); + + let input = b"Hello World\n"; + stream.next_in = input.as_ptr() as *mut _; + stream.avail_in = input.len() as _; + + let mut output = [0u8; 256]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = output.len() as _; + + assert_eq!(deflate(stream, DeflateFlush::Finish), ReturnCode::StreamEnd); + + let n = stream.total_out as usize; + + assert!(end(stream).is_ok()); + + let output_rs = &mut output[..n]; + + assert_eq!(output_rs.len(), 81); + + { + let mut stream = z_stream::default(); + + let config = InflateConfig { + window_bits: config.window_bits, + }; + + assert_eq!(crate::inflate::init(&mut stream, config), ReturnCode::Ok); + + let Some(stream) = (unsafe { InflateStream::from_stream_mut(&mut stream) }) else { + unreachable!(); + }; + + stream.next_in = output_rs.as_mut_ptr() as _; + stream.avail_in = output_rs.len() as _; + + let mut output = [0u8; 12]; + stream.next_out = output.as_mut_ptr(); + stream.avail_out = output.len() as _; + + let mut extra_buf = [0u8; 64]; + let mut name_buf = [0u8; 64]; + let mut comment_buf = [0u8; 64]; + + let mut header = gz_header { + text: 0, + time: 0, + xflags: 0, + os: 0, + extra: extra_buf.as_mut_ptr(), + extra_len: 0, + extra_max: extra_buf.len() as _, + name: name_buf.as_mut_ptr(), + name_max: name_buf.len() as _, + comment: comment_buf.as_mut_ptr(), + comm_max: comment_buf.len() as _, + hcrc: 0, + done: 0, + }; + + assert_eq!( + crate::inflate::get_header(stream, Some(&mut header)), + ReturnCode::Ok + ); + + assert_eq!( + unsafe { crate::inflate::inflate(stream, InflateFlush::Finish) }, + ReturnCode::StreamEnd + ); + + crate::inflate::end(stream); + + assert!(!header.comment.is_null()); + assert_eq!( + unsafe { CStr::from_ptr(header.comment.cast()) } + .to_str() + .unwrap(), + comment.trim_end_matches('\0') + ); + + assert!(!header.name.is_null()); + assert_eq!( + unsafe { CStr::from_ptr(header.name.cast()) } + .to_str() + .unwrap(), + name.trim_end_matches('\0') + ); + + assert!(!header.extra.is_null()); + assert_eq!( + unsafe { CStr::from_ptr(header.extra.cast()) } + .to_str() + .unwrap(), + extra.trim_end_matches('\0') + ); + } + } + + #[test] + #[cfg_attr(miri, ignore)] + fn insufficient_compress_space() { + const DATA: &[u8] = include_bytes!("deflate/test-data/inflate_buf_error.dat"); + + fn helper(deflate_buf: &mut [u8]) -> ReturnCode { + let config = DeflateConfig { + level: 0, + method: Method::Deflated, + window_bits: 10, + mem_level: 6, + strategy: Strategy::Default, + }; + + let (output, err) = compress_slice(deflate_buf, DATA, config); + assert_eq!(err, ReturnCode::Ok); + + let config = InflateConfig { + window_bits: config.window_bits, + }; + + let mut uncompr = [0; 1 << 17]; + let (uncompr, err) = uncompress_slice(&mut uncompr, output, config); + + if err == ReturnCode::Ok { + assert_eq!(DATA, uncompr); + } + + err + } + + let mut output = [0; 1 << 17]; + + // this is too little space + assert_eq!(helper(&mut output[..1 << 16]), ReturnCode::DataError); + + // this is sufficient space + assert_eq!(helper(&mut output), ReturnCode::Ok); + } + + fn test_flush(flush: DeflateFlush, expected: &[u8]) { + let input = b"Hello World!\n"; + + let config = DeflateConfig { + level: 6, // use gzip + method: Method::Deflated, + window_bits: 16 + crate::MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::Default, + }; + + let mut output_rs = vec![0; 128]; + + // with the flush modes that we test here, the deflate process still has `Status::Busy`, + // and the `deflateEnd` function will return `DataError`. + let expected_err = ReturnCode::DataError; + + let (rs, err) = compress_slice_with_flush(&mut output_rs, input, config, flush); + assert_eq!(expected_err, err); + + assert_eq!(rs, expected); + } + + #[test] + #[rustfmt::skip] + fn sync_flush() { + test_flush( + DeflateFlush::SyncFlush, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 0, gz_header::OS_CODE, 242, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, + 81, 228, 2, 0, 0, 0, 255, 255, + ], + ) + } + + #[test] + #[rustfmt::skip] + fn partial_flush() { + test_flush( + DeflateFlush::PartialFlush, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 0, gz_header::OS_CODE, 242, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, + 81, 228, 2, 8, + ], + ); + } + + #[test] + #[rustfmt::skip] + fn full_flush() { + test_flush( + DeflateFlush::FullFlush, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 0, gz_header::OS_CODE, 242, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, + 81, 228, 2, 0, 0, 0, 255, 255, + ], + ); + } + + #[test] + #[rustfmt::skip] + fn block_flush() { + test_flush( + DeflateFlush::Block, + &[ + 31, 139, 8, 0, 0, 0, 0, 0, 0, gz_header::OS_CODE, 242, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, + 81, 228, 2, + ], + ); + } + + #[test] + // splits the input into two, deflates them seperately and then joins the deflated byte streams + // into something that can be correctly inflated again. This is the basic idea behind pigz, and + // allows for parallel compression. + fn split_deflate() { + let input = "Hello World!\n"; + + let (input1, input2) = input.split_at(6); + + let mut output1 = vec![0; 128]; + let mut output2 = vec![0; 128]; + + let config = DeflateConfig { + level: 6, // use gzip + method: Method::Deflated, + window_bits: 16 + crate::MAX_WBITS, + mem_level: DEF_MEM_LEVEL, + strategy: Strategy::Default, + }; + + // see also the docs on `SyncFlush`. it makes sure everything is flushed, ends on a byte + // boundary, and that the final block does not have the "last block" bit set. + let (prefix, err) = compress_slice_with_flush( + &mut output1, + input1.as_bytes(), + config, + DeflateFlush::SyncFlush, + ); + assert_eq!(err, ReturnCode::DataError); + + let (output2, err) = compress_slice_with_flush( + &mut output2, + input2.as_bytes(), + config, + DeflateFlush::Finish, + ); + assert_eq!(err, ReturnCode::Ok); + + let inflate_config = crate::inflate::InflateConfig { + window_bits: 16 + 15, + }; + + // cuts off the length and crc + let (suffix, end) = output2.split_at(output2.len() - 8); + let (crc2, len2) = end.split_at(4); + let crc2 = u32::from_le_bytes(crc2.try_into().unwrap()); + + // cuts off the gzip header (10 bytes) from the front + let suffix = &suffix[10..]; + + let mut result: Vec = Vec::new(); + result.extend(prefix.iter()); + result.extend(suffix); + + // it would be more proper to use `stream.total_in` here, but the slice helpers hide the + // stream so we're cheating a bit here + let len1 = input1.len() as u32; + let len2 = u32::from_le_bytes(len2.try_into().unwrap()); + assert_eq!(len2 as usize, input2.len()); + + let crc1 = crate::crc32(0, input1.as_bytes()); + let crc = crate::crc32_combine(crc1, crc2, len2 as u64); + + // combined crc of the parts should be the crc of the whole + let crc_cheating = crate::crc32(0, input.as_bytes()); + assert_eq!(crc, crc_cheating); + + // write the trailer + result.extend(crc.to_le_bytes()); + result.extend((len1 + len2).to_le_bytes()); + + let mut output = vec![0; 128]; + let (output, err) = crate::inflate::uncompress_slice(&mut output, &result, inflate_config); + assert_eq!(err, ReturnCode::Ok); + + assert_eq!(output, input.as_bytes()); + } + + #[test] + fn inflate_window_copy_slice() { + let uncompressed = [ + 9, 126, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 76, 33, 8, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 76, 33, 8, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 10, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 14, 0, 0, 0, 0, 0, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 9, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 12, 28, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 10, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 14, 0, 0, 0, 0, 0, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 9, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 12, 28, 0, 2, 0, 0, 0, 63, 1, 0, 12, 2, + 36, 0, 28, 0, 0, 0, 1, 0, 0, 63, 63, 13, 0, 0, 0, 0, 0, 0, 0, 63, 63, 63, 63, 0, 0, 0, + 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 12, 33, 2, 0, 0, 8, + 0, 4, 0, 0, 0, 12, 10, 41, 12, 10, 47, + ]; + + let compressed = &[ + 31, 139, 8, 0, 0, 0, 0, 0, 4, 3, 181, 193, 49, 14, 194, 32, 24, 128, 209, 175, 192, 0, + 228, 151, 232, 206, 66, 226, 226, 96, 60, 2, 113, 96, 235, 13, 188, 139, 103, 23, 106, + 104, 108, 100, 49, 169, 239, 185, 39, 11, 199, 7, 51, 39, 171, 248, 118, 226, 63, 52, + 157, 120, 86, 102, 78, 86, 209, 104, 58, 241, 84, 129, 166, 12, 4, 154, 178, 229, 202, + 30, 36, 130, 166, 19, 79, 21, 104, 202, 64, 160, 41, 91, 174, 236, 65, 34, 10, 200, 19, + 162, 206, 68, 96, 130, 156, 15, 188, 229, 138, 197, 157, 161, 35, 3, 87, 126, 245, 0, + 28, 224, 64, 146, 2, 139, 1, 196, 95, 196, 223, 94, 10, 96, 92, 33, 86, 2, 0, 0, + ]; + + let config = InflateConfig { window_bits: 25 }; + + let mut dest_vec_rs = vec![0u8; uncompressed.len()]; + let (output_rs, error) = + crate::inflate::uncompress_slice(&mut dest_vec_rs, compressed, config); + + assert_eq!(ReturnCode::Ok, error); + assert_eq!(output_rs, uncompressed); + } + + #[test] + fn hash_calc_difference() { + let input = [ + 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 112, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, + 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, + 50, 0, + ]; + + let config = DeflateConfig { + level: 6, + method: Method::Deflated, + window_bits: 9, + mem_level: 8, + strategy: Strategy::Default, + }; + + let crc32 = [ + 24, 149, 99, 96, 96, 96, 96, 208, 6, 17, 112, 138, 129, 193, 128, 1, 29, 24, 50, 208, + 1, 200, 146, 169, 79, 24, 74, 59, 96, 147, 52, 71, 22, 70, 246, 88, 26, 94, 80, 128, + 83, 6, 162, 219, 144, 76, 183, 210, 5, 8, 67, 105, 7, 108, 146, 230, 216, 133, 145, + 129, 22, 3, 3, 131, 17, 3, 0, 3, 228, 25, 128, + ]; + + let other = [ + 24, 149, 99, 96, 96, 96, 96, 208, 6, 17, 112, 138, 129, 193, 128, 1, 29, 24, 50, 208, + 1, 200, 146, 169, 79, 24, 74, 59, 96, 147, 52, 71, 22, 70, 246, 88, 26, 94, 80, 128, + 83, 6, 162, 219, 144, 76, 183, 210, 5, 8, 67, 105, 36, 159, 35, 128, 57, 118, 97, 100, + 160, 197, 192, 192, 96, 196, 0, 0, 3, 228, 25, 128, + ]; + + // the output is slightly different based on what hashing algorithm is used + match HashCalcVariant::for_compression_level(config.level as usize) { + HashCalcVariant::Crc32 => { + // the aarch64 hashing algorithm is different from the standard algorithm, but in + // this case they turn out to give the same output. Beware! + if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") { + fuzz_based_test(&input, config, &crc32); + } else { + fuzz_based_test(&input, config, &other); + } + } + HashCalcVariant::Standard | HashCalcVariant::Roll => { + fuzz_based_test(&input, config, &other); + } + } + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/fast.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/fast.rs new file mode 100644 index 0000000000..fedb38db24 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/fast.rs @@ -0,0 +1,109 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{ + fill_window, BlockState, DeflateStream, MIN_LOOKAHEAD, STD_MIN_MATCH, WANT_MIN_MATCH, + }, + flush_block, DeflateFlush, +}; + +pub fn deflate_fast(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + let mut bflush; /* set if current block must be flushed */ + let mut dist; + let mut match_len = 0; + + loop { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need STD_MAX_MATCH bytes + // for the next match, plus WANT_MIN_MATCH bytes to insert the + // string following the next match. + if stream.state.lookahead < MIN_LOOKAHEAD { + fill_window(stream); + if stream.state.lookahead < MIN_LOOKAHEAD && flush == DeflateFlush::NoFlush { + return BlockState::NeedMore; + } + if stream.state.lookahead == 0 { + break; /* flush the current block */ + } + } + + let state = &mut stream.state; + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + + if state.lookahead >= WANT_MIN_MATCH { + let hash_head = state.quick_insert_string(state.strstart); + dist = state.strstart as isize - hash_head as isize; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match length < WANT_MIN_MATCH + */ + if dist <= state.max_dist() as isize && dist > 0 && hash_head != 0 { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + (match_len, state.match_start) = + crate::deflate::longest_match::longest_match(state, hash_head); + } + } + + if match_len >= WANT_MIN_MATCH { + // check_match(s, s->strstart, s->match_start, match_len); + + // bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH); + bflush = state.tally_dist( + state.strstart - state.match_start, + match_len - STD_MIN_MATCH, + ); + + state.lookahead -= match_len; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if match_len <= state.max_insert_length() && state.lookahead >= WANT_MIN_MATCH { + match_len -= 1; /* string at strstart already in table */ + state.strstart += 1; + + state.insert_string(state.strstart, match_len); + state.strstart += match_len; + } else { + state.strstart += match_len; + state.quick_insert_string(state.strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + match_len = 0; + } else { + /* No match, output a literal byte */ + let lc = state.window.filled()[state.strstart]; + bflush = state.tally_lit(lc); + state.lookahead -= 1; + state.strstart += 1; + } + + if bflush { + flush_block!(stream, false); + } + } + + stream.state.insert = if stream.state.strstart < (STD_MIN_MATCH - 1) { + stream.state.strstart + } else { + STD_MIN_MATCH - 1 + }; + + if flush == DeflateFlush::Finish { + flush_block!(stream, true); + return BlockState::FinishDone; + } + + if !stream.state.sym_buf.is_empty() { + flush_block!(stream, false); + } + + BlockState::BlockDone +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/huff.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/huff.rs new file mode 100644 index 0000000000..58a6ae980a --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/huff.rs @@ -0,0 +1,45 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{fill_window, BlockState, DeflateStream}, + flush_block, DeflateFlush, +}; + +pub fn deflate_huff(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + loop { + /* Make sure that we have a literal to write. */ + if stream.state.lookahead == 0 { + fill_window(stream); + + if stream.state.lookahead == 0 { + match flush { + DeflateFlush::NoFlush => return BlockState::NeedMore, + _ => break, /* flush the current block */ + } + } + } + + /* Output a literal byte */ + let state = &mut stream.state; + let lc = state.window.filled()[state.strstart]; + let bflush = state.tally_lit(lc); + state.lookahead -= 1; + state.strstart += 1; + if bflush { + flush_block!(stream, false); + } + } + + stream.state.insert = 0; + + if flush == DeflateFlush::Finish { + flush_block!(stream, true); + return BlockState::FinishDone; + } + + if !stream.state.sym_buf.is_empty() { + flush_block!(stream, false); + } + + BlockState::BlockDone +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/medium.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/medium.rs new file mode 100644 index 0000000000..030279470e --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/medium.rs @@ -0,0 +1,339 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{ + fill_window, BlockState, DeflateStream, State, MIN_LOOKAHEAD, STD_MIN_MATCH, WANT_MIN_MATCH, + }, + flush_block, DeflateFlush, +}; + +pub fn deflate_medium(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + let mut state = &mut stream.state; + + // For levels below 5, don't check the next position for a better match + let early_exit = state.level < 5; + + let mut current_match = Match { + match_start: 0, + match_length: 0, + strstart: 0, + orgstart: 0, + }; + let mut next_match = Match { + match_start: 0, + match_length: 0, + strstart: 0, + orgstart: 0, + }; + + loop { + let mut hash_head; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if stream.state.lookahead < MIN_LOOKAHEAD { + fill_window(stream); + + if stream.state.lookahead < MIN_LOOKAHEAD && flush == DeflateFlush::NoFlush { + return BlockState::NeedMore; + } + + if stream.state.lookahead == 0 { + break; /* flush the current block */ + } + + next_match.match_length = 0; + } + + state = &mut stream.state; + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + + /* If we already have a future match from a previous round, just use that */ + if !early_exit && next_match.match_length > 0 { + current_match = next_match; + next_match.match_length = 0; + } else { + hash_head = 0; + if state.lookahead >= WANT_MIN_MATCH { + hash_head = state.quick_insert_string(state.strstart); + } + + current_match.strstart = state.strstart as u16; + current_match.orgstart = current_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + let dist = state.strstart as i64 - hash_head as i64; + if dist <= state.max_dist() as i64 && dist > 0 && hash_head != 0 { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + let (match_length, match_start) = + crate::deflate::longest_match::longest_match(state, hash_head); + state.match_start = match_start; + current_match.match_length = match_length as u16; + current_match.match_start = match_start as u16; + if (current_match.match_length as usize) < WANT_MIN_MATCH { + current_match.match_length = 1; + } + if current_match.match_start >= current_match.strstart { + /* this can happen due to some restarts */ + current_match.match_length = 1; + } + } else { + /* Set up the match to be a 1 byte literal */ + current_match.match_start = 0; + current_match.match_length = 1; + } + } + + insert_match(state, current_match); + + /* now, look ahead one */ + if !early_exit + && state.lookahead > MIN_LOOKAHEAD + && ((current_match.strstart + current_match.match_length) as usize) + < (state.window_size - MIN_LOOKAHEAD) + { + state.strstart = (current_match.strstart + current_match.match_length) as usize; + hash_head = state.quick_insert_string(state.strstart); + + next_match.strstart = state.strstart as u16; + next_match.orgstart = next_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + let dist = state.strstart as i64 - hash_head as i64; + if dist <= state.max_dist() as i64 && dist > 0 && hash_head != 0 { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + let (match_length, match_start) = + crate::deflate::longest_match::longest_match(state, hash_head); + state.match_start = match_start; + next_match.match_length = match_length as u16; + next_match.match_start = match_start as u16; + + if next_match.match_start >= next_match.strstart { + /* this can happen due to some restarts */ + next_match.match_length = 1; + } + if (next_match.match_length as usize) < WANT_MIN_MATCH { + next_match.match_length = 1; + } else { + fizzle_matches( + state.window.filled(), + state.max_dist(), + &mut current_match, + &mut next_match, + ); + } + } else { + /* Set up the match to be a 1 byte literal */ + next_match.match_start = 0; + next_match.match_length = 1; + } + + state.strstart = current_match.strstart as usize; + } else { + next_match.match_length = 0; + } + + /* now emit the current match */ + let bflush = emit_match(state, current_match); + + /* move the "cursor" forward */ + state.strstart += current_match.match_length as usize; + + if bflush { + flush_block!(stream, false); + } + } + + stream.state.insert = Ord::min(stream.state.strstart, STD_MIN_MATCH - 1); + + if flush == DeflateFlush::Finish { + flush_block!(stream, true); + return BlockState::FinishDone; + } + + if !stream.state.sym_buf.is_empty() { + flush_block!(stream, false); + } + + BlockState::BlockDone +} + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +struct Match { + match_start: u16, + match_length: u16, + strstart: u16, + orgstart: u16, +} + +fn emit_match(state: &mut State, mut m: Match) -> bool { + let mut bflush = false; + + /* matches that are not long enough we need to emit as literals */ + if (m.match_length as usize) < WANT_MIN_MATCH { + while m.match_length > 0 { + let lc = state.window.filled()[state.strstart]; + bflush |= state.tally_lit(lc); + state.lookahead -= 1; + m.strstart += 1; + m.match_length -= 1; + } + return bflush; + } + + // check_match(s, m.strstart, m.match_start, m.match_length); + + bflush |= state.tally_dist( + (m.strstart - m.match_start) as usize, + m.match_length as usize - STD_MIN_MATCH, + ); + + state.lookahead -= m.match_length as usize; + + bflush +} + +fn insert_match(state: &mut State, mut m: Match) { + if state.lookahead <= (m.match_length as usize + WANT_MIN_MATCH) { + return; + } + + /* matches that are not long enough we need to emit as literals */ + if (m.match_length as usize) < WANT_MIN_MATCH { + m.strstart += 1; + m.match_length -= 1; + if m.match_length > 0 && m.strstart >= m.orgstart { + if m.strstart + m.match_length > m.orgstart { + state.insert_string(m.strstart as usize, m.match_length as usize); + } else { + state.insert_string(m.strstart as usize, (m.orgstart - m.strstart + 1) as usize); + } + m.strstart += m.match_length; + m.match_length = 0; + } + return; + } + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (m.match_length as usize) <= 16 * state.max_insert_length() + && state.lookahead >= WANT_MIN_MATCH + { + m.match_length -= 1; /* string at strstart already in table */ + m.strstart += 1; + + if m.strstart >= m.orgstart { + if m.strstart + m.match_length > m.orgstart { + state.insert_string(m.strstart as usize, m.match_length as usize); + } else { + state.insert_string(m.strstart as usize, (m.orgstart - m.strstart + 1) as usize); + } + } else if m.orgstart < m.strstart + m.match_length { + state.insert_string( + m.orgstart as usize, + (m.strstart + m.match_length - m.orgstart) as usize, + ); + } + m.strstart += m.match_length; + m.match_length = 0; + } else { + m.strstart += m.match_length; + m.match_length = 0; + + if (m.strstart as usize) >= (STD_MIN_MATCH - 2) { + state.quick_insert_string(m.strstart as usize + 2 - STD_MIN_MATCH); + } + + /* If lookahead < WANT_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } +} + +fn fizzle_matches(window: &[u8], max_dist: usize, current: &mut Match, next: &mut Match) { + /* step zero: sanity checks */ + + if current.match_length <= 1 { + return; + } + + if current.match_length > 1 + next.match_start { + return; + } + + if current.match_length > 1 + next.strstart { + return; + } + + let m = &window[(-(current.match_length as isize) + 1 + next.match_start as isize) as usize..]; + let orig = &window[(-(current.match_length as isize) + 1 + next.strstart as isize) as usize..]; + + /* quick exit check.. if this fails then don't bother with anything else */ + if m[0] != orig[0] { + return; + } + + /* step one: try to move the "next" match to the left as much as possible */ + let limit = next.strstart.saturating_sub(max_dist as u16); + + let mut c = *current; + let mut n = *next; + + let m = &window[..n.match_start as usize]; + let orig = &window[..n.strstart as usize]; + + let mut m = m.iter().rev(); + let mut orig = orig.iter().rev(); + + let mut changed = 0; + + while m.next() == orig.next() { + if c.match_length < 1 { + break; + } + if n.strstart <= limit { + break; + } + if n.match_length >= 256 { + break; + } + if n.match_start <= 1 { + break; + } + + n.strstart -= 1; + n.match_start -= 1; + n.match_length += 1; + c.match_length -= 1; + changed += 1; + } + + if changed == 0 { + return; + } + + if c.match_length <= 1 && n.match_length != 2 { + n.orgstart += 1; + *current = c; + *next = n; + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/mod.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/mod.rs new file mode 100644 index 0000000000..6aa90def8d --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/mod.rs @@ -0,0 +1,82 @@ +use crate::{ + deflate::{BlockState, DeflateStream, Strategy}, + DeflateFlush, +}; + +use self::{huff::deflate_huff, rle::deflate_rle, stored::deflate_stored}; + +mod fast; +mod huff; +mod medium; +mod quick; +mod rle; +mod slow; +mod stored; + +#[macro_export] +macro_rules! flush_block { + ($stream:expr, $is_last_block:expr) => { + $crate::deflate::flush_block_only($stream, $is_last_block); + + if $stream.avail_out == 0 { + return match $is_last_block { + true => BlockState::FinishStarted, + false => BlockState::NeedMore, + }; + } + }; +} + +pub fn run(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + match stream.state.strategy { + _ if stream.state.level == 0 => deflate_stored(stream, flush), + Strategy::HuffmanOnly => deflate_huff(stream, flush), + Strategy::Rle => deflate_rle(stream, flush), + Strategy::Default | Strategy::Filtered | Strategy::Fixed => { + (CONFIGURATION_TABLE[stream.state.level as usize].func)(stream, flush) + } + } +} + +type CompressFunc = fn(&mut DeflateStream, flush: DeflateFlush) -> BlockState; + +pub struct Config { + pub good_length: u16, /* reduce lazy search above this match length */ + pub max_lazy: u16, /* do not perform lazy search above this match length */ + pub nice_length: u16, /* quit search above this match length */ + pub max_chain: u16, + pub func: CompressFunc, +} + +impl Config { + const fn new( + good_length: u16, + max_lazy: u16, + nice_length: u16, + max_chain: u16, + func: CompressFunc, + ) -> Self { + Self { + good_length, + max_lazy, + nice_length, + max_chain, + func, + } + } +} + +pub const CONFIGURATION_TABLE: [Config; 10] = { + [ + Config::new(0, 0, 0, 0, stored::deflate_stored), // 0 /* store only */ + Config::new(0, 0, 0, 0, quick::deflate_quick), // 1 + Config::new(4, 4, 8, 4, fast::deflate_fast), // 2 /* max speed, no lazy matches */ + Config::new(4, 6, 16, 6, medium::deflate_medium), // 3 + Config::new(4, 12, 32, 24, medium::deflate_medium), // 4 /* lazy matches */ + Config::new(8, 16, 32, 32, medium::deflate_medium), // 5 + Config::new(8, 16, 128, 128, medium::deflate_medium), // 6 + Config::new(8, 32, 128, 256, slow::deflate_slow), // 7 + Config::new(32, 128, 258, 1024, slow::deflate_slow), // 8 + Config::new(32, 258, 258, 4096, slow::deflate_slow), // 9 /* max compression */ + ] +}; diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/quick.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/quick.rs new file mode 100644 index 0000000000..4b397ff68e --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/quick.rs @@ -0,0 +1,145 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{ + fill_window, flush_pending, BlockState, BlockType, DeflateStream, State, StaticTreeDesc, + MIN_LOOKAHEAD, STD_MAX_MATCH, STD_MIN_MATCH, WANT_MIN_MATCH, + }, + DeflateFlush, +}; + +pub fn deflate_quick(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + let mut state = &mut stream.state; + + macro_rules! quick_end_block { + ($last:expr) => { + if state.block_open > 0 { + state + .bit_writer + .emit_end_block_and_align(&StaticTreeDesc::L.static_tree, $last); + state.block_open = 0; + state.block_start = state.strstart as isize; + flush_pending(stream); + #[allow(unused_assignments)] + { + state = &mut stream.state; + } + if stream.avail_out == 0 { + return match $last { + true => BlockState::FinishStarted, + false => BlockState::NeedMore, + }; + } + } + }; + } + + macro_rules! quick_start_block { + ($last:expr) => { + state.bit_writer.emit_tree(BlockType::StaticTrees, $last); + state.block_open = 1 + $last as u8; + state.block_start = state.strstart as isize; + }; + } + + let last = matches!(flush, DeflateFlush::Finish); + + if last && state.block_open != 2 { + /* Emit end of previous block */ + quick_end_block!(false); + /* Emit start of last block */ + quick_start_block!(last); + } else if state.block_open == 0 && state.lookahead > 0 { + /* Start new block only when we have lookahead data, so that if no + input data is given an empty block will not be written */ + quick_start_block!(last); + } + + loop { + if state.bit_writer.pending.pending + State::BIT_BUF_SIZE.div_ceil(8) as usize + >= state.pending_buf_size() + { + flush_pending(stream); + state = &mut stream.state; + if stream.avail_out == 0 { + return if last + && stream.avail_in == 0 + && state.bit_writer.bits_used == 0 + && state.block_open == 0 + { + BlockState::FinishStarted + } else { + BlockState::NeedMore + }; + } + } + + if state.lookahead < MIN_LOOKAHEAD { + fill_window(stream); + state = &mut stream.state; + + if state.lookahead < MIN_LOOKAHEAD && matches!(flush, DeflateFlush::NoFlush) { + return BlockState::NeedMore; + } + if state.lookahead == 0 { + break; + } + + if state.block_open == 0 { + // Start new block when we have lookahead data, + // so that if no input data is given an empty block will not be written + quick_start_block!(last); + } + } + + if state.lookahead >= WANT_MIN_MATCH { + let hash_head = state.quick_insert_string(state.strstart); + let dist = state.strstart as isize - hash_head as isize; + + if dist <= state.max_dist() as isize && dist > 0 { + let str_start = &state.window.filled()[state.strstart..]; + let match_start = &state.window.filled()[hash_head as usize..]; + + if str_start[0] == match_start[0] && str_start[1] == match_start[1] { + let mut match_len = crate::deflate::compare256::compare256_slice( + &str_start[2..], + &match_start[2..], + ) + 2; + + if match_len >= WANT_MIN_MATCH { + match_len = Ord::min(match_len, state.lookahead); + match_len = Ord::min(match_len, STD_MAX_MATCH); + + // TODO do this with a debug_assert? + // check_match(s, state.strstart, hash_head, match_len); + + state.bit_writer.emit_dist( + StaticTreeDesc::L.static_tree, + StaticTreeDesc::D.static_tree, + (match_len - STD_MIN_MATCH) as u8, + dist as usize, + ); + state.lookahead -= match_len; + state.strstart += match_len; + continue; + } + } + } + } + + let lc = state.window.filled()[state.strstart]; + state.bit_writer.emit_lit(StaticTreeDesc::L.static_tree, lc); + state.strstart += 1; + state.lookahead -= 1; + } + + state.insert = Ord::min(state.strstart, STD_MIN_MATCH - 1); + + quick_end_block!(last); + + if last { + BlockState::FinishDone + } else { + BlockState::BlockDone + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/rle.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/rle.rs new file mode 100644 index 0000000000..d01d18c48c --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/rle.rs @@ -0,0 +1,83 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{ + compare256::compare256_rle_slice, fill_window, BlockState, DeflateStream, MIN_LOOKAHEAD, + STD_MAX_MATCH, STD_MIN_MATCH, + }, + flush_block, DeflateFlush, +}; + +pub fn deflate_rle(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + let mut match_len = 0; + let mut bflush; + + loop { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need STD_MAX_MATCH bytes + // for the next match, plus WANT_MIN_MATCH bytes to insert the + // string following the next match. + if stream.state.lookahead < MIN_LOOKAHEAD { + fill_window(stream); + if stream.state.lookahead < MIN_LOOKAHEAD && flush == DeflateFlush::NoFlush { + return BlockState::NeedMore; + } + if stream.state.lookahead == 0 { + break; /* flush the current block */ + } + } + + /* See how many times the previous byte repeats */ + let state = &mut stream.state; + if state.lookahead >= STD_MIN_MATCH && state.strstart > 0 { + let scan = &state.window.filled()[state.strstart - 1..][..3 + 256]; + + { + if scan[0] == scan[1] && scan[1] == scan[2] { + match_len = compare256_rle_slice(scan[0], &scan[3..]) + 2; + match_len = Ord::min(match_len, state.lookahead); + match_len = Ord::min(match_len, STD_MAX_MATCH); + } + } + + assert!( + state.strstart - 1 + match_len <= state.window_size - 1, + "wild scan" + ); + } + + /* Emit match if have run of STD_MIN_MATCH or longer, else emit literal */ + if match_len >= STD_MIN_MATCH { + // check_match(s, s->strstart, s->strstart - 1, match_len); + + bflush = state.tally_dist(1, match_len - STD_MIN_MATCH); + + state.lookahead -= match_len; + state.strstart += match_len; + match_len = 0; + } else { + /* No match, output a literal byte */ + let lc = state.window.filled()[state.strstart]; + bflush = state.tally_lit(lc); + state.lookahead -= 1; + state.strstart += 1; + } + + if bflush { + flush_block!(stream, false); + } + } + + stream.state.insert = 0; + + if flush == DeflateFlush::Finish { + flush_block!(stream, true); + return BlockState::FinishDone; + } + + if !stream.state.sym_buf.is_empty() { + flush_block!(stream, false); + } + + BlockState::BlockDone +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/slow.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/slow.rs new file mode 100644 index 0000000000..3a0fe644d7 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/slow.rs @@ -0,0 +1,160 @@ +#![forbid(unsafe_code)] + +use crate::{ + deflate::{ + fill_window, flush_block_only, BlockState, DeflateStream, Strategy, MIN_LOOKAHEAD, + STD_MIN_MATCH, WANT_MIN_MATCH, + }, + flush_block, DeflateFlush, +}; + +pub fn deflate_slow(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + let mut hash_head; /* head of hash chain */ + let mut bflush; /* set if current block must be flushed */ + let mut dist; + let mut match_len; + + let use_longest_match_slow = stream.state.max_chain_length > 1024; + let valid_distance_range = 1..=stream.state.max_dist() as isize; + + let mut match_available = stream.state.match_available; + + /* Process the input block. */ + loop { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if stream.state.lookahead < MIN_LOOKAHEAD { + fill_window(stream); + if stream.state.lookahead < MIN_LOOKAHEAD && flush == DeflateFlush::NoFlush { + return BlockState::NeedMore; + } + + if stream.state.lookahead == 0 { + break; /* flush the current block */ + } + } + + let state = &mut stream.state; + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = if state.lookahead >= WANT_MIN_MATCH { + state.quick_insert_string(state.strstart) + } else { + 0 + }; + + // Find the longest match, discarding those <= prev_length. + state.prev_match = state.match_start as u16; + match_len = STD_MIN_MATCH - 1; + dist = state.strstart as isize - hash_head as isize; + + if valid_distance_range.contains(&dist) + && state.prev_length < state.max_lazy_match + && hash_head != 0 + { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + (match_len, state.match_start) = if use_longest_match_slow { + crate::deflate::longest_match::longest_match_slow(state, hash_head) + } else { + crate::deflate::longest_match::longest_match(state, hash_head) + }; + + if match_len <= 5 && (state.strategy == Strategy::Filtered) { + /* If prev_match is also WANT_MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_len = STD_MIN_MATCH - 1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if state.prev_length >= STD_MIN_MATCH && match_len <= state.prev_length { + let max_insert = state.strstart + state.lookahead - STD_MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + // check_match(s, state.strstart-1, state.prev_match, state.prev_length); + + bflush = state.tally_dist( + state.strstart - 1 - state.prev_match as usize, + state.prev_length - STD_MIN_MATCH, + ); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + state.prev_length -= 1; + state.lookahead -= state.prev_length; + + let mov_fwd = state.prev_length - 1; + if max_insert > state.strstart { + let insert_cnt = Ord::min(mov_fwd, max_insert - state.strstart); + state.insert_string(state.strstart + 1, insert_cnt); + } + state.prev_length = 0; + state.match_available = false; + match_available = false; + state.strstart += mov_fwd + 1; + + if bflush { + flush_block!(stream, false); + } + } else if match_available { + // If there was no match at the previous position, output a + // single literal. If there was a match but the current match + // is longer, truncate the previous match to a single literal. + let lc = state.window.filled()[state.strstart - 1]; + bflush = state.tally_lit(lc); + if bflush { + flush_block_only(stream, false); + } + + stream.state.prev_length = match_len; + stream.state.strstart += 1; + stream.state.lookahead -= 1; + if stream.avail_out == 0 { + return BlockState::NeedMore; + } + } else { + // There is no previous match to compare with, wait for + // the next step to decide. + state.prev_length = match_len; + state.match_available = true; + match_available = true; + state.strstart += 1; + state.lookahead -= 1; + } + } + + assert_ne!(flush, DeflateFlush::NoFlush, "no flush?"); + + let state = &mut stream.state; + + if state.match_available { + let lc = state.window.filled()[state.strstart - 1]; + let _ = state.tally_lit(lc); + state.match_available = false; + } + + state.insert = Ord::min(state.strstart, STD_MIN_MATCH - 1); + + if flush == DeflateFlush::Finish { + flush_block!(stream, true); + return BlockState::FinishDone; + } + + if !stream.state.sym_buf.is_empty() { + flush_block!(stream, false); + } + + BlockState::BlockDone +} diff --git a/third_party/rust/zlib-rs/src/deflate/algorithm/stored.rs b/third_party/rust/zlib-rs/src/deflate/algorithm/stored.rs new file mode 100644 index 0000000000..b2ca120e3a --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/algorithm/stored.rs @@ -0,0 +1,273 @@ +use crate::{ + deflate::{ + flush_pending, read_buf_window, zng_tr_stored_block, BlockState, DeflateStream, MAX_STORED, + }, + DeflateFlush, +}; + +pub fn deflate_stored(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { + // Smallest worthy block size when not flushing or finishing. By default + // this is 32K. This can be as small as 507 bytes for memLevel == 1. For + // large input and output buffers, the stored block size will be larger. + let min_block = Ord::min( + stream.state.bit_writer.pending.capacity() - 5, + stream.state.w_size, + ); + + // Copy as many min_block or larger stored blocks directly to next_out as + // possible. If flushing, copy the remaining available input to next_out as + // stored blocks, if there is enough space. + + // unsigned len, left, have, last = 0; + let mut have; + let mut last = false; + let mut used = stream.avail_in; + loop { + // maximum deflate stored block length + let mut len = MAX_STORED; + + // number of header bytes + have = ((stream.state.bit_writer.bits_used + 42) / 8) as usize; + + // we need room for at least the header + if stream.avail_out < have as u32 { + break; + } + + let left = stream.state.strstart as isize - stream.state.block_start; + let left = Ord::max(0, left) as usize; + + have = stream.avail_out as usize - have; + + if len > left + stream.avail_in as usize { + // limit len to the input + len = left + stream.avail_in as usize; + } + + len = Ord::min(len, have); + + // If the stored block would be less than min_block in length, or if + // unable to copy all of the available input when flushing, then try + // copying to the window and the pending buffer instead. Also don't + // write an empty block when flushing -- deflate() does that. + if len < min_block + && ((len == 0 && flush != DeflateFlush::Finish) + || flush == DeflateFlush::NoFlush + || len != left + stream.avail_in as usize) + { + break; + } + + // Make a dummy stored block in pending to get the header bytes, + // including any pending bits. This also updates the debugging counts. + last = flush == DeflateFlush::Finish && len == left + stream.avail_in as usize; + zng_tr_stored_block(stream.state, 0..0, last); + + /* Replace the lengths in the dummy stored block with len. */ + stream.state.bit_writer.pending.rewind(4); + stream + .state + .bit_writer + .pending + .extend(&(len as u16).to_le_bytes()); + stream + .state + .bit_writer + .pending + .extend(&(!len as u16).to_le_bytes()); + + // Write the stored block header bytes. + flush_pending(stream); + + // Update debugging counts for the data about to be copied. + stream.state.bit_writer.cmpr_bits_add(len << 3); + stream.state.bit_writer.sent_bits_add(len << 3); + + if left > 0 { + let left = Ord::min(left, len); + let src = &stream.state.window.filled()[stream.state.block_start as usize..]; + + unsafe { core::ptr::copy_nonoverlapping(src.as_ptr(), stream.next_out, left) }; + + stream.next_out = stream.next_out.wrapping_add(left); + stream.avail_out = stream.avail_out.wrapping_sub(left as _); + stream.total_out = stream.total_out.wrapping_add(left as _); + stream.state.block_start += left as isize; + len -= left; + } + + // Copy uncompressed bytes directly from next_in to next_out, updating the check value. + if len > 0 { + read_buf_direct_copy(stream, len); + } + + if last { + break; + } + } + + // Update the sliding window with the last s->w_size bytes of the copied + // data, or append all of the copied data to the existing window if less + // than s->w_size bytes were copied. Also update the number of bytes to + // insert in the hash tables, in the event that deflateParams() switches to + // a non-zero compression level. + used -= stream.avail_in; /* number of input bytes directly copied */ + + if used > 0 { + let state = &mut stream.state; + // If any input was used, then no unused input remains in the window, therefore s->block_start == s->strstart. + if used as usize >= state.w_size { + /* supplant the previous history */ + state.matches = 2; /* clear hash */ + + let src = stream.next_in.wrapping_sub(state.w_size); + + unsafe { state.window.copy_and_initialize(0..state.w_size, src) }; + + state.strstart = state.w_size; + state.insert = state.strstart; + } else { + if state.window_size - state.strstart <= used as usize { + /* Slide the window down. */ + state.strstart -= state.w_size; + + state + .window + .filled_mut() + .copy_within(state.w_size..state.w_size + state.strstart, 0); + + if state.matches < 2 { + state.matches += 1; /* add a pending slide_hash() */ + } + state.insert = Ord::min(state.insert, state.strstart); + } + + let src = stream.next_in.wrapping_sub(used as usize); + let dst = state.strstart..state.strstart + used as usize; + unsafe { state.window.copy_and_initialize(dst, src) }; + + state.strstart += used as usize; + state.insert += Ord::min(used as usize, state.w_size - state.insert); + } + state.block_start = state.strstart as isize; + } + + if last { + return BlockState::FinishDone; + } + + // If flushing and all input has been consumed, then done. + if flush != DeflateFlush::NoFlush + && flush != DeflateFlush::Finish + && stream.avail_in == 0 + && stream.state.strstart as isize == stream.state.block_start + { + return BlockState::BlockDone; + } + + // Fill the window with any remaining input + let mut have = stream.state.window_size - stream.state.strstart; + if stream.avail_in as usize > have && stream.state.block_start >= stream.state.w_size as isize { + // slide the window down + let state = &mut stream.state; + state.block_start -= state.w_size as isize; + state.strstart -= state.w_size; + state + .window + .filled_mut() + .copy_within(state.w_size..state.w_size + state.strstart, 0); + + if state.matches < 2 { + // add a pending slide_hash + state.matches += 1; + } + + have += state.w_size; // more space now + state.insert = Ord::min(state.insert, state.strstart); + } + + let have = Ord::min(have, stream.avail_in as usize); + if have > 0 { + read_buf_window(stream, stream.state.strstart, have); + + let state = &mut stream.state; + state.strstart += have; + state.insert += Ord::min(have, state.w_size - state.insert); + } + + // There was not enough avail_out to write a complete worthy or flushed + // stored block to next_out. Write a stored block to pending instead, if we + // have enough input for a worthy block, or if flushing and there is enough + // room for the remaining input as a stored block in the pending buffer. + + // number of header bytes + let state = &mut stream.state; + let have = ((state.bit_writer.bits_used + 42) >> 3) as usize; + + // maximum stored block length that will fit in pending: + let have = Ord::min(state.bit_writer.pending.capacity() - have, MAX_STORED); + let min_block = Ord::min(have, state.w_size); + let left = state.strstart as isize - state.block_start; + + if left >= min_block as isize + || ((left > 0 || flush == DeflateFlush::Finish) + && flush != DeflateFlush::NoFlush + && stream.avail_in == 0 + && left <= have as isize) + { + let len = Ord::min(left as usize, have); // TODO wrapping? + last = flush == DeflateFlush::Finish && stream.avail_in == 0 && len == (left as usize); + + let range = state.block_start as usize..state.block_start as usize + len; + zng_tr_stored_block(state, range, last); + + state.block_start += len as isize; + flush_pending(stream); + } + + // We've done all we can with the available input and output. + if last { + BlockState::FinishStarted + } else { + BlockState::NeedMore + } +} + +fn read_buf_direct_copy(stream: &mut DeflateStream, size: usize) -> usize { + let len = Ord::min(stream.avail_in as usize, size); + let output = stream.next_out; + + if len == 0 { + return 0; + } + + stream.avail_in -= len as u32; + + if stream.state.wrap == 2 { + // we likely cannot fuse the crc32 and the copy here because the input can be changed by + // a concurrent thread. Therefore it cannot be converted into a slice! + unsafe { core::ptr::copy_nonoverlapping(stream.next_in, output, len) } + + let data = unsafe { core::slice::from_raw_parts(output, len) }; + stream.state.crc_fold.fold(data, 0); + } else if stream.state.wrap == 1 { + // we cannot fuse the adler and the copy in our case, because adler32 takes a slice. + // Another process is allowed to concurrently modify stream.next_in, so we cannot turn it + // into a rust slice (violates its safety requirements) + unsafe { core::ptr::copy_nonoverlapping(stream.next_in, output, len) } + + let data = unsafe { core::slice::from_raw_parts(output, len) }; + stream.adler = crate::adler32::adler32(stream.adler as u32, data) as _; + } else { + unsafe { core::ptr::copy_nonoverlapping(stream.next_in, output, len) } + } + + stream.next_in = stream.next_in.wrapping_add(len); + stream.total_in += len as crate::c_api::z_size; + + stream.next_out = stream.next_out.wrapping_add(len as _); + stream.avail_out = stream.avail_out.wrapping_sub(len as _); + stream.total_out = stream.total_out.wrapping_add(len as _); + + len +} diff --git a/third_party/rust/zlib-rs/src/deflate/compare256.rs b/third_party/rust/zlib-rs/src/deflate/compare256.rs new file mode 100644 index 0000000000..948862c22f --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/compare256.rs @@ -0,0 +1,221 @@ +#[warn(unsafe_op_in_unsafe_fn)] +#[cfg(test)] +const MAX_COMPARE_SIZE: usize = 256; + +pub fn compare256_slice(src0: &[u8], src1: &[u8]) -> usize { + let src0 = first_chunk::<_, 256>(src0).unwrap(); + let src1 = first_chunk::<_, 256>(src1).unwrap(); + + compare256(src0, src1) +} + +fn compare256(src0: &[u8; 256], src1: &[u8; 256]) -> usize { + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx2() { + return unsafe { avx2::compare256(src0, src1) }; + } + + #[cfg(target_arch = "aarch64")] + if crate::cpu_features::is_enabled_neon() { + return unsafe { neon::compare256(src0, src1) }; + } + + rust::compare256(src0, src1) +} + +pub fn compare256_rle_slice(byte: u8, src: &[u8]) -> usize { + rust::compare256_rle(byte, src) +} + +#[inline] +pub const fn first_chunk(slice: &[T]) -> Option<&[T; N]> { + if slice.len() < N { + None + } else { + // SAFETY: We explicitly check for the correct number of elements, + // and do not let the reference outlive the slice. + Some(unsafe { &*(slice.as_ptr() as *const [T; N]) }) + } +} + +mod rust { + + pub fn compare256(src0: &[u8; 256], src1: &[u8; 256]) -> usize { + // only unrolls 4 iterations; zlib-ng unrolls 8 + src0.iter().zip(src1).take_while(|(x, y)| x == y).count() + } + + // run-length encoding + pub fn compare256_rle(byte: u8, src: &[u8]) -> usize { + assert!(src.len() >= 256, "too short {}", src.len()); + + let mut sv = byte as u64; + sv |= sv << 8; + sv |= sv << 16; + sv |= sv << 32; + + let mut len = 0; + + // this optimizes well because we statically limit the slice to 256 bytes. + // the loop gets unrolled 4 times automatically. + for chunk in src[..256].chunks_exact(8) { + let mv = u64::from_le_bytes(chunk.try_into().unwrap()); + + let diff = sv ^ mv; + + if diff > 0 { + let match_byte = diff.trailing_zeros() / 8; + return len + match_byte as usize; + } + + len += 8 + } + + 256 + } + + #[test] + fn test_compare256() { + let str1 = [b'a'; super::MAX_COMPARE_SIZE]; + let mut str2 = [b'a'; super::MAX_COMPARE_SIZE]; + + for i in 0..str1.len() { + str2[i] = 0; + + let match_len = compare256(&str1, &str2); + assert_eq!(match_len, i); + + str2[i] = b'a'; + } + } + + #[test] + fn test_compare256_rle() { + let mut string = [b'a'; super::MAX_COMPARE_SIZE]; + + for i in 0..string.len() { + string[i] = 0; + + let match_len = compare256_rle(b'a', &string); + assert_eq!(match_len, i); + + string[i] = b'a'; + } + } +} + +#[cfg(target_arch = "aarch64")] +mod neon { + use core::arch::aarch64::{ + uint8x16_t, veorq_u8, vgetq_lane_u64, vld1q_u8, vreinterpretq_u64_u8, + }; + + /// # Safety + /// + /// Behavior is undefined if the `neon` target feature is not enabled + #[target_feature(enable = "neon")] + pub unsafe fn compare256(src0: &[u8; 256], src1: &[u8; 256]) -> usize { + let src0: &[[u8; 16]; 16] = unsafe { core::mem::transmute(src0) }; + let src1: &[[u8; 16]; 16] = unsafe { core::mem::transmute(src1) }; + + let mut len = 0; + + for (a, b) in src0.iter().zip(src1) { + unsafe { + let a: uint8x16_t = vld1q_u8(a.as_ptr()); + let b: uint8x16_t = vld1q_u8(b.as_ptr()); + + let cmp = veorq_u8(a, b); + + let lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 0); + if lane != 0 { + let match_byte = lane.trailing_zeros() / 8; + return len + match_byte as usize; + } + + len += 8; + + let lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 1); + if lane != 0 { + let match_byte = lane.trailing_zeros() / 8; + return len + match_byte as usize; + } + + len += 8; + } + } + + 256 + } + + #[test] + fn test_compare256() { + if crate::cpu_features::is_enabled_neon() { + let str1 = [b'a'; super::MAX_COMPARE_SIZE]; + let mut str2 = [b'a'; super::MAX_COMPARE_SIZE]; + + for i in 0..str1.len() { + str2[i] = 0; + + let match_len = unsafe { compare256(&str1, &str2) }; + assert_eq!(match_len, i); + + str2[i] = b'a'; + } + } + } +} + +#[cfg(target_arch = "x86_64")] +mod avx2 { + use core::arch::x86_64::{ + __m256i, _mm256_cmpeq_epi8, _mm256_loadu_si256, _mm256_movemask_epi8, + }; + + /// # Safety + /// + /// Behavior is undefined if the `avx` target feature is not enabled + #[target_feature(enable = "avx2")] + pub unsafe fn compare256(src0: &[u8; 256], src1: &[u8; 256]) -> usize { + let src0: &[[u8; 32]; 8] = unsafe { core::mem::transmute(src0) }; + let src1: &[[u8; 32]; 8] = unsafe { core::mem::transmute(src1) }; + + let mut len = 0; + + unsafe { + for (chunk0, chunk1) in src0.iter().zip(src1) { + let ymm_src0 = _mm256_loadu_si256(chunk0.as_ptr() as *const __m256i); + let ymm_src1 = _mm256_loadu_si256(chunk1.as_ptr() as *const __m256i); + + let ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); /* non-identical bytes = 00, identical bytes = FF */ + let mask = _mm256_movemask_epi8(ymm_cmp) as u32; + + if mask != 0xFFFFFFFF { + let match_byte = (!mask).trailing_zeros(); /* Invert bits so identical = 0 */ + return len + match_byte as usize; + } + + len += 32; + } + } + + 256 + } + + #[test] + fn test_compare256() { + if crate::cpu_features::is_enabled_avx2() { + let str1 = [b'a'; super::MAX_COMPARE_SIZE]; + let mut str2 = [b'a'; super::MAX_COMPARE_SIZE]; + + for i in 0..str1.len() { + str2[i] = 0; + + let match_len = unsafe { compare256(&str1, &str2) }; + assert_eq!(match_len, i); + + str2[i] = b'a'; + } + } + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/hash_calc.rs b/third_party/rust/zlib-rs/src/deflate/hash_calc.rs new file mode 100644 index 0000000000..a73c574954 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/hash_calc.rs @@ -0,0 +1,295 @@ +#![warn(unsafe_op_in_unsafe_fn)] +use crate::deflate::{State, HASH_SIZE, STD_MIN_MATCH}; + +#[derive(Debug, Clone, Copy)] +pub enum HashCalcVariant { + Standard, + Crc32, + Roll, +} + +impl HashCalcVariant { + #[cfg(test)] + pub fn for_compression_level(level: usize) -> Self { + let max_chain_length = crate::deflate::algorithm::CONFIGURATION_TABLE[level].max_chain; + Self::for_max_chain_length(max_chain_length as usize) + } + + /// Use rolling hash for deflate_slow algorithm with level 9. It allows us to + /// properly lookup different hash chains to speed up longest_match search. + pub fn for_max_chain_length(max_chain_length: usize) -> Self { + if max_chain_length > 1024 { + HashCalcVariant::Roll + } else if Crc32HashCalc::is_supported() { + HashCalcVariant::Crc32 + } else { + HashCalcVariant::Standard + } + } +} + +pub struct StandardHashCalc; + +impl StandardHashCalc { + const HASH_CALC_OFFSET: usize = 0; + + const HASH_CALC_MASK: u32 = (HASH_SIZE - 1) as u32; + + fn hash_calc(_: u32, val: u32) -> u32 { + const HASH_SLIDE: u32 = 16; + val.wrapping_mul(2654435761) >> HASH_SLIDE + } + + pub fn update_hash(h: u32, val: u32) -> u32 { + Self::hash_calc(h, val) & Self::HASH_CALC_MASK + } + + pub fn quick_insert_string(state: &mut State, string: usize) -> u16 { + let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..]; + let val = u32::from_le_bytes(slice[..4].try_into().unwrap()); + + let hm = Self::update_hash(0, val) as usize; + + let head = state.head[hm]; + if head != string as u16 { + state.prev[string & state.w_mask] = head; + state.head[hm] = string as u16; + } + + head + } + + pub fn insert_string(state: &mut State, string: usize, count: usize) { + let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..]; + + // .take(count) generates worse assembly + for (i, w) in slice[..count + 3].windows(4).enumerate() { + let idx = string as u16 + i as u16; + + let val = u32::from_le_bytes(w.try_into().unwrap()); + + let hm = Self::update_hash(0, val) as usize; + + let head = state.head[hm]; + if head != idx { + state.prev[idx as usize & state.w_mask] = head; + state.head[hm] = idx; + } + } + } +} + +pub struct RollHashCalc; + +impl RollHashCalc { + const HASH_CALC_OFFSET: usize = STD_MIN_MATCH - 1; + + const HASH_CALC_MASK: u32 = (1 << 15) - 1; + + fn hash_calc(h: u32, val: u32) -> u32 { + const HASH_SLIDE: u32 = 5; + (h << HASH_SLIDE) ^ val + } + + pub fn update_hash(h: u32, val: u32) -> u32 { + Self::hash_calc(h, val) & Self::HASH_CALC_MASK + } + + pub fn quick_insert_string(state: &mut State, string: usize) -> u16 { + let val = state.window.filled()[string + Self::HASH_CALC_OFFSET] as u32; + + state.ins_h = Self::hash_calc(state.ins_h as u32, val) as usize; + state.ins_h &= Self::HASH_CALC_MASK as usize; + + let hm = state.ins_h; + + let head = state.head[hm]; + if head != string as u16 { + state.prev[string & state.w_mask] = head; + state.head[hm] = string as u16; + } + + head + } + + pub fn insert_string(state: &mut State, string: usize, count: usize) { + let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..][..count]; + + for (i, val) in slice.iter().copied().enumerate() { + let idx = string as u16 + i as u16; + + state.ins_h = Self::hash_calc(state.ins_h as u32, val as u32) as usize; + state.ins_h &= Self::HASH_CALC_MASK as usize; + let hm = state.ins_h; + + let head = state.head[hm]; + if head != idx { + state.prev[idx as usize & state.w_mask] = head; + state.head[hm] = idx; + } + } + } +} + +pub struct Crc32HashCalc; + +impl Crc32HashCalc { + fn is_supported() -> bool { + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + return crate::cpu_features::is_enabled_sse42(); + + // NOTE: more recent versions of zlib-ng no longer use the crc instructions on aarch64 + #[cfg(target_arch = "aarch64")] + return crate::cpu_features::is_enabled_crc(); + + #[allow(unreachable_code)] + false + } + + const HASH_CALC_OFFSET: usize = 0; + + const HASH_CALC_MASK: u32 = (HASH_SIZE - 1) as u32; + + #[cfg(target_arch = "x86")] + #[target_feature(enable = "sse4.2")] + unsafe fn hash_calc(h: u32, val: u32) -> u32 { + unsafe { core::arch::x86::_mm_crc32_u32(h, val) } + } + + #[cfg(target_arch = "x86_64")] + #[target_feature(enable = "sse4.2")] + unsafe fn hash_calc(h: u32, val: u32) -> u32 { + unsafe { core::arch::x86_64::_mm_crc32_u32(h, val) } + } + + #[cfg(target_arch = "aarch64")] + #[target_feature(enable = "neon")] + unsafe fn hash_calc(h: u32, val: u32) -> u32 { + unsafe { crate::crc32::acle::__crc32w(h, val) } + } + + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))] + unsafe fn hash_calc(_h: u32, _val: u32) -> u32 { + assert!(!Self::is_supported()); + unimplemented!("there is no hardware support on this platform") + } + + #[cfg_attr(target_arch = "aarch64", target_feature(enable = "neon"))] + #[cfg_attr(target_arch = "x86", target_feature(enable = "sse4.2"))] + #[cfg_attr(target_arch = "x86_64", target_feature(enable = "sse4.2"))] + pub unsafe fn update_hash(h: u32, val: u32) -> u32 { + (unsafe { Self::hash_calc(h, val) }) & Self::HASH_CALC_MASK + } + + #[cfg_attr(target_arch = "aarch64", target_feature(enable = "neon"))] + #[cfg_attr(target_arch = "x86", target_feature(enable = "sse4.2"))] + #[cfg_attr(target_arch = "x86_64", target_feature(enable = "sse4.2"))] + pub unsafe fn quick_insert_string(state: &mut State, string: usize) -> u16 { + let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..]; + let val = u32::from_le_bytes(slice[..4].try_into().unwrap()); + + let hm = unsafe { Self::update_hash(0, val) } as usize; + + let head = state.head[hm]; + if head != string as u16 { + state.prev[string & state.w_mask] = head; + state.head[hm] = string as u16; + } + + head + } + + #[cfg_attr(target_arch = "aarch64", target_feature(enable = "neon"))] + #[cfg_attr(target_arch = "x86", target_feature(enable = "sse4.2"))] + #[cfg_attr(target_arch = "x86_64", target_feature(enable = "sse4.2"))] + pub unsafe fn insert_string(state: &mut State, string: usize, count: usize) { + let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..]; + + // .take(count) generates worse assembly + for (i, w) in slice[..count + 3].windows(4).enumerate() { + let idx = string as u16 + i as u16; + + let val = u32::from_le_bytes(w.try_into().unwrap()); + + let hm = unsafe { Self::update_hash(0, val) } as usize; + + let head = state.head[hm]; + if head != idx { + state.prev[idx as usize & state.w_mask] = head; + state.head[hm] = idx; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg_attr( + not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")), + ignore = "no crc32 hardware support on this platform" + )] + fn crc32_hash_calc() { + if !Crc32HashCalc::is_supported() { + return; + } + + unsafe { + if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") { + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2423125009); + assert_eq!(Crc32HashCalc::hash_calc(0, 540024864), 1452438466); + assert_eq!(Crc32HashCalc::hash_calc(0, 538980384), 435552201); + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2423125009); + assert_eq!(Crc32HashCalc::hash_calc(0, 540024864), 1452438466); + assert_eq!(Crc32HashCalc::hash_calc(0, 538980384), 435552201); + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2423125009); + assert_eq!(Crc32HashCalc::hash_calc(0, 540024864), 1452438466); + assert_eq!(Crc32HashCalc::hash_calc(0, 538980384), 435552201); + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2423125009); + assert_eq!(Crc32HashCalc::hash_calc(0, 540024864), 1452438466); + assert_eq!(Crc32HashCalc::hash_calc(0, 538980384), 435552201); + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2423125009); + assert_eq!(Crc32HashCalc::hash_calc(0, 170926112), 500028708); + assert_eq!(Crc32HashCalc::hash_calc(0, 537538592), 3694129053); + assert_eq!(Crc32HashCalc::hash_calc(0, 538970672), 373925026); + assert_eq!(Crc32HashCalc::hash_calc(0, 538976266), 4149335727); + assert_eq!(Crc32HashCalc::hash_calc(0, 538976288), 1767342659); + assert_eq!(Crc32HashCalc::hash_calc(0, 941629472), 4090502627); + assert_eq!(Crc32HashCalc::hash_calc(0, 775430176), 1744703325); + } else { + assert_eq!(Crc32HashCalc::hash_calc(0, 807411760), 2067507791); + assert_eq!(Crc32HashCalc::hash_calc(0, 540024864), 2086141925); + assert_eq!(Crc32HashCalc::hash_calc(0, 538980384), 716394180); + assert_eq!(Crc32HashCalc::hash_calc(0, 775430176), 1396070634); + assert_eq!(Crc32HashCalc::hash_calc(0, 941629472), 637105634); + } + } + } + + #[test] + fn roll_hash_calc() { + assert_eq!(RollHashCalc::hash_calc(2565, 93), 82173); + assert_eq!(RollHashCalc::hash_calc(16637, 10), 532394); + assert_eq!(RollHashCalc::hash_calc(8106, 100), 259364); + assert_eq!(RollHashCalc::hash_calc(29988, 101), 959717); + assert_eq!(RollHashCalc::hash_calc(9445, 98), 302274); + assert_eq!(RollHashCalc::hash_calc(7362, 117), 235573); + assert_eq!(RollHashCalc::hash_calc(6197, 103), 198343); + assert_eq!(RollHashCalc::hash_calc(1735, 32), 55488); + assert_eq!(RollHashCalc::hash_calc(22720, 61), 727101); + assert_eq!(RollHashCalc::hash_calc(6205, 32), 198528); + assert_eq!(RollHashCalc::hash_calc(3826, 117), 122421); + assert_eq!(RollHashCalc::hash_calc(24117, 101), 771781); + } + + #[test] + fn standard_hash_calc() { + assert_eq!(StandardHashCalc::hash_calc(0, 807411760), 65468); + assert_eq!(StandardHashCalc::hash_calc(0, 540024864), 42837); + assert_eq!(StandardHashCalc::hash_calc(0, 538980384), 33760); + assert_eq!(StandardHashCalc::hash_calc(0, 775430176), 8925); + assert_eq!(StandardHashCalc::hash_calc(0, 941629472), 42053); + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/longest_match.rs b/third_party/rust/zlib-rs/src/deflate/longest_match.rs new file mode 100644 index 0000000000..37b7b28fb7 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/longest_match.rs @@ -0,0 +1,359 @@ +use crate::deflate::{State, MIN_LOOKAHEAD, STD_MAX_MATCH, STD_MIN_MATCH}; + +type Pos = u16; + +const EARLY_EXIT_TRIGGER_LEVEL: i8 = 5; + +const UNALIGNED_OK: bool = cfg!(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "powerpc64", +)); + +const UNALIGNED64_OK: bool = cfg!(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64", +)); + +pub fn longest_match(state: &crate::deflate::State, cur_match: u16) -> (usize, usize) { + longest_match_help::(state, cur_match) +} + +pub fn longest_match_slow(state: &crate::deflate::State, cur_match: u16) -> (usize, usize) { + longest_match_help::(state, cur_match) +} + +fn longest_match_help( + state: &crate::deflate::State, + mut cur_match: u16, +) -> (usize, usize) { + let mut match_start = state.match_start; + + let strstart = state.strstart; + let wmask = state.w_mask; + let window = state.window.filled(); + let scan = &window[strstart..]; + let mut limit: Pos; + let limit_base: Pos; + let early_exit: bool; + + let mut chain_length: usize; + let mut best_len: usize; + + let lookahead = state.lookahead; + let mut match_offset = 0; + + let mut scan_start = [0u8; 8]; + let mut scan_end = [0u8; 8]; + + macro_rules! goto_next_in_chain { + () => { + chain_length -= 1; + if chain_length > 0 { + cur_match = state.prev[cur_match as usize & wmask]; + + if cur_match > limit { + continue; + } + } + + return (best_len, match_start); + }; + } + + // The code is optimized for STD_MAX_MATCH-2 multiple of 16. + assert_eq!(STD_MAX_MATCH, 258, "Code too clever"); + + best_len = if state.prev_length > 0 { + state.prev_length + } else { + STD_MIN_MATCH - 1 + }; + + // Calculate read offset which should only extend an extra byte to find the next best match length. + let mut offset = best_len - 1; + if best_len >= core::mem::size_of::() && UNALIGNED_OK { + offset -= 2; + if best_len >= core::mem::size_of::() && UNALIGNED64_OK { + offset -= 4; + } + } + + if UNALIGNED64_OK { + scan_start.copy_from_slice(&scan[..core::mem::size_of::()]); + scan_end.copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } else if UNALIGNED_OK { + scan_start[..4].copy_from_slice(&scan[..core::mem::size_of::()]); + scan_end[..4].copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } else { + scan_start[..2].copy_from_slice(&scan[..core::mem::size_of::()]); + scan_end[..2].copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } + + let mut mbase_start = window.as_ptr(); + let mut mbase_end = window[offset..].as_ptr(); + + // Don't waste too much time by following a chain if we already have a good match + chain_length = state.max_chain_length; + if best_len >= state.good_match { + chain_length >>= 2; + } + let nice_match = state.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0 + limit = strstart.saturating_sub(state.max_dist()) as Pos; + + // look for a better string offset + if SLOW { + limit_base = limit; + + if best_len >= STD_MIN_MATCH { + /* We're continuing search (lazy evaluation). */ + let mut pos: Pos; + + // Find a most distant chain starting from scan with index=1 (index=0 corresponds + // to cur_match). We cannot use s->prev[strstart+1,...] immediately, because + // these strings are not yet inserted into the hash table. + let Some([_cur_match, scan1, scan2, scanrest @ ..]) = scan.get(..best_len + 1) else { + panic!("invalid scan"); + }; + + let mut hash = 0; + hash = state.update_hash(hash, *scan1 as u32); + hash = state.update_hash(hash, *scan2 as u32); + + for (i, b) in scanrest.iter().enumerate() { + hash = state.update_hash(hash, *b as u32); + + /* If we're starting with best_len >= 3, we can use offset search. */ + pos = state.head[hash as usize]; + if pos < cur_match { + match_offset = (i + 1) as Pos; + cur_match = pos; + } + } + + /* Update offset-dependent variables */ + limit = limit_base + match_offset; + if cur_match <= limit { + return break_matching(state, best_len, match_start); + } + + mbase_start = mbase_start.wrapping_sub(match_offset as usize); + mbase_end = mbase_end.wrapping_sub(match_offset as usize); + } + + early_exit = false; + } else { + // must initialize this variable + limit_base = 0; + early_exit = state.level < EARLY_EXIT_TRIGGER_LEVEL; + } + + assert!( + strstart <= state.window_size - MIN_LOOKAHEAD, + "need lookahead" + ); + + loop { + if cur_match as usize >= strstart { + break; + } + + // Skip to next match if the match length cannot increase or if the match length is + // less than 2. Note that the checks below for insufficient lookahead only occur + // occasionally for performance reasons. + // Therefore uninitialized memory will be accessed and conditional jumps will be made + // that depend on those values. However the length of the match is limited to the + // lookahead, so the output of deflate is not affected by the uninitialized values. + + // # Safety + // + // The two pointers must be valid for reads of N bytes. + #[inline(always)] + unsafe fn memcmp_n_ptr(src0: *const u8, src1: *const u8) -> bool { + let src0_cmp = core::ptr::read(src0 as *const [u8; N]); + let src1_cmp = core::ptr::read(src1 as *const [u8; N]); + + src0_cmp == src1_cmp + } + + #[inline(always)] + unsafe fn is_match( + cur_match: u16, + mbase_start: *const u8, + mbase_end: *const u8, + scan_start: *const u8, + scan_end: *const u8, + ) -> bool { + let be = mbase_end.wrapping_add(cur_match as usize); + let bs = mbase_start.wrapping_add(cur_match as usize); + + memcmp_n_ptr::(be, scan_end) && memcmp_n_ptr::(bs, scan_start) + } + + // first, do a quick check on the start and end bytes. Go to the next item in the chain if + // these bytes don't match. + unsafe { + let scan_start = scan_start.as_ptr(); + let scan_end = scan_end.as_ptr(); + + if UNALIGNED_OK { + if best_len < core::mem::size_of::() { + loop { + if is_match::<2>(cur_match, mbase_start, mbase_end, scan_start, scan_end) { + break; + } + + goto_next_in_chain!(); + } + } else if best_len >= core::mem::size_of::() && UNALIGNED64_OK { + loop { + if is_match::<8>(cur_match, mbase_start, mbase_end, scan_start, scan_end) { + break; + } + + goto_next_in_chain!(); + } + } else { + loop { + if is_match::<4>(cur_match, mbase_start, mbase_end, scan_start, scan_end) { + break; + } + + goto_next_in_chain!(); + } + } + } else { + loop { + if memcmp_n_ptr::<2>(mbase_end.wrapping_add(cur_match as usize), scan_end) + && memcmp_n_ptr::<2>( + mbase_start.wrapping_add(cur_match as usize), + scan.as_ptr(), + ) + { + break; + } + + goto_next_in_chain!(); + } + } + } + + // we know that there is at least some match. Now count how many bytes really match + let len = { + // TODO this just looks so incredibly unsafe! + let src1: &[u8; 256] = + unsafe { &*mbase_start.wrapping_add(cur_match as usize + 2).cast() }; + + crate::deflate::compare256::compare256_slice(&scan[2..], src1) + 2 + }; + + assert!( + scan.as_ptr() as usize + len <= window.as_ptr() as usize + (state.window_size - 1), + "wild scan" + ); + + if len > best_len { + match_start = (cur_match - match_offset) as usize; + + /* Do not look for matches beyond the end of the input. */ + if len > lookahead { + return (lookahead, match_start); + } + best_len = len; + if best_len >= nice_match { + return (best_len, match_start); + } + + offset = best_len - 1; + if best_len >= core::mem::size_of::() && UNALIGNED_OK { + offset -= 2; + if best_len >= core::mem::size_of::() && UNALIGNED64_OK { + offset -= 4; + } + } + + if UNALIGNED64_OK { + scan_end.copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } else if UNALIGNED_OK { + scan_end[..4].copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } else { + scan_end[..2].copy_from_slice(&scan[offset..][..core::mem::size_of::()]); + } + + // Look for a better string offset + if SLOW && len > STD_MIN_MATCH && match_start + len < strstart { + let mut pos: Pos; + // uint32_t i, hash; + // unsigned char *scan_endstr; + + /* Go back to offset 0 */ + cur_match -= match_offset; + match_offset = 0; + let mut next_pos = cur_match; + + for i in 0..=len - STD_MIN_MATCH { + pos = state.prev[(cur_match as usize + i) & wmask]; + if pos < next_pos { + /* Hash chain is more distant, use it */ + if pos <= limit_base + i as Pos { + return break_matching(state, best_len, match_start); + } + next_pos = pos; + match_offset = i as Pos; + } + } + /* Switch cur_match to next_pos chain */ + cur_match = next_pos; + + /* Try hash head at len-(STD_MIN_MATCH-1) position to see if we could get + * a better cur_match at the end of string. Using (STD_MIN_MATCH-1) lets + * us include one more byte into hash - the byte which will be checked + * in main loop now, and which allows to grow match by 1. + */ + let [scan0, scan1, scan2, ..] = scan[len - (STD_MIN_MATCH + 1)..] else { + panic!("index out of bounds"); + }; + + let mut hash = 0; + hash = state.update_hash(hash, scan0 as u32); + hash = state.update_hash(hash, scan1 as u32); + hash = state.update_hash(hash, scan2 as u32); + + pos = state.head[hash as usize]; + if pos < cur_match { + match_offset = (len - (STD_MIN_MATCH + 1)) as Pos; + if pos <= limit_base + match_offset { + return break_matching(state, best_len, match_start); + } + cur_match = pos; + } + + /* Update offset-dependent variables */ + limit = limit_base + match_offset; + mbase_start = window.as_ptr().wrapping_sub(match_offset as usize); + mbase_end = mbase_start.wrapping_add(offset); + continue; + } + + mbase_end = mbase_start.wrapping_add(offset); + } else if !SLOW && early_exit { + // The probability of finding a match later if we here is pretty low, so for + // performance it's best to outright stop here for the lower compression levels + break; + } + + goto_next_in_chain!(); + } + + (best_len, match_start) +} + +fn break_matching(state: &State, best_len: usize, match_start: usize) -> (usize, usize) { + (Ord::min(best_len, state.lookahead), match_start) +} diff --git a/third_party/rust/zlib-rs/src/deflate/pending.rs b/third_party/rust/zlib-rs/src/deflate/pending.rs new file mode 100644 index 0000000000..c7c9c4d995 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/pending.rs @@ -0,0 +1,95 @@ +use core::marker::PhantomData; + +use crate::allocate::Allocator; + +pub struct Pending<'a> { + buf: *mut u8, + out: *mut u8, + pub(crate) pending: usize, + end: *mut u8, + _marker: PhantomData<&'a mut [u8]>, +} + +impl<'a> Pending<'a> { + pub fn reset_keep(&mut self) { + // keep the buffer as it is + self.pending = 0; + } + + pub fn pending(&self) -> &[u8] { + unsafe { core::slice::from_raw_parts(self.out, self.pending) } + } + + pub(crate) fn remaining(&self) -> usize { + self.end as usize - self.out as usize + } + + pub(crate) fn capacity(&self) -> usize { + self.end as usize - self.buf as usize + } + + #[inline(always)] + #[track_caller] + pub fn advance(&mut self, n: usize) { + assert!(n <= self.remaining(), "advancing past the end"); + debug_assert!(self.pending >= n); + + self.out = self.out.wrapping_add(n); + self.pending -= n; + + if self.pending == 0 { + self.out = self.buf; + } + } + + #[inline(always)] + #[track_caller] + pub fn rewind(&mut self, n: usize) { + assert!(n <= self.pending, "rewinding past then start"); + + self.pending -= n; + } + + #[inline(always)] + #[track_caller] + pub fn extend(&mut self, buf: &[u8]) { + assert!( + self.remaining() >= buf.len(), + "buf.len() must fit in remaining()" + ); + + unsafe { + core::ptr::copy_nonoverlapping(buf.as_ptr(), self.out.add(self.pending), buf.len()); + } + + self.pending += buf.len(); + } + + pub(crate) fn new_in(alloc: &Allocator<'a>, len: usize) -> Option { + let range = alloc.allocate_slice::(len)?.as_mut_ptr_range(); + + Some(Self { + buf: range.start as *mut u8, + out: range.start as *mut u8, + end: range.end as *mut u8, + pending: 0, + _marker: PhantomData, + }) + } + + pub(crate) fn clone_in(&self, alloc: &Allocator<'a>) -> Option { + let len = self.end as usize - self.buf as usize; + let mut clone = Self::new_in(alloc, len)?; + + unsafe { core::ptr::copy_nonoverlapping(self.buf, clone.buf, len) }; + clone.out = unsafe { clone.buf.add(self.out as usize - self.buf as usize) }; + clone.pending = self.pending; + + Some(clone) + } + + pub(crate) unsafe fn drop_in(&self, alloc: &Allocator) { + let len = self.end as usize - self.buf as usize; + alloc.deallocate(self.buf, len); + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/slide_hash.rs b/third_party/rust/zlib-rs/src/deflate/slide_hash.rs new file mode 100644 index 0000000000..629645bb39 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/slide_hash.rs @@ -0,0 +1,164 @@ +pub fn slide_hash(state: &mut crate::deflate::State) { + let wsize = state.w_size as u16; + + slide_hash_chain(state.head, wsize); + slide_hash_chain(state.prev, wsize); +} + +fn slide_hash_chain(table: &mut [u16], wsize: u16) { + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx2() { + return avx2::slide_hash_chain(table, wsize); + } + + #[cfg(target_arch = "aarch64")] + if crate::cpu_features::is_enabled_neon() { + return neon::slide_hash_chain(table, wsize); + } + + rust::slide_hash_chain(table, wsize); +} + +mod rust { + pub fn slide_hash_chain(table: &mut [u16], wsize: u16) { + for m in table.iter_mut() { + *m = m.saturating_sub(wsize); + } + } +} + +#[cfg(target_arch = "aarch64")] +mod neon { + use core::arch::aarch64::{ + uint16x8_t, uint16x8x4_t, vdupq_n_u16, vld1q_u16_x4, vqsubq_u16, vst1q_u16_x4, + }; + + pub fn slide_hash_chain(table: &mut [u16], wsize: u16) { + assert!(crate::cpu_features::is_enabled_neon()); + unsafe { slide_hash_chain_internal(table, wsize) } + } + + #[target_feature(enable = "neon")] + unsafe fn slide_hash_chain_internal(table: &mut [u16], wsize: u16) { + debug_assert_eq!(table.len() % 32, 0); + + let v = unsafe { vdupq_n_u16(wsize) }; + + for chunk in table.chunks_exact_mut(32) { + unsafe { + let p0 = vld1q_u16_x4(chunk.as_ptr()); + let p0 = vqsubq_u16_x4_x1(p0, v); + vst1q_u16_x4(chunk.as_mut_ptr(), p0); + } + } + } + + #[target_feature(enable = "neon")] + unsafe fn vqsubq_u16_x4_x1(a: uint16x8x4_t, b: uint16x8_t) -> uint16x8x4_t { + uint16x8x4_t( + vqsubq_u16(a.0, b), + vqsubq_u16(a.1, b), + vqsubq_u16(a.2, b), + vqsubq_u16(a.3, b), + ) + } +} + +#[cfg(target_arch = "x86_64")] +mod avx2 { + use core::arch::x86_64::{ + __m256i, _mm256_loadu_si256, _mm256_set1_epi16, _mm256_storeu_si256, _mm256_subs_epu16, + }; + + pub fn slide_hash_chain(table: &mut [u16], wsize: u16) { + assert!(crate::cpu_features::is_enabled_avx2()); + unsafe { slide_hash_chain_internal(table, wsize) } + } + + #[target_feature(enable = "avx2")] + unsafe fn slide_hash_chain_internal(table: &mut [u16], wsize: u16) { + debug_assert_eq!(table.len() % 16, 0); + + let ymm_wsize = unsafe { _mm256_set1_epi16(wsize as i16) }; + + for chunk in table.chunks_exact_mut(16) { + let chunk = chunk.as_mut_ptr() as *mut __m256i; + + unsafe { + let value = _mm256_loadu_si256(chunk); + let result = _mm256_subs_epu16(value, ymm_wsize); + _mm256_storeu_si256(chunk, result); + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const WSIZE: u16 = 32768; + + const INPUT: [u16; 64] = [ + 0, 0, 28790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64412, 0, 0, 0, 0, 0, 21043, 0, 0, 0, 0, 0, 23707, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64026, 0, 0, 20182, + ]; + + const OUTPUT: [u16; 64] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 31644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31258, 0, 0, 0, + ]; + + #[test] + fn test_slide_hash_rust() { + let mut input = INPUT; + + rust::slide_hash_chain(&mut input, WSIZE); + + assert_eq!(input, OUTPUT); + } + + #[test] + #[cfg(target_arch = "x86_64")] + fn test_slide_hash_avx2() { + if crate::cpu_features::is_enabled_avx2() { + let mut input = INPUT; + + avx2::slide_hash_chain(&mut input, WSIZE); + + assert_eq!(input, OUTPUT); + } + } + + #[test] + #[cfg(target_arch = "aarch64")] + fn test_slide_hash_neon() { + if crate::cpu_features::is_enabled_neon() { + let mut input = INPUT; + + neon::slide_hash_chain(&mut input, WSIZE); + + assert_eq!(input, OUTPUT); + } + } + + quickcheck::quickcheck! { + fn slide_is_rust_slide(v: Vec, wsize: u16) -> bool { + // pad to a multiple of 32 + let difference = v.len().next_multiple_of(32) - v.len(); + let mut v = v; + v.extend(core::iter::repeat(u16::MAX).take(difference)); + + + let mut a = v.clone(); + let mut b = v; + + rust::slide_hash_chain(&mut a, wsize); + slide_hash_chain(&mut b, wsize); + + a == b + } + } +} diff --git a/third_party/rust/zlib-rs/src/deflate/test-data/inflate_buf_error.dat b/third_party/rust/zlib-rs/src/deflate/test-data/inflate_buf_error.dat new file mode 100644 index 0000000000000000000000000000000000000000..2b937a7f43ee323e096b319e7a0269c47bca53a4 GIT binary patch literal 67008 zcmeGlU8@~6aIdZXIQUQy!3PU{s2>OwS}hg9a(xo|aP%TRh}2jAfr4=VyP15PO(rwh zWRu;KoI6Wp2MF7lR4vf(}17#m6Vd zV~TB~pNF6MWV~_L@#g0DWzN4{t^zew3rJ~ceHi*bFgNP&+n@{>Q0l{%rVXAZh&&u_ zRDmyCs+ocF3~TRzgUy`=37!ylQI-ubf!a_L6qxcHtw`)SD)V_e&ruF@^V1@quNG_Q z3W~p!!vsi1Hs!M5jI_ zPh2V?>C(Q(YN*~=kdjVd18tpf1qo^uwtigj(lbicTxu~XpauXV%ZAGFXfergm#h#g z<1%vD!;f^p-nq19l!)xjf#T9Fb(mO%b^>3%M`1M1NcADtzz{#}EMd3C-b%xQ?3daN z)A}ykGcj@R5_@k_cTcB5k-<|upZtR_G9$=vn;SJjfvISuMT(=5${ciqA&{Mn*#dE_ z11N(+d8PK%#En}asR;*+M3s2TreV*3nQ^9JNd2AdpU8gc>>8k{^m!>;x1Z${AjtTn zf8I~_OCi=22Ntbe9atifTE)k=z`JF?RBsROa@YM#0S+ZXmhk*K=no(8h z%0v*bvTfYS1t=5AP38BNo$gvPiXJ;n8#Kn5HR=7#cq# zN0SkkX(?@}M~Yg=E1jAXXU!Crf16&B)Cw{vKF#B^e?{m-D=YO!NLx0s?My1NvVJmN z(xjk)fvk=qfvf=u55ZXrAy}5HW@`n}$#PYA>c4~I{aQf->Sm9@4AryZ2%z8#=r(^_ zaLp)uj@H3Qx9JRbfK^}VHl^DPJIWC1pxZosu0r05bAcssUl=CGN9L6Mk9bH$c6nr% zXAa$Cr&{dtXbC`ENKgERA6*t}x`lAlAK$T3R}l$ak+2IhRd*c>*vCyEcYt1*j9sf2$kacIo#n==z$u zCV%qq|6tmB6*hUAG=$mfq2ybBG^JbS@{FKXKS6K|@~BV=Z8g&rqwFXL@i07C6Ti-U zB1ncaGMqsp$-8dA(0oPG#lP`OoP0n(pt+qhUWrQSk`nrNh(ZL?^_y291?+(@#~J zKAAeYkrVW9ASH`Zn`@uPj`Y|n}w*1{0x=nf_#G=m9WfI)5v1(p@8QOQMYUiJStSebt0(6zCgso@LL9WHuEd_N=lt3Z)_oMku}l~XnH9831F8MvX_D8wNV$@kw0wiyw6K+SFK)BG z_TcJr;B-DwdM9+~0upXRhk}| zWZKe5)i#ilMXAjaL?N$*6&r+T1>&*V)lh<1|6*S5lZ3S8nD}W*RcyR_Js@8VcZNH_ zqKSMpe0B>^TYAC6)|KCeE!aA^e{Ys>S;`M}1L}r&UsiFE+xe}p2cklkbep~{m096l zwWZs1Ml0Rsem}A7WbWUM#jl=?TU0&IGl4@J5#~iR`51;)nNnZbxixJr+FBx!8cQPn z`sM~>u63IW{t8&QX!bB}4w1hSVI=zc3sG6R(vXxcT$DU}(h zUGj_1fhr}+=``KRjAPE(lm?xr1^kDtRh(8}y=Bom(VvivaBX&MlJo2JNRC1P~wHoR;Gwr(sUoIlCxDjxzEqB4^#B`PCET>J6LaE(ieL>L}=9P9ydz@IVv4@a50~vg)ZP%h~rWJ}rl-HwH zsGTiDHh@gz`km++QP#Hz_Q97Ppc>g|)SwLom`K0k;n8A}qxJD}jvSN>R}Z^-1ux3f zR^=lr!o2*YG4ucf@(p%W!q6@sSGIy#Him3va-A@%f*uO8xjSb?R#4SMv6xYTZV2V2 z!EDl4G%SYlCst}O{_P78#L|N z-2fxY`UY)nhthFz>k>WPdA1Ri%RY)8U_idXj!GEXWyWg-vuq66%9O!jwx|j#p5KTy z!7Le6K{kuj!#a<}Q2qpq3Kg)J8yC2*0IfocX!byaZX4f*Gk2exMvqU_2E}``zD)gP zc1WUKg*c;wpA}Lp+I4fxn*QLo6+04nU!bM2?;9(!zR5<^IWBHpqNh8e)dLZgQN*yG zsXU-;Bk~&B;06S$DE$dr>u};{AjMV}QuPeBYG4;Uj_g~P=;_W&08ttF87j{O`35^G zVVS9>k;U9Y0nZ(xZrK=kRH%fDxTwXxK*U3zAS<$IVvEuRb$o7sTaDI#tUcOqpFh3p zhJO)5F&*0ITXlKE|D)gM2NLosxg>Lp3SPf-RouN`0P~F=eVDdGS_66(Mlh~n|Ne&$ zK>B-}LBmVLtFy(QPG4%W?Vmd8BPt@o8Oh@ZmkAF1LIX&@bQ4{-G1iNGPg zHXL86{nq;d^T>@p4xS2XPReT^g*g$N8KMxDJn$?*!y^qO1uGJ8TDS5-LXY0!R_NJy z0MAM&qdXwYTaE}4$}-JZLK!~>$`oN(ZNyN + + C=10 M=100 Y=50 K=0 + CMYK + PROCESS + 10.000002 + 100.000000 + 50.000000 + 0.000000 + + + C=0 M=95 Y=20 K=0 + CMYK + PROCESS + 0.000000 + 94.999999 + 19.999999 + 0.000000 + + + C=25 M=25 Y=40 K=0 + CMYK + PROCESS + 25.000000 + 25.000000 + 39.999998 + 0.000000 + + + C=40 M=45 Y=50 K=5 + CMYK + PROCESS + 39.999998 + 44.999999 + 50.000000 + 5.000001 + + + C=50 M=50 Y=60 K=25 + CMYK + PROCESS + 50.000000 + 50.000000 + 60.000002 + 25.000000 + + + C=55 M=60 Y=65 K=40 + CMYK + PROCESS + 55.000001 + 60.000002 + 64.999998 + 39.999998 + + + C=25 M=40 Y=65 K=0 + CMYK + PROCESS + 25.000000 + 39.999998 + 64.999998 + 0.000000 + + + C=30 M=50 Y=75 K=10 + CMYK + PROCESS + 30.000001 + 50.000000 + 75.000000 + 10.000002 + + + C=35 M=60 Y=80 K=25 + CMYK + PROCESS + 35.000002 + 60.000002 + 80.000001 + 25.000000 + + + C=40 M=65 Y=90 K=35 + CMYK + PROCESS + 39.999998 + 64.999998 + 90.000004 + 35.000002 + + + C=40 M=70 Y=100 K=50 + CMYK + PROCESS + 39.999998 + 69.999999 + 100.000000 + 50.000000 + + + C=50 M=70 Y=80 K=70 + CMYK + PROCESS + 50.000000 + 69.999999 + 80.000001 + 69.999999 + + + + + + Grays + 1 + + + + C=0 M=0 Y=0 K=100 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 100.000000 + + + C=0 M=0 Y=0 K=90 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 89.999402 + + + C=0 M=0 Y=0 K=80 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 79.998797 + + + C=0 M=0 Y=0 K=70 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 69.999701 + + + C=0 M=0 Y=0 K=60 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 59.999102 + + + C=0 M=0 Y=0 K=50 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 50.000000 + + + C=0 M=0 Y=0 K=40 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 39.999402 + + + C=0 M=0 Y=0 K=30 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 29.998803 + + + C=0 M=0 Y=0 K=20 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 19.999701 + + + C=0 M=0 Y=0 K=10 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 9.999102 + + + C=0 M=0 Y=0 K=5 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 4.998803 + + + + + + Brights + 1 + + + + C=0 M=100 Y=100 K=0 + CMYK + PROCESS + 0.000000 + 100.000000 + 100.000000 + 0.000000 + + + C=0 M=75 Y=100 K=0 + CMYK + PROCESS + 0.000000 + 75.000000 + 100.000000 + 0.000000 + + + C=0 M=10 Y=95 K=0 + CMYK + PROCESS + 0.000000 + 10.000002 + 94.999999 + 0.000000 + + + C=85 M=10 Y=100 K=0 + CMYK + PROCESS + 84.999996 + 10.000002 + 100.000000 + 0.000000 + + + C=100 M=90 Y=0 K=0 + CMYK + PROCESS + 100.000000 + 90.000004 + 0.000000 + 0.000000 + + + C=60 M=90 Y=0 K=0 + CMYK + PROCESS + 60.000002 + 90.000004 + 0.003099 + 0.003099 + + + + + + + + + Adobe PDF library 9.00 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 145 0 obj<> endobj 1 0 obj<> endobj 2 0 obj<>/Font<>/ProcSet[/PDF/Text]/ExtGState<>>> endobj 3 0 obj<>stream +hÞ”[MsÜF’½ëWðnmU(s™e{¥ÝñØkjw²`7ÈƨhhÒœÝ_±‡ù½›ïe€&›rl(BÑÄG¡ª2óåËúæ_o’‹ûáÍ·ß|óƒ»H.>Þ½)V¥sæ"–þ§ËWq’\X¯âØ¥÷obÞïïåÇÇ5þ{|ó)ú¥^×íxyºl•D]ÿE~gÅ*vMû¥Þè_YôþÇAÚ¨jqÕÙèÝ·?ób¾*¢]ýPïøW¹rÑØñ‰UÝ×mž©?ôõ04]‹»±\¹}ºüüñßÞ\¯Ê²¼¸NVIîd=ßɼöuÕÊp6wòñîN~¹re¢ßŽU;6c565î–2éc³®v¸„uì» gƒ¿ŠèSšü3Í>_áïD04í½¬îçQwñ#*Îåã¿Èׇ}µ“ÁL%´ÇýmÝË_9f€¹˜ÜÊ0Ü“²^YצYÓN¾9nëpsìe)ë¾9Œ²òŠÃ&ò„|÷€O›"–Ý~lÆíüýms¿•=2yT­×ǾZ?­ø'Ñ=ÊV÷Wø;“ù¨`L)·T0¦XåA4&ÅåÝq'×»êIGJd½×©Å·ÍC7bb©1QßíêðtÓrJ1EãÊ\ES·Ã±çR!â"º«dîwÇ +?‰ÖÝþ°«G³ÞqÏ p§Û¢õÝ_ß⧑«}}؉øü+.ÅDûöAèþ¹˜É¤$&þ¼ +*÷vÐoˆ¼:UçTæ¿išÍ‘ksØô÷?ây'ÒÛVƒ^4Ñm]Oß½ëŽA½©Ä$x‹I;#ŠúŠ¹4Õ.|ö®ëý®oîýŽQˆwÇv­KÊ,ăñ2kd‡6ÕX‹³,–‰4#.CÍ›¿ ²]ó¥Þ=é‹F6­õw¡â–QD1ü{~Û´Õ(µ}ÒËE´œK_ßw•*hZ@CtûEAËgÛ/Ê)rjöòìJÿ´Ñ‡vS×è\a¼ #ŸxhêGý­FšæØ“õ¶ïöøØü}l¶cYŒh)ùª¨â(»·ÇTþæNšÒÉþ¨ñÈSb”²áû[,Ê”¥W%üÊ£MswW÷/S2²¨ÌXËGåO¨¥ªáï5Œ´Ìåþr>ë®ýû,ž„Ø ¼Îb`'%ÉóÍÅE,Bþ>ö|$•G0§,1%ñž@ÜèÏT/¿2Ž;ë‡,žBQC)e¸‡™]…MÎR™Ø¶±~˜Rmê[Qž¾ +P c§ ƒ] î©QÉkO‡NFšáJ_¶Øù•É‡·Íz{θ‡C½nîš5”ÚÉ<Âòe’ƒÚH²˜¥‚Q`Su/JCSI£cÛüvôf“F·M·ëî¡asÖ£ßpΪ?™äŸÆ²óy»·Ý€˜'°#‘ó¡°ø;¥nåi*s¨ð#–}ðêÞõO¸‚ß×ëmÕ6າˆY‚Â^õzÉ .R`cß­aôXg|_Ž½~¬á"ÒÜhjñ@÷þͼ ú,Îø=qr‚Ðf²Î®½Â¥Œš40ÆP“Ûu}€ž`‘Ë@4Ë ë;ÂzRìÏ—¶{í»¯u,"ÞM¡ØOµ&SÔ›&´©÷"a™*W`èÕ"IˆF$—,Ñb¥OÚè¦És=<¦Ò#jáâå¬ú{ˆ~ñ›rå-"ß"· .êYF}V$¹[ù'=ùžªJ’}ÛJéZÄgŽÂ6`v©õÆ&v—‹¬Àeøœ¬z|$Üã¥lUr«»«iÚƒþ]ªÀ³øŽ=Xê3M7ª˜‰-ÉuÕ®• ÛîQ/ç1y°Ü8âöî8ˆÑ@š®ôv…—’å´pËÎÓ:c²‘Ș‰…€ei$ˆŸeTW=]C +Çè]•¼E³Á;ÍÈ»p×~Í +åU{¯»Q*0÷5á.õxr"ÎCŽ¾ë»¡;l›]uùñï³$ÍJĘ‘C…8Þ÷22´?¡Õá×@Hr… ü4AïØÉð$[ˆ­Z«ë3‰£X+!M²·Í?86À[T°¢>yúÙœh×ÝÒ°q ¢Pç$áð +ŒY¸p%«öb¥#XŠ5¡|–b¥^Q*B;óN™ºËJ:”à§3RÕÿüã…ò»¬Èå*ðÄ›9"‰a½­÷x¼pNA +è +S²b' –Uäp‹~tÜ…å6ûC×äs$Œt€Wh¿eÞ¢»+hªq², GFÙIHÆø[W5‡SØa<DèŽìßXÝî¦ÝSq-¾Í˜Ô1æ¨+£"G[»†‘!&f,Ý­pág‘ âä|ùž‰ùç­v0EÂQÍ`ÒŽIYZå)Ž+S ÄÔåðˆwMïï¹@Å]ÁàÚçG\¡Ñµc¬v[ŸøCÝ?0˜!ÿ¨Öâÿ8äÖC1Rµ<*—ªåùŸ`yqY¦ˆ!K5¦_¨Ñq7ß|èM ¾õQS›:¦Y0âªްYuÈIaf>]"B”ç] <-W½{0psõïÛ涹¼f^HãGØè¾Ñ¸ÍÆÁ†dV`)0¥ÉÐÒØYohjVÆBÕ訅ôù¤aRpvã)øP¬¾ßO¢ûÓí%‰Ãâ̹ Wˆ-%Œ~©×— >ì-œ@¨Üe‚\›:¹‘Ô¬¸ ‡+pÌXÈËðI”ûRt/€·¸'* ÓO€.©áXIMh=N`B—šû©epxcš_ ±¾~¿»dâ¦~–§žÐR„‡'%¤ÚWº( &­£o×·+,NyL'³$RxÜa9™KBˆYXW2¿ÆòÓ¨ò³/0Ã,sJý1yX>(f$ÆWò(»J +쇋®ŒÃD~äŸ1R­ÎáîûîQg#¨p©øpœ2 :}R·ŠHX0 ‹â= ³#Î1pëë:º­]³cö®ÕQ3&ŸsdÊëÙÖ̤j¸¾×íoF?¦ÛË8âV&Ñþ–Ó’™âñSnÞ#ÅÂ:tÂb0£2.£»±¡×žz••D-º‹;„¸+,ø=߃`®p©ð!jΰL “D]asÉ ›ÀäáF½cÊÌT óÊ\0ø¦>I/LPaªf¡¿ rF“´ HKìØ™e(ÕÎçO/ìe£ì;ex~ÎZôYï þPŽÉò3c³»d|¾¸Võ4ádOЇÒ)óñZ~Fë$¸Ö•K$tI¦‰@[µAuÆ0\¼d‚ ™FdõÕZ¸sËj†?K~ºoXŽå&=xÕï ìØ6U8¬~.PTZ;@°WaNCnuÿ›ðùè¡ùPä(Ψ-ñ&âfM’¿Ȳñ!<™ó±×4¬lÿ×ÈÄømC ãåÑ5cÂ^A®Ö—Y‹1xU_§–2Ðg¦t´i¦´Mc¡¾%='0Ä>ÿâ·¢ÖÚ“uWHh*ZC‘w3ÿ¨‚ÌH£¶ÛVwAûðкÛa Hœ¯‰Êð“*^¶I˜Ø½SÄ®¡lÖ«p*>Q„!:MÖ¥¥€Ml±µ’™¡Õ²"rÙ9ù1LAéëDà‹m]X؆¡IÓ)ÑW”'Szó»¾S4CBå…lĉ‡™&6¼q“j¦È‚Ÿ©:î ·ŠS³”H+z·ý ãG?_KtÉŒb~£Ùî> 4=t£Uÿ¦® *¡8g2a¨¼Šj£DÖÒ&§üý_ß©Büô¬å{õ +™ Åg­B$E»Ä³Mõt|G +þǨ>#!›8ÂJM:>ž„3ðw•Îy².ê#®­Á’˜3—Ÿ:0QãIó.Žµ8k±"t›NÈZ}õGÍøØ%@i"çÜ·µL¥ž€·5)³½w?/Æ>Ñ+ú$´.&Ž¡NØô3ꔈ{[ª“-R 韹¡n>Êuš e›ã‰P 4~ð€z¥£åZÝË](œiæîð~ð|¢Máë 6A8°*¡Ÿî‰®;Ù:±üMãõê‡ùh‚!÷¥GÍ°þÁÖ#;ÌB­Î¡±jPëDía•¦h±¶S~‚¯È—wjyÇ¡Q£|¨ÃãáE‰½êQ÷©ú'ࢳ»ªX +Î|J1c@«Ø"ëA¾'cÝeI3ÈŠ°Z²G£#s>]žME÷Ìnó,ÓÑR\ÉFuNT':òƒnÉöjœD“JÁXI…¹gc÷ëq«¸Ðm¼†7óÌ°¬Ž‚5“zÚŽDyò®Öý¬ú¶F ÇAN;·etS?L°£óÙ…1g«B†üÔþBÐ@¨Ï3V̶žºžuÙD»|±“Ão‚nh®ÓAìJF*§ƒgyÆhL¤“V¨²â±VÎBb¬eh£¿¯‚Ì×”†|é0*n7AHRiDª£ÆH‹‚§Ä*ÎH,puÉ¢—)?Ëe —÷°;šÐÉÍ55§îåÎܬÓ_눉8Û3¯¼SíYéMÙˆ tþ¾mî4„BXIâÞŽA…õ•<.}ûú"!‡.ðüõÌd>?3Aq«ÝæÌ‹xîHÁã—Šžt} lh*Qô„®ðLPô3ÉC{ËA+Í¥Þ[Ù²Ìü½“Äþêz'ñw’—/ýéÙKiž„·ŠsoÉEúú›×óý$ö¤¡(ž +{giÉÿ´â0sä +úäIÌÑŸŽ›¬â8õ48²'eö—ŪLL"ã\FxË _¬BOù!¬óÑ'o¯=µ`$žjð† Ï̵õ4ËÝ©Â#,$Y¡·†×»ÛØãÛµì½ÈR²…Gíª,|{`²Œ§öWlÐŒš•/†¬Âpïí¿«aÕšÉ%ã/·÷Š—è[Ó$¦G’¢RŸ"/ŸAØiôŒ£;F«ÓË6ä”’+um`P­þ,ÎåÑkë‹€À••¿¥‘ŠŒ^T½tÄÇfTˆ‚'Íã)É{.\¯Ur!|©ÖOÚÄ +ÛùÙS¹ªÔËvíÿ* + ¡ó«…Å!Xwµrñ»»Fá,ÄûäýXÑ•vvºhë™0z +õ'wJ)s² üüî]hµízoá‰/1#œ—AËû-—ø+Æ/ÇÎ6ñ=ân–ò„f©Ý˜`7‰µötÄòåˆ/­-óÉî(þÀ†¨¿ežÍ>Ίe£h"ÙAOàä'Þê¡ñ¶yôám(‡K@ ®6®~J2U#œ +Òã<‹â†²ÖãrñJqÃä¢óé[ä $ÊÓê‚o0-ó¸xf>f¥A´Q'n¼C*Ë9»Ṳ́ÇOÚ–œè VJ|×vœœØ‚ðª?2*“×( XŠ¦dø\îÓ0)IPÐù«sföèOˆœ§ñ.Í7Î'‡£N£ +„àÅâ8ÉltGÖšÈü®,Ìœ¡Œ¬Kñ‰dîÆG´ÆdOšH^e1g³µ›pÆ5ö%Æ‹$æ$¯Aé¤/9hoZK¿Ä`_Z%SæBõPVçß[þZ¦ì´P7‘ô/¬¥±ŽwV•S6p½O®´‡Quîl6à ×” ˜­F±akï׊¬–'d§yvÕèyi¸ù*m4,Å>éÑ ÜG]ž“Õ 9D7ÿ"˜¶*™éœ¨ºWíAØh8ªD\©›1¥qšuÄ51Ëc¯ƒ÷u«YÔéñyÜתkÒæÌŒÏݱ+ezuœˆÝ¡80T,•ŠÉÀôäÜJµ®™*y‚+š¢Â”L^5•³Fæ–µ¿îzãV1àÜ›gª¼ì¡eþu×­µL[yzÝü#ä·¦cƒñŒA¬m“´×GôüDÛþL-d>ô©šâ{[sGžíÉ•,£ê5yþ¥i5,çiKàèäÖç ôv7eÈä™W +ïĺ‰ái´”[v¡Ÿªx~ÊÖe@UpžéRDOÿï¢ÂUhâåV•F;€uCǾ4Ö&Èä!ˆÖ¼æ3Ð,§3xeÁ(ÏCHϵÍìŬ,Ì{Ë¢j ¯ðAsùJè6ǯBäõ OÆÌÏ€+œ}ø ɯp9)êÈeš;Á)¨g…ùäe»ÓrŸb­Z«Ã‘7N}Ç£4)[V~¥ñæš‹ãóVû@õ‡›¿©P?œe·ýÏ_~‡ +—%Šø_ßþ ëæ¼-wQ[ž ól‡¯²EÏ6bÙ¤çåjc{޷뫾ÖÀs”ÈÉøLÆ2=éÂÿZ%Ë‘H0èÛi4>v:ò26¿ +#œDiæyé +m—È8#ˆuïK˜€àhÑæK#ziT”\Ýûá =e̽òݲ±ž%œ>â¸'o?þ¬¹Þ¨'–{H4Ày±'›ªõ•LŸ=ÇÌëÞ‡x‹ŒŸ¯…ŸÇ‹»jí1|}óc£ª‘^i‹¾ïÝÉÕùtB×}¥[Ñ~¾„VÀ;-9¼l¯ÔNï§[pô#[rÂÙ–øùäë«s¨n!à†¹OŒEtôp·`ÓÜôÖí|v+bþE‚R»šyoXT€`Ûãz§Uw(#äE¸ ¥žRõm÷à3Oý•+´©-ÖÍBoU`úÇÆ{ÌmóŠäÎUÐî”jë›0ÎvU0ù{òÜÕØÓ4AÔ#x/kqC8øÉ&‹(Ž£/^Ôs²äÓY×g2›ê"@grÞ½É6Ò™™â6˜ÚðÕÑL9À9·.o³KùœMPºWtôu)="kúÔRfH©ûkßÊÓoØQ‹Î¤Ä¼B[ÎHi}?Üqí‹sSŠg“°©èxËOhï¢ý” ­S )·C¥Ìa)žÔºYð:ìk=ƱYóÅÑ—".òS²èar/{˜DÒ¦Lç¢t:µ h¢MlÈæÏÚ²KL¾ŒbxD®ºÑÌAÆ/­'–V˜å¥#”_lÇ×wŨŽ{ù-“å™P3´¯°ŒaæÄÚç„ô09úpŒ,Æœ,†ÿsÕ¾;Ð+šW!ÀEëÏ _Ehí¾çÔ­•D6•vÃ$Ñtxéd›ôŒ¢ß&ÜwÑc£my82Ñ+pÔÕFO)ŠW%_6‘AˆgYý<ÈUÈ*:p|+ó<öá¬ðºîµ„Æt}8…,!e„óÉü4@áË„R\s!{ô>ú%!–e +éÌþ¶·É0ÒZw?ŒO~cÇ=L"RÈ'mSQhkŸ£Y¯ð9 +¨ëŸtË žÿ>·ç}½¯T-ŒwÆS0k Í»ªG ®‚Ý÷µÿKâËV6Uøg½’l×ûšç"ñªcéOGžQ¢ëe÷âtd=ÎÙyyÜ<…*‘J-V›Þ©Òoq€ z[áå…X@4¯Va`ñ) ‚º? Ù-aoN`,‡ÝiîšÙÀ´*¦Í…æ¿ü™v6j›øi–dçØÅS…4DÎõš¸ :QßæÜð°ƒ>ü·Z‹¼l­êúQ]güÎõYêà"ÁïÍb}$ˆ âP#í™è‰òqŠc²¥ÍiGY^;ò;®äaEv0ÌÐqಙ±Þ•“¢º¢ -Œ…¡øª^ÌJ÷d49[ŸºaArë]½÷ îŒvFMTQÒ¨8ÃvǾ¹=2IžÇ>V´l“¹;öãVy Èg½;®›¦Ó]áâŒ(—f„¤¬7#6vûæ7Ãã[M Å?oª} 2´ +€£ŒCf© `Ü ôsthC“ÿ‰BV.ÿ]àXA™+YýýDZ’mGÓ'̇ ˜ó£Li7ŒõÓ‚F©¾¥ðÿœè[Š½ÿ¨Ð¤§­ E¦¼¸.e‘ÂQuù?ÿ姛°ØwÝþp9–bË¿¥÷„I±)ÿp6»ôøø¸:ìºA(?cï𳫮Ǚ +ÇtZzy]:œþ­jZËM±—iœX§e§ÿ«Û÷µúï=arÝ?`KhŇaÀ &ˤk¢¯%óûuÇÆ&e/þO€¦±.µ +endstream endobj 4 0 obj<> endobj 5 0 obj<>/ProcSet[/PDF/Text]/ExtGState<>>> endobj 6 0 obj<>stream +hÞÌ[Û’äÆq}çWì‹#0Ž™.uá‡%)YT¥][K>`z03»M=Ãa8üþ^ç9Y…KO/I…eKÁ.¦ª²2Ož¼Ô¯þí]öæaøäÓ÷Ÿüê7îMöæýý'å¦r®x“ÊáÒ–›ÔöÏ‹I3óæýþ“”ôrñ~‹ÿ=ò!ùíp¬®2¿©’ôê¦0~S$õUš øC^•?ø«Oöu•Yù廦Ço©üÖÝã*ß”I½Ý^eÕÆ&Í0´W™Ì"¹Ý5úœI¶òn±É“n_ã¦KÆö°‘»…‘ë·».½ÜoxÅÈ8õî*ËäßÝ5~±xåñ*Ëå£Õ'»v1ˤ›«ÌÉ﮾}ÿ;Y×M¶É¼Á|.ë;ö ^Ë“»Vfhäý±}šr©“»g,-O°2—æae¶²r5Èœø¬ÇVF.“9z½h¾™ìøµLæ"Z™ÿI…éÒLÆå¤Éã˱ƒÜ‹y]Cû#„“͛ŚÊÜèššZÌ·H,=¶ +¿Ì=‘-·.Ï!þnçmrÛj|T&ÞõíUžb·!|ÑáËSU26ýS2É®ÖMxÁ•Ìñ¶Ÿu¨¦ÁVeÆÅÝÕéøˢšÞÿ3V‚ù@Ínwøº“A®nŒLÇR ú‡›õëÔÇñ܃îÝɈ.¶œG‘´ÇQÅÒv Ãh‹‘Éy +•ßl{¡Júf‡Uù¤[Ì¢HºÃðI‰Jã‹Ï­l‡3òÆQÕj×^Q7ó¢¶âÂçó*•Ïížfá“Ã(~^zä ÞΖšWNž>4?Œxˆ{ÜLzÛan2Âp›Xé3^)ñ©BÀšñbå©jaØVUϹIïÌ,‡¡6œý¯~S(žT"¹#\„ˈ'N.r—åÀ“Ég¢X7NF…b¢ÙX`ßR¥Ä´ ѼÃØ··'™”LÎë†è-ÅŽT^ýÍ™ñu>€½1ïÚÃÃly–OFÝaûK*í à!KîpEÝÙq¸’›¡UÅÜcÈðaÁA[ƹ©>ŠªÎoÒ,{ãd~EšzÂOõ;$æÚŽØ!5z‚Д‡þí»;H[6y§Áyg¢n:(âBôµ¥frûË„š ¡S3]%³ÄS™èCƒ©8Ž;7ÍœsÔUÞlªªZÃÊeT ø~Àë¸VX\|þû·ºQåÒ¶Ðñ|9Yu$¯«ò/ðÚ÷úÚI Q&]->7k³ÂB–.k¤3Mn~Ôå7óºÚq£c•ÉûGhå €.€‚]Ó~Óäjuk»ø·ºƒ·–W·õ 3ž'ªÂ6- S +0F(=8G;ŒqKkÕola»“§º7ÈÛ—ø†x‰¤~“|Ù( ¨e˜ Ööövнév'Uƒ‘Ô ÊøN J¼ïá;%õþ­fÖC=ÂÓYò.Â_³•äÌm…Ë?1¤‡çY ?f“¯šñQ—ÛÝ JÝLrßõ—¬ç®ë€O»AÅöÍ•`hÚö¡°zïÚXE›o¯õȲpˆŠ"ªðN™²÷ÇF©ãžK Ë3oj’<öy8ªo¯ûAA£D­ d6–üvÉy船L{§`ÕaÈÒÉ$=`.Ä;JEA§‡NöšTøˆß^UñHß mÇÝ Öâ“ëK¶{_ouêí +S*›™¹¹Í¡C+·9 öuôÐ7£ZË +s1@µ4)Ljƒ{ØÑ?5*õâÑè<ð góœ²z BÄ›ªè‘¾ö“€Ø1eø è‹ÅjE<µZÀ“\&¡…¦Ål )49ªkÁv5Om §r;”ávíuáÇ]§÷BX6y$§ ½k‡­FÈtÙä¢Ö=ù‹pÿa« Ñ ¿ãþŽqi´ìiƒ„ÓÄ°T9p}eW÷hTÊ×Þ‘S0^Åþ­ò8{¦˜XG¾D|áÉsÍ÷AOÇ0ƒ}Àd~žeQø /8‹ix‚§]ˆÐe›K°§?dZ n~8FF¨Ë¥‚áôñs#³´¥cØ·nß©„F,ûp#QÈ“Zh¶e= ÿXËöæiäéÖ ÛÓÇ+1© vóÙ§_jìYÂå…v<Û Áœ¨½)¿UKЈ+’ð< êú›öá ° Z3,?Ëè•v§AtÄX~‚ÈôEwš~ÐðØHT)æ&zñÎÝûlEë^ÂÑP¨ºÉ9×”Ý(¯ìëö ¡NVEßn¨²”QGP‹¬À7êË /.þû›«Ò˜êIÕ$AçÒɇl˜g‘M"ïá$”!¹)ŽÂÇ,Âáæ¾ÛöT%ÛÜñÂþ>‰ë½ ±¤‚=¯Œ lW.á_æõæþB†XÀy߃A9¥ÇDqGl9õÇn€[°þgÃ%Ô6yíæÝQj»Ú"ÍÂÞ@²@êƒòH ~N·ÜÞ)56OI€¿?1š'©„Ðltœ÷"Þk}BwChh½}œ÷QxÅá.z@Œ™{È\e,à+¹Òbe²úŽ Ó£Pâ†ð˜± ¸AËœa^2½vêú„(ÚÇ[|aš™Œ +[Q†ÇvGç!ß&¿æJƒáÛrËÌGsHy!üÉ­RmØ/· < +±Pª¯?ûL½uÆ$¥¦'<ܾ©ÁTf.`­¦rÛBH‡&Fâh»R–3Ú€ÀNpz¯Òùs³ \õ:’ºdØ`‘j·{ù18æ c1;¶×ÄYL™1Üڧ&f³ŽÝ3y“åbFmx Ù'—#Šû3áÏÑ½É ü Yìš'*#ySåq9¢¼¿t Gç(zhïäþݵtÜ‘¸¨qLû#FßÊÀ”¢Ód·Ê,”£p™&§5°ÈB¦QX·€rb‹^c‹,×›‰ +²pë¿Â­4ÜÂòõNîdᎩ*nýËÙK¹Ïâ[6]Å1HI|¨÷à€¢.\‘dŸª’EÕ!æ¿;%´Ú ó©û—A›ªtÅÚ”çÀÉÞo¯•y™äSuiÖ³"NîÄÌ2Ro­µî‰¾üØ>Óß#Ó-Ϭ±‚?ž¿'ÀðÍ•ä7^–dÏÀ}8=<ÀJÈñWû‡·¤Ô½°Žé A Üp)a|áa°5Ö! œÊ2>hÈhe“†*ƒk$W{3•–EMY2ƒ<{J¹•²´ Ž’fÉï»±¾Ý½@P• 9ayóHf*ÛEКMC ÁzH¤u&j~D¾mõ‘lòMòÇí â*“C7Æk\ȃô~x‰uªA¨nÃ:*~R³·>ÕLóEÙöÂ,èõJˆ¬e—hGl1³³$*•™œi”o’cW,Ý=¶ý„*E¥œvasBœc>GY|Å72²Aœ£¬»öNŸô* ¡¶]ß7"·F“¼•zaù°r +³`Œ©¡’† ZhÇB\é&À_@»W†,ð䫵GÛòyZFãú׫›Ì +¶e %ˆÔ™¹ûÍÈ• :ê_qÇ&ŸÁ¿Ò §«ª\«Õûú»†ô¯Ýý ½“S˜HÚµ6>¨ã,è%·]NR ÒÎY YKbÌØÇfÊw[:^Ìø—ã®I¡é[úùŠL[`~¤)CY2æ=+Ø$T¿çÌð¦K^>œ1윕fVàh÷á3× > +`ÿÐîe’ŽÂ'…ý§kežZ¥DÈ.)ìS-È+¬Pš*×Ú±,¿þâbsfÜ&­¼û[›…ÀŒŒ0Qäb˜GÇ…ê3fµ"ñ±»Tzþ?.-gð÷E¨,ÿÛq¢6à:ñ¹Ò¼¸Dø¢`=<¢6l™XœÜ¶-cýö+\6C,` ­6Ý},°ÐR/CÇõž–ä¡õ‹ð6„¦EÐг¸žCV>mðN1`-dnC LOêô?Û-“?]CÎøY.í"n"5,à ‘)…8‡)–e7[ %7ö +´°%™s5lQœòrYx³–èZ,–"¾p¹ › ?¦¯9~œ9ƒË!`€Ýç¨R9r@ø:ÇìüšŽMö½®æ4~@K`^!ÌAòl)±ôÊOmw¸³L¼8³h®œ@/ªokÆÄ“›öš÷*ÖÜBÝ6àÚúW ’¹é8ag*Ƙ°³Y̸9ëÖìA,gêŒaa÷Nóч—Kê´ y +cÐ1ŠˆÙ›Gù6¤¾ýôf )J²ý»€'Ú^çÑNï»a‡ÒÔ@©õ=-› +[w®ÌÞ‹I `3¢&"ÚBSݨ±SñšÈiHÅÜ—h#ScÞɦږŶšƒ> ¦Ðm›ah†Îq%‚«ÂqUHnÈoÆî†K5%‰»ø&èb'l1´}`‹)Í4ÙàÅʘÐá H´Ý®{½Þ-?ZÄ>†Ó(ï³¼i,‹¯Ù ®Æ±Å%fH1ë̾)d4lcˆœKgËÂËY€xaÁëOt›uê¥K{™W­ú­Æ„mˆû¢}êuB¹OIé”/j®ñŒg/ò$ÄYú«2ÔΗêSh‘úP1eæŠÞî‹Ãv'¨©ÀœFMâØŒ¾µÚœ ò¿˜z` r~™plT¯²=÷¢€çù1ëýG°43ö"–ê€etÉËÀPøAþ×V`–wK³ÞÿeÞV—} +€½æºW!Xá³)CÎKÛfœÓ0`•Ô#¨R‰Ž»¢ñ&4RB‡.lø¡ì±71ï jæ‹*xÞ„¶²“òxüíÕW{6Ý®|µ'\DŽâ¦{ÖUþ•1$Ÿ÷ÝÐÛ]½«|¤p“ÇÛh»®GLÄ3‘-kÓn…¦uPäíño©ìŠT)Öðk91Š¦Ðpî…)ˆ² ¯tóÂ,Vr[*6.Àck*ä?šÙQøÓ`ûúY\X­­^yµÔÐh\´èú£ºÃØØ´šì&–#þpÐÀ¥XVš†zßè=*¤ÊàÅ¡~ /ØœÖC"](¸þÉ¿ÉF¾Z,á°_ +9ŒZg÷¢VÃÒØ4}g\5(ÿ¿¤oP;€Äú6IùŒ›)¼zDôHYr³_ƒ›) +é;¨ÏQ¦ÓÉZ63ëôîÙE ®Ö†°)krA²…Clóýü"¹œ–S" +Ùl­,ðµòfÛ„2à„oi5qõkUtŽáS²Ù„[2FÒüðØÞ¶cìßuÏš|È3¾ÖŸ + #S7©cÁÚHG°[ »šþiáÇ.ãØMï2ùùÔ>uë8Lt¼È}T€cÓS¹:kyh¡Íå”y•áQÀàNÝî”îa¯֒À€lb©`æ«Ö¾z­dè \Õýä/vZÎ1²þÎC|ÊsÇlÑâ+©'!þu"Ù,Žïë—XeN÷2`8²P-’YwÒRêU/hÚá´¿Õ‚˜çË,ÑæTÜÚ¶ýöÔŽ¡A¼ä>Fé‰S‹e(´áxÄ £ñéE6ªo×­s‡ö}_!ôNû½@Á5þFã@Ñ—Õb§ôwÝ)y'xsvä“ã~óD¾d³ÌÍaùB¯W¹"ÃV-f”IÿÕ›záUyÁ¸”áÒŸerYŠ<Á˜jŠÉC²á–0Ÿ8;íØG–Yk,1)ÝžºÝS¸u K…Tò`Sµ! iþzA¬ËW)™Y!!¢åßgÙ`I“&³.ªÚlv§…‡C +SM™tè|,ç1=€î¥jù+õÖ!¹$—°¡Ú-sYH‹P‹) +=€ò‘\™ª²Yfy6}†ÔmZUùl_™föRþ,ä‹çc\,Jp#´ÝYãÛÀ1™Ë’ˆƒ†Ç!Ü/X2;?Å1çÎxR‚äPŒfw]—×V)‡Wy3öZ.&ã1ôVßTÚŽˆTãä˜È‚—<¬BnûòsY¸Q(â´(åÞѱs‡F©dÍ\n&«zPgÙ¦i²ŠI-üʲËS󢧲IF|ätn>¸`óL´Ûô\2ŽÆ¯s­j ìlºìÒuÌ¢„F*Ç8;p¼áٽࢠí^.›ü"ÀÖ('Æ™ŽÇÚèœÕ¾¥A]YÐ5‡i„T `‘“×^ +çÙ¤}Š•öu”µ,v\bß¡ã‘œ Êøœr_æ# +jÆa“÷YÄâ‚åK5y¯ž?2_ÒÃúâBŽíL>»0ÌÈ÷Ùв2”TÚ´,äöûS­]*ûZûžðÀúï7ÉWï”M2MJÿy9Åâyû‚.ñî¸ýž©$†ƒ»®Ü3°ÁǼ™²°4ëAÀ3í2‡ÆxÊKhŒùx6tª3|ûæöå#‰!XPq-c¥Å_ïÌ[ +Rì)?¶ÛGTà ØÄçØÍ;¥1Q[Õ=;mts9CºŠ<ÓxÇi_ˆ>ô9xqy$ìò¢ ä ¯4r¨wìfcƒé[ßqó=Pm•ï"c’Oì«G±íªôÅÌ܈—ç’×™ ãÛ+Jç–X´ÞÍdZºÐŽ¤© m¿G·¹F¼å¢•P£êØhN^O;jòé,ln—Ïf‚wÍìÌtðËcÇ#–Q…*çF<÷-¤쵊…ýkÎAro”äå‚0{ªlõ¹ØÀ2'FB'`,ú¯[ +Mb 7,¤ÿû!t™M½—Á®*L¸iWý^jôÚat¦ßQ8ZêÌÍDG-;FtÔæZø˜•’?•‹Þ•Zí† Ïâ×ÇÂÄÝT>.‰pV1Ì”É*—a«Ò¶2Ÿ:0½à¤:¨lh³*%ÔºA[ïæ¢r`Ùýа5I{©ž Tmdžø9 +mQFëæ¬ëLusWÄî íªšbë4²î%> cŒeS¶Dí 8iHc˜–C"‰]:ˆm˜ùL1‘ÕãeìøðÁhC3ˆvø, Î:Õ/ÞXd¤Iÿ¦-¹6µåÇ|±³15kÜG}1«c>ñ­¥—iwšG÷S&óZ{›mr× Çvlôn¡¾‰ç\Cq˜GyWYö, ¦* ÖV« +Ã?Š˜Šì'ÄÄ#>È£h>ۼ纽åÚgö†ë¹¢Ð9˜©èÉ£œýñùR{yˆjÖð,–Ä_ ë•gÉ#4¼¡'7¶ÿ³$v뱜ÿ©èG>×­š2¦rJkÙ!¤Y,Ë3Óü!ј—ÿˆÎÄU?¹tVQ×%»Œ½Tyåbê7gÎþ¬è¨Ï‚,m 'ÕÔ”’.¨ºàL> £Ã'Ãã¡8ŠTrïBS6*Ÿ±wÚóˆmèv6Þ/’2x¡dRfëµYì€V¡k-Œ–JÏ}ÙîC\´Ð°eg>;Àdìy‘Ü0U¨ >³a™!ÅfT 9+K—û M +VÏB…¼ ÑŸâN½7—y ÖÞxúU³csɆG$˜•ÏåJìÍ/3÷ÚÅ"ˆ˜> +DãvË…‚<4јΛ|Ø€`íܾÀyæl\[æ> kû¶¼kGàšSiø%MB!‰MB¬™kŸñ Ë_´·Å_È•²þrž ]Õdª>Í™0— ê^þ÷Æ‹*_M˜ÿñ„nãgÃëx” îè«é r‘ÇCH»µÉ4‡¨þ´Šp¹ÅïŠiLèÛÍŠêÍØ[é[(¨¯¿üû˜ý쬆Êüê§ì:{ÑÖ5“ü§Ð†NåùùysÜuÃöŠ4Y^EÚ¦ëÑ'ãxˆ¹¸º©\…³¤¿«'MƒQGó438Å€­ŸünwÚ³cAX–â÷ð€©°%_ Nṯ¯eóûM–¦…É´Mé×ï?ùW)Ý» +endstream endobj 7 0 obj<> endobj 8 0 obj<>/XObject<>/ProcSet[/PDF/Text/ImageC]/ExtGState<>>> endobj 9 0 obj<>stream +hÞœZÉrãF½ë+t™pF„QPð­7íðÒ¶¾´ú’ 7Ð(ZŽ‰ùŒùÞÉ—YÅÅ-M8&Ñ µdåòòeB_üóV]oÆ«×wW_|•_«ë»õ•OË<7×ýO3gܵ*ò´4>¿¾Û^e$M7ÕCµœš¾gs£UZ&‹z:Ôu‡Ÿ6uÉ×ßãr©Iî“ÙÇ»oé`eäd¥R–ö½{{• ³»_ñRËËÔ¹L…Wÿ¯²°.ÍH¾ð. ïTXfËÒ…W_^.£Ã\^VÞåŸïø!¹Ä:-’Ûýn×ÖÛº›ªá 7*R›|ÕlöC_&õÉ­}}?»á‹Í]¸4æz®Rå}!›-ûnÝ Û¦ÛÌæÚ*RIß-i¹6Ž–W›ªéð#Oódz¨&<z–Ñ"é÷, ­‡j[úá¿¡ÝP¯Ö>oTËåžÌÑÔ#Ës÷w:¾Q-é¿ë'1EžTÓt™ñ¡®Œ–4J¢Žõoûšå3ÊCÖ5ž +zšj1q‘tûí‚Wñ§)뺚H5c_Ý6Û¦­†öéæ$Ðz?ÐV´Úæ9­©Ÿênä+XW’F°u¢Ž³2Üö«ºÅ•,žð¾ û4ݲ݇¥¹ ÂÊÒŸx5¿­›/ª±^ÎÞÔ.A“5Lêe¹ÉuÒÖu _Í‹T‘®û-=“D:ùà²<‡6î‡ø´Ý·SóX M5…=óäëfµb×'¡óäûjøÔ?žNÿ—"Í-9‹N–tN5ÁØ6ÃƉ¶åWA'«§?⧧Ÿ"”ÍJz&¼ûáÍoßÉ€¡¹æãé¬U³bu‘ØìÐÜØlºfÝ,«nj¡DºF™4ÛÝÐ?ÖòóÒ¥0b¢S±Ö-ø,ŠÉ%èöêÅ(ÎíóQœ–eùÄp¡âªBÿ)†­³ªn…—síRE÷¸ ÉU5qdä3gA1>ô‡î~–F¼º«>±1 ¦T2õ›~{#Ábá#‡INÖ O"wãNMGJ¿ ×*6ÞùäÍë÷çáIrÎFô1R:m%dƾբųÉè|þ?GÌ®eÐpÚ“ m³y`ƒ:$EŽ!ËáMt.æ\ÀeÃ0‹ãÄ‚ú(‹8s@„HÄ ·?¼ÂPFÖê]‹«…Y†dœšnpz¾6p×q¿ÙÔã$°çèVÒ6Ay²çtèeœ\´žÎ”9óL#²à·¥ß„T“è „êvÕ05U %Ä÷ÛsàÎ3h¦éÖý° ²cž î6Øà[üÚ7'†.S&Ëj V7<Ô˜ÆXÇa{ÓÚâ,Š %ZB°Ðåss. ðŠ¬,)^rŸZc9Û~HîH)9ùÙÐï7ØNpÐØŒ]µOcŸ³Š-óXW `F°|»˜Í=é½éª˜  Ã+ÊZi%ñÐŒ´¢2º ãtZ3›Ã.ë`sÚD—0àC5,ú¡‘%Eó— +¨Ø³ÁKhæÓ>Ä +á-bìJjcSœÄÉ*XœjA—G®Ý#lÈS½ø Ý›Üòèƒt8Ò#8B„ጢó òaærzOæ#XS¢ó¯k +Žg²².,{˜e¬Ü’4È3 /oV4‘$‘i!Ua’O¾«Æ™¢Ä +Ÿ¦T¢¡Å™ÂÕa9˜£‘„,9ìÅñT€@@ŠlÞ=DTnÉË›™¢‡;z +! ¥€¸"%ß1ô€ŸÍ8ײår°¢-m®6SHÌØl‰8ÑîJpÒxP‚-=ŒF?:HO±Þ>ý1S`"@œÌÁQxªÂ=±3"êô–’ D@%V$ʲYhzØô,]-ã*`cÍÑh!ÚØ@Çã8Š’غ©q”¡Õ4#¿Ô:‡’B–Æ Ž±„[$j/>EN7⛶št¼XàRžÈnð¹Ä÷ÉWŒaª¶\bH'Ð&ëuÉT ´‡ <à/¦)x‹›¹•D1 *僆y9b›Û‘ëʾdCámðW-î–‘ºü¦Ç+lkÞ“LÃ<3î3!ÌáJëç\ÁåyW0Z`PËsH0É¢’XÍý–I½d÷.hæsÕcÅ$mV ¬bxΑ×ÌÚ²å1:oιÒZ$~Åñ$ÝĘüU»Ý ŽÑ“àPrD&S¼%ò«f^´8²Üú hm!;=U`óMÝsxÔ"É44ÐKšàa!2Ü„ô0±B)ª›Nð‚IŒ‡Ó7,—Jvý(‘‰{+á8ª8G;ã)÷í^¡ 6ô Ib=8=Ì »–¿Œ)´%$€9fåuÈ + Ç;Ü¢á <™Ÿõ4ÍX=R,‘ æä4B^2ˆòÁ:l©“P¯Ê(ï²ò3˜t"®'×TÌÎñŠE_Õ;#tZñ| u­$`Õ2`Pä žjv+böeDƒwwW¿]YhÇjNPTm§%UÜ\‚ÛkàÊÜõr{õÅ7[uý¶¿úIŠ÷À¯i¯"“¥á1ïsJo^R[,Z-Wu*Ånt»|¨A‰–RcX$W²ˆ$…À‘5ZuLç–£Ÿ Ó?ËP#5ª˜—+U«A)8‡Y2P’^r`ø”Y‘6q9Â1±ë\*rÉsà¼lR°ñ©ò¼`[.™Ïb)qŸ¼ºŸqUÇá^D<Ž.T‘Ø[*/§¡âĉèDI¤ +rѵü(ƒ6²âB¦ô\E†ŠúÎ2acôy¢1胰ûX)5¡¶™Ô[wýÏ7²ž2v»¯ãÁtRMbiË âŒUÔ#ù©eÚ¨$ÌÞ£dÂh3XòX×yÑ3i–±¬[_–ad›Â—ìváÑ0(“—Äg)®¼+àw‰Â²Ï}Ô’—[¸k. +bd˜|ΰ± +¤¤*ÇÓ…¶Ó‡$Mg(Ï£O!¢Ña27¨âfþX6fæü*Ÿ_€ +âåâlc^Œ60P•]Þäñd“ .OÂÔ(¿•ª4—ž·ªUÃà` +Ãl»ml ‰ÈåTu›¶alS0õPGþmOT +rsÉwì¡FÒb`¥ŒD^ÑOܸ)l(ï䈊ћöRÂlòi!8ýîÒ$·SäÕhù‰pÈ^Ìox^#™ýîöVv†WIA]cï8Ey},˜%T +ÃÂìö!ÏÛX {”»äÈCó{LL +x?WëgiÂæ{Ÿ,úiâîwDÖúsœh, +g=4èáI)ý=,AiSûAv—tò’V Hº8‘éøé' +Æ.”{Ÿ¼fgÉ@—Þ Þçè3î%×1tÍ•_É}vˆ•´ÀÐqØÏ2Ø>ÿþöl‹¯BM>Âd(§Öû.~Å)‹øE%Ó¢Ø8ê;­†æxËTaWbrRÇÚœlûÍ ÁŽ´”™¿Øeʪ¿îÈvEiòk¸qŒw°F!mæH´ŽôÚË|aË¢Œùâ~õì[ÉPœ%T¨ÖE¤6ÌÙñFùåDë(äÄ¿‚Öj!sªž48Ù…‘ÓM Ö±<ÙøX裸ËHW࢕ëÕ†Â5ŦœXÑÊãvä†ý ^âv %œ— +ã†OEЀ¸ßDÚ÷0yl³Ýoe¹“ø ú=¼) +ÆósVCuè„u˜³3WÕø ²¸p(wxJ4l_Eâ@£’‡[Xž›'4íÔTÄ\8&+‰Ô“ &! xd|0Œ0Â}G‰D}Ž@…:Fh¨Ï¾þd:Þ}Š\©è>áS¥FYlWDำp„|ò“Ö<Ê·æ1„¸b&ø¹`«DŸThcˆoŠ +iŒ×m*‡ùHTÔ%#„2¼|ÐÊ;!óñs{)º¹).Xl¤3™„ZËÅ%ò~F¨†pÇâ¼ú€ÊÏ@Ÿï×Ö¤›U*& ¤úÃ~ò^´$ +E™Nn2îGÑù ÀÌiü¯s°+Å•—¢½Ž½ Ùßq7šžtï|,ðÆXãóØEìÛ¾Ÿd¹âæ[Ëê崴‡èé)6ëF[€ÕB¼]ÛO©¼Sò)WޔϹ”Ðt<G\É|s$™Üëëeß­æÜ°V|ÍÙŸVHÓŒ¹ïø¸B.ßY,€ÿñëâçèo‰+MÚd”ûJFñD¿P¡ƒ‡¾Öš¤ô>|!¹GwÉæy$|¶ Þóè¬&ÃfäÞåtþ²™[÷ÌéL&Þβ„]Õq©Ö­BqM€V^Â=KÄõþgÌW#§‘64Íδ9ÉC€ä^ª÷©Žõø^¤ñ&“&Á?.‘Ê‘ò"Rëäž¹À;f þÇ QJÅÿ|ƒcÚ„˜.Tò¾®†‘gæJ€©1•k.<ëõºYrA!âÇP”É(Ck™h% Ä/M§ÏÔØö,þþ\®ÜH=§¤~fÈe/ˆð”£ñ‹·xóßós˜nF‚K&ðê‚à&‹†"bꇋö!ÚRÄ6ÞÓŸþÂàÄ+â_øÓõDLøý%:HÅ$]é,V}ó%)SQ53㯜_üÚjÓÝrѤ<è:MÉ ‘(¾”¥-m¯zžÎç­~âÍ„ ¯¤¿‰ÅVpD +™ÓßÒŸò½S£øó9†þÈw"·óxàM‡"žøþ»oå3Q‘¼é·»PÝs¢×@æ× aßÖÁ4ä_øF‡û‡”°n\Š#ÑÒÍLû„¤Œd`gó2/‘]¿­º}øÓ(@“&R‰ïy aÇ éÛý]GžF“¿*òËÌö›qä¦f‰†’’eê´¾V¢âØ0ÿ¯¹ à +endstream endobj 10 0 obj<> endobj 11 0 obj<>stream +hÞTP»nÃ0 ÜõStmt4¼äxèµ›]‘hW@M ´<øï+)N‚ <€GîH¹o-Ùò‹î0À`É0ÎnapÁÑ”«ÃÖeÔ“ò £¸[ç€SKƒƒºò;çÀ+ìNåÛkñò“ ²¥v}ùsŽD·xÿ‡R€š Bîß•ÿP‚̺Ù¯¡Ê}¹Y;ƒ³WYшPWØ\É<ÏnŠË ‹ëfQTÇFÄÝMªtÌ=^˜c¸|qŽÌ-áý)Þùä•Jü 0fdi` +endstream endobj 12 0 obj<>stream +hÞbd`ad`ddò ðò ðÑvL) 0q6q5µ‰ŠþæËùÝ÷«ægëyþ+‚Ýßy…@ÜHꀀ‘Ÿ™‘‘IH‹ïû¢ï³¾ÿmXñ»Ärj.+ˆr@tEñâ¼¼ââ¼¼ÅÅ+V,^¼BŽ ÀªÅ'c +endstream endobj 13 0 obj<> endobj 14 0 obj<>stream +hÞìÛO«+ÇÁ'àûÄlf˜Í+È:AÙ½Œ ÖÖÆzg6Yi“¥ !Ûƒ÷?€£p Z_o´t6ƒ áÞ…!Èp `4' ƒÁp¦¸‹vWÿÓ¿sԭ硸Ü#u—ZUÝ­î_U?>p6»ÝîEƒétª}ÆêîîîÅ æo-—Ëõz½ßïµ'À¥…K¯–˳ív«‰FéÄ<¿"Ü]Jõ.'ÏóÉdÒ~=¦•Fé¼y~n0×뵆¸„p¡Õy=–繆Ÿ³çù‘>À%ÌçóÎ+±,Ë4Àø\(϶ۭæ8£ý~ßç2l:j+€ñ¹\žïFà¼V«•™7«)ÏŸN§ó.7’ëõZ œK¸Bë™ç/—KÍ02My~x½ÏêÛív6›5ÝH. - p›Íæ ‡%ó<×hcrbž„[ŦH:ja€³X,µW\MWbY–i4€19=Ïl-¦…N—çyíµÖd2Ùï÷fVÜ‚³äù<àr²,«½ÖZ­Váݦ)úÛíVÓŒÆEóüÉd¢…N×”Øïv»ðîz½®}w¹\j:€Ñ8Kžn$k+Y,ZàDM×ZÓé´X Ïó¦‡%Ã[`Î’ç/—ËÚJÖëµ8QÓµV–e-À žç7Õ'ŒpŠÉdR{¹µßïã2ÛíÖ%À¸5¥ñËårÛj½^¯V«p‡Øôp÷f³Ñ¼' +]µ×Zóù¼²dÓ…Y¸rÓŒ#ДçŸh¹\j[€ÓÍçóÚË­õz]Y²ež†fKäù¡N pºý~ßtÅ•çù) 08çÍó'“I:U €ã:å¾i2–e`è.1?±Xì÷{m p¢étZ{¹µÙlj—_¯×µË‡z4&ÀÐ]"Ï7 àtÛí¶é‰È¦Uò<ïÖ®jÓ¤ƒv¹¿kn$Ã2³Ù¬=Òoz€yž7]_ív»–›fõ¡N 0\My~ÿ©õáÆ0,Üôd÷t:ÕȇZ¯×gv2Ô©a†ëô<¿°ÛíÜ9œKçSGujX€á:WžßRÕb±ÐÎýµÌ”8Q¨Yó Ôóüý~_[Õt:ÕÎý­V« åùËåRó Ôóü éÎQ;ô7™L.”燚ó<×ÂC$ϸ*ëõúÅ%…ú52À1Ïßívò|€-‹Ú ªét:?DX¾¶žÙl¦‘†èŒy~Ó½g¸ÔÎ}ì÷û¦ ›Íæ ªZæZ„·45Ààœ+Ïϲ¬é†qµZig€>š®©&“ɵ5MÑ_.—š`pNÌó·Ûíz½žÏç/š™ÐÓyø–Ñ<ϵ6À°4åùç2ŸÏ52@Ûíö¼$ò@OËå²ö‚j:]çb±¨­s6›ip€a¹hž*×Â}äy>™LÎ~MµÙlÌ»‡ËåùËåRóô´^¯›.«öûý)57 ¸Z–Käùáž1Ë2m Ðßl6«½² +¯ŸXójµjºfËó\Ë ÅyóüpWnOœBpkò<Ÿ7Øl6'V¾Ûíš*ßn·`(Öëõü«Õêî­,Ë­¢ö §‡‡Wîó,ûòåKí×ìÍë׿úégŸ|ª)àš½÷λ¿úé‡ïðæõk­WÎ5cuÿÕ«WÚ€ýâ‹_ýÇ´(ŸgÙÃÃ6«õáûx f¬Þ{çÝpÖ4¹¿¿y~(ï½ó®9¢pµ¾|ù²x &¹Zcd>ϲй¿ûècãª4ùÝG—#ý"PúÛ×_k¸6ÅAúÛ_ÿæ¯_|¡AÆ$Ž®†ÎýòåK @ª˜ñ›©>\¡?þþñ ýðýÞ¼~­MF#thù ì) €‘ùêÕ«ß}ôq,ŸgÙ¡å³O>­Íó¥úp!á ‹Çì¡3±Ã!_9Hÿò§? ~¯Ä›×¯Ë'äCWOGWîòðð aÆáó,kIãÏU>|ÿƒCSG Éï>ú8\á>tõßþú7•#4¼êü>»¿}ýu¹_]=ô`zúÕ¹£ñ4y~Œ•L…Ó˜çÿåOn:B¿ÏëÄ\ÔEóüPù—/_jägqézïwÃZùÓŸ4&‚Á‘ç•2-ÄG08òü±rB …øGž?VNÈ´ÁàÈóÇÊ €â#yþX9!ÐB|ƒ#Ï+'dZˆ`päùcå„ @ ñ Ž<¬œ®ÄÝÝÝ‹·¶Ûíõl•øèP¡ûŠ~ ª5xòü±rBnÙ~¿ß6Ëó¼iÅÍfs÷Öz½•t~Ðn·+–ϲ,ü¿vyþÑBOµôcKõé—Ê–,Viê&y>ÏNž?Vò|à–ŽVm`»Ùl¦ÓieÉÕjÕô»Ýn>ŸW–¯¤ƒòü£Å½Vm®Þ¿_ +áõårYY>ì é(€<Ÿg'Ï+y>pËÒD·=Ï_¯×åì7˜L&ÅŸËå2­·ÛÅf³YX>Ž„?+ѱ<ÿhíã2i®~P¿<¾ óÃë1ÃËÇ?C=•H_žÏ³“ç•<¸eEžß3wÝív1òÝï÷Å‹å¤w½^——o)ñd2)Gôqšwe@ž´¢éBoöYøÐ~ ‹EñVVŠFãàN¨­¼°<Ÿg'Ï+y>pËŠÜu³ÙôY8Næ¯ÌÇÎó¼˜ì]Éuc>Ÿ%yZ¬*Ž <Êóëõ:´I¹‰Ú»fµZõ©öÐ~‰ùüb±hªª<”#ÏçÙÉóÇJžܬ<Ïûççûý¾iòv°Z­Ò¨¿˜^ ù ›Í&”kóüíÏúja3ŠµÂw<±•ž1>*Òõ>ß½xD¢g~~h¿ÄyûéÈBÜ…ÊQmž\„O,Öê3¨‘<¬äùÀÍŠ¹kŸ…³,k™ÌŸF¸»Ý®x¥iÒxñî|>¯”óü<ÏÊŴÿBøX MƒãGo…eÊk§¤úƒÈóûËÑ/E{Îf³–,ïE•!ì9ÅB¹Gjóùòþ­¬>¨ò`4‘ç•<¸Yëõºižvj±X”cóT%nÏÿërà˜ç‡UŠ ç©ðzebzܲÖd29: +¾þ:Ñgû¡ýÒ™ÿ§OU”óü8·¿Ot®„Ö‘K'yþXÉó€›U$±“ÉdþÖb±¯4åÞEÌnª­˜Mgqǘ·©Â˜ÙÆ|>®RTUž¿Ùlâ¬ûJ°Óã"Ìß"ÆÚá£c:Ý4½¼Óõçù±æ? M××Ú/±ò¬!-F…Êq•¢+=Ç\Ò)÷cø7~ñ°zèô8ÐgØ‚'Ï+y>Àà„ÛÀí/¥ÚpǺMq·ê wµáF8¦ñþ:܇6ÝY× +ŸnœÃ-pyªa¹´„-íMV «Ç<$V¶Íì•¡i2êYv¶güŽa»ûY9l9ñ@†¢itøihš;§ß§*óºÓé÷é¼îøJí4ìp:Š?aåSSLƒðÒŠ¿¤ÇMí¾þäùc%ÏœKäù-3Øû$ÛMÉl6+f/—ŸyoÏáËSéÊâDè¦í,ϻ묭¼m§¤ã6Ö Ô)y~LMÓ¸eît1\~bŠ?ãÏPíÔciÐ9ÏóÊ*-gÝ4Žî“÷©¹Épóüø8C¹×í—ؼMóÂë•YG÷Hgžß§fx”ç—<`p.‘ç7MW.¢Î2ôߤÅbQ¹GÞívéb•H$|Pšü‡ÛÕÊ„›åtƒÓq‡Ú‡BýY–•+ ÿ·áµ#1ݽMcÍóÓOO;:ìw%éw—çÃ-H“ÕÎyÝ•U:#ô´Â[Îó[¾ì)¿AG4re•ÎæM+”çóìäùc%Ïœ³çùiî] ·›f£Ei˜ßãËQj´f wiòþìü¬°LSD¿ßïÓ1‚–»é[p;yþ釡PF)ýQ‹lí¯Iü=ç„xÂiú9+~ËÊ?7}R÷b­øÀc¿Œ7|‘£Oz#ÈóË× GôKûNÚ¶õHyšAçHØæ³ÿ.3Jòü±’ç ÎÙóüøPy ½ã fg>ÿX—Ž¶Ü`¦cåÁ‚bôùjñ~6*?þè|ûÚùü•§ Ú…ûñmIü¸PIøjóŸ…ÿWª-žQ,°Z­6›MŸO õ„Ãò±òPIh™þO´lÛAÝV ûIQIøOø³eú'êEË”¿`gåíûjî9±Ëb¢ê/wel“ðŸâ•ÙlVy<¤ÒéÀÐ¥á|ùÅp^JW©âÓì=ª|c%MQsí6ĪZ~²[¶¤Ó óü4œ?¢_j³÷BœcPþˆ£{¤i–BŸ-2yþXÉóçìy~e¢ûr¹\¯×•h¹gL³Ùö,zþKíy~Ëçîv»JUå(5­*|¯Î¦¨ m:ïºÒÅ}ýjµzQ'~ñðŸJÄÕ[¾þ~¿O·¶²z{ú*oª¡ÈˆúäùE/4mÃl6«]«Ož6¯©é +Óé´ç¨Gô¢KÜÚ¦é÷é~噫˜šVÆ銇¹Ây»rŠo…˯Ç3mz>ŒQäç™J=éZå +ËçÕÚÅXíqÏ 7Ïc¸•ñ‘Cû%^¥ ?¢|ISî‘Ú¹q­J…í(ÆjýÜÐIž?Vò|€Á9ož¿ÙlÒ4>Ïó–Yôi6{ô=f–;Ô¶RŸ‰Óéýƒ¾Kšç·'Ò¡©Ó¡“J^é‡í¬h5¨ÕVf˜§Ãy~ûÆ·lCgžß¹y ÓDò| "œNk³ÖxLO2ñÔWy+®R9éÅçÅ*§ô¦zÊç™ðVåW ¾[9۔ϫáƒ*_*~V: ÑÓ•çùÅóqéëñ‹§ƒ#‡öËci(§|E‘+ÑÞ#ñÝ´GâZá­Ê—*ÿúŸòÀ7Bž?Vò|€Á9ož_‰mãóÝqrZçÓâu1i¸«Í²¬6$i‘ƼEdn®ÍÒíé¹bq·~\óV¶¿3rO?«iª|Yÿ0¿%Òo™Tß™uz†ùµÛЙç´y-ƒM;ª<n\ñ#8›ÍÂÉöî­ðŸxŽmT§ˆp/ÖŠ¯Ôžâ©#Ô\|PüñMãÜbáðÑÅqøˆ¸mq 3¬Õ”ÇeÂGT¶íE×t-®<Ï/~’B[ÅoÄÙJ\¿<þòÇ«ø òÞRÙ¸pñ)a±¸måK¬´Gâ®UÔ¾~±Vù‚-½6€”<¬äùƒsÆÀàœ1ÏOoùã i|=Êšojsì–l¿e“:ç?—ãÓ¦Ûít{úßü¦Ðÿ‘öôs+Ï5Ôå†Íó<Í«ËADÚei|”~J¦)¤QI¡ÓĻҕVJ§>¦ÛYžLØžçW>=‹I¿`Ӟг›:²tÿé\Šp)†\ço…ÿô|¾,œLÂùªX+œâ:,Ba±bù°bÓð_1nß –×jú -çù•Ï +ßèˆÇÜ*ž1> +_omiÞÐq±GÚ¯Žè—(´dø òÞRÛ¶¡Úbœ·ügŸ)ÿö•?+8âÉGn™<¬äùƒsÆ<¿2ñ¯2¼’ú†?[ªª Ø$|P¸«mº“­ “›L§ÓôÖûzòü4I¨ÌµKç–§-YÞ€J§„Õk›1ÒKGj*i!¥_ތʷ¨M?ÒÌ¿¥¡ZöðÚ¾«l^vÈ]ª<ŸJžvâ£'Ó4– ‡’ç•2Ààœ+ÏÏó¼=×MgA·Ï +Ûn·iÜÅ7Mœ ]ûŒyËtýr¬}=y~g÷•g­7U7 ÿC¡a›fà÷œÜž.7£Rye(J·6~ÐAy~¨?Ǫږ4_QžœÅß¾þúó,+Ê—/_>ïÆÈó{ +={-|©+ÜBy>ç"Ï+y>Ààœ+ÏOço6›òýÓã²ív»\.{û“ɤi–~±…‹Å¢g°_¾óPžŸnXKž:¨O_¨´[8ÿé³ÿ¤#M›úú®AÓÖÞPéŠñ ‘°ña¯hùÖOÖMò|àó,‹qÊï>úøy7FžßÓõ'œò|ngoç8ò|€Á9Wž?›Í:gYW–™N¸bÜívëõº3Û¯<Pk»ÝfYÖ™íÇ)èéHDX·çf‡%z*¡²ÍóÓ »ÿ~“¦×Sý7£§øeÛ*Ïó>ƒ8¡§*#POÙMò|@ž?Dò|n‡<¬äùƒs–O.¤­7#´aå­PgZCøÄÊqZ*}«v¸!ýOÜMò|@ž?DNn‡½}¬äùƒS´ö£ìJ&\NÔkµÏ…NÓÑ°@S¤^oÉÌÓ:lj:Cûñm¤¼\.+ ¯V«ö +>.#Øï÷iø_ Òûx‚íÙÞPµV´mOÐMM‡aùQ`ÜäùC$áävØÛÇJž08'æùiÛ'¸®¬þ¬,pD¤ß”™é·Ì¥?"Ò?.Ì|ª<ÿ &jj™Îþ +Ö¹=#ýétZyt¢³¡ÚÒ‹'è¦,ËäùpãäùC$áävØÛÇJž08§äùéÔît†|­4¹ UU–Ùï÷ý·- H˦N§Ó>õL&“tKRi:}܆µ{²<ÿñí,ýö& +-Óþ]Z"ý"!ï¹íãaKGú4TgÍÅwì|ºäBÝÔ4N$χÛ!Ï" '·ÃÞ>Vò|€ÁY¯×wGÙï÷›Í¦òbmH› +‹UVlJÑw»Ýjµjš^ϲ¬2[»IøˆårÙ”Z/‹Ðý'Ò‡%ÃG78´aMÂê•Vêì¾´ýÓJZ¶*ÔÚ¡ÜÚ¡¹Âw ߥOË„eBýqõÉdj‹›tèf”{*lCØ ÂÎptC›jû@ew +Úûg隸‹†¯9/9ôa`¸äùC$áävØÛÇJžÀåìv»íÏš¢Ýž¶%'¦îçÝ0n“<ˆ$œÜ{ûXÉó€èþþþó,‹¥çbåòåË—Mkýíë¯›Ö +o5­Õ´J(a3ݼs•rVöÞ;ïž½þÐ ×SþúÅåø誶í òáûÄoñ—?ýy(›ýððàÔÄ¡äùc%Ï¢žAAe±ri™¬^žÓ^)-qSÓ*E°|èæ)ÊÍ–¦c³åxi:0[Žeå¢=Ø¿üö׿)9´®rÍ¥<.Y¤Ê—/_¾|®aåûûû¦Ušf\?:µåÍë×M«„·šÖjZ¥²m®ð€±’ç+Š<_ž¯(Š¢t^n÷º®å²üÀQ¥ô¼æt…ŒÕEóüÏ>ùTž¯(ò|EQEž/Ï8ÝEóü–Û1y¾¢ÈóEQyþAM«Èó€1¬<ÿáááÐÍSy~ÿãEž¯(Š¢Èó®Ö°òü#6OQäùýy¾¢(Š"ϸZò|E‘çËóEQy>Àõ{óúu¸iŠ¥çbåòÙ'Ÿ6­ÞjZëË—/+ o6›»»»ívÛ´Êq›7”"=PäùŠ¢(Š<ÿQžpõÖëõ‹Ÿm6 Â-{óúõß¾þúôê©­ÿáá¡i•ûûûÚUÂëgÙ$¥ùêիϳLQŠ2ô1kåŒå½wÞ•çwn›k €‹úß~øß&“¢ü×bqhÐÑBgÔ2딉dÀÉóàúÉóàúýßÿú?ÿó¿ÿ¢ü¯ÿüÏß}ôñAåÍë×Ú.m>Ÿ¿øÙÝÝ€+$Ï€ë'Ï€ë'ÏžÑ~ÿãrùÝ‹ÿ¯(áÿáÍ)y>ð\v»&“ob˜_”ðŠHRò|àYl6yæe6{£} Bž<½õú_µI~,«Õ½V€2y>ðIJìûö0¿(›M®­ ’çOi¹ü®O˜ÊdòMžÿ¤Å  ÏžLÿ0¿(óù· €´Ûí¶Ûí~¿/¿(Ïž@žÿ4›½9(Ì/ÊÝÝ?µ5k·Û¥oÕ&öåÓÐ^ž\ÚÑa~Q¶ÛkCèo¿ÿ15¡ìv?hJˬV÷óù·E ÿ¿»ûgKɲtàhEö¾ÝnÓ·jûöwåùÀEív?L§?:Ì%¬žç?iIh±ßÿ¸^ÿk¹ü®r¸ÍçßJõ Yöý‰'¢Í&׌Jž Ån÷ÃdòÍ)ZQ‹hLH¯,û>íGYx׈Øf“Ÿ~"ò¸G烰Ýþû,a~Q²ì{M +=3üJY.¿»ñv;ñ)¡ò,};!‘ç?¯Í&_,þ1ŸÊrùÝ~ÿ£6Ôzý¯žùØlöf·û!PK†Å4,7(üÐÜÝýóÐ ßásÄé¨O }aŸ ?yþ3Z.¿«Ü×O&߸µ‡ŠƒÂü<ÿ)¬þíÌ*ãÂp;V«û³¤Ðóù·7ۆ皜÷ˆ.'Üçn6›»_ +/îv; ”<ÿ¹dÙ÷Mw÷Óéß·Ûk"x¬öj ˱X8ˆ:W •kanǹÂü¢l6ù ¶áy'ç;\BžçY–Íf³­&“Éb±X¯×Z yþ³è„|sö¸qýÃüÚ@¬OzFíÌ-ØïæŽÎ#n6{£µ·íöß—H¡ÃÁuSÏ‘]hr~Q6›ÜŽ +pŠív[žrŸeYí¤µh·Û…ef³Y\Ë,}`äùO)Ïêœ-l$<öŽû<À²Ùäõ¬V÷Úœ»\ÝòtÌÈtNÎï[l_=ô‘à‹Å¢¸Ͳì Ãòq@3×o~šÊc‰òüv‹Å?N‰MÂÍþvûo͈ƒ¥˜Ü:ërù]çñåàb¬²ìûCg݇0¬µÛýðØc,àFŽövè“ƯV÷î.§¸ ],G¬»Z­ŠÕÛ§ôŒ<¿EŸD±OY,þ‘ç?iOF¬s"ëdòM‘4öÔçјP§#‹ñ {uØ·ûŒ‡©˜á—u>,3Ÿ;úf¼»ûg{#ô^ìì g!€£m·Ûâ&t³Ù±ú~¿w Ü&y~“õú_g óã-–}¯U«öèìÐ0¿Vé<²n!–äÖtÎ  ì÷?¶WöJÂo܈۰3‡ïêèX.¿³Ó!æùGO°w Ü&y~­ÎÉÇ•ùüÛ#RMžWžÿtw÷ÏÐwE1.Sk:ý{Ëžt£…;«Ð;ÚŸÑèÆ +ÇZŸz:™ õŒxbyg~åû×Ö~~ Å/;Àbž¿^¯XÝü|àfÉóSáƼ}^_œ!Ù9‹ò\•yÆa6{SéÄðʈs°#l6yûnJs-ÿè<¬SŒFç¼úp¸õ¬ªój¬cagœœ_è<ÅyPà8ÅMèl6;bÝpëzâô~€’çWäùO3ñBY.¿+–¯Í{oyV䘬×ÿj +…âÀcWä~b[õ9$ÃèF༹qg¬ÞÝï_3žwr~¡sœåˆ:X,Å}høOžçýW̲¬Xq2™hFàÖÈóËòü§>á|X¦²b–}ßgJÿègEŽIçÔVMTØï¼tÌjè<¦FKrk:‡®}%ü6õ›³OÎ/„–ï©·j·ÛÅ[ÑÉd²\.7›MK°–ϲl:ƵŸš¸5òü²åò»>a~íìúýþÇöYÊ'Æ2<™žÃ:fcڧž+ãêœp»ZÝßòî}CÍçßÆ$3ìÃáEûçh¥£³÷γÙÈNe—˜œ_è¼BȲïíƇZ¯×/êÌ©œáGËåR—sÐóƒOIžu†¡L&ß´çð›MÞ9Á²i’?×`»ýwÏG-ŒÈÚwøõú_ç;Y}Û~lÞÚŽšeßÿöÍ/ÄŽì<ðzôCD*a‡! Å&Æ,¤À;ì—ÆYðîãZ{`½YÖS/Æ »‚Ç ˜fÈ,fm‡‚dÿqÏNU´ØRÆÊÄÓ‰Ù†3šY:Es©ò¢XL¼Ñg§ÜËáγKiÆ|XzÞîKqÏHÖašë´Dg¤Ï èÁ"åÃF ì@ЧÒä|Žt =Ö ‚ +oÓÃá^¨Wƒü²ÒëÂKý ‚ ˆá0‚.ý_‘•-`YSúðÕqœ¬-zÞùü ˜ª¸²|IwREÜ=ÙF¢h¾TÎs隺¥H%aéYª=»dÒ—&õ£ÛûZ4øëûQÁKHË;£¬:9ŸoJ¢Ç:ADKA^ö ‚ ¢‡¸®ÛG<÷Þð wguunÍ4M~›Q%ÿ°, þäû~͵*g/ôÜç+ŠÜÜþVš.‡çé_èfQ—ùЛ$E9¸=ƒV­¿³òÅÝ4$ gåÊ| +EiK=~XåaÔêpX=Éù iü¥”ÀAQ'ð"¬"7~ãÉßþÜK¯fôg/ÿ!‚ :Cžïa²{á©øžoÛ6ûÆ4M×u‡ïD€KC=Oî¹Ï—¾•3-EóÜ—ºøҥ¤âÖá8;Š.Ô4×KO8o5Ð õgƒC±ølêÏÒ”ï(¸ 5Ï£5;>wà°íQ{›±žä|†t£ô) l‚ ˆrñ}õ1ƒÁÞÍK/ñù8ýëO?ÿM8à›G¯Ì?øÙWß~'õ€?µQל>}úÌ™3O=õ™«¶C]I]IèÆ“O>Ùê®ìÀÿžç±{IýçATâŽãÄ„ý°ƒb@¡Ï>_jÚ™,j®Ä¼Ab)¤‚K4]dAÕ§O)' < ·(ŽÉ¬}ï ÛÛÛë999¡¡Øj¨+©+ êÊâ ‡Ã.ù|×uSî ø#ëé_?|+ã8*ç÷ÙçK5»a\)%; g¸j€Ã÷£^5¾Hs,ù±ººGÍöGH‹9ÎNu—vÝ[ŽŽ©,¥äGj¡K‹ ‡w¥Û7ÚØ’u&ç7ÕwA]%Š"ö®-bš&ÓõüE;‰a1ó_Äç_Ü=f®þüÖ~¼<ž">ÿÚGÆææÑýK{÷6'íØ‚½¹¹ÉtÓññ1 ÈVC]Ù666¨+©+›¢c>ŸIï,Ý ÿ„°;õ<¯ñªŠ[U¶"öÖ竸Ü»4á–ÞýkFjc(“! gx»•ÓóêU#3â‡i®«Ÿì8;´ì4H#9Þx$®;\¤!°Šb|5ï­ ‚è*âÛhL×Ã[¶išü7–eÁÉðU¿Ä ‰ŠŠ¾Ÿ>·†q¥‘버Ì6zÈv«`ž´L‘¯kséÇJG*x—Ê¥‡3U6¡´QáöaªÔà íLbyƒÉùŠÓ¶º¸ AD@:KÍÊÀç™l¥¼ƒã>Ÿ |æç/íÝC|þædvq÷XL×'‚ ˆ¶Ð1ŸÏ2LÓ\Í€ÿ³±šMÕ•Œ%ç+¦è÷Óçã&°R¯%5l®{‹ê‚©Jº²º5í!¸¿ª4Vf +®¾ÛÕªž7–ŽÌe‡eÍm{¤®ô¡g)ŒU:èti@¡O¢f“óÒgJëÖ"‚ ˆÚàÆ^c“õ<ùëâqŠ~‰ï°¸Ïçß»ú(cäæÑ}Äç_Ü=ÞœÌÄt}êk‚ ¢-tÌçóç{*­!ü?cFêuñÿpzèó¥£R‘¢â“)¯²i2ÇC9ìðý¨žúÀHƒ¾nWwKZm¡}jRʽHGfî8£J¤@ fÕ6þ{‹t£V=.ÌU·O­DOÎW¬F· AÔ7© öø_µù|Qàßž>€ß >ÿÜèdþÿxíÎ õ5AÑ:æóyz€¶>‰8††aÖ{èóñ ùÒù¤2Ç4×)K¶þ®¯awúWT@†q¥žëG«¬xMv +T}#Åv8¼«É}2-A!ÝÀ_ëi|­¶Ð:$ç3¤‘bx¦ÓÈ'‚HÂïûÈ_uðù€wuŸùùËãG#ç·&ˆÒ?™?? ÃÕÂTZ½¬ä|†ã8YŸí›Ï—ŒrzáÝÞîuÈÏ츈f‡mj¨ €ÔÈB+ü3®­j€¾éàE ¢’?_|] +ÙJs2»¸{̾?{ý€úš ‚h óùšcÛ¶tw@VbCß|¾&úBV¨'²Ðƒ}YþEÌ Œö6c#þéïФÙÚ%î‰í +Q9jsËÐp›<âßÀjìº·à—¾Á¼¨ÓÍV‡tå¯9‘[šâ®s³ã§þð(¾Ѷ;‚ ˆTLÓdï¡A,ûYþ +œã³I¤>ÿòxÊüü…Ñ!üxóè>âó/íÝÛœÌø“=‚ ˆv@>¿‘¦F°,+õã½òùRwQ§ý“æZÖ ïR‚©T™Â µPVV¶Zš‹Ô¼©M%xZ¬þ“oÒ*nA%¶“•zHߤ)뢅ú8Îô;ÜHë<¿tgVý= 'u)øþ!­RY9‚ ˆ.Á-:àºnVZŒ(ŠÇaŸ2M³ÜšdùüÅãœüµ£ÛÓðýÉü!âóÏoMÄ®Ý9¡¾&‚ Zùüz€fxVƒ”T]ß+Ÿ+ôš#£h.u;ôú_O;ÃáûQmUÒMè)¢g*¯´V:oyð¼q#a&•W¬¥Oè8X—ªrØöHÿ Mxì‰ÝEýµ’nºÑ³1ñ0DýÉù üYÓÈ&‚ ý±,Kå¥uñ蟇Ðu]ñíð}¿”j¨øüçnDˆÒO¸<Öú¿”ƒƒƒõõõíííùœžS톺’º’ÐýýýÖueß|~žç9Ž³òø`0DQTõuyfB*|"'¹±?>Þ£qwT¿<÷ýHê©ô—Tš#Í®¿ëñ*i›¢‡Ã¬6žÝݔٓ†3©Íö¼qEW‡õPejÄZ²¸„ƒ}ËÚ(EãWt¨¹»›Úk€W¬Îmkê©gKRŠ>ADà•9öÒšõNšÜ–oÜeU#‡Ï¿¸{Œøü›G÷oOœßš¬íÌêÜë9>>¦Ùj¨+©+ êÊâôÇçAKà†Q©!‡`øµÇñ}?öOÎâqƒçy<íÁ4ÍX”¡ŸEsÏÛöøFÏ 4ib#ÕÆU¤Îv7FΠ…g‡™:¨¶#WÐMåÄJÓtõL)×VúIãbz®HR^ÃÜ—Åä&¦ÜFÕ°>”•ß"ùÌ.õ š^mCum¬0>¯)EŸ " x…÷YöÒªâóá6™¨V„>s2C|þ¥½{miü›7o2Ý4›ÍÚRgE¢( l[†™çya"Ÿ‚¡5DÁÇ>”QQæg‡»2uA`99G§ÔÐÀöö6ôãÆƆJW€„̶m>ÎáG|ï’Ê(Uo‡Ó¤?,Õ•úL®>ø|˜#†aœBKª˜æ0;àÒ0UÅIŸ/ž2Ó4aš‹¿/îóƒ`S4ð£†Y妹®a¯t×€æ ÆÌá#mkÛ£¦’f¥©’pXÖFývEÚé +4i8LçÙ]]–{n JÒlózrŒa­Æ[¯ y†»€›]öE×½¥[w‡w¥’5¯¶éîY輡@Ú׎O‚ ˆ¶†!“T¸ŒÍGŸ2ˆøüó[“µíññqÇ pEŽã – e¥kÆR7¡üÔ¡ÈÇ\EÑE÷¼+³XÊ7f,öˆçyÒr`̈©¢—êJXMÓDFi–âS¥¶mgÝ£ÊÇYª‹z´…ÖÍÊ>ø|X½¹Ì‡o\×eòÀ`01…^ +©ÿÉ >?ëƒ}~–™¬MF)È»Úú +iv±VJ?¦l/ÆRy¶¦¹îº·êläd˜)u”6x’æEëÓN7Tx{ÂðÓª1a"Hg1XÆa…YÊ™Ãx€6g|~L=ªÎÆGL}² ¡&ÒpFSA϶LpÍc‹ …­7ºÅG‚ ú’wÍ^Þ?øÁJ}þÉÉÉ|þË3Î^?@”¾´>bQYÀ pµTQ,õQE6ƒd9*>Ÿ— +(šR¯õà²EáÖ+V”ŠÏ·,KZ”ëºY>¿þ¶Â#Vbä(iÔsŒÒX­Ô?žÌp¦Ñ®yQ}ðù|‡Ir +ÃíêJQñùYw‘Ïç#Y¦ZüýºñthÛé¬ôó9ü¬¦®!yruuO¥ª ¦qJSôµÚ”¡ú®´†Ãáݶ,GM­H¾5¥ß«8Ùz“µiØÝ1ô—äŠÓG‡<¤ùÚî¹#‚è61—Êúúúk¯½†²··çlll°d˵#ÄçÿôŸßQ/*øœ§ÁÉT”bQ¯¿þº(óÇ¥+üõÙgŸ=}ú4’bÍ ÉÓO?½š—õÆo<ùä“<+8™<ÏÊÓ>ô¡qKÎä†ä•W^ɺÜp8äAÏóÄ?qS +ßdÝ \‘ÛN¸õ`Ž¢ë•,*õd^_b]+ +†Sì|îókn«¯}ík*I¹/¼ð?-k”ž9s&«Vb~òÇ>ö±X­’Mº¿¿+j0$cÌã7˜,**J½¨ÍÍMiQìœsçÎuÛçû¾Ï&r”ábgÖÓZù|n÷ù¸è{≷©UìL©åËJ)¯¨Vp¡’u-knœÅ} +Ú•o¿¸„Š„3w>Òýÿü™ŸÖ_«Ôq¥(úšõùÒœØWÿþûü ˜J§UjØ®ÎUô³Ï¼Ù „‡öYYÙ‚Ã4׋—CWTúõ¯íÒ½ÐÚŸ ¢aò¤PÅ(æçç;ßA +a)Ž›››óù£÷—ÉlŽøüW¶"õ¢RáÙ’± p**«¨3gÎdYúXQpEžkSܬ­­!µúÊW¾’šü,ú|äa óÇΡ\ª(•ü|^žŸ=ȃeYHQ| q'5?¿ž¶‚Í +ßøÆ7ð¢ž}öYƒH¥Ï=÷R+Q0Æj•lÒÔämÅ¡i½ª¨¨ñx¬R”J~þ+¯¼ÒmŸÏÆrßJ*Y;¹J§~ŸÓ\_4íóß~† ´/=ûtðù ó“ªôK¯UÎkRâá8;ÏÿùbÆUÑ®À§>þñ«_ë‰'ÞŠ]¨)ç#MÑOæi×P«Ø¸‚ ‚Û×Fj•:Úq|æOÞhÜç[ÖÞãÜšÖY«d~ûÅ*îs)7º‹‹îq` +ü…w ágŸy7¿o]þÝß{kY¥Ïùš×vߤkQƒOœØ¸:ÿ7?TYŽšõùxl1ù4ojm_çìõƒ,Ÿï]ݧžªÑsª¸ž<ëtnHðBø D|>^žüœz!ø¥çy,hUMî5è9K­Y'óä®> ìB¸óç]œÚq0á÷<àèû>Rf ‹[‰µU¥xÓIÛŸ§7§ÖF5ŒmÖP0ÚkP¦„ +¥?auƒ|¾¢ï6ëó¿ðÅ˸êI:ä¦ìJÍ¥º/©ôË­•çkHËÇ,ÏüÉ0®Tì +ôÝgŸy76`ªÜ;T˜ å/;J¡Î©éýêíŸö‚ßóx–Üâ}ÕÑyŸÏVïä¨F&~¹Q9i³çðù_þò—áµ”wŽ²>ÂÏažËmÛ£“““ØGøñàAú8põÔóÕkÅßú­©ÞŸþiØH­ MRÏçw¥ +(¦ô˪Õ÷‡{ð×4ùIûúÌ3ëçßÊj«o}k7G +ñK/Ý®´—íùRô«®W0*Ô«W[­²z0Šæxmÿê¯nÕ_+4”T>ýëÿ\s­¤ãêoÿöê|ðtðýBs0¦Š &Ÿ~úzk»tjÃí7þĉ+XT¥›qê¯?ð'TêÓ¼Áµ}¡¢¸Ù›A‘ +¼b§šØÜäöù—ÇSÄç_»sBUŽãàJVEŸoÛ6;MÔ¤‹e|>³¢¿å‰âYP3£\Ÿ¿ÒïSKø³|~ª æ†+}<íŸWÏìùV<|”ÂTâñˆ|íÏ£lb؋Dz΢R:ïóy Jú°`ë<,57{ŸŸoÖø~”CHÖƒÎuË"¦ŠMÌÒ/ˆT=5x@k8ÎÜlÍßçwñ(’J2¹6+IÎýzÀ}ô‚ní‰WضGMU .N “Ñ|Ó-ë0ÍuÏ—µöªokb³‰/#•"Í͆Y¯áÓÀ—£:¥7©†í)]ÞµõA=dYŸíÎÉ¥½{'ó‡·§Ÿ¿¶sDm[ܦ4ÞRŸÏÒ°³ö(šR®nD1Ë ÅŠYÊð{>jážPºÏ}²Ñö§ŠwþKè) ž‚~ä#_^T|>7áC™*£Ôó<¶×¾&ÛD±ýùlââÚ„; ø`†Fãµ¢¸Un&³ùÍ£û é¼Ïç#“ ¬sxŒ‡ªÔˆÏ¼¸a’««{ÍõÑ–žr§N¥×R·aˆ›‚Æô¼ñpxwñXb@ÅŠ›j?¤-’ùŒ|)ú5 h ʽì5ð®†)­•¶v—³»øü…ÉË–ˆrG.á¬K5(}i¤ÁÇ"¬“zúgm+†#]Þ5\E ‚ úÉR>s2cºþÂè~ô®îgùü³×ô¿÷ù|>wwwÇažMg †Yj…ŸSPwsCbYÖJ1¾O^KÅ”ÞÔbæ3×G©J9kG@¬+³®ëºß7Œ¿œ™ïQ4Ç ‰¢ÃG*rœÅ©îXYÙÒY–j›¢‡Nšš×R4 /Jc[0´ŸâtÎÒæ0ÅRBÐàpˆûk®± ¹—Màf¥ж—µMƒ×vãŽty×y0AôŠ¥|þµ;'ÜØÃF‡HŠþdöè_ “ùÛG÷Ù÷º±½½½¾¾þÔSOinòERefYJ4$80lŸ/5¥ISÄÿšª‚ `%dù|Ö•ÀÉÉIò¯®û}ÍM¾x¬¬|ï¦|#'µ>ëÅ$ü÷7ÝûR÷S}~Ö~ të»T79PlVW*îþP_ñ¤Ø¶ƒÀã)Ü…&kË/-î@‰M@ žŒèÚجYY.wÙsçüÖ¤H9}ðù !´„G‘9[.Mù|ék#ïÚ¸Þ±¬ ÍG—¢Ò‡sr¸©áð.®=³Ì´*îð3fʾ4aµŠ*¬sÔ†£aŠ>Lê–îwÀËõÛ3if»¶©Å­C*Ò .›ŠGºnk¾(áku#ïYmc‹ JÑ'‚hKùüÉlÎuýædviïâó¯ÝyäpÎ݈à{ï꾆Jssóõ×_o‘ÌÏrõû|&íc¶GÝ”&MÏg†ord„BW2s˜š Ü"™ÏŽ0Äœd>?æí91ÏŸêóù†‹ÜVM,vcc#µ+ë÷ùl &CHêeÚó |hÏÚLiƒdueœ½~@ùùËÞi,ö„/ïUW¦Ÿ¿ÐOžKmd+Þ «PúùÒò¡‹ë¯0œ­®îåˆ#äÛ>ЊœgÞ2øíÔŸ¢¯aˆA}„ã³Æ÷#}*£sK¶XØÕ7Uñ®®¶=Ò¿ u“熖Zð§¥èAp|߇Rx?µ,+öZ ¿´mÛó¼Š^®—òù‹÷k“›G÷ŸÏ¼ +ÿñòxªS“?âðððµ×^#ŸÏá†D´µ"0a(rkšfêXB€îºnÒØÇ|óYÕHíÊíííÝÝÝÔ¿¶Îçö:¿Tw+ú|èYöhv±»c¿Lõùb¿ÃØpg0,µ^‰Å²®ÜÛÛË:§,ŸŸUN†Pq)ŽÅ8T¢0€“Iø0ìùÜasê·œ#€Õ +²º²tbæ"EuÌçóÑžu u˜°\ìØdó·æz6èó¥B²æŒDÜFjžÎ'RDéC§@³Ã­‡ëÞZYÙR—]¼døl¹7åû‘mª“ùp§Q¤ãnV<"V³õ•Zèúã %6fBUjwKŸ\„âšYÅH†KK—ÓV,MZm¸“þw¡DLºs¤EÑg‚ ˆŠ€÷PÑðH3¢KÑ^Öç¯í1mrîF´t}ò`'œßš°/Œõì$GQCR»‰»Ç‚A©ÏgDQÄM+•:˜Û/â_<3¦µ“n0&îÔX¾ïóñPÊŠ'¥|ÏH,;ˆï…šºà0· ÉÖKýýåñ”?w +^¢o>_ôù Y]ÍO‡k—C“:"nŠ  à°¬²Ä8”V*‰¢¹çña£U…+E«ýö&ç+N™zê/­,S­ <µeÍT_á̲zAºšµEÛâq(¸ÍÞV&7øÿ$m ôATAEÉl|àS%æs.ëó7'3nN&³9×õ©œÀM‹wUÓMâA¨‡TšÅ4ÍT£ÅÅc2%8 .Å}>ày^RuÏ † %§Î è£ÜÁ¬ ›æ‹­ù†ñ—xrþ¢2ŸŸ´÷IßåóÓÚ¡„TY-ŽÛÜ>Ÿoëƒ&P¥üŠ±}(Å}/TŒÏÙІôpL…­N°$F‡ì)Ï£‚W!ŸßÍú|ß4q€Ò\¸Ö)_é•~Æ•ÚÔSÍággÙ½15ZóÒÑ$E¿íÉù \çÖ“¢/µ»5ç9÷ +ÆêJ?uÓ²HWi¨O[ZO«”x­6 T7pîFÄäÉÚÎÑÍ£ûˆÏ‡‚l¹´wº¾ +DÙ¥¢:y&¶˜·¼XÆçÃP¬ÔçÇٲ†}«©Èç/ÞŸŸL×_¨ù|‘ xDYè‹]jDQÄï]Ü„¢>JÅr·¿"lgJêvBÉü|ñ4¾ðo?)´Á|~#4îó=oÜø«÷px·KRE¤¥}TµçT$ g0œl{$Íiì’‘êÇF/®%ëÉl/ŽÔ¯šæzu#J–ƤŠ'„¥Ì©R4µô*­‹#k"Ò5 +”‚ôŸJÑ'¢‡0o–TRà|®ô“Tqrøü‹»ÇLžœ½~?">Ÿ°¶sÄ~<¿5¡®¯.7bŠ> žçÓ§ê>Ÿ›U×u“c)‡]a™Øbi±a¿ì(í0Õù|Ñá‹n?ÙÅ|„ð|û,]ÏC?ȨPôù¢ô}*ü^b÷¨>JáŽø®Üí«RlÇA û A dÿêyôOo/ΟZ\,´DÏo„Æ}~Íñ×Õò¨q¯ÒöœØJ•¾m4tãP%ß [cz¶ÁMÕ!MÑ7ÍõfX‹ÂaRÅZ ”îqhé.¡–²Ô² ψe—Aé^Œ–¦^㱞æÒõ°u<<ÑÆ;"‚(Ϧö?>„Rר¤xç]“ÞÉõ +YîÔÓþù5 Qúâ•©8J¡pöŠ­´E|>û ´ 2 àº4ȳ·dÓñýbO?dþfèû˺VšNœY¹©¹‹ñù ™C³¬J[@úú_ƒ‚¨š*”¾i®·ÂÓÁÔóÆЖR ]i'žUÞ®p˜t5¨(I®‹‹Ð–ÚÝVãûÞ)±õPe`À9®{KºXµÚØhpwÍ®W t¤)úé#¢WðW×ÜoÊ%¾Ãæðù'ó‡ÜÏßž>¸´wñù×îœLfsþã愸UÁ»’õfR| ®(á›äþnH<ÏK;P‚hQbéôE|>ÿ¬ã81¥?r½\J «íTçóB"tê& Tñ.›Xiðq©Aö©û| â†ÆŠ…mÛ΢±‘–:Èaâðñ–§Èí{ùÊe&[ZOë'¼;`p&ÿÊ.þÄ»Ð'wðtÕ硆zêàóƒ`Ú`~/ž[unsm”«ô]÷ÙE}€¾hÊw)9_eA¨(ÂhÛ£NÚݶÏ&ènÅUfYVð7 gЃ*¿í›ÂOo|ƒ@PŠ>A§í>¸vçäüÖäâî1|óè>âó×vŽàœ³×Øì#DEˆ’w+CüeVnsì489&Þ‹øü˜§…Y} |ß•Þ7*õù<‡<µÁSÅ»èâLÓ„Xßá^]Zlbæ<¿(ä±`Dª_ÊpBÉ™RÄsŠS Ú‡54¯yj ­Ïˆ+Cê(bå/¼}àôÃÇ>ÿÝ"—#Ÿß[Ÿ¿½®V—~&¡•&6×>&÷ú“–ß7¤[Ñ$êRr>_¤Þµ\».Í¿íLT±ÀxF[²Lã«G*ÝRøÓÜuoUwi<¼Ïú–6©4ç¡ÒV%‚Њ0 UW¾ï—˜«œÏçÇ@|þÙëpÂÅÝcöãù­ €Já³IŸ% }¾iš©þ¤ˆÏ_¤yZ˲báƒÞR©Ï‡^àIæÛg‰wX‹#M8_Êç/;^1XR²ò±ká° Rê+â9¡@¾a!õ¢©¶>#­¬Æ‰þÁÞ`ÇÊÊõ"—ëªÏ_)@ õÔÄçK³|+J?ƒ·`üºËBwœee h«–&7ö©….]v/9Ÿ!ì†q¥ÄIÚqAkœ¥‚¡¶=‚©!ͩ•JõꞪ †ªv·wCADx6æ²öFÔA¥¤q–âó/Œ¥?™ÍoOœ½~à]Ýßœh´ëàà`}}}{{{>ïÚ–íÁ``Û¶˜® ýëº.>ÞàS«(žç!% ‡CvZî'0¼á㢨1 nDºêpW¦ÎYF‘“Ù/S–$¹Âð.Nþ ~ã8Ž(«aøÁoTƒX¬zWÂÉ0¤ÅÑWd£ ýðk!àu^ªý³&T[Œ^Á0¹:±*eVòÀ ²=ÇöW>ÿöKEêÜUŸ¯y=5ñù ™Ôª"O^jíªÛÐ ¾‰MmW˜®‡›…F†šŽV'ˆöèY|<—î|ðÄãVg•K#_¶=*åBž7®çBDñù…oæ*å¨Tw×ÞPÅ…ÃpÖHV@=àwG>Ÿ ˆ^!戦ʱTƒ7´eeÍ•âó/§ˆÏ¿vçDÏ^ØØØXÌññ1ÉVC]I]It¯+ù^¶ÔÝ"¿ä pÿ½÷žÏ?|ËûŸEêL>¿-TäóñHøRúà6²í¯ÿD‘¦û~TÖµ¤á°Vï戢¹TÞoL•«Ð*¤A0•n¦(xtc¾ñ ž¼õ_´Æ 2zÞ˜¦'A½BLdeɇ®ë²ÔP–2mÛ¶˜Ì ß—’œ¿(Éçßž>@|þÚΑž]póæM¦›f3úOµÝPWv†íímèÇ êJêJÑ®gn^¸¶jþfÈ|þïœú_ó%·¼!Wì@Ï_–(š×):ðð%¼m$¦ø¨.1g´:9Ÿ Ž´1 ¦RKwT±/‰(ô¸4j–ûèÌCGš*_Åþ¯F6Ôܪ©÷Ø=AKE‘mÛ§–Ç4Í ˜²)ÅçÞÕý,ŸÒ¶ŽIvêJêJ¢{]麮eY™Éù‹ÅÎËÎ{Éù‹ÿj¾T°ÂäóÛBE>!³[%&õe½‹Çpx—–¢uàIªe)ân'çs¤æZ;wá*ÁÒt-e9Ûu©»ñ¹Ïúr/‡GߪØß×°hÄþu«ŽA´ß÷Å×RÃ0à½53M1eùü £C$Eÿöôõ5AQ.ƒÏÿÊç¿â|³`iäóÛBu>_*¸Êrì•j:‚h(šã±*økÚw>9Ÿ!M3.’i,]…|?¢ñ¬-ƒÁ¾4(¬rÀdÇMñ)©aûà«P¹Á |6uéíæycÛÁßPÈ " CÏóÇWTÃ0bÙøðKx]õ}¿ŠK—åó/§ˆÏ‡¿R/AåbÿÇè=Ÿÿó_ ¾[°4òù2 àF kÄ_Vçóµ$õù~„ Ú½N´Ïã#¼à<êIr>cuu¿Ù|û†pÛ ¬„4’5'™,½¬Æïvf5Þ8%®Ò¸[÷Â%A„”åóoO >ÿÂèšš ‚(Ãøerþïœúá÷ý( +•Ö1Ÿ·³ú˜VßS÷±»¨ÔçK5WÁsiö2¥ÅÀ4׫ÛêbÛ#<Ö·Æô¼ñ²«´Ìn›ÞÎ]iYêf‡ã씵ÑLs\÷Vé°¢ÐAQeù|À»ºŸåóáOÔÔAD¢(bIÚžç…a(þéÔ©ŸŸ:µøð'ÞýwŸ¿÷ôóGýãéú/ÿïý§,AÇ|~7¨ßç/döluu¯Háø‹?½ûÝ@šBŸ{œKSa ÎÐ66¦a\Y*Î(Íù‡eŠÆp‹pœß·HqmkEm‚ B¤DŸatˆ¤èßž> Ö&‚ –b0†qJÀu]þ×uúò^ŽÄgÍêöÿð¿½Ey®E>_Cñù¸ì*’ýÓr½Ahü•Z› ‚PÇ÷ýSi0¥‹˜ÌçÇÿøVž2ù| iÄçGѼ + XÖFßR‹‰Þ"õƦ¹¾¬7îar>_”ð`E3 hÛ#¼ÏÓèm#A0uœ˜V0T˜Æ§¸ .Û™o‡v+r !ˆµ¬ezÞ ùŠ%mqÝ[åê÷~&ç3¤f‰ÀïáãÒ\eZ…ˆî! „Á˜Ï½nH7ÎІ;‚ ¢: +úüÉlî]ÝÿêÛï\Ü=†Ï^?Ȳ+pµ6A¡H©2ÿ /á™rîFô«GYOœÕäyâÏצ|~Lñ—ôe3úà¥^j†Ã»ÔãD—f•Ã_Õ}Wo“ó9R!ŸLöýHªi":Œ4’‡mr”,W„¥ö'‚ ª£ Ï¿<žŠº~mçIÑ¿=}À>5™Íù÷ 2ŸÏÇãñññ1 ƒ¶ÓÛ®Œ¢h8AЙ; +Ãpmmmk ûnÙuÝ•ÇÀ7ð‘Š* ; VßÃ÷ýê®E³2 tnRæhå?ðgÊ—Ö'NŽ+’Ïצ|þB¦Îgg©Òl{„¿ø/[ A´iV¹úÈ—zé'ç3¤ .äƒ`꺷¤1ÄR¬&AhŽÊΔe£Ò• 8‡Ÿ ‚¨Ž‚>ÿöô¨ë¯Ý9AìÊ¥½{ì#bJƒloo¯?æää¤íýÈåÆp8Ì}²hHÇQ¹®iš5H•^ueŽ~ ü7\HªÌ謓ù²@«Ô ÿH¾Å„ñ£ýJ8}úô/~ñ‹ÔàfùUØ톡2ìÕ‰¢Z@Û"–e‰ ã” (Ú*«ÂâÌÎA* Åg%ôlòöÿèÏ^@ž2üøëËyÔ(ù|mW¹F|¾ôm]]ú~„eW:¯"‰ÞbYÅsÂ¥©þ=‰ˆ­®îáišëp,¥ñsì• ˆ«‡Ê¤€'µb*2&µÀä<—ÇÓÉlŽ–ó[8ÿÒÞ=1¥¿A677™nê@^wé>ß0 i9Aˆž­AŸß¥®TÇ÷ý¤o/Ýç*ùÿ¢z-âó766>ùÉOB!®ë&ÿE\Ȳ,ø†ý& CøQ1è Ül–ɱm›×Aä”2©!3ŸÏà +©ÐèÊ"³’ ï$_Z{[Åç¿~9ÌqQòùÕ1Ì õ¦|þâQÌz÷‡*^Å$PÑééÿ–µ!-Dê±ûã¢óéúÒó“ ¢EÁTÅÀÃiÒ¢Td>M(‚ ¢Šûü £CæOàøñìõıÀ 7î‹)ý Þûáááöööîînú±tŸø¾—㺮&>¿K]©3Û±äüE5>?U­‹ÄÔkŸ]ÉRôSãìB±‘É2öU‚R X`Âó<î¡Y˜ZäF=Y‚øÙ$±HA²aù„ÂSKˆ)}‡èÁÁÌʽ½½¥Ú߶mÇq`xÃ7I™ÿOþ¶ŠÌ‡ãÆFžÕ€|~uœ*FS>_ªáõÎÁ­¾ëÞ YYÙ¢BtÛåi…ál8¼ëûÌ2JÎçHã#9Ó\§-BD·Qñð–µOE™/-‡ ‚ ŠSÜçÇòí×vŽÇróèþâý)ýÔ¥P…ÏO͉ÉÉ}~ogn2/½ +Ÿ/Í~‡¡R–Ï L–Ã*–z*#‡‡HØ-gèy2æ¥68 CÑTÃËNd±±hNgÖ±Øä|ô?¯"óÿûÚF¾ +ϯŽ–ú|xWysG¬¾JN`òŠ‰Þƒ\:‰ß÷#¥M8` Êú¸¢Ì‡ÕŒëAD ÷ù±|ûkwNÍriïÞBHé?¿5¡.(…r}>ó†a …A žL>¿NÂ0dmîy^ìOåú|Þ¹xö;Óàüäâ>Ÿ._Í®EQÁ‹ò¨„eYxilG@ªW´Á<ëAʼn\|ÝÖÞé¬ R¥îç^zUÅçÿõ•wòÕ|~u¬‰>WýèQ÷fLHÆ>nYø§VW÷ôê*‚¨jØ+=«¼‡ÉùŒ(šã–ÊÌ'™Obm‘ÎetÔ<ª Èíýa|àô¯«È|8®Žþ%_Èç·…:}¾J‚}LŽÁ[?û¬ç¥'So=¡DM;\þûŠŠ4ô…ãì´ÎäÍçsšM¥ó½ï}ïàà€¢¬+ŠÓd>AQ'¥øüó[fQÖvŽàdz×Ór2(:ÿÍ íG+r}~EìÇq² +aÂͲ,nÀ’R%îè8†aÀ™mqŒ‚÷N¹>Nzu1¸€\Ú󼤤…3³F,œ i¸T’í Àe~†©ù½1x| +ó"r!ß÷EÕÉ€–WÙéÐì¨f½‰$çøŸQôù{?#Ÿßqêôù/·•#åÕóÆRi0Þ¥Þ$úƒb‚ëRLÏÞ¶gŽ¥ Ûñ˜cë¸zõêÑÑM%¢*azÑÌÃ7*!’ùADÍ”âó/íÝcåìõG‘ýµ#Ä´0Ï? )×çÃ÷,íÙ0ŒÔ‚ àÉÉY>Ÿ ÏTLÓ¤\ý|ð†M5´¥û|îÕ³²Ö™†eZ;µ´(Š² -¢ãx +zR°û¾Ï. +’Ž"$Þ$ÂkˆìIQAÑóËÅZUq"óÐIìBÉðY,z¢ÿ¨fõL­ÿÓÏ“=5V°Q +*±E˜20_HæAÚRŠÏ¿ytŸ»øqs2CdËÅÝc8¾Š!¢ ¥û|®×Rõ&OfÃ0Õ—Âï™q…¯pòð=àž¤mYu\X¨…5~ò¯¥û|îÕSÓàaxˆÁ…ÔÒøhßÃil$À7¢|Nfl¨Ä‚J¬4(J1¤èó˲¸*åˆ ’o"óé)–ÀûÚÚø%\Ž§¾ã{„8à›ä>Æç^zUÅçÿý›Û¹«A>¿-ÔìóäûÛÅAä`8¼KÉù%²ºº'Ý+亷ÂvCÄûpœ•†d>A¡-¥ø|àÜè«o¿s~kߟÌ"²… |ÑùOfM¿ÒÞòo:‹‹+Z?q·‡YwÀå†ã8«2¸.C|>ONfG/Þ­LȧúRn,“ZRÌÖ.˜ ­ÔîƸÎÔP¥=XÓemàÝ}$ ܨ#>ñžk…“—ã%@·.Ò|>H©+ ÷Ò©Á¹àIìlcHê˜Ìîz¹Ï­àHcjƒ‹ñ,Öh©sñùð'îç=Ïã¿gÝJ íÆ?’ükãðý>l£GÖþ‚â3ð¼øÒÚÁ^ŽGÌ7îX(Èç·ƒú}þãáq^íËòƒÁ>õ#ÑOT4%ç«cÛ£TÁíLŽ‘ JÙ.D2Ÿ ‚hŠ²|> jy¦÷³v&ÿñæÑÿgßÜ£âªÎþŸ?»Þµº^úÇûG»Ö»Þù½ï]ËÚMâ-ÈÜu !$$“û ¹z‰bÔÞMÆK¶VÆKÒX'*jm©£F£fLˆ¤Da A,r ad~ÏœÍl7ç²çÀœ3ÃÀ÷³ž•3‡3ûìËs2Ÿýœ+©ì‚3%‘ÃcÒ&jý†!Ê ëH|~$fSõÞ˜Ë7æ }©æTx!q²ê*#Ôt y—ðÎ7[°¢´ŽÜçÓ@k¼:‡Ybš*ìWýÙâêt¾¹#ÉNÜZÓ+ô‰•F˜iêAùüÄӠŧ«Ðwf$ÞÆœ×ëåÝÅvÄ«–_‚d‹-åð]!êñ© =Þ….Ïd¿äæRrì˾6,àóÓ…”øüØ$±Á꣨ŒfB¡+%¯Ø³NII3“Ô±nwm   Oˆ‹¢„ÏEXnR…>_äxÓ%‰r9ÙÝÅ®hìdåúÝá¾”]’N2Ÿâ¨qý°>Ÿ×Nkªè¹ …B‘x>?ɦŌŒtòùrÈ{›+t³lôù4Ðý6Õëãû24UØ+Ÿïr¹Ø„±ßGà³H2ÏÍ4õðôùfM²¾õ;q»bxŸà`»ò«>–9gQäæò豄j5áóÓ…úüØTIÈê‡B=D0š))iZ,­;·»–þ‹8Á`v¤)ùü‹]½åRVÛ>®½µµµá£§ÓÌç6¶L\nø|¾Êxð_¹ÏçžÍãñˆ‡¹\.z‘NÂ~5ô¥|/€I­2¬F¶q(«ªªêêêÂá°þÝô’ùˬ™ÂâÃAÝw&pa.÷ù‘X= ½x·¯¼JÜðllÂðêë@  ˜WP‹C©×ì4‹Ì®e¸Õ盵“š!ÖØkZeÑç»Ýnýæˆ(ÃéZƒƒÝ@IæªÔw>ë ÉUS¿Èž·³SrsÙ±ÿr"m†ÏORîócf(V¿¤¤ #€DéÓ²¢ðz/Ð1ô_Zh°÷‡ðû[ ó¤#ù|ÂwºÅL¹Ð[ÃáÚ«‰OßaõùVJsÍÖø|Âív3 Ë_ ƒ|〽bæK Kmé#œpû4’U*úwÓ«>_èlÙ‚ëó­¬h³ƒõ>Ÿ›qìhbhž0<ý ;RÄårº}q(‡ Ù³upyNŸ¨—]A³a1,Ú`ÞŸÔ3bXÙ˜3;'GÜ)àçO•Û—¯J±ÙlzÐ|з_äÁ¯Ð»»¼Uâó7nUi3|~º0L|~lÚ Âê»\UŠÆ‰Þ|{|¾æ’’&ú—Öú|<žzÈ|i‡s>¿¬¶]b]:®¤üÚªªªš+6¥“Ï¿0¼‡|>/³ú?×ëõ²W¸”Ô?Ó[lGÀPìÛhõÙP==\~:ù|j­•›dŸÏ7Mö +M öŠ_h±ÙG+ŠBçä…úá,^K]]cuu5 å|þ˜AÂ/p°—®ˆo +6 æ‹k° Ù3+îñx$OFØŽ8”q;“²Ÿcf(óL¹ñÉm¥èˆò”ïX"m†ÏO†•ÏMž»\Uq Œ%0ÜÈ̬†Ì^8çóÏ|Ý-/Ãáò;;;£®ébeäLIµÓ‡|¾¢(ܲW˜’ÍÌÌäÇH|>?I  wEÃD®5ÃýCi](µnøGÜÑK•ÏÄü3¯`çÏ_ˆŠ8îGƒAŸÏG«qû|›@Êdú|>9E».og Ùçeâ>ŸA+Ëï÷S¯jܾ¸r&ËW¥¾WhˆÛíV^vO(è’ÜV¦¯oU^žH›áóÓ…aèóô_bõÝîZŒ0ÜP”pFƧùÒç|~[OX"^JÏ)è|qÈç¬À>###¢ÊXv€ÏçãÄõù"Š¢ˆõâÅV žO•Ïçͬ )Á,«ø‡ƒJ&tQáêKLJàó%×(ŸŸüê,~ðD3‡‡‰Ï …Btul¼¬oX$ÃÇ7DgëYôTáÙc_ TDNxi|~º0l}>ÃÐêgfV+Jc C‚Á.È|púº]¢’ îðz½Ù*ÌMZœóùDé9Eâ^ºÃ}˜ÏváœÏ÷ûý\rû*ÖÕúR¶Héo @îܬÙðÞÖˆtý¶û|>j4 xuºfˆõgãÛìY ^篟º|î%âë,ú|~uVßØÒ¬…È`|>ßÕûpÈ>Ÿš!¿3ÚÒ™ÎÁg”!*ÔU’Jɱï¬}‘Z¿-ë >˜S°8ÿÿþÇ5äøàĉ$4’¾õ»ÝµÙÙçé_`˜C7k‰Ì÷xêÑE†5*cHÎãDdZ÷§fµ¢±S¢_Î|ÝùlÎù|EQØ‹‡Ðfffj–›~I²#YU¿!ðùC#îVˆs>?SÐ4¸\ÂkŠêõgãY|¦ÃÊg‰o™ý­¬??Â/Šæ­dŸ—.™«xúÉ×ón¡Ïû0Ÿoq£gxú|±ÜZË'ÿ;î°ä†Rx ½rï5‘ÎP"Í€ÏOÒÂç ½ðxê!óÀ!¬ø|+ßÇáó5ýé„Y­ië‘è—òúÌg»pÎçn·›‰GC¹jè ¹54±ôbâžvÔÂÂl¯ÄQŸÏŽµA¯ŽõgãžÙåriäDuã’­6ñˆDž¢²î±ycX{ Ÿ.¡³‰Çè¯(î݇®…¯}«¹1ñ†v—-éâß?og©ä†2v~säõÌ[ŸŸ.ÀçÀ ôJßë½€n€ÄÏw¨?ª”–èßi<~nŽú|^KÌ…B⻆¾TttZ:{d†~àŸb¨CA\¸˜Õ „f8œðùïª7Þ†gëÞ½^/~Š~æ›D†ù<îSVT]z0äMbM½]¢B­åeù’þ1ƒAó¨K$±“¸N©ÏëgŸÏÇUÿð|"FÜà0“ùDÑ‘JÉ eåüÒÈ'Þ[ŸŸ.ÀçÀ!*+ÿ]RÒÄ"êA‡€-Àç;ÔŸyž²Úv‰¹ØÕ‹)m Žú|EQ$ÒÌ—jv4˜éPÞ±fäÎù|BtÚfÕéš³Ñaâ_éñx<ú¶ñ½Ãw­3(ŸÏ>—/‰‡7›½Öe¾×ëMp!ë‘‹qjö0ÜA£&‰{(¾óÝÿœºp)ýð½ü·äV²»¼u磕ý½!Á{ +|~ºPýÙgœ81ähooG@Ò€Ïw¨?íòùÝá¾ÃçÛ~qê_Ç›.ѯ'›»$†Çëõf«X‘äfó×%¢wÈt³·hqéÕhFF†Çã1¬-VàþÓívëßåÃa¨‹-Ì£0œNü-3møµ™R^ÛfffîJD„m‹@ HwIæ§úPþ„½(?Ov#ÙøûÞþ»äØt§XûÄѱóó%·t÷I¤1ðù€íÀç;ÔŸvùü†Ž+\­Ð¯»zs/ ]¨Œš|[àeØÃÓÐJ…B|2ÈÏJú].WjL36§.õ-ïça¾w¦ß}àL(XÏo…ž‘ÜJJŽ}É~(«M¨î>°ø|‡úÓ.ŸßÖ接¦­‡^9x¶UâaºÃ}tÌ™¯»égßé–†Ž+I»öp8ÜÒÒÒÙÙ‰e•îÐP677ž¡ …BlÙú|¾9”ï¾û.»ÀAÕƒ´[•¢?×ÃþÚ'ŽZ‘ù'›»i3|>`;ðùõ§]>?"üŠÆ¨É)¯ï¨æüŸoc¿ÒÁI»öººº*•îîn¬¬´f¥×ëåë å-·ÜboRÃdUúý~š´4²ìé þ¤‰žï|÷?ùmBîóÅhë 'Òføütáþ}÷,ÎrTöú’|¾Cýi£:ã¿ôœB¿Ö´õHô øì׃g[“ví555L7¡D?Ý…C©(JFFÆÈ«`¯®®~óÍ7‘œGÆPjV%Ÿ´ìÑþ˜‰!cçç[ôù¼>?ñÛGÊ}>uõ ÝŽyG™!ù/Ðh `qþÿýkÈñÁ‰X¡4àóêO}þ™¯»¹ié÷QHT 30 Wø+»z“sííííuuuXVéÎèÊ@ 0òJôi(,X@×åõz1±ÓšÖÖVZ•MMMü~»!‚Á ø«ž…ûaw„¢#•»ËOY)ÎgO„%Bj}>õ -ç1րχÏ€t>ß¡þ´Ñç‹¿¦­‡^)=§H$L[O˜Žá¿žlîÂ<À +,¤}V³‘‘¡( +Æw$!ç³Û¼½äØìŽp×s/[)Îç·›DH¡Ïû>?.ðùFÀç;ÔŸ6úüˆ ðËë;è×ãM—$B† ü²Úvöëáóm˜çXAQÊ`Á`pÄ\Q(¢+¢1¸# ±Ÿ†Øï÷KdõUÙ³ù ¢ìØ3}~âL¡Ï÷z½ìs].u–€ÑçÓÏù|ƒŠ .  iÀç;ÔŸöúüŠÆN&Xžm¥_/võJ„LYm;s²¹‹¿ÒîÃT€ƒ¦8Ÿß‚ Y¸ï‘þ;ȇ§J߯”Ü>v—‡ÄûH‚¤Ðç»\.&óñdŠDŸÿχ€á |¾Cýi¯Ï¯iëá¾¥­'L¯øN·Hœ @‡ñ_éÏ1Õ`d )΃c¤ì.?Åîw=sÚŠÌçÏy%H +}>ûP¿ß? +§G(òx<™™™Ôô¿‘¸'Àç@ŸïPÚëó»Ã}\³4t\¡WÊë;$Z† üƒg[Ù¯t0¦:ŒB¡¦8ßãñHd>Ão ÷Énwªã;Ålã8ARîóGáHü~?Ÿø|Iˆþ¹Äþ•°Äöl;|¾C>Ÿ(«m5Ë™¯»%Z¦¢±“Ž¡Ù¯϶bªÀÀív‹ÅùŠ¢èý­ˆßïg÷‚]‡ë ´Kno~úÕÅ®ÞãM—ìz¤+…>ŸÕQ57B¡ïpÇS©âõzãþa‚>ÿÅ^ ¿B ,>8ñCk}‹@ #/ðí04D]o ðùùüîp_CÇ^3I?H´ ø5m=üLõQ-F¶Ýæ÷ûEA‡€Ä¡‰T#nÑïÈ# ú|>ZSôoJ.Ÿ +ÛH¼›xFFFÿ_žð¸Ç$w’c-Á`»í)(U>Ÿ’ž7âaRÊÃIÐç‹Ž@ ò=èÐGß"ÄÈ‹Ñö} +`ðùõg4Bé9E"g.võòcè_LõAáõz³U‚Áàæ¯>k†Äãñð?ñûýCn¿¢(™™™­7Êצ€fñÒ˜²á°âÇ̦¡äÃÊl\hÂð?¬šs‚P(DÍàÏa‰óŠ•Ç]f¸Ýn‰»Î ú[ævÜŠn.K9¾¤WÔpŸO=¯¨È‹óé–ÔŸžr]•Ý#¹eøÊöM¿ú|‚åÀá°|’Ÿ ƒÝÀ…ÏG àóŸH#àóêÏ$øüãM—$ræds;Œ‰}0(˜Ù³8ŸÍæ¯.Wü;u(2qC€‰GŸÏǬ5,33“ @ ®Ô9ÌW‹ãÈ…¤•mv°&ÍZ©ëÍyÊkŒ­Ü&hÊÎ.qÈ1ô®ÖïPôA No6|Ôó†çaõÞt™løè_·Û’[^ à[ôƒ¼[ú'Û…€½gá¾É-cìüË••—ímjj}>ßÖdÛ£•RFÀÃ&üBW=Ø¿…ÏG àóŸ£–dúü‹]½9sø|[’¯½µµµººº®®.§û8Úî󉸥þ>ŸÏ.ŸÏÄ£ø ++ëµXó?’†Ò:LjV®>?nQ7¯ÁN<™ÐPVUU%2”š¢tjLI ·Û-‡gffêM¸uŸ¯Ÿ´‘Aî86` ßpéÑ[ú]9öxBÒ¬f(5;€²þ<áq ì.o•Ü2¾ó]꼑ãóÙƒ!ò‡ìʷÄA%+ 6úüŽýÑfŒ¿zÆøçŒÿIÎøŸª‘™3þš™ã¯9~ìÌñã¢1nü¬h\§Æõ³ÆÝ0{ܳÇޤƄÙc'RÌ;iÎØÉs®¥Èšsmöœk§ÌÆÔ¹×PL›{ÍtŠyј¡FN42gª1k~4fÏÏœ£ÆÜhü”bÞÍ?‹›Õ¸E 7Å-?¡¸U±ÈÃ…Ñø1‹E±Èb1[£‘¯‹%ѸÚ, +îqËÀ¸™Ç æˆ%óÆÜ1g`̳ÆÌ‘30f1Ý ò£ñ“hLSÆ”‘=0²„˜¬‹Ic¢úc1‹›DÞM?e±hB,T#W (&RdÞªÆsO>æÐ2ÏɺvF,¦ŒiÙј‹)Ñ›‹,Š)ј‹I±˜¨ÆŠ©ã(nŠÅ±¸AëYLw],ÆGc¼ã(¦‹kcqM,2cñS5~‹ÇâêéÑBñ#5®šq ö+{ëêœh†añ!Õ°l™ÑœÃÒε±ä3VHAãfõg!<]KJ7Ì{c,nÏQ,MMRÓOVY±”•=·?k©‰ëÛÜÕŸ¾bLŸÇ4©Œe³Ù&9MŸÖÌ2Û­²ÌfœÓX*Ò—Qš²š…ÔD4Ø\do:Òd¤¸IÉƼd˜$©IŸÌ”>G¦©Üþ4õm¦¢pÇâ–XÜL1©?æÇb^\37s(&÷ÇìXÌŠÅÌXäPdQ\+É]†é‹g0yÓç1ÃT¦Ïf† í:]BëÏi&iM’Ùâæ·«&fÂçÀp#™>Ÿðn‘ø™îp_2¯½ºººJ¥³³3ÝÇÑ ŸoX~,ÂJI÷KÌêÍëÖÏ9’†Ò"\jÑ Ÿ·zVStH2Ip(Å–¸ÝnÃfñêô“\¾”E¡‰*®ÍaüäfS7 Š HÐÊòÔ_©ÙÕ%íé ýPj¶ZL‹ó‰2¾ÿCÙþoÑ%óªÛÛœBŸ?¨$ø|}þ5[æM{sÏÌ¿ì™ó×Ýó+vßZ±sáßv.~kgAåŽÂ··{Ž¯9V¼þïÆw¼[ßÝæ}·hû{E»ßÛzÛû[ï<±åî6ßóÁæû>Üüó7ýêäÆß|´ñÀGúxÃ#Ÿl8øÉúÇO­{âÔÚ'ƒkŸútí3Ÿ®=tzÍ‘Ó«Ÿ;½ú…3«ÊªV=»ê•³+_=»òõ³ž?æùKõŠŠs+Þ:·¢òÜòwÎ-?þ÷Â÷j +OÔ,ûðü²Î/ûøü²Sç—~úùÒÓŸ/­ú¢àìÕµKÎÕ.©©]r¾vÉuKjëòëBùõ¡ü†úÅê7Ö/þ²>¯©>ïŸõyÍ ÑøWC^Ë?Q|ýEÊŠ…mþ[Ž ¹r/5F£«1·[Ë_F£çËÜ+ÑXÐÛÔa5¾Q£/·j"b_Þi¼5ráÖ>Š,èkXÐW¯FhA_Ý‚¾Z5¾XÐ÷ù‚¾ó¹}5¹}Ïí;§Fuî7Ÿå~sVªÜoNÇâÓÜo‚¹ßœÊ ’þ87üQ,N.  Æ‰…½ï/ì}Owö_ØûŽÇõ¾½¨·R·õþmQo…]Ôû—E½o.ºòfÞ•?ç]y#ïÊëj¼–w¥<ïÊ«Ñèy9¯çh,y=/åõ”åõ¼˜×óBÞåçcñÜâËGÔøãâˇ_>¤Æ³‹/?³øòÓj<•ÙŸ¹4ÝOæwÿ!¿û 5~Ÿßý»üîÇ—Dã±%]Æâ·KºYÒõ𒮇–t=¸¤Ë·ä‹K.=Ðüû‚öýÊþ‚ÖK[,ý—oéW¾e;eÿô-kò-k|pÙ…—ýã¡Âú‡ +CÖ>\øÅÃË?xùù‡—·|ph™}ríK¥kËJ×¾PºîùÒuò¯;â_ÿGÿúCO­ö© Ï<½áé§7øŸÞPúô†?<½á‰g6üþ™?»ñ±g7<´é·‡6=rhÓÇ6?xx³ïðæ‡7?ðÇÍ¿ùãæ_ÙüË#[~qdËÏl¹ï¹­ûžÛzÏŸŠJþTt×óE{Ÿ/ºãù¢ÛŸ/ºí…m{^ضëÅm;_ܶýEoq™×[æ-*+ÞZV¼ù¥âM/o|©xC xÝÑâµG·¯>º}ÕÑí+îXñòŽå/ï(|eçÒWv¼²sÉ«;¿º3ïÕ‹^Ý™[¾kAù.÷k»nym÷ͯïžÿúï™óúžY¯ï™ùÆžœ7öLÿóžiÞ3åÍÛXPb™þæžœ¿DÓˬ¿F3̼Šh’¹¹b—»b¥š‹f›¼·¢‘_¹cI厥•;–Un_þööoo_ùvñªcÅ«¯}‡RPñ5 m>¾mËñmEïnÛönQñ{Ñt´ã½¢ïíyoëž÷·ÞþþÖ;NlÙ{bË]'6³ìt/%¨6ßÿá&ÊQ¿8MS¿þhãmØÿÑJV¾7W3[ˆe¶Ëlߦµ¯(­©9­õ‹(›µ«ÙŒ¥².5ƒQîb)«O’…bYÈZ"êã‰È,iÒÑÉÜð‡æé¨?#©éh°éµþŒMJ¯y‰'%5/]æyéO&y闞ΗšòYjú6;ýv`ve§ýÆ JÙ¿ôk£%¤©eõj¦ª‹fªå_¨iŠâï¬8§Æg¿]qö·+ª]qZࣞSz>yÔóÑAŠ•>¶òƒÇVžxlÕ{GãÝÇW½£ÆÛ¿[Uù»UoýnuÅï£ñ—'V¿ùÄš??±æu5^ûÃÚWÕxùɵ”¸OFWYéºþÜUÍ]ÑôõÔ€ôõ”š¾¢ì™o3X4‰Úô¨Ä:ÔŸÄöÿ±?ýú¥²þ<ö³#[îWSÙ½ÑT¶•RÙݱlv§šÐn{¾ˆ²Ùn]BÛf”ÓÖGÓÚv1­y^îÏlË„Ì–¯f6Š…±ävëkÑüvókÑä6/–ßf«ùbÒC«àó`¸‘dŸ_^ß!Q45m=ɼö††¦›zz’ú¹N`¯Ïg¢^_Ü+Â}2·úCöKŠ¢PK4…ÊLõX¬ÏIC9¨×›v{}>\C1Ρ©"œH2©««£q¬®®ÂPŠ2V>sè]3!oq)ñÃ4åîq}>ƒ?Û’‘‘‘àL`Ý®ïsj¿fÔh‰%³>_3”VŠóy*»§¯¿$¹YL(èº'wS¤5ho›S^Ÿo‹¹qx"yŒÅbö€Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï€QK’}~M[DÑ”×w$ùò;;;G†¶×çsÙ ÍNÂá?ØX/J ËPÑHþÑ0”ûÇÌZÛëóÅQ6; MÍÁ &“!%ŸÀq-‰µâ¿mq)y×Å]4½ã®2+ð½ yƒC¡3ÿVR„-„Ãaq(­ç³Rϸ³*‹Ž(’›Å÷Øüùÿ‹ô(ö¶9…>TŸŸŸŸŸŸŸŸŸŸ`È$Ùçw‡û$ŠÆwº#24ìõù¼’VâEy ?7`z©(Šßï§ÓruIÇ»ÝnI#飙÷£?IÐsŽ`¨Yé÷;ìõùt¯½7; MÍ´1ühMY^ÃÏ£²²eS©"Ÿ|[Áâ6?^óŠÅ¥·ëâú|³쪡ã 7&Ĩ1ìl©*ê¶RœÏ·HˆïýàkÉbwy«ë¿>ŒTØÏ…>?ú4D `ø½Îg©ÐÙø ¥…ÊÓ>|>|>|>|>|>|>|>|>|>|>`dC_ékc‰ +}?¥/’èN’}>qø|›DÔ\ìêÅ  {}~DÐõ†g…¿™Ï§uÇT°!n·[#]éWf†322,jÞÑ ÷·Ô‡úwm÷ù¢®7<‰(üÍ>šŸD ·™NäX¹"Þf3­mxùŒ!,%®"5{^ úüÁ®Ûß!ôïR;™É§nIá½ÏJq>ï1c~0vþç’ÛļÞYû"ç|¶·sú|6“iÖi&îC$îRZoá¿ðùðùðùðùðùðùðùðùðùðù€4…Õ1z½^ú2hXvÈ‹KõtÃê3’ïóO6wIDÍñ¦K”!`»ÏçºÒ°ZR|×ÐçÓÚäK/33³$† ìxW®1aòãÂ=›ÏÈbÙîóy»áÇiÞ5<Ÿ-4èl&Ð|†Ä}ÃÊñ©• r´²”èöÁ‹ç5·‹>Ÿoʈ~°«FßÃâ}ÎÆþÐív§ö~g¥8_<Æã).<ð‰ä6qUvO ø¦HkÐö¦ŽBŸÏ&‰f^‰3œ¦"Ÿ~loÃçÃçÃçÃçÃçÃçÃçÃçÃçÃçF ¼ìÐLžV—‰E¡ëÙ$ßç·õ„%¢¦ôœ’üNèS”ÞÊÊá}æ"…ûZ•ñ`µ÷rŸ/Vàë?N¬Þ7ôù\0ê%0­;¾rù¤:º$»Ã} W†P;ã^ /Æ6Î|8¨KãÎ>LŸX¯AS½ox66ÜúàˆP¶mø¬ÇJŽÒOª¡!_J@€.™–~Ù¢Ïç.öê`W~ÐE+ˆÆp§;ÉX)Ρy"¹G”kÉø†ÈQG¾J$ÍçÓ Òœ·/i¤Jƒ•­[+î‚ñáàS‘ïÜÙ8£àóáóáóáóáóáóáóáóáóáó£ +½ÐȱºL¢ôQ œ|ŸO<Û*Ñ5m=ádö@8T22ZÇŒþAí ›¸J±‚×:Ÿ(í5‹KTý†>_s* |¯ý 3Evé)=»z}§[$Snøµ“Z+¿^Âmø®($­#÷ùi¯o —Òú³Në—cvZ³c×°Ö—’¡Øä]G7)Ã=:@|jLô¨ƒZ5†—/®VºÁÉ÷’ƒ•â|ºSkÿwÜ„ïÿðjúµ¦­G²F +´çו}üNÜ•2’æóùÿO¸0l·kpõ÷6ú-<öÿ.Ã'Dìmø|ø|ø|ø|ø|ø|ø|ø|ø|ø|Àˆ‡1Šf^£VDáOßI¹3aEq¶#N_’ãó/võ>ßVVÛÎ\}Ec§Dלùº;™=.2ŸÅ¿M†É ŸÏš¦XóºÜçZzEQ˜Ûd~X¿¢í]¡¥ç”´ù,žm•_ŽÜ7:áóyi®¦n\ÿºÄç›e: › q/y¸ù|ºïè éy×YA£Fµjä—χ&îXÛˆ_Eó¢•â|êÆy;ïgóÿd}sy}‡Ôçeq¥ äû|þTª|>k‰8p|kF“½nãüχχχχχχχχχÏŒxå÷!z¹AÇð\.—¾Ÿ]E‰~r|þáómÌÀT4vÒ¯òò˲Úö¤]~8L#™ÏÂðB¸ ¢Q^,÷ùš:|Ž¦nßÐç‹V“þC_·¯?›˜±éÏý~ÿRnJ|¾ÙRr»Ýâ=H³:¬û|½Ôª1k6û+³A7|¬ÀÆ[‰x]’mqG#:W}Á&ÿñ¦Kò§i¶>þñðù4 +4‹hEðµC¯” »hbÔ¶0iÈØô¦ ‡>>>>ß:ðùðùðùðùðùðùÀ ï¼ü붙—qáJÓ!¹‘.$ÇçózËÒs +{E¢k|§[Ø1¬ŒÿàÙÖîpŸC û&J/™¯è C^Ùkñ`ÏèÔ}ÄHòú|EQØߊÅÌt~:fP–ÒÒÎçK&|\6(Efv°ÞçëÕ}ÄHòžMLÚ\ì{<C·oh5%;¼…ܱ'¸Ekq)‰î]ì1£š™XºC62‘U3¨ `;¢·w»ÝúVIŠó©7®ÊžÍ'ÿÉæ.ÉÒ¸û•O~xJܶ—¤ùüá¿d6Ùø:Òï71ó¯y¨Ä–†Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡ÏŒlÄâI³c¸zÊ0‘Ÿ„Ïç‹{žÑ@r|¾XßÖ¦WÊjÛ%Ò†Žöds—­ +‡Ã---_]}ùüK‹õëÂ^ŸÏ— ׉úW }~D•“ôŠXÉ,ZJzËÆGcØPvvû=¶1”.!>%U>Ÿ [_Lé_‰˜ÒÓyÌÔ.½.ÎøجÊ}B›ïˆBÞúyøÓ †O¦èu¨†¼jRèó©I|\Ì ú}Ãâ|·Û]xà^r/_­÷=úWþsCÇÛ¯eú|q&‹;núQfÓÒÆø|ø|ø|ø|ø|ø|ø|ø|ø|ø|À(Á°$R/q 5$òEr$‘ŸßîãæÌ×Ýô +ý+‘6¬ðòðù6+†sÈÔÕÕUUU}öþûJA’‘1ÌM~›ËÕenòùúj|}ž™Ïçús½§¥SÙ¥ôÙPÝÝ݆oºtðlë07ù¾Ó-4óåO£¤ÊçGtÕø†ûò¦#}>¥eQÿjž“š4iÒÐ|>oϲÜã'ç¡õ¥Ä¯7AŸ?äU“BŸ/Ú`~Õ\ÿÊ‹óéÈüÂåâÖ­|î|ºV󗽤ÐçƒAútÉl… ËífÛFl¶Ó»6îÃÂçÃçÃçÃçÃçÃçÃçÃçÃçÃçF¼"TRx,\ìŒÂ2<=Éñùœoë K¤ÍÁ³­tÌÉæ.þŠMª©©aج®;pÈçG +|½ÞXðù"@ÀãñpÑ缇ñC)'…>_#ð5zŸaý£™Ûç{¯<¥¿ôÒK¥*o¼ñFe ®²+upÿÉíº¸Ù$WkŽ·¾” {Ï.Ÿ?ØU“*ŸÏ»]Ó|¶È‹ó#÷vÅ'¹ôQt¤~ÿ‰²ŸËë;]_ÉÿA+Ó†­'˜EE±wvÁçÃçÃçÃçÃçÃçÃçÃçÃçÃçFV¾ý‰ßǃÁ älðù‘$ú|.çy]eé9E¢nÚz»zù¯ WloR{{{]]]ccãGç|¾Ïçã«IüY¿âD¿Ä\«Ù´ý阑4”q‘[kç|>ßN¥i þ¬o›x¶P(Ä&ƒYY¯f6²¡ljj’ŸÖn¼yµ¿•U ñ¢Ö—_âƒ`‰øüDV ß±±|:.4¸¼Ïé¾·"Þ… ˼ù ôã`EÍYÉMaÿß.hžó²´ðùìÈðh!|>|>|>|>|>|>|>|>|>|>`4`åÛ×)q¿ÃçG’èóõr¾¢±S¢nN6wÑ1϶²_7]Âü—àœÏkòÅZ}ýªM³|’Jéä̺ 7¨†ï:çó#BM¾¦V_2¬\z›9v³ÏÂl᧢.’oæòV‰byPK‰þŠõ†æÒñù‰¬šäßΨø&ø[âë†ðm ñA­3åù¥ïWJn +÷má?w‡ûœ¸¨4ªÏ‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï‡Ï¤V¾ýq#ÿ†È-%|~ÒÌ*—ó‘†_eµítLy}Géæ9ó_‚s>?ÓGÜ^z½^ÃU)š(·Û-iÿÍ©À ÆZãÒ5}ë„Ï矋}Í õgã•üfíá—#),·xE¢aÎÈÈ0[ ➯Og­,%z‹F¿'âó‡¼jøí,™Ž—·Vó„ß+1Cœ6ü¹-Šæ²«%w„ÝåMOžúJ¼;8Á0÷ù4ÃùûÜèä4vÔ ùŽ¡½-™·~¿ŸÞÕÏy}þU3®»eÞø­ó®ß:÷†­so*š3±hΤms²¶ÍÎöΞâ=Ý;k†wVŽw֬♳‹gÎÝž3_[väܺ#gÁŽœ…;)fäíš±x׌%»¦ìž¾t÷ôe»§bÏ4Ïž©«ÔX½gêÚÛ¦¬»mÊúÛ¦l¸}ÊÆÛ§lº={óÙ[îÈÞzGÖ6Š;³¼wfß™µýά{³vîÍÚµ7k÷Þ¬=wM¦¸í®É·ß5ùŽ»&Ýy÷¤½wOºëîIwGc"EÉÝïQc_ÉÄ{K&ÞW2ñþ’ ?cqÏ„Ÿ«ñ‹{nú¥¿Ú_«ñ›hÜøŽßÆþXˆ…/ˆ¼/Å{c±O{nŒF‰wRÜ¥Æ^5îŒÅjÜ®Æmjì»ÕØ‹7EcÇM>ŠíjÇÂ+ĶX©±U-Ñ8°yBlRc£b±^uj¬Æ~Š5j¬¦˜UB¬TËj,W£Pe±XÚP¨±$ùj,ž¼X,ŠÆoÔøuÞ¤_åMúeÞdŠ_äMþùâÉ?‹Åý‹³îËϺ7?kŸ÷äg•,ɺ[·^ô;´Ì7.ŸF±aù´õ+¢±nÅ´µ+¦¯Y1}µ'«ÔX©†gåô+g,_9£Pe«f,휂U9KVåä¯ÊY¬FÞªœE«r®îÜÕ9 (Öäܺ&ǽ&ç–53o¦X;s¾óÔ˜»vÖœu³f¯›5K™ëf嬧˜M1cýìéfOÛ0{ªS6ÌÎÞ0;kã“7Ι¤ÆÄs&lœ{Óƹ7nœ{æþ¸>ó®Û4oüæyã6ϫƵ[æ]³%úïX5Æm¦—ëb&Eso,Š¦Š ”p¶EÎd5çDÃÛŸy¦ª1Í;‹¥ –…rŠgÎ,žÉrÑœh:Šf¤y±¤DqóŽhjrDzӂ9¹j‚¢XD±«?SåïšÎ’ËWjÊšN)‹by⚶rÏÔ•BúZË`ýIì¶hS#[HeÙEwd© Í{gˆ9Í0­‰™MLn,³í˜ÙÄ´&æ4–Íx*ÛK\ÑLeœ…,'¢½‘<iÒËEšt´Ý(y¦#ž‘Ô¤t`ËÀŒ¤IJ&%!/í—&šæ¥•ó’&5jSSüì´x@vÒ$¨_Å”>Gݟߟ¦î¥)1SQÜ¥ÆÞ‚¬;Õ¸£ ëvŠ¥Ù·-ÍÞ‹ÝjìZš½séŠK§lW£xÙo,¶©QT8•bkáÔ-jl.œº‰bùT–¸ús×rž» ÒË`!ƒ±$¶l@›Á’˜>-ZmœÊx6»eí·ÙL“ÐxN›©Ëi<­M‹¥5}f›Ël<¹EóÛ&ãüF‘™?> ô}Sþ][<@þ½8èÝÂ($™>_/ç}§[$§;Üwæën§ 2GŽú| ÓT>ú|þbFF½ÎÍ3ý@¿r_dh¤Å5+VDë{Þ ŸÏå¼™ 7<›¸Ç*¶™~æoy<I;­_µÏ.–ÞéZ*cÐÏ|[ÊìCy“èo³Ï ï¢D|þW ¿ áC‡†8¨£ø^ ý ö¿!b¡{Kï[o˜»¦Ir;øÍ¡jÍÓ[NdŸwïC‚Ù/Cn‰~àÄhÖÑ@Ó1öÎ"¶¦ 7vÅ]3ýÚ·Ñç#ˆ‡|:”åз1òbø_ O¸K1ô–ô ×L³hðx¿¦­‡ ö +7ü†AÇ·õ„Å_1ÿÍpÔ狳hª‘#&>_\bÉñQ£®RÍ$˜s>?"d`C±lx6c7,Ø–çGãóÙÇq (ÁìÙ¾ +âbø@">È«†?7¡Ùksîíé_qìâ¶_Óíü¡­«²{ŠŽ(’ÛÁËÇÿÅ÷é¾àÐu%Ùçk6ȬcoŸ?,ÛÝØÚ7ÜFtö°»ûÀç#ðù€Ï¤5\~ŸåßCåUdâwöQ.“éó»Ã}LÈпì±ü^åõ¡€³¢±óß G}>Á©Þ‚šù|6» E®ËåJš‘0±¦ß[‰8ïó¹ú3ÌÀfÍ +q Í$¥t¹Ì Òç3|>Ÿ¦žãv»%Ë$®Ï§)Mg ‡a³ôùC[5lyÎç…BÔb'ˆ7V³®ÓtÚÅ®ÞÃÁOŸ=üè÷~ðä^PrìËP¨>Þt©¡ãŠs•dŸ¸Afe ‰æ§oðúÚbàë°hÚ'ó>Uàóø|@ÀçÒ±T˜Õnñ·ÄÊ@IÕ½X,jïÃãéH2}>ÑÖ>ÙÜÅ«+»Ã}‡sðl+SÑØÉ~=|¾ ó?íP¥²²²$†ÏçKZ ñ†º1Éõض@­õûý|2¸&ßÞOÔø瑱jxwÒD«Y›ãªiãÝóŠì{rï™PÐ%¹Ü´19W‘|ŸÏaIÉDö'Íöœa°ÿ-¸Ýî$·Ð Ÿÿ¾{é ‚EÙ /8´~Ñ·1òbø™ [ÄgÃÙ÷Pú®§)hÔ—_*ŠDçâüHÒ}¾^~o»z:® >Êf,ãI6.Á(ÝÔô¥ï)i†ã[Lg(rxŒë¿B…Ú%7‚9+{’s£Ð糇;4~H|~òÿ«à„Ï|Øsßfè·ÖòÃF!)÷ùÇ›.I4ÎÉ殈ZÕ±«ƒ€få¦Üâ‚ÔÂwv|)Uš@`L<Œ18SR¹7û;ß•=¨Ur¬e̘Ëɹú|ö ‰¾ÁiØÅjÒ|>'0Tôf–^0d¾¦gRåó/võJLÎáóm# q¹\))èÖÀi&¤° ¡PHó|œÓYzÔå™ì;ÿ²ä.°p_‡ËÕœœkI¡ÏOm±âóYý›äÂçÀH" +ù|>úv™­âõzÍjÛDŸŸ™™©y´|4“rŸOøN·HdNw¸Ï¡Ïmmm­®®®«« ‡Ã˜ iÍèJæGX‰> eUUV¥xq~ò‹ºEè–*—ù.—‹MÑ`0èñxèNÝ?c[ƒÊÿ¡h—ÜÆοì]ûa2×Ô¨òùÌÒûý~ñE}ðÉ–ü Dø|ЗtúJßXC¡zCd8øüòú‰Ì©iëqès««««T:;;1ÒšQ;”g„•ècUZ‡eïÔ>köÿÙ7ûà6ª{ïëOÊ 3âþhfîTÓçÎô™¹£ççÂ-5}á5¡KH€„„n)ÜR¨!ô¦´æ¥o’JHÀ"“@J‚ LE0o /Â/ØØoLŒ¯C­ŒËŠ…õü¼':9ìJÇ+k­]IßÏ|ÇcÉ«ÝÕžõ9»Ÿýp8ì›gŸ}–-L£ {Ge6\:é”iIÿO¡¢«O¯Ì×ñ‚ÏÇãÔ² R‚Á Sÿõt]$>saXohÚ½ +ø|@Ä >¿óHZ"sZŽÏÓv™9Ìd29PÍÔmSêºNÿÂj é¬jÇžžüWÎ +µ;µ¾‹³3Dû]ŒÅ‹³¦æglÃYúw2’þå†1ÿÉ}¹ÝÊ#Wþù#Yqð)^ `JŸOôí{n8× ´ Út±'ðù€ˆ|~:+«ÏlêNÌߦS©´am€¦DSÑu]UÕH$"YÀï÷Ës0eËsSMŸbÏ t}ÒçË-¹S6?ëôE“¡³ïͽ®Ì·vÑçÓ1¡ÃeÇäÓbt0¹{/Ÿx<Λ2p{O—Š¢ð?Ñ/ŽçG£Qö4cÝ|> âŸO4÷ê¥321…–€Ê ºåbJßN%9w³´kay,ö™Ï÷^ã¾QIçÒ)ÓÑÕgæFb•ùâ.ú|>+ŠÂ\=;¢·WUÕï÷MÓœÝ:µ”üimÔq™ÏˆXç›Ì·ÏÿäËáø‘5œKJâx:l¤ÓœO)]_O·ýÓ„ôé=žO(S’3é3ÒŸÏ'F>Mö:6“FŒhcý R¾ìûÌÈ¡/û†Œ|>Þ7<þ1åÆ?ÿøpj&_¤>þWªw4Õ{„r´7q´W?Ú›<Ú36ÑóåDÏøDOj¢çhú£‰ôGéôG“鎥»§&»³“Ý_MvOgºs™®šJöð|um5v ê$“ÅÒ=“´½LHst¶¤º§g͸4_Ζ1IJ£Ï–„4GldT–¯(ÿbù¨p¾°—ÃÒŒHó?ö2,Íç³eÈFÍ–ÏÇ‚{%ÀÜ {ÛFGqü¾¸ºðˆÏo>*Q:ûOàÌ€ +`*W ÉR>pHà+ù€°¡Éï5<.éùoÚ®ûOÌíôWì»»èó™½b«ÏÏíó7^G"ëc:¨¹­šÝ©CMçfDß®à’ÖG eú|ñã‚< Þ?O=Ž-‚ Hí·K€¹aG#”„ƒ“Ö«úxºëóG&¦$V§¥?‰3æ›x<ÎÝ;s¹V‘+ÛCQ¾¼X†m¶{v·Kzþ³–O„ξ7÷v¨b_ßEŸo ÁŽ›Uq³§-Õ·ƒ§AÌÀqÏ¡3DòÀhVàó>AÏTðùót<Ýõù„Ú1*;éì4N~˜?"‘Ȭ2ß$ü øECN£L_2ÓÒŸlJ±¿Ê»ýo~gê·Ûö?ÛÙ921U™#àºÏ/HØè‡MK²÷C!gs°‰Šâs„J~ß9gø|ÏGAàóU„Éç7”uw}ÏÊûü‘‰©æ^Â\MëÁq‰ØéKfpòÀ<‡Mös“ù&)Ø›ôAMÓ¸À?Ö÷ÅaIŸÓö‘…k>g¿ÓèP™ƒà¢ÏgV21µëãAIŸ¿~ÃÃMÿü€ýÎëùç}>kõëjší‰©xžµ‚SCv0dS**ùeùqö‚Ïÿ÷+ÎùÞƒ×Ô@δæ¯39ËFþCÈ÷çjÊÙùü€òЉ4äseãÕ?4ò£!–ùÉÆйWQÎÛ¸ê|–¦U4­º°iÕEMW-Ü4“E›®ºxÓJŠòðL.yxåâGV^úÈÊ¥F.Û¼âòÍ+–ÍäÊ囯\±ùÊ•[®¼jËòУ˯~tù5.ûÙcË~þز뚗]ß¼ìÍWÜÐ|ÅÍWü*ry8rù-_¶æñËnÛºô×Û–®Û¶ôömKŸXrÇKî~òÒ?<¹øÏ-‹ïyê’û¶_¢nWØ®<´CiÚñÓGž¹øÑg.Žì\´mç–gnßµpçs=½pOô‚Öèßs~ÛÞóc{Ïko=÷­ÖŸ¼S[êß6Oÿì5v ê+ÏÙ+dO>»ó‰Zò\>»fòö³Bv²œ{"Ïäót>;òÙ~î[¦åé{n¨üü,}>;VŠ¢ˆoÒU BûFW8¼±ÔÒ%vAØ,¢2—Oš¦ÑOŒXž’&K:èóÿÏ/6¼ôk/çœòò×nó#!?¶ä'/ϹFÎrþ+ÇsÁ+·]øÊZ–‹(mk¶­]4“[)·ÝúÓ¶[#—´­YüêšK,yuÍÒ¬¹ìk.ÿÇš+bk–ÅnY»åÊØ-+b7¯ŒÝ|Õk7¯zíæ«_[};Õÿ¹oõµ¯Ïäº×Ã׿¾¡ò«ßøÕ¯Þ¸iõ7ÝüæMkÞ¼éÖ7o¼í­×½õËÛßþåoß¹¡ñîz熻ÿyÃÿù‹{öÿ×½ïþ×}ï^¯¾{ýƒï]¿ñýëþàç›?¸ö±øµxíþì©Žÿ|ºóšg»®ÙÝ}ÍóÝW¿ðQ襞U¯ö®Ú×{Õ¯|§Å{ý+>üäÊîO—|`ÙeƒÚ埼ì‹Áˇ–ŽZ2ùù¥_ /Î _RSß1_ÿó5v ê$Ÿ2rh&Ó,Ÿ-žÉ ‘ƒB´|Œò©‘OŒô³\:“>#éÒ“ÏG—~EéÒe¤ÓH‡Ä|0“,ËûFÞËç]!ûüsÉLÞ9‘©·¼eäM!oi7òº}Kgòš‘Ø×ó#¯iòŠ‘—¼4“c/]6“¿yÑÈ Bþ–O«‘ç…ì½,CÙcd·¨‘çŒìò¬‘3™¤<#äi#;.ŸÉv!Oi1ò¤'Œl3²UÌ“‰i>‘ôcF5²EÈf#y˜eÙñl2Ò´l‚²QÈCFþjäA!¹ßˆ:“£<ŒÜgä/È\òZø"ø|€SÐ-!ÝBì—‹>dbJ¬Õ¤wZú“½CËì?<Á~oîÕÑvP>4h²Q sªŠ¢Ì*ói=º®›>HC ÈlµÔoóùVƒ½’Þþw{?nkû½øÀ·2¸èó骆m—öA|“·Î¬‡zΰ§´Î +\8™¦XJÉχχχÏGàóáóáóáóáóÕ Ä~™¸èó µc”›¶¡½äº¾`è¯}É ™ÌdËÜz6›M¥R8 ª4e-5åáÇє•$‰PÿOÃe1EÌ«Äå2ßô,ÀÔ”ÔcóÞ»óHº¹S“ôöϼ¬5}p€ËÿŠ +}>këózǤô­‡º|èJ)°g:áp¸±8âã†9ŸŸŸŸÀçÃçÃçÃçÃçGÓ4º e7¤ûöq×ç·gƦ©;‘ûzž5-ýÉtvZ4Ben}`` Ë Nç@5ƒ¦DS‚y‚VŸ "‘ˆ¼)©Ç>1Ùê_ŸHºzÊkí‡øï}ÉLž¬»>¿º®«ªª( + Óô‹ƒ•ù­ÓW +tÍààqžó…|>|>|>|>ŸŸŸŸŸ¨%âñ8ľ}ÜõùÖzû¦î„Dò¤³ÓͽºSE›}}}L7¡¸ÚASÖ ===hJï`§2¿ Ì·6å®c¬ën~/þn׋’~þ/Ïõ· ¥ØïjÇh%¿¯7}þ¼ŸŸŸŸŸÀçÃçÃç#ðùï ûlF¹ã3Ö«w}>ÁÎþÃ9¡b¿`ú’™öá£bI9Œ á4¨vД5C"‘ ¦Æ¡p›2Ÿ³Ó”jÇ(ëºÛ_^ÛôÏ$ýü‡ï÷:øܶ$êÐçG"‘ÆR Cäàq†Ï‡Ï‡Ï‡ÏGàóáóáóáóáó  r±_çVßuŸ¢h³WÏ}½bßšÖƒãƒãÇøË‘‰)œÞà8eÊ|b¿}×;$|ã¾Ïµ¾Qñn%¿uú|W€Ï‡Ï‡Ï‡ÏGàóáóáóáóáóÀ&ž#ÅfÕ‹ë>¿óHš«›d&›ÎNKT«É7•ôp +]×mÊü`0hs|^Uã¾Ñ…kR’N~ÏîvêØùK*ùÝ=âói7f-›¯êKø|ø|ø|ø|>>>>>ìFM¦>ß]Ÿ/ +üÁñcôNKRb{F&¦xI?Óû¬P÷N{8¶ÿ]׃Á M™O Û\í»½¬Ó^rçxã¾QI¯uõóbþÖƒã>b®û|j2¿ßoçøÓ’Õ{fÂçÃçÃçÃç#ðùðùðùðùðù0+Lã¼M†Ïw×ççŸÌdé¥Xœi ýU,陘Âé "4ä‰3Ñlsöe> ¦š¦•°C;ý¿¹ûÁ³–ž¾hRÒ½?ÔúÁ´ñŒ`püuõ.ÎϹíómN‹€ÏÏÁçÃçÃçÃç#ðùðùðùðùðù€ÚE¢ñ@8ŽÇãu~ˆ¼àóÓÙéÁñcLæ#SáÓÒŸ¤eÔŽãžíÃGqž#‰Pgnïì¸w ÅGr™_ÚÐy ’kñN[çó^r縤{_ÿä»GÏEŸO '^ŸÐ¥K£§JèB¨¡h?<Îðùðùðùðù|>|>|>|>|>0 ñíãŸo¥©;!q>´@ÛPŠý>8~ ‘HÄ*äƒÁ ñKŸ-8bÚ”ù4àÒRt`}!¹î ŸoóI§LK:vÊ© ¾*]Í:‰‹>ŸÏŒP+{¬O*0/>>>>χχχχÏ4þð¦Ïo=(«áìKfh™Áñc#ShA@CݸÕäÓ;6K©iÜ´érƒÁ ®ë¦ÓØ*DFb¹_ð[«}¾O_4)éØoÚ®û|ô]&]<’.ú|¶Q:˜Þ®}ŸOgêóáóáóáóKn>>>>>Š_ÞôùGÒíÓ6”BÃ@îë +Z4ùVñnEÓ4^>7™Oã/_@Q”ÛاÄnÿ_>ßzŸ¯ûÚ-IIÇ~Öò ŸvÉ+³Â›fµ3™ÂYè)&EUUv}åHe¾é8ÃçÃçÃçÃç#ðùðùðùðùðù€º‚nBÃá°µ(¿$¼éóÓÙi‰öiêN á ÷u í—OÓ >·/óiåk _ +¹ûåŒÏ·þÔG%½:å¤S¦ƒßz'—Ñ=r0+¼iö`%zð£¦g»§–nÎåÇ>>>>χχχχÏÔš¦Aã;ˆ7}>ÑÜ«KÌO2“-‰D¢§§g`` ›Ízê»4e=7eWWš²$TU¥ž¼¤ÒnÞóÛF«Ì§wÄØú5åÏ·Åù[ÏZ>!éÒWnóùr‘ëB¹‘˜‹GÒEŸOXtŽƒ ++vX4'fPØñù´!É)í Ïÿ÷+ÎùÞƒ×Ô@δæ¯39ËFþCÈ÷çjÊÙùü€òЉ4äseãÕ?4ò£!–ùÉÆйWQÎÛ¸ê|–¦U4­º°iÕEMW-Ü4“E›®ºxÓJŠòðL.yxåâGV^úÈÊ¥F.Û¼âòÍ+–ÍäÊ囯\±ùÊ•[®¼jËòУ˯~tù5.ûÙcË~þز뚗]ß¼ìÍWÜÐ|ÅÍWü*ry8rù-_¶æñËnÛºô×Û–®Û¶ôömKŸXrÇKî~òÒ?<¹øÏ-‹ïyê’û¶_¢nWØ®<´CiÚñÓGž¹øÑg.Žì\´mç–gnßµpçs=½pOô‚Öèßs~ÛÞóc{Ïko=÷­ÖŸ¼S[êß6O]G¨úÊóFö +Ù“Ïî|¢–<—Ï®™¼ý¬,çžÈ3ù<ÏŽ|¶Ÿû–)Oia9o&OyBȶãy“gk>çɧù|s3ò¨-ùl¶ä‘|6²IH“‘…ò‘¿žÈyÀ’û…¨F6äsŸ%¹àDÖ¹WÈ=Fþ|<í<ÊçBþ`ä÷–Ü=“×Yî2r§;X.<žF!¿3ò[!·ù%ëX.šÉùõEûXn³d­[¬rËL^s³‘Õù„‘Ò²yE|> |¬ß‘ãé5Ÿß>,+æì<’.===]©T +gBUƒ¦DS›Äb±‚Ä‹ +…¬+áÛ’eXSþô§O>ÿ͵­ I—~ú¢Iÿɺþx nëósùý‚Ó 8X¢/ñùš¦ÑgŽÐKëã$}>‚ ¨÷ÏS¿c‹ R{Áý`n˜|¾¢(åáH±Y O¯ùüÁñcù³ëÀ˜›dæ0“Éà?«ªASÖ ÔŽ===hÊX,fÕ˜å@k ‡Ã¾R å ®G”ùÅÆÖ” <äó­?uA»¤?oÜ7êóåBgGro‡\?æ.ú|:°t0y•‚üÒ¥¤éŽÀöÍ‘KºîbßÂ:­ƒþD_ŸÞ× Ø´ëFáó>AÏTÖúü2©üM±7§×|>¡vŒó?ô'G6‘J¥  k4emÍfë¹)u]F£¼>™~:¥ôK-˧M[]+ƒv/ ‹í!kÊo|Åç[ú¢$>Éã>_.ºZÉÄÜ=þîúü\)W8´d…÷?¸T0QŠ¢ÐvM¥ðùŸ ‚Àçªøüy:žôù»ŒIÐàø1ü;jMÓTUeõÏŽP´rfDí ãñxÁµE";2_$´tÓÊ Ý’Îü» ™ÀiZn·ûwîú|qÖƒ×|>o÷P¨Òs(ØUŠé>AàóAø|@A7• ŽRÌZÔ ^öùGÒÔ6”¿ zÑu=KÊæm +sÉú©‡g¥þöQE²QîuíÎÈèÓÖ5î+:ÙŠþäóåÂ竹^ÕõqÑ竪*¶;R*VŠ@gd›µ1Сp¼>¨^¼ì󓙬Äç7÷êh>@õR° ŸëÜ2Ÿ5ÏÁäª 5JËØÙ½‘‰©]Æz¥û» »%=ùÊ c'2ý‡è‡ô{ûðQw[ÄEŸÏŠó©É¢Ñ¨NÂbgfå…Ž‰u»ðùê¯ùüd&ÛÔP;Fû’zÙÜ«KDP:;T)&ß®(Šªª¦:ä9‰D$5ÿÅ q¶ä{×±|þç’nüêköÞ|ÛÓü¥»-â¢Ïg¥¹ÂÛµïóËœ-27Ø%Šõ|>€ºÅk>¿}ø¨X~ß6”’ˆ Î#iþÁd&KAƒª…H$Bo(rª${n&Ÿ=Jp\Õª£’Þ›'Ñôo-oìöȬ+×}¾³Tì0«Ïƒž¢%A¥ ­[ÿŸ nñšÏïKf¸çIf²âKkZŽ›>Ūú ~Ðuzò¹™|¿ß?ªvdbÊŽÌß²7–|æßøËý‡'Ü=’.ú|æÕ]ÑæÞ$ÓÉYlR|>‹ÅÂápƒ¢(š¦9¾¯ùütvÚT~/qAjÇ(ûTK’½³ëÀÎ@@ƒB(òûý¾9ACŒãeùŒý‡'ìøü—žòÝö?ñ—Ôÿ»{<]ôù‘HÄ;±ëÈe~>PÓPHãÑ< Ð`Î4Ðý{Á¿Òõ+Õ³Bï;kõ½æós9O?%:hdb*÷uw”Ìdq‚j›h4ª(Šo®X,æünˆäzÕ\F—÷ÛdbJ4<âKkZú“ìS¦ª~; t¤Óiœ“U šMYÛP‡¯ªªX³77Eqv†× 2zn§Ÿùü‘¿/´Sœÿôs¯· ¥ØïjǨŽ³‹>¿Ø¤¼bØ1ðö·kgmlI:…\9¦=„ÏÔl––”èx„b +=‰ð‹7Õr‹‹Å¸ÕwêžÚƒ>ŸhêN0ÉÓ6”_L:;³TõÛ¡¯¯™CW;hÊš¡§§§š’n½©kUËÖŒñxÜô0wÎPo§¢;Ò’4¾”lxq~‹ïÝ®íøü×^ý˜—ñ·÷BÃÁçϺ¤G.àóµG±À© Y LŠ)tEQŠÉ|†®ëÜí8R­áMŸßzpœIž¦î„ø²`ú’Z&™ÉšÞ™•±±±¡¡!œÕš²fH$Ô”ÃÃÃÕûâñ8/¤Ÿ›Ò§;÷p8\~5>ƒ† ›*€6:G]lçGWÿoÿÉwN[wß«‡ìøü—^îá¿LLy¡í\ôù‘H¤±œÒ;6}>?2ðù0Oˆ£°È|M¬%Rì¾Øï÷Óû@@òÙh4ê`µ†7}~_2Ã=O2“_Zà ;MUýPaâñ8ëÆKõùº®G"‘P($~¼Lh(¡uÚÙº¦i¦Y4ДðµßçZ|ÓÖù|ë)û>ŸUæ¯ß½÷sñ¹­pÑçW:+ò𫎆âˆç†ê yŸ¨=h,¶^85#”O1…ÎއÒÏêº>—úÉ"xÓ秳Ó\ûtI‹/­á.¨m(å5;¨"‘ˆx'Nꬳ¨èæ]UUV#í ´B›&?g<#w›~·ÿÙRZ®Å¹î &ómúügZ»G&¦ÔŽQÖÉ{¤ëÄç‹_³$èÜpdb`ùÀçjêŸÅÙy¡PÈ#½.ÈÍæógõ5ïó‰]Ƙö™˜¢—-ýI‰Jf²9KU?N3@ňD"¢ù¤{ðY—ïÙ‚¶[ÒÔ­p8,~< ÆãñÒ¾y[ƒXœOùæw[¹¡{mkBÒi¿Öþ…±N|~.?°$EÑ4Í#ûŸ¨ah ¦ñ&ÀkSèlV;êóƒãǸ–o>*QCûO°Åø;ôYœf€Ê`’ùòΙnÒYWï ~¿? +•¤[­»1—:ÀCÑ\‹O]ù}.óóy±qßh±›þt$®y®=ãói7è2€ÏÚô»ªªº&‹ø9À£äG<ó|>€ +SL¡³RIºy—|–‹£h4ZþžxÙç‹ŒLLI|~s¯ÎcÚŸ^¦³Ó8ÍÀTâN]t±%u]…BΚü`0H[,Õôjšfz Ùm»ú–oøO¾Ëäó¿}F\Òc¯Ü0VÊ‚ÊáºÏ§vä¿àSÕiwÍ6çHy@%Ï€*BÓ´˜£¸2™‘ß›‡ÃaºæõoôíèMúS±{vÚÛ@ À>^R)f1ªÅçjǨDñJ~¨¼ UæS¯ÎºwG €†9¢¸ƒs/Ànñ…ξÜRœ¿~ášÏ%Ýõé‹&ÝxK;,•ß:ïvÎP(äàFÙD€9>Íqø|¨"Lò¤|bn” J ¿·–ßÓ;Á`ÐYý^E>¿õà¸Dµ ¥ðߨ0¼šZRâN£ ïºË„¶ +…ʶt]W…Fœ2 ³ãÛ~a•ù>ß曶ë’îúœ ¿òfkºëóÅs‰ÚE|ÈB;&Îì¨:ýî8ðùPEԆϧoA÷æüæ½ &ÍbZxîå”EŽ§÷}~_2#DMÝ üw*L4õ듳 Ö‡¼®ÓаÃêóO]Ð*é«oÚ®—÷ aqÑçG"¶]EQŠM¤sŒ=ñ§ŸuþŸ¨a¨·wk +9À_„®Öhè^ž¾ÝÈso/ñùÖæU‘Ï'ÔŽQ‰&™˜Â?À#°ør†§`0‡zzë8±Øg…Šóן¾è=IG½pMÊíQWò\óù¬ü>ÈßÃùx¸C+o”Bg£G¦ÀçjêÛi à#õº°ú¨yølt¿ßO×?tgªiÿ+ýN×Hô>+oóøŒuºxw>—÷ùôÓÙÕåóÛ†RMD-im‰D¢§§g`` ›ÍâߧªAS¢)½F<ƒsÓøÔ«ªj<ˆ¦% úü•I:êoŸq̳ßÈEŸÏŽËöˆ.fÜ:] ðK#9Þ˜\Ÿ¨=èÊÁÚë:ÛÛx ºÚá&D^É@åæßËJß]ãÍG…Fuùü‘‰)‰&jêN”´¶žžž.ƒT*åýïДhÊj!Ú´£Zž&ú`uUâÅbŸ56¾Xp¯èó÷HER/×|¾ý ƒlÔvpÈæWDv@}>ÌÅzc”è VÑ4]ðƒA›×<ü’Éû5óJuù|¢©;!Qú#SöW588ÈÌa&“Á?QUƒ¦¬¨{zzª·)y§jßä;åHiøSU•:óJ–óÅZ_eþ7¿ó˜¤‹^¹aÌËòµ}>{lÓ@€ÖL;Àæ•Ð‰ËÃfÐOï8%ø|@íÁæb[qvj6€wàþ$ÚüÝ–²„B!º*òùmC)‰,¢¿–´¶T*\ )kƒl6[½MIÃJ±›ñb„ÃaG©¦i4–‰“*vûÿƒÿ÷gÑ矵üo’.úôE“ñ¸w[ÐEŸÏÎ;b˜owê‘ Ûn àç!{Çtþ°K…J>'’Ÿ¨=ødsu^{€†+”9|Šnc]Üsºe…B´\ªÏZ¨É ¼#;Pu>dbJ"‹šºøwT]×™hµ u¹q'Ôv4-ø!^on*Χ¬Ü𾤋>ó’ÉÁñcžmD}>‹ý~¿ÜÛðrzûÕ rØ3 UPâ¬ßú<ˆ]¨Ä½ñ<>P{Pÿ/>—gPŸŒ#€Z¥Ÿ_ùÛvN±2Œ`0(¹e®sŸO4u'$¾¨/‰"m@E¡›?–º[Ÿõ¹­-ÒRp£Ô™W¾8ÿ¤S8}Q”"éœç<‘ªb¸èó5Mã§G±æSU•-#–Ó—‰u6»* Ÿ¦%Ù‹GJôáó5 õÆâÈ +…œêí<7ó%UŽñw÷¹˜ð)výV‡>?™É6u'ÔŽQæêÛ†RSÔzpÿ€òá–^®ßi1kA]1‚Á`ù÷æÑh´à¨A7þòêng‰<ôKKÒ›-î¢ÏÏ Ã1+ÈTU5–‡þ$§Šós…|>›`½$`»ç‘Kø|@ C×Ô-Ãä æáwÁ¡PÈæGøm{0¬ü³ûe.Òé%íÝ¡Óþ‹ïË¿¬³‡ÎË>¿}ø(³@ͽ:½™˜’˜"µc”0™ÉRð(S/]l±’d¾ýJŽ8R°jmêÉç÷Æ?¥ÍD@×'ýþ¹Ï_ÛªÙ÷ùÔ¥{³ÑÝõùÖ–-Hù“;DXi¸N:‘ +H°%áó8Ýu–t«+ë¤ò + ‹ím,ãû¦ºK­CŸßy$ÍEóóͽºD±2~ú)¾›˜´j±a"Ú—ùjX¶]Vï`©vQDr-¾™:±­;nmá2ÿÔ›ìË|ÊÈÄ”7ÛÝuŸÏW,Å7=¸q¼¹Ãá°õIS÷t‚±º}]×ù¥-ï…–‚Ï€€Ý~òHMÓ +.ÆnK¹¡_\™Ì(WètÃ.Ù½:ôùéì4AGÒôÎþÃYÔzpŸhéO2´ëÀ½Lf²³ú"kU?HˆÇãâ0á÷û‹•CÛ—ùÔµÚyj¬išjàÊ#æ¢dôÜ Áã2Ÿ2co7œõ°èóWnxß¾ÏgÏ[½‰w|~%¡Ë :ñL¢¾àîà“2Ï€Ú@×uEQ¼_0Éäi}>‰À´ŸõéóyA>¯ílîÕ%ʨ/™±Võ@1¨Cæ½.Šüyë¬XÈš MÐÚh[ö?RQÞçZ|ñ?.PÎ….¸M×'é½è“/‹2Ÿb_æ{¼7vÑç³R|:j ºå¤›b¹É…B.Ö@Úñù9¡:ÎdÚëÓçLL‰®>'~I (wþ¬ªßD6›M¥Rø¯©vДhÊ2‰F£¦é]ÅÆ>‘ùš¦ªEñJcˆäZ|ú–oN[Ǽ½ª¾§ë“÷Š2ÿ» O—äóÓÙiÏž~.úüªˆ½|> &¡kºx`RéR¤Ø$A€Z….‡"‘H8nhll¤ë"M>ß7vç>k%]ȱ%Å˹úôùDSw‚é ¶¡×—Ìd%ÊHíMg§Eço]áÀÀ@—A:êýêM‰¦,Q­óð4vÈ‹¨Å#­‡w¼V™ïÖÄ13‰x®ÅGQÎqu‰tݱîSqþÂ5ûìËüæ^Ý˧Ÿ‹>ŸÍ.ôûýè쟨=ÄÙÙv.'@… ìÎ]þp»Z’KžºõùmC)f„šºì^~_0GÒ¢ógUý"}}}Ì¢®»ÚASÖ ===®4%ï ‹Ý8S_Í°ÎJ$)¶!êÕYÿoš2æ…gÍ'HÄs;ý¹_äº3¸·ohØ¡õ šd>em«fßç·õòéç¢Ï§!žm—NEwý 4x¹¥àóµG8.8¯GÀ#pw éöY²$¿´ãJ¿n}~_2Ã¥P2“¥wÄò{kZŽç„ª~öRdlll```hh'dµƒ¦¬‰5åððpå7M¬¦iÅþd-™›ƒÌ'Lë¡ÞCŸ‘Ñs»¹_ü ü'ߍ½ßÿ ¦%• #&™ê‚Möe>edbÊ˧Ÿ‹>Ÿ 3‡tV;ç 6gÄtršˆF£Þ)…ÏÔÅæÊojvãI7§Š¢4pÁB¿ðBww÷P¼qƒ¡P¨`9œ©(4dPŸ>ŸàRhÿá z)–ß[£vŒæ„ª~öJ¾̧Åh葯¯Šº\/ FèUs->}Ë7§­ãÞ>ý$Öúºµ8ÿÛgeáš}×né—ôÃk[ M¯ŠævÑç+Ë,FÁ€9@\æ³Çü ÜC”èÃçjq ‹¾pdPÛHª(M>Ÿ¹× +{ú î³dIú +¦oçÈ>T—Ï'Çq™Oì?P“ð>™Pœ€ÚF×uQwÓpÃï|M~F¼uÚ º~›õöœ¾c$¡¯ÀÊõÙtÕù|ÉLVâ‘š{uZ¦óHš~oêNÐÂøOÌ +u¶öý*uÈ´|Í|wU}‹ú`p«®OF6·Kd>åÇ×i’~ø–û&«å»»èóãñx¬œšcÈÎsÓåGÁ#À®¿T /N6lÒŠ}mŸ¨U¨{gw…ÑhG5õbá=¿7ïUéMnþ@·j÷ù9¡ü¾`àð%Çih°)ó©ç¬%™Ÿ›Þd–ÞïPÓ’Zß ÿ令>óµ[’’Nxõº¯ªå»»èóÝ‚]™Dze|¾¦iÖ§f6? ŸÕÝr™/Þ–ôù¹¯ósù_«Ð—eeawÓ+V¬X´h‘d%Ùlvtt4•JÉ·E Ðb´p%Wõü'£•Ôy$íÊ^aUXVå‘UE£Ñ‚unWE#‚8ÕKN(ª½Ã·Rè—\F§_äÅù>ß‹’xmkÂ4ÆzùXµµµÕ›Ï/øe ¾‡ôùtÙÆÿÑèZm0´¿ò2}þ³;wÒ§ayçíw橇Á±E©½ÔÉE2 2¨ªZÐÛóù9CÚ°?)ŠRÛÇZÿf¥«««££C²’.ƒt:]l™T*Å–¬äª^éøDb“žüè°+{…UaUX•VÅ$¤ÕO\Ÿ¯dZsÍö;Ö½0›Ì_ÿ|@Ò/¹s\Óæå ҟ쬊þjU[·n­7ŸÏ®ìÔçƒAñ´/>§’®Áø ûS]ÊôùâÇy@½žz[AÚK\$*ݲCÓ=©ÄççòÓÌï‘ìÔšvuu HVÒÓÓÃt‡¤Êqtt”-SùUýåƒ/$BÉ­½Âª°*¬ÊÅU½õÖ[gžy¦ØÑIV¥ë:Œv'v% ;{Õ××7ëôÔªb/uÎ*óC¡/½í¨¤û½ôÆ´g¿ uUÍÍÍõæóÙ/>Ó„a=üjÊ‘)ôïÆ+óí;|ø|ÏGAàóÕ/A7½/÷ùÅ>åeâñxC›¡»ï†â:ÍÍÍkÖ¬‘¬$‘H I–Éf³ƒƒƒ´˜D›ÌÓªv“¥}½]Ù+¬ +«ÂªÜZÕž={N9åîfý~¿ÉCŠ«ÒuÕÛVF­«¢-.X°@RÀìñÃNË‹ïëúd`Á½r™ nU”îk·$%Ýïêu_Ü«±±±9ìÕ|¯jïÞ½®û|:QEaC³„‚W5s@Ó4¶BU°â¦#@ÿŸ}³’¢¼÷ýþ­JÝηêƪS™:§NYÇœh+˜_`xµ£øÆ‹´ ¢Øˆb≎c£¶r_0Û®q±MÜ@<‡ã\B¼$\“,îÞÅ°Í!ìÉ:=›v˜0÷7ýì>ôÎKOÏìÌÎtÏ÷S¿¢všž~yúy~Ïô§ÍŽ§lýžÿmVö ’ðù|>@ àó~§q|>?£J6µ Ûš÷uÈþφ\„RÛá¼ßŠÅbÝÝÝ.žø\J\J'ªª:Íg(ÊzuË w•^E1ï¦h¡óM¨\é:­hq¾®ÚÔô‘Kî]Ó{î¹>ÊŠÏ°%QRW¬”ÏO”賟š¦qÃωvÄûv¥vÊx”½Á +úü '|ù¢_ F|yÆå—L¿ü²é—_>íò¯M›ø©¯š2aÒ” áð„©á˦O¾lÆäË®™té¬I—^7éÒ믾töÕâ W‹7^%Þt•(]%~ó*ñæ«.¹ùÊKn‰9vÜÊãŠKn·ÇÅUˆÌöoµ€ Û7íã¼ÉŽ탟}uæDèt®µÏ‹Înæ¤Ké4§Ä´ðetîS™F˜l·ÆÕS&P³\9eÂS3MDñõ©©¹¾:m"µÅÄé—O°›±h\ê9Doq‰·¸Ø[|Å[üëôË7¼ùZ•ÒšÿÇTV\^øW/1Ý-¾Rz\ì9¼ôÉ¢}»èqh +ÇDgL;——™±Ÿ_ã1u8¾žßÈWŒŽ+1…"“²âêÑ1itLæÎDxtL9”è2éÎÓx8²bnÌpÄÌáÈäÒk1Ë×:â:v6æ1{8D6Ñ°¸‘ÇH&¿id’F¦!7çLI·äLOÎjôÄtq=Ÿ+³çPgÜz…c¶uœàœ-iœ‘¶â ˜™GæG{Š¯Ï™%3¥}­³fIê]|Šdó#u{63ÒøºøÊKàóUB–evoH÷¡Îåî>Ÿ×›ùèLáóó2”:ëâ”6ˆåýVGGG»{ý*¨p)q)9|:àÀ.ź®;=¼;…6•%ó Õç×û#é]R:fúíµÝEe¾ª~LñßvɽsÖ|ðA—Fe }>u-ï]±²>?wÔä…Ö©ÔîêÊç_zÿìðß +FÌØñè7ùÈ‚_¬^¦¯ZýŽòøÛ+ŸÞ|¿Úºâ•Ÿ,×Z–ýT[º­ùÞ÷__òÁ¦{>|uñîWýöå»?Þx÷7È^ZØùï ®¿ëÐú»¿¸àÈ‹ó½0ÿ¸:ÿ„:¿WÿWu^ßóó>{~žõÅÜøssûŸ›û·g‡c w&ì8Y¹ ÍÒ¾h¿t~aþ‘t¯_@GHÇIG»oƒüûòï^¾ûÿ¼²èׯ,Š¾ºhçk‹µéž_¾¾äç?^ònó’·›ïݬ-}ëeo´,ûñ›Ë^ýÉò oÝ·þ­û¨5žÝ¼â›ïjËkö5Ñco¯|tëƒÔ\Ê6åþwW-×W-yï¡Eï=´ðç«yÜÅâ«dâaŠù£cžsߎ;sâ;n‰ÛFÇ­#1§â‘[râf;¾IñËLH£bÍM#q#Åö57äÄ쑸>^7:®Ýþè[ÿ³J™mÊxuþ)Œ_‹©Ùñ(ibº{ìÈÄŒÑ1st\S(¶?:Ë×:âº|q}&ØE?ײ»ë6vðŽ4ªƒ±Ž7Ò oÎêœï?2‡ú­£;;6ëí¬ó;‡ÃÜ_d‚ç8ZðóÕ F†›sÊï­¾ÛŽEöØd±ø½‡î±cÉHÜ«¯¢Xª¯Z64œ—¿»ê>;VŒÄýÛV=°mÕÊ‘xp›BAÃÕH<ôŽ²:>lÇ#ï<¸fk&µã[[W~ëí•ß¶SÅ¿Ùñ·W>nÇo¯Œü,Of"“dÖmyà»#ñÔæ¾·ùþ§íøþæû)ýÐŽg6¯xæ§+~ôÓÏÚñ\ëŠç[W¨v¼ÐºâÅ·V¬ÏÄ}ÿþÖ}/½uß;6¾ußË?YþŠ¯¾¹üµ7—ozsÅë-Ëší œOٯŎ7[–ýäeo½A)qi«¶t³[´¥?k¾÷m;¶6ß»-™ä©ÿxÉ{?Î$Ò_¼¾ä};Ú^_²}Å=;6ÝCi–fÿØ´ø?_[LY÷¿^[L³ eàÿýê¢]v6¦øÍ+‹>²c=ËP¢Þ»ñîÿ›‰LÞþÃÙØ Ó¼³oÃÂý¶¿”I韼´°ãß3ÓÐÿ³g"Š?Ùó¥}óÅ4+õÐÄôÂü£/d¦š›øôôßê|š&(bö •™žì‰©²óQI‘pÄÀpd&Ê¿9‚²ßžL)¬áÈœÂgö¹PüõùyÿmŸ`¯}¦ì”ÿl·µCÝ&Ô8ÔDŸÚÍEM×a·$5é7,¤F¦§–ßc_>KÒµ£ëH×”.ñ;Í÷nÉÌ’K©Ÿ¼þæ2êH/ÙS$õCêŸÔ©WS·§A£†Æ—ôÜ]ðù€*¡iZÞ{CŸÏ+Ðüå±é°##TdƒÁðùDs§å¢•N žÉýJOO3‡ÉdƒÈ×àR†îînºŽå]Ê,-éž'ùÄá…B–>ë‰@gUHZéátkS&ÞËÿkÜøÍïŠÊüpxK:£ O-^û.‰÷†e+ûRÖ„ú|>Sw¢¿³ŠÆêÉ…Þ CRKwæ…;’þà?i¨ñ½o>>>>>>>>>>àwxaýk_îâóùí$Ý]6rÓÆçï>~ÒE+ííÌû­D" p)ƒA*•*ûR:ý<ÍîzÐKA2ßT¡i"ë‰@½Ëü˜‘qøLæSlsW1Œ^AXï.óiË:•YûD´õ7ï¹$^å™ÄßOù¨ûÕÐçó¿a*m–fù¢/P ЯI’Â6´¾®ë.o¸” +ÿé5Æ7àóáóáóáóáóáóáóáóáóáóÀYÛÆ5N^Ÿoš&¿£¤;h´[0|þ‰Á3.Z©¹Ó Øp»î.Ei +EÑ»Ì/´©,™_Ô”Ö˜C7ùÖ¦óoº4£÷GcY§Ä~²hq~4z„òmÏÀéôþˆKÖõcϯö#!UUiûÔó³–S÷¦³·×h˜Ð þ"ý¡¤â +ø|ø|ø|ø|ø|ø|ø|ø|ø|ø|@0pÖ}I’¤Úð{d^uæ40%½ßH|íó·êÿþþÚz0Î>n<sÑJC©³#Êù”Ó\䤮ëìe./ˆ¢X¨29«¼¿ÞßóÚ#s™¯-È´|$òѨu’–(¶•ùŠòaW<É]}QŸOá£þSCŸÏºeI5ê%Áæú܉žýpªÞ~]f,û…χχχχχχχχχÏ˲²t½{Õe:…èhª½G_û|âIúØvxÀÅ)íÿlˆ}k(u¶gàt<™Â q ìª(J“gdY.$ó ÃðÌOZéí"—ùʬ¹™‡·8W”çþ´¨ÌÅ–ôȃTú|°_/Õ{˃•7侓ŸŸŸŸŸŸŸŸŸŸŸ¨9š¦ñW¹ A7°†aÔÉÓ‘°7Ð]=°× \ŠNËÆ×>Ÿä· ¼j4o°uø·Ô}}¨Ø A 4+Š¢w™ï®U)óä\×/yÅŒôV™|kÓyáYæ”óšÖÎW|ò‘Ö¢2_ÖF/­LÉÓ»Ïßy,á£~RCŸÏvM¿^ +=EûજËáóáóáóáóáóáóáóáóáóáóáóu‚®ëtÓš%pè¾UQ”ú1ù¦iºhüB%£•µú¾öù;%˜2R÷õ¥íÂ{­ÄÖI;ªúyÅ> Àhš&‚÷4ë¥Þ>Rò¬Æ3ÖJ²Kb2ßxú‚Ðÿ|ÌiæuýSGû´•ùì+îMsƒ½<åjèó öþH–o¯ ü÷ ÚKĆÕ?ÐE¼Q‘XðùðùðùðùðùðùðùðùðùðùàG Ã(I19Ëõ+øHÂ×>ÿÄà™,k´íP¿‹Yê8Më4wZYû€ ÂiM²kíÙI·6iK' +ç¯ãZ^[X™=Ãøð/2ŸóSÚ,Éçûë5¨qðù–eE Ô»(Šš¦E])ãYRÙ¿:œT¤’>>>>>>>>>>|݉;o«%Ibeo¹*‰Ö¤åªªÒ:ÕN¾öùÄÆ1§œßÛ;èb–vKÐ:»ŸÌªØ˲JzJÅ@É|›ï|©å%I·¬Sü?pªþB!Ë;øW(mz—ùÍ–¿šk|¾sãïÕé…,Ëðùðùðùðùðùðùðùðùðùðùðù€šcFØFÓ4_¡5ÙWj"pø µ$IÞ«ì,ËâV¿RúÝï>籄SÎÇ“©¢rÉYÕÏ*öƒ{(òn))µR‚ X#(ʇN-‰|äü_Mk÷"ó%Iç_éŠ'K*ÎgP}Dà}>ƒ½#±aÄ~D¼A_{#ÀçÃçÃçÃçÃçÃçÃçÃçÃçÃç¿Aö~o8öÛɱÀŠóEQ,㻼â´"O"üîór¾+ž¤%Í–‹_Š'SiG‰éûŸö%>3N —T*ÕׇKðKÉ^VòòTÓ4ç PEQK÷¾ ÞÂœ¼ ¬×õOG7Q{Q“O!Š-¬žß0zé¶Ã%ùüß™'ü5*ÇÁçóòƒ1â½z¡X' ÿ!ø|ø|ø|ø|ø|ø|ø|ø|ø|ø|(Ãçó +ùñ÷ùt;Ïv]Þý8ÿzE”ß}>±ñ@Œ¹£¶ÃiGÅ~ÞØÛ;Hëp+µÁøK{{ûÐБ¯éîîn·Á¥ ê¥Ôu)zú×} <§y! +Õä­ñ!S/¬ÅÃèÍZîEæÓw™Ì—åì#ê1þÐþ‰¿Få8øüzCQ” +>ð|>|>|>|>|>|>|>|>|>|> ᯊ3¸œ÷øÎ8ÝÀVä¥õ²žíºì÷Ö+xäðù\à«ûúècÏÀi¿ÔÜiÑ:û?:gø÷w ®Ûïtuu1 ŒKéw:::r/¥3c»ˆV˲$Iò.óiâ ¯4Z {—ùì)€ª~Ì–\þYI2Ÿ=-õרl@Ÿ_àóáóáóáóáóáóáóáóáóáó HI˜îèº>ÎÏAy»¶, >ßɉÁ3Ü õ œ¦%îE¤ñdj(u–üõ¡¿`@ùþþþîîîcÇŽ¡)üN,£KyüøqöÑ4MQ³$|Þ/RbÌZÓA\ +’)+R>ÿ©að(ó)týÓtæu°^AXÏ–\9÷—^4þ÷ÚºYþøÈ_—ÒÀçðùðùðùðùðùðùðùðùðùðù€¤R>¿&› yI’Êøº¦i|ŸOl;ÔÏkÃ.ºioï ­Óz0Î>Òw1 ¨C(Å ‚àE—$óiMÃ0 +픿í<£ûäcÛ=Ê|Mkg_žpËc×µ}ztÃÞøœµn öÍöoÕÐçSߦž©SÓ¦iR …B¾~µ>>>>>>>>>>ЀÐoØ79t“ö†$I.õ™Õ†°Zâ}¨a\pUäv>>?‹®xÒE71í¿·w}l=Ç€ ÞPÅ£„/IæS¢+”9³¶C™¶®(i¥wI™H˜E×µ¬S’¤—*óey_¨Ìº1ÝÚ”>U”ô’Mq—»cû_ýÛëjèóé7‰Ëë'NèwNM^-¬ uåó/šñÕK˜¸bö˯/¿næÒY×/™%Ý3sÎâ™w.š¹àîwËÓïY8mÙ]ÓV,˜ºrÁTeþ”Õó¦<2/üè¼ð·çNþ·¹“¿sòwN~òŽÉkîŽÉOÝ>ù{·O¢xúöIß¿-?¸mÒ3qõ3,n½úGŽx¶ÒAÛ¤}Ñ~鞺}ÛöAÒÑ>6wò·æ…×Ì Ó)Љ¬š?…ΈÎëþSï»kêò»¦-]8mÉÂé‹åé‹äéòÝÓïº{ÆüE3æ-šA­qû¢™·.δÌÍ÷̤&ºqÉ57,¹æú%×\{ï¬kî5séµ3–^;uÙµSf±œÅu“½Å¤œ¸:'®Ê×_™W8ã¾ë¿‘/¾î!¾–‰ÙYñÕûfoúek•{™Ërc…טPJL,%./öÅÊ_+™‹þuo‘·_}#«ûåtÎ|}xT'Ïn£†µÑbª#¦9bº#f,=3³ƒ†ö¬k–fÆ8Ŭ‘¸Ö×%O;®™=7äÄ#qÓ=,2É„Å7G‚2ÌÍ‹gÞ2sFe¡[eâ6;n‰;ì¸s$æÚ1/3xP6›÷ŒvÜeÇÂáȤ;Yž~·‹±ØŽ{2A&–dbÚ½vP¶\zWfv X~.2¹ô¾SWØA©õ;VÚñ …uyP~h^&VÛñ°ØYz=Ñð Ôým{ÞyÌÊçß±ƒæ 6 ±ˆØó›’جô];ì¹éÜôÄf¨ ÏPÃÓS5¦¤²'²¼Aè3#GûÃá>‹Ü6<ç²³ûž#èÜY#¬³Û„µOd¤Å¨õ¾c·ç·íùñÑ‘)òaûº(ŽYr…=KÒå¦>°xáð,I}‰O‘l~¤ŽM]ýºÌ´8‹Æ×·M†ÏT ~^ö½á8CwâN¿¤iZQ9o†³pTQ”ŠI }>¡îës1Nñdj(u¶õ`|ãXW<‰@ýëç)õÊ”™Þô‚KÚ4M3Kæ»Ôðמ„™Þ.f;Åž"Ø0zeöe~$ò_(~i•µé¼ôVöû¿þá¬Kjìê«ÐÔTjèóY7öRfÀ~ øå×N^êÊç#ˆÕª4ØѶ¼ðño}@ýá;ŸŸ¹%Ï*@ ‡Ã‘ÑÐj´×äó5+RœŸ®Ïo;<à"ööbÔPŸð¤Ä¼º‹át¾¯äNIÛqy .ˆµÎd>Åïݺ®*ëK•ùô_(œ¿Îxú‚ÌŽŽfJÂ/ +»½ý4g퀇óú¥†>Ÿí”Àãñõ”mšfÔ†þ(o ðù|>@ àó~‡n ™ýör/\?¨ªêQF9‘$©R2?\Ÿßw“NÍVN€ A‰Ñ‹W/Iæ»lGÓ´,™_Á[y²dþv1,x´Î{÷„õÑè‘‘†íuþ×°Ìß%¥3¡ÓsÖº=*½(œôP`^¿Àç×ôÓ®ÐÈ…ÏG àóŸhL4M£ûb­¦ö=‰…BM~ÅXÕçê¾>ïO¦0¨C,ËRm\¼ºw™ïîç)ÿ;W–뼸Ü!óµ¥™o×õOóµá)IÒ½Ë|Ãèåß ‡·œ«Ø_:1³»÷Bì© ¤×´Å\òêç>¶Ü‚뺠†>Ÿý ðòƒ„½ÜTŸ¶Ñuÿ.¢?r­þ}þSk×Ѫ“¯¼Šá¥_¹¸Ú»CT$èJñ«FW°qN|ÛÖwª4¢ÑÕ§cœ}íuEקuœ_Aú"0¥Ö[ò'(À_Ð=#+ݬ‡ƒ¡ÛUö|A’¤°ºsgïT©d4À>¿í°[éÞÞA üˆ®ëe¾»Ÿ§¬ë\YQ”º>í|2Ÿ"ù(kEÓŒ‹bKy2?ÑÅ;Ø=yËÌÌîh§´ë̳ô/<ã’T—l¢ýú»kÕÐçÓÔïe"¦_¬óÓÜÈÑM- ØÐ0gW„}Ìú 4FŸ?ÐQ9}Q /Vð¨ÿ~Ð@N9ÿÛ={Š®Oë ÌØw`J€FÀ4MfÅ‹¢(J­nÛëŠûü®xÒE=5wZ/øŽ¬Šú²e~z´Ï¯í‹ZÅ) ósëó£Ñ#‚°¾l™OXÝ¿¥]諾Ìv—>4Ü2’”ž¾ô¤KR½rî`?)J }>ïØî]‘ÿtaº;x°B 竈ªªæ6 |>¨P¸ÁwÀç7˜R ðp5]¡PCOåöù„º¯ÏÅ>Å“)Œ|DeþpŠPUI’œò°I˜…d¾¦µ>=š| +Ql±¬Syv·K6ù*_LSÄÊÍ–KFýâ…gê¼!‹RCŸOЯ¶kµ€;â2?À¿[˜ÏϽ(Yï#Àçƒj… Ð||~#€)‚®ëMeQïe™U&Ø>¿íð€‹}ú¯?õvtttww§Rûþ&‹áRþR:_ªªˆÌ÷ '¢Ee¾e’åÞe>­\pw{äa™¿gT3¾ülÌ%®i‹ ‚ïGem}¾ógL(¢Ù9:u~nû\œŸ†Ï5 + 3øøüFS*ç­®(ŠtKÈ—ÐáAà«Ñ ²iš ÞnÁöù]ñ¤‹€Ú`ü¥Ý&‘H`ùšŽŽ\Ê:GÓ4–“Ýe{¡KIßò(ó³¼_HZéí¢‹Ì7͸(¶x—ùYUýyv·?â¬Ìgüñ÷.étÎÚIòý¨¬­ÏO{{…~º8QÀ烅 Ð||~#€) ¿Á0 ¾œÝŠ¢è\Y×ufõ³–7&Áöù„º¯ÏÅAíÝŸ1NÉd=Á×ôôô0sˆKYo˜¦IIÆù ÕÝ”vwwÓuìèèp^Jï2?¨ï[iZ{!!o½‚°Þ£É§5iýòŽÁýu§‹Âɬ¶Ï{)뜚û|v ì§K.¡P(À•ù ø|PC p:ƒï€Ïo0¥@€áR:ëŽ/·,˹Ü0ŒÀVr–ÛtAòùñdªgà4ûÛÝAí>ƒ‰D—²®ˆF£y=¼{ªI¥RÎKI©[Å—ù†Ñ[HæGÛ~-œ¿Î£ÌÅË:å}¿C©³”?)(£¦‹=ìÊüïÞÞÁB—Ò/¶æ>ä¢4;óW éïÀ›||>¨!P¸ÁwÀç7˜R ÀH’ÄnÀÅùi»Ÿ-§ûÁ¬¯pmšf#7]ð|~ÏÀiæ—vKÐÇ®xÒÅA5wZ>TMÓòJxZX’r§|žUØ߀2?ñ™GòÊü¬¢}÷å¥îw÷ñ“,On;ÔbðŒK"åÑz0î󦮟߰À烅 Ð||~#€) 9=k9¿7Ï­Ã7M“ý—ÚØ?Ò‚çó¹ƒR÷õ±%îe¥¬ôt(u¶gà4ûP6ykòiaîCUw4MóhòA(uã¾#ù(Þ¢ëŸ:Ú§™¯ª—±Sž9Y•¾Ÿ¿íP¿¯Û>¿æ(Š’õkÄ0 Z’õÀΩÚÊ/ÎgŒ@>ø(\€Îà;àóL©` +ù|˲ØrºCÌýV( +’Ç.àù|giÏÀiZân¢ööÒ:ÄØ#€¡ÔY (ʆgcfÚ)ÔñTÞ‡…d~ÖkY Jþ’$ÑÁäý_¿ã]æ ÂúhôÈè–9¥ªG"Ñ.»ØÿÙ3‘º?åAßòuÃÂçûø|Pí~…‹Î€Îà àóL©`¸AÊG.²ºÐS€†"x>?="ç)vKÐÇ®xÒE@5wZ´ÿH+c@P6š¦ ‚ ŠbV=­G,Ë¢ïŽQæÓBú¯àe¶‘ö*óE±Å4ãÎïÒGZÈþW–w¸ì¥õ`œ¥DJ§î)Ô~ +ŸïàóAµû.::ƒ/€Ïo0¥@€áR:× 15$Bî·àóÓõù¼ ã[â^\O¦š;-ö7} +€šF¹‡/ +åv˲r7Â(ðÕdYR©êÇe¾,ïȪÀ7Œ^AXï\¡Ð^(%:ß`rÅ)ëÙ¨ß{ |¾/€ÏÕîWP¸è è ¾>¿À” +Æ0ŒBåš’$±ÿÒuݹܲ,ܶ§êóÕ¤ñd*í0üycoïàÎc ö·º¯ +'”TUU-¯ÞÞ#”EiòŒ‹Ìw®&ËrÞÕꎄ™>-º–,ïð(óUõ㜖UÕ/þó“Y¶ß O˜”)…º?å±ûøI¿wuø|¿ÐñÉ'¿Ý³§ìèïï¯öB>ø(\€Îà;àóL©lB¡¿ ‡Ã\=q½C+8ÅŽ,ËÁóØeHŸO8]}z´áÏÖƒñƒgøGZ +48ÌáK’ä¬uW«sK«ëº3…ŽÊ‹ÌWÅm}HK·6eâ÷nì]ækZ»ûwåI·[›ÎKïÉÿæÂPê,øm‡ö6äEæSPõ{·‡Ï•òÁ@átߟß`J€`ã¼ wÚi˲¸¢?E‰D"¢(ò5«ZtZÿÕço;ÔÏ]=[â^b:”:»ñ@ŒýMßÅ€¥JJ†”!)é”.*¾Sþ +•G +C–Ì÷Mbé­Â°ÏßY0 —-ó-ë”(¶8Wxò–™î»s +üƒgx.uÊŸðù R@>ø(\€Îà;àóL©x4MãêÞi§UU-¤†DQlðF ªÏw*©¡ÔYZÒvxÀEFÑú»ŸÌú +ð ©Tª¯¯/‘H )ʆ¿²äRošf÷¨ëº³ø¿(´2}%廬 ó)i.'™/ë£Ñ#Î/Fo(ôÚ¹Î_§¯úò¹ÝÍߘÍKƒOüÊúÁ³g=çS‚ À¨„Ï•òÁ@átߟß`J€FÀ²,UU%IRŹœ>æÚ¡p8Lë7x‹ÕçÇ“)§«§%]ñ¤‹ŒÚv¨?÷+À/tww·Û á•InY¾ ´RD4­ì¾hƒ.ozöjFÞ­™¦éw™o¾ð…è+«-ëTîZÞe¾aôæ\Ó-|ñK«Œ§/6ù´ß˜Qè¸xœpÃ) +—´ù@ó¹Ò}J°•ðù R8åÃ¥_¹xîíw ê?èJñ«¶lɽèÆŒÓçO¾ò*ŒŽº1ú|4 /‚Æ |>42¦i*Š¶‘e¹Pg£TŸŸvT™î>~’>¥Ü +MÕ}}ίl;Ô¾á#ººº˜9D‰¾˲¢Ñ¨Ç§–”C¡Kªª’çc„òpÑò¾àrN뙟´ÒÛEfק/Î_×Ôô£P赬µÆ"ó IÒÙ +ÒDÙÚtް̧ý&ݺKƒ+7[MMé%›â.i³eÛ ¶2ý›»ŽŽßJø|P)œ>áÇ€2jp²D1ÂQ†ÏG 9>%À>¿+žT÷õm<‹'SlɶCý.nŠÖßÛ;È?òoú§¿¿¿»»ûرchŠh4ªªª,Ë¢(òÊöz80˲ò¾'UÊQE7Nç +…ü(ó­Mç‰_ZÅÍüè““ÌOgžžÄŸ¼ãVuÁÕÃ&Ÿbì.óÓö£ÏžÓŸûüÙ/\ðw—„IñÉÎnZŸVλX,F£òøñãþ>ðù "ÀçC_ŸŸ@rê™ûü\ö6äâ¦Ú8køO žA÷õiš4Š?%úU‚öNG(B©&? +E£Ñ^³™O!M”¹™W”ù*c—ùöGΙ| +úè MK75¥¯œ;è’0<ß_ÓnUàóA¥€Ï‡2¾>>ä Ô3 åóãÉ”‹žÚx –¶ëÁøîã'Ñ7@ýcšfQ+.IR­¯l“O(ŠbϧG9ö'o™Éͼ(¶ðU*#ó‰]Ò𾶠+飺÷c¤Ù ©)½r³å’0'Üpªv=«ZÀçƒJñÛ={^TÕ‰5«vÊ–`œÔ;[·¢72Ô‚=l'_y•S㤎=ZôÊÒ:HÈHÎ@h(ŸO4wº*ÔäáÔAh8+Š¢ëz­”¸iš²,—gò[–ÏØfŽ]_õe§™·¬Sìÿ+&󉘑ÙÝ.)ó‡g ##ó¿pÁß]RedW­¼I>€2ȪwEƒPÿ8_@xQUÑ  @ÝÂýs¥²8*¥=Äçïít‘T;%0Ä@m1 CUUMÓ<®/IR(¢ñKcY×uÓ4k{üÌä—é,‚Y–Ï9ª§· +ÆÓç¯ãrž›ùJÊür‘åŒÏŸýpÂ%UÎY;@ëOÀçPÐGøøü ‚„  nϯR{6ˆÏ?1xÆER5wZb`œ1MSÓ4EQh :S“ê·Û+:‹¬S( Q Ãh„+nY§B¡×¸œ×´v¶¼d¾e¥!ãó×´Å\RåEá$­¼ËŸ@@à;àóƒ +2€º>¿JíÙ >ŸØxÀÍSÅ“)Œ2Pm,Ë¢¡GƒN—Ju_œ‹išŠ¢¸œHQ軾{x1Âá-\Î+ʇ™EI«d>Aס©)ýÅ Ýž{FvõÑ:¡ Þ#ÂçPÐGøøü ‚„  n1M3ZY–¥ž‘HDÓ4þ¿¬––;Ë_i¹eYÜž èówK¸¨ª½½ƒe ÚH’䮸iÊuu~º®¥ Ÿ™|JA–„¹œ‡·d>'-ù¦ï—!ó5­×öW +šššÒ³vK’ô¿´Ž¢ðÒÀçPÐGøøü ‚„ ÀwhšÆ‘{É=ý/³ú´¦a Þn èó{N»¨ªÖƒqŒ&Pmr58%%EQ(ÕRÒu]–å±ä3h#ŸY¨ª$í/Š-MM?¢-ë”w™ +½æ”ù¼ž_U?®à±ÉrÆç¯is{‰é‹ž¡uêþqS9ÀçPÐGøøü ‚„ À_X–ÅäýëEÑú\é£>¿Ñ|>¡îës±UC©³SÀ;ÑhT×õˆûÃDŽa’$ɲÌÞòÅiVJã³lãñ±ÏÕÌÿ¨ÏÉÈütZžûS/2Xþ·É©px ÿ¯Hä£ +XÊ0ZÂßvIkÚbMMiQ ìX†Ï T ððùA €¿PU•Ý€kšæñ+¦i²¯D"‘FnºÆôùm‡\„Õþφ0¦üE,ëèèèîîN¥RUÝå ¦îeY¦!“+·iI–Η²«$IM‚Íýù…óR† +…øwé0ÖoßøáKeÈ|VÞÏBÖ;‹öÇΙhtóóoº¤ÇÙ'ššÒ^nýÇmTVø|ÊúߟTø ®›J*¶geŸbP ½Ñ˜>¿+žtVÛõcLù‹ŽŽŽv›D"Q½½8]Ÿ ~oLÊ¢¬ßéÒÇmÐKM>¿”mmmÎÇ%”¨ö.•ñî3c”ùâ—VO_îTÇr»Ÿ¤Œwbð ûO¦\r#Å/:×O$…d¾³Ì»Y[Ë mŠ% Qi¼Ð1ÐñÐKJ;õ9‚$I^Ú§ h³´ýR§¯¯oÉ’%Y‚Ö¹iâ—VUFæSü^)û@6ˆeù|u_ŸKb|èñ¿<þîpæl=wßx*•*4*ëyPÀçP*ÐGøøü ‚„ À_(ŠÂnÀ#‘ˆÇ¯˜¦É¾ +5ôLÇ}¾ eT,³Æ»â}SYUÓ¹¨žpjšÍãïþši¨çö˜ôñ»?Þ⢭Ú°íœ<Óz0N#…1 ÃãQÑšQW¼ËO^s>öM9*ï zqݯ ÇÎàQÂ{iy§ s1Ï>uò%Aç¨ë:°MÕ„¶O°Œ#¤ šõ‚€êë{ÌùNÌ'Ý^1™¿§ü‡¼8Ÿ‚½¸ä\’‘]}Ñ>ãw?¼1Ÿ@@à;àóƒ +2¡ë:÷r^ŸeYÜ°ø³¸Ï/¯bÙ‹,­ì¦¼\_Z'÷‹n¸ƒ›¨/\ð.æJÝ×Ç6Õz0ΖÐ×]ŽÊ‹ Î{Tå‰e/ºÛ㦼•ÇÿÎàeSÎÁ +…ø“øüE€e>š¦it²üu¤êA]Žv4–Æt>h ­•÷P .HZéíbÆ·ïýÞSÌИ^’Ì·‡Ã‘ŠË|¢¹ÓbÉmãXÖ’¼ñÝ–£NáO¦‚7^àó(è#||~PABà;¸­*jè†ÝYÚu¹.¸øüq¶Á7UvIöç>ÿ?¸‰š¾t -yâW†‹¼:1x&íðù ž³~u}nª‚Á²¬¼þÙù‰÷÷>ñtø ʨ´Gºjcß|sŠpþº¢>_×?ÍݤñáÑïüS¥d~Úñ¤’ç·pɇo:|¸÷ïY‚|>e}€ï€Ï*HÈüˆa%Õ£Bæ§>ߣþõ5]ñ¤³üžÂÅ_1ÍO¦¯°€‰F£”ÁdY.úd§þ5~ HZé­Â°u§?#­Ô©†ÿeYQ™‰|”³|›•ùÎRüÝÇOÒ’¡ÔY÷âüWßèu>ܤõƒ:¬àó(è#||~PABàS,ËŠD"E+TC¡÷¢ñ`ÓP>ŸP÷õ9Ëï7ˆ¹(¬žÓ´Ns§Å>n;ÔjE >AIU’$MÓ ñ‹°K:'Þ;UË:e½é„];¡¨Ì—$½àf+'óÓŽâ|ʇÌÌï>~Ò%®i‹uV#dBø|ÊúߟTø˲4MË_ápXQ˜|'æóÛ8ËïwK¸X,Z™Öi„ªTP‡ÔVàó´@)Â0 \OÕω÷]’e„õQÿ ¥hq¾(¶Ðú·|HK \ No newline at end of file diff --git a/third_party/rust/zlib-rs/src/deflate/trees_tbl.rs b/third_party/rust/zlib-rs/src/deflate/trees_tbl.rs new file mode 100644 index 0000000000..07abb66b96 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/trees_tbl.rs @@ -0,0 +1,140 @@ +#![forbid(unsafe_code)] + +use crate::deflate::{ + Value, DIST_CODE_LEN, D_CODES, LENGTH_CODES, L_CODES, STD_MAX_MATCH, STD_MIN_MATCH, +}; + +const fn h(freq: u16, code: u16) -> Value { + Value::new(freq, code) +} + +#[rustfmt::skip] +pub const STATIC_LTREE: [Value; L_CODES + 2] = [ + h( 12,8), h(140,8), h( 76,8), h(204,8), h( 44,8), + h(172,8), h(108,8), h(236,8), h( 28,8), h(156,8), + h( 92,8), h(220,8), h( 60,8), h(188,8), h(124,8), + h(252,8), h( 2,8), h(130,8), h( 66,8), h(194,8), + h( 34,8), h(162,8), h( 98,8), h(226,8), h( 18,8), + h(146,8), h( 82,8), h(210,8), h( 50,8), h(178,8), + h(114,8), h(242,8), h( 10,8), h(138,8), h( 74,8), + h(202,8), h( 42,8), h(170,8), h(106,8), h(234,8), + h( 26,8), h(154,8), h( 90,8), h(218,8), h( 58,8), + h(186,8), h(122,8), h(250,8), h( 6,8), h(134,8), + h( 70,8), h(198,8), h( 38,8), h(166,8), h(102,8), + h(230,8), h( 22,8), h(150,8), h( 86,8), h(214,8), + h( 54,8), h(182,8), h(118,8), h(246,8), h( 14,8), + h(142,8), h( 78,8), h(206,8), h( 46,8), h(174,8), + h(110,8), h(238,8), h( 30,8), h(158,8), h( 94,8), + h(222,8), h( 62,8), h(190,8), h(126,8), h(254,8), + h( 1,8), h(129,8), h( 65,8), h(193,8), h( 33,8), + h(161,8), h( 97,8), h(225,8), h( 17,8), h(145,8), + h( 81,8), h(209,8), h( 49,8), h(177,8), h(113,8), + h(241,8), h( 9,8), h(137,8), h( 73,8), h(201,8), + h( 41,8), h(169,8), h(105,8), h(233,8), h( 25,8), + h(153,8), h( 89,8), h(217,8), h( 57,8), h(185,8), + h(121,8), h(249,8), h( 5,8), h(133,8), h( 69,8), + h(197,8), h( 37,8), h(165,8), h(101,8), h(229,8), + h( 21,8), h(149,8), h( 85,8), h(213,8), h( 53,8), + h(181,8), h(117,8), h(245,8), h( 13,8), h(141,8), + h( 77,8), h(205,8), h( 45,8), h(173,8), h(109,8), + h(237,8), h( 29,8), h(157,8), h( 93,8), h(221,8), + h( 61,8), h(189,8), h(125,8), h(253,8), h( 19,9), + h(275,9), h(147,9), h(403,9), h( 83,9), h(339,9), + h(211,9), h(467,9), h( 51,9), h(307,9), h(179,9), + h(435,9), h(115,9), h(371,9), h(243,9), h(499,9), + h( 11,9), h(267,9), h(139,9), h(395,9), h( 75,9), + h(331,9), h(203,9), h(459,9), h( 43,9), h(299,9), + h(171,9), h(427,9), h(107,9), h(363,9), h(235,9), + h(491,9), h( 27,9), h(283,9), h(155,9), h(411,9), + h( 91,9), h(347,9), h(219,9), h(475,9), h( 59,9), + h(315,9), h(187,9), h(443,9), h(123,9), h(379,9), + h(251,9), h(507,9), h( 7,9), h(263,9), h(135,9), + h(391,9), h( 71,9), h(327,9), h(199,9), h(455,9), + h( 39,9), h(295,9), h(167,9), h(423,9), h(103,9), + h(359,9), h(231,9), h(487,9), h( 23,9), h(279,9), + h(151,9), h(407,9), h( 87,9), h(343,9), h(215,9), + h(471,9), h( 55,9), h(311,9), h(183,9), h(439,9), + h(119,9), h(375,9), h(247,9), h(503,9), h( 15,9), + h(271,9), h(143,9), h(399,9), h( 79,9), h(335,9), + h(207,9), h(463,9), h( 47,9), h(303,9), h(175,9), + h(431,9), h(111,9), h(367,9), h(239,9), h(495,9), + h( 31,9), h(287,9), h(159,9), h(415,9), h( 95,9), + h(351,9), h(223,9), h(479,9), h( 63,9), h(319,9), + h(191,9), h(447,9), h(127,9), h(383,9), h(255,9), + h(511,9), h( 0,7), h( 64,7), h( 32,7), h( 96,7), + h( 16,7), h( 80,7), h( 48,7), h(112,7), h( 8,7), + h( 72,7), h( 40,7), h(104,7), h( 24,7), h( 88,7), + h( 56,7), h(120,7), h( 4,7), h( 68,7), h( 36,7), + h(100,7), h( 20,7), h( 84,7), h( 52,7), h(116,7), + h( 3,8), h(131,8), h( 67,8), h(195,8), h( 35,8), + h(163,8), h( 99,8), h(227,8) +]; + +#[rustfmt::skip] +pub const STATIC_DTREE: [Value; D_CODES] = [ + h( 0,5), h(16,5), h( 8,5), h(24,5), h( 4,5), + h(20,5), h(12,5), h(28,5), h( 2,5), h(18,5), + h(10,5), h(26,5), h( 6,5), h(22,5), h(14,5), + h(30,5), h( 1,5), h(17,5), h( 9,5), h(25,5), + h( 5,5), h(21,5), h(13,5), h(29,5), h( 3,5), + h(19,5), h(11,5), h(27,5), h( 7,5), h(23,5) +]; + +#[rustfmt::skip] +pub const DIST_CODE: [u8; DIST_CODE_LEN] = [ + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +]; + +#[rustfmt::skip] +pub const LENGTH_CODE: [u8; STD_MAX_MATCH-STD_MIN_MATCH+1] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +]; + +pub const BASE_LENGTH: [u8; LENGTH_CODES] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, + 160, 192, 224, 0, +]; + +#[rustfmt::skip] +pub const BASE_DIST: [u16; D_CODES] = [ + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +]; diff --git a/third_party/rust/zlib-rs/src/deflate/window.rs b/third_party/rust/zlib-rs/src/deflate/window.rs new file mode 100644 index 0000000000..c6a1e7c365 --- /dev/null +++ b/third_party/rust/zlib-rs/src/deflate/window.rs @@ -0,0 +1,141 @@ +use crate::allocate::Allocator; +use core::mem::MaybeUninit; + +#[derive(Debug)] +pub struct Window<'a> { + // the full window allocation. This is longer than w_size so that operations don't need to + // perform bounds checks. + buf: &'a mut [MaybeUninit], + + // number of initialized bytes + filled: usize, + + window_bits: usize, + + high_water: usize, +} + +impl<'a> Window<'a> { + pub fn new_in(alloc: &Allocator<'a>, window_bits: usize) -> Option { + let buf = alloc.allocate_slice::(2 * ((1 << window_bits) + Self::padding()))?; + + Some(Self { + buf, + filled: 0, + window_bits, + high_water: 0, + }) + } + + pub fn clone_in(&self, alloc: &Allocator<'a>) -> Option { + let mut clone = Self::new_in(alloc, self.window_bits)?; + + clone.buf.copy_from_slice(self.buf); + clone.filled = self.filled; + clone.high_water = self.high_water; + + Some(clone) + } + + pub unsafe fn drop_in(&mut self, alloc: &Allocator) { + if !self.buf.is_empty() { + let buf = core::mem::take(&mut self.buf); + alloc.deallocate(buf.as_mut_ptr(), buf.len()); + } + } + + pub fn capacity(&self) -> usize { + 2 * (1 << self.window_bits) + } + + /// Returns a shared reference to the filled portion of the buffer. + #[inline] + pub fn filled(&self) -> &[u8] { + // safety: `self.buf` has been initialized for at least `filled` elements + unsafe { core::slice::from_raw_parts(self.buf.as_ptr().cast(), self.filled) } + } + + /// Returns a mutable reference to the filled portion of the buffer. + #[inline] + pub fn filled_mut(&mut self) -> &mut [u8] { + // safety: `self.buf` has been initialized for at least `filled` elements + unsafe { core::slice::from_raw_parts_mut(self.buf.as_mut_ptr().cast(), self.filled) } + } + + /// # Safety + /// + /// `src` must point to `range.end - range.start` valid (initialized!) bytes + pub unsafe fn copy_and_initialize(&mut self, range: core::ops::Range, src: *const u8) { + let (start, end) = (range.start, range.end); + + let dst = self.buf[range].as_mut_ptr() as *mut u8; + core::ptr::copy_nonoverlapping(src, dst, end - start); + + if start >= self.filled { + self.filled = Ord::max(self.filled, end); + } + + self.high_water = Ord::max(self.high_water, self.filled); + } + + // this library has many functions that operated in a chunked fashion on memory. For + // performance, we want to minimize bounds checks. Therefore we reserve initialize some extra + // memory at the end of the window so that chunked operations can use the whole buffer. If they + // go slightly over `self.capacity` that's okay, we account for that here by making sure the + // memory there is initialized! + pub fn initialize_out_of_bounds(&mut self) { + const WIN_INIT: usize = crate::deflate::STD_MAX_MATCH; + + // If the WIN_INIT bytes after the end of the current data have never been + // written, then zero those bytes in order to avoid memory check reports of + // the use of uninitialized (or uninitialised as Julian writes) bytes by + // the longest match routines. Update the high water mark for the next + // time through here. WIN_INIT is set to STD_MAX_MATCH since the longest match + // routines allow scanning to strstart + STD_MAX_MATCH, ignoring lookahead. + if self.high_water < self.capacity() { + let curr = self.filled().len(); + + if self.high_water < curr { + // Previous high water mark below current data -- zero WIN_INIT + // bytes or up to end of window, whichever is less. + let init = Ord::min(self.capacity() - curr, WIN_INIT); + + self.buf[curr..][..init].fill(MaybeUninit::new(0)); + + self.high_water = curr + init; + + self.filled += init; + } else if self.high_water < curr + WIN_INIT { + // High water mark at or above current data, but below current data + // plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + // to end of window, whichever is less. + let init = Ord::min( + curr + WIN_INIT - self.high_water, + self.capacity() - self.high_water, + ); + + self.buf[self.high_water..][..init].fill(MaybeUninit::new(0)); + + self.high_water += init; + self.filled += init; + } + } + } + + pub fn initialize_at_least(&mut self, at_least: usize) { + let end = at_least.clamp(self.high_water, self.buf.len()); + self.buf[self.high_water..end].fill(MaybeUninit::new(0)); + + self.high_water = end; + self.filled = end; + } + + // padding required so that SIMD operations going out-of-bounds are not a problem + pub fn padding() -> usize { + if crate::cpu_features::is_enabled_pclmulqdq() { + 8 + } else { + 0 + } + } +} diff --git a/third_party/rust/zlib-rs/src/inflate.rs b/third_party/rust/zlib-rs/src/inflate.rs new file mode 100644 index 0000000000..b6e128e842 --- /dev/null +++ b/third_party/rust/zlib-rs/src/inflate.rs @@ -0,0 +1,2271 @@ +#![allow(non_snake_case)] // TODO ultimately remove this +#![allow(clippy::missing_safety_doc)] // obviously needs to be fixed long-term + +use core::ffi::{c_char, c_int, c_long, c_ulong}; +use core::marker::PhantomData; +use core::mem::MaybeUninit; + +mod bitreader; +mod inffixed_tbl; +mod inftrees; +mod window; + +use crate::allocate::Allocator; +use crate::c_api::internal_state; +use crate::{ + adler32::adler32, + c_api::{gz_header, z_checksum, z_size, z_stream, Z_DEFLATED}, + read_buf::ReadBuf, + Code, InflateFlush, ReturnCode, DEF_WBITS, MAX_WBITS, MIN_WBITS, +}; + +use crate::crc32::{crc32, Crc32Fold}; + +use self::{ + bitreader::BitReader, + inftrees::{inflate_table, CodeType, InflateTable}, + window::Window, +}; + +#[repr(C)] +pub struct InflateStream<'a> { + pub(crate) next_in: *mut crate::c_api::Bytef, + pub(crate) avail_in: crate::c_api::uInt, + pub(crate) total_in: crate::c_api::z_size, + pub(crate) next_out: *mut crate::c_api::Bytef, + pub(crate) avail_out: crate::c_api::uInt, + pub(crate) total_out: crate::c_api::z_size, + pub(crate) msg: *mut c_char, + pub(crate) state: &'a mut State<'a>, + pub(crate) alloc: Allocator<'a>, + pub(crate) data_type: c_int, + pub(crate) adler: crate::c_api::z_checksum, + pub(crate) reserved: crate::c_api::uLong, +} + +#[cfg(feature = "__internal-test")] +#[doc(hidden)] +pub const INFLATE_STATE_SIZE: usize = core::mem::size_of::(); + +#[cfg(feature = "__internal-test")] +#[doc(hidden)] +pub unsafe fn set_mode_dict(strm: &mut z_stream) { + unsafe { + (*(strm.state as *mut State)).mode = Mode::Dict; + } +} + +impl<'a> InflateStream<'a> { + const _S: () = assert!(core::mem::size_of::() == core::mem::size_of::()); + const _A: () = assert!(core::mem::align_of::() == core::mem::align_of::()); + + /// # Safety + /// + /// Behavior is undefined if any of the following conditions are violated: + /// + /// - `strm` satisfies the conditions of [`pointer::as_ref`] + /// - if not `NULL`, `strm` as initialized using [`init`] or similar + /// + /// [`pointer::as_ref`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_ref + #[inline(always)] + pub unsafe fn from_stream_ref(strm: *const z_stream) -> Option<&'a Self> { + { + // Safety: ptr points to a valid value of type z_stream (if non-null) + let stream = unsafe { strm.as_ref() }?; + + if stream.zalloc.is_none() || stream.zfree.is_none() { + return None; + } + + if stream.state.is_null() { + return None; + } + } + + // Safety: InflateStream has an equivalent layout as z_stream + strm.cast::().as_ref() + } + + /// # Safety + /// + /// Behavior is undefined if any of the following conditions are violated: + /// + /// - `strm` satisfies the conditions of [`pointer::as_mut`] + /// - if not `NULL`, `strm` as initialized using [`init`] or similar + /// + /// [`pointer::as_mut`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_mut + #[inline(always)] + pub unsafe fn from_stream_mut(strm: *mut z_stream) -> Option<&'a mut Self> { + { + // Safety: ptr points to a valid value of type z_stream (if non-null) + let stream = unsafe { strm.as_ref() }?; + + if stream.zalloc.is_none() || stream.zfree.is_none() { + return None; + } + + if stream.state.is_null() { + return None; + } + } + + // Safety: InflateStream has an equivalent layout as z_stream + strm.cast::().as_mut() + } + + fn as_z_stream_mut(&mut self) -> &mut z_stream { + // safety: a valid &mut InflateStream is also a valid &mut z_stream + unsafe { &mut *(self as *mut _ as *mut z_stream) } + } +} + +const MAX_BITS: u8 = 15; // maximum number of bits in a code +const MAX_DIST_EXTRA_BITS: u8 = 13; // maximum number of extra distance bits + // +pub fn uncompress_slice<'a>( + output: &'a mut [u8], + input: &[u8], + config: InflateConfig, +) -> (&'a mut [u8], ReturnCode) { + let output_uninit = unsafe { + core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut MaybeUninit, output.len()) + }; + + uncompress(output_uninit, input, config) +} + +/// Inflates `source` into `dest`, and writes the final inflated size into `dest_len`. +pub fn uncompress<'a>( + output: &'a mut [MaybeUninit], + input: &[u8], + config: InflateConfig, +) -> (&'a mut [u8], ReturnCode) { + let mut dest_len_ptr = output.len() as z_checksum; + + // for detection of incomplete stream when *destLen == 0 + let mut buf = [0u8]; + + let mut left; + let mut len = input.len() as u64; + + let dest = if output.is_empty() { + left = 1; + + buf.as_mut_ptr() + } else { + left = output.len() as u64; + dest_len_ptr = 0; + + output.as_mut_ptr() as *mut u8 + }; + + let mut stream = z_stream { + next_in: input.as_ptr() as *mut u8, + avail_in: 0, + + zalloc: None, + zfree: None, + opaque: core::ptr::null_mut(), + + ..z_stream::default() + }; + + let err = init(&mut stream, config); + if err != ReturnCode::Ok { + return (&mut [], err); + } + + stream.next_out = dest; + stream.avail_out = 0; + + let Some(stream) = (unsafe { InflateStream::from_stream_mut(&mut stream) }) else { + return (&mut [], ReturnCode::StreamError); + }; + + let err = loop { + if stream.avail_out == 0 { + stream.avail_out = Ord::min(left, u32::MAX as u64) as u32; + left -= stream.avail_out as u64; + } + + if stream.avail_in == 0 { + stream.avail_in = Ord::min(len, u32::MAX as u64) as u32; + len -= stream.avail_in as u64; + } + + let err = unsafe { inflate(stream, InflateFlush::NoFlush) }; + + if err != ReturnCode::Ok { + break err; + } + }; + + if !output.is_empty() { + dest_len_ptr = stream.total_out; + } else if stream.total_out != 0 && err == ReturnCode::BufError { + left = 1; + } + + let avail_out = stream.avail_out; + + end(stream); + + let ret = match err { + ReturnCode::StreamEnd => ReturnCode::Ok, + ReturnCode::NeedDict => ReturnCode::DataError, + ReturnCode::BufError if (left + avail_out as u64) != 0 => ReturnCode::DataError, + _ => err, + }; + + // SAFETY: we have now initialized these bytes + let output_slice = unsafe { + core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, dest_len_ptr as usize) + }; + + (output_slice, ret) +} + +#[derive(Debug, Clone, Copy)] +pub enum Mode { + Head, + Flags, + Time, + Os, + ExLen, + Extra, + Name, + Comment, + HCrc, + Sync, + Mem, + Length, + Type, + TypeDo, + Stored, + CopyBlock, + Check, + Len_, + Len, + Lit, + LenExt, + Dist, + DistExt, + Match, + Table, + LenLens, + CodeLens, + DictId, + Dict, + Done, + Bad, +} + +#[derive(Clone, Copy)] +#[allow(clippy::enum_variant_names)] +enum Codes { + Fixed(&'static [Code]), + Codes, + Len, + Dist, +} + +impl Default for Codes { + fn default() -> Self { + Codes::Fixed(&[]) + } +} + +#[derive(Default, Clone, Copy)] +struct Table { + codes: Codes, + bits: usize, +} + +pub(crate) struct State<'a> { + /// Current inflate mode + mode: Mode, + + /// true if processing the last block + last: bool, + /// bitflag + /// + /// - bit 0 true if zlib + /// - bit 1 true if gzip + /// - bit 2 true to validate check value + wrap: usize, + + /// table for length/literal codes + len_table: Table, + + /// table for dist codes + dist_table: Table, + + /// log base 2 of requested window size + wbits: usize, + // allocated window if needed (capacity == 0 if unused) + window: Window<'a>, + + /// place to store gzip header if needed + head: Option<&'a mut gz_header>, + + // + /// number of code length code lengths + ncode: usize, + /// number of length code lengths + nlen: usize, + /// number of distance code lengths + ndist: usize, + /// number of code lengths in lens[] + have: usize, + /// next available space in codes[] + next: usize, // represented as an index, don't want a self-referential structure here + + // IO + bit_reader: BitReader<'a>, + + writer: ReadBuf<'a>, + total: usize, + + /// length of a block to copy + length: usize, + /// distance back to copy the string from + offset: usize, + + /// extra bits needed + extra: usize, + + /// if false, allow invalid distance too far + sane: bool, + /// bits back of last unprocessed length/lit + back: usize, + + /// initial length of match + was: usize, + + /// size of memory copying chunk + chunksize: usize, + + in_available: usize, + out_available: usize, + + /// temporary storage space for code lengths + lens: [u16; 320], + /// work area for code table building + work: [u16; 288], + + error_message: Option<&'static str>, + flush: InflateFlush, + + checksum: u32, + crc_fold: Crc32Fold, + + havedict: bool, + dmax: usize, + flags: i32, + + codes_codes: [Code; crate::ENOUGH_LENS], + len_codes: [Code; crate::ENOUGH_LENS], + dist_codes: [Code; crate::ENOUGH_DISTS], +} + +impl<'a> State<'a> { + fn new(reader: &'a [u8], writer: ReadBuf<'a>) -> Self { + let in_available = reader.len(); + let out_available = writer.capacity(); + + Self { + flush: InflateFlush::NoFlush, + + last: false, + wrap: 0, + mode: Mode::Head, + length: 0, + + len_table: Table::default(), + dist_table: Table::default(), + + wbits: 0, + offset: 0, + extra: 0, + sane: true, + back: 0, + was: 0, + chunksize: 0, + in_available, + out_available, + + bit_reader: BitReader::new(reader), + + writer, + total: 0, + + window: Window::empty(), + head: None, + + lens: [0u16; 320], + work: [0u16; 288], + + ncode: 0, + nlen: 0, + ndist: 0, + have: 0, + next: 0, + + error_message: None, + + checksum: 0, + crc_fold: Crc32Fold::new(), + + havedict: false, + dmax: 0, + flags: 0, + + codes_codes: [Code::default(); crate::ENOUGH_LENS], + len_codes: [Code::default(); crate::ENOUGH_LENS], + dist_codes: [Code::default(); crate::ENOUGH_DISTS], + } + } + + fn len_table_ref(&self) -> &[Code] { + match self.len_table.codes { + Codes::Fixed(fixed) => fixed, + Codes::Codes => &self.codes_codes, + Codes::Len => &self.len_codes, + Codes::Dist => &self.dist_codes, + } + } + + fn dist_table_ref(&self) -> &[Code] { + match self.dist_table.codes { + Codes::Fixed(fixed) => fixed, + Codes::Codes => &self.codes_codes, + Codes::Len => &self.len_codes, + Codes::Dist => &self.dist_codes, + } + } + + fn len_table_get(&self, index: usize) -> Code { + self.len_table_ref()[index] + } + + fn dist_table_get(&self, index: usize) -> Code { + self.dist_table_ref()[index] + } +} + +macro_rules! pull_byte { + ($self:expr) => { + match $self.bit_reader.pull_byte() { + Err(return_code) => return $self.inflate_leave(return_code), + Ok(_) => (), + } + }; +} + +macro_rules! need_bits { + ($self:expr, $n:expr) => { + match $self.bit_reader.need_bits($n) { + Err(return_code) => return $self.inflate_leave(return_code), + Ok(v) => v, + } + }; +} + +// swaps endianness +const fn zswap32(q: u32) -> u32 { + u32::from_be(q.to_le()) +} + +const INFLATE_FAST_MIN_HAVE: usize = 15; +const INFLATE_FAST_MIN_LEFT: usize = 260; + +impl<'a> State<'a> { + fn dispatch(&mut self) -> ReturnCode { + match self.mode { + Mode::Head => self.head(), + Mode::Flags => self.flags(), + Mode::Time => self.time(), + Mode::Os => self.os(), + Mode::ExLen => self.ex_len(), + Mode::Extra => self.extra(), + Mode::Name => self.name(), + Mode::Comment => self.comment(), + Mode::HCrc => self.hcrc(), + Mode::Sync => self.sync(), + Mode::Type => self.type_(), + Mode::TypeDo => self.type_do(), + Mode::Stored => self.stored(), + Mode::CopyBlock => self.copy_block(), + Mode::Check => self.check(), + Mode::Len => self.len(), + Mode::Len_ => self.len_(), + Mode::LenExt => self.len_ext(), + Mode::Lit => self.lit(), + Mode::Dist => self.dist(), + Mode::DistExt => self.dist_ext(), + Mode::Match => self.match_(), + Mode::Done => todo!(), + Mode::Table => self.table(), + Mode::LenLens => self.len_lens(), + Mode::CodeLens => self.code_lens(), + Mode::Dict => self.dict(), + Mode::DictId => self.dict_id(), + Mode::Bad => self.bad("repeated call with bad state\0"), + Mode::Mem => self.mem(), + Mode::Length => self.length(), + } + } + + // ---------------- + + /// Initial state + #[inline(never)] + fn head(&mut self) -> ReturnCode { + if self.wrap == 0 { + self.mode = Mode::TypeDo; + return self.type_do(); + } + + need_bits!(self, 16); + + // Gzip + if (self.wrap & 2) != 0 && self.bit_reader.hold() == 0x8b1f { + if self.wbits == 0 { + self.wbits = 15; + } + + let b0 = self.bit_reader.bits(8) as u8; + let b1 = (self.bit_reader.hold() >> 8) as u8; + self.checksum = crc32(crate::CRC32_INITIAL_VALUE, &[b0, b1]); + self.bit_reader.init_bits(); + + self.mode = Mode::Flags; + return self.flags(); + } + + // check if zlib header is allowed + if (self.wrap & 1) != 0 + && ((self.bit_reader.bits(8) << 8) + (self.bit_reader.hold() >> 8)) % 31 != 0 + { + self.mode = Mode::Bad; + return self.bad("incorrect header check\0"); + } + + if self.bit_reader.bits(4) != Z_DEFLATED as u64 { + self.mode = Mode::Bad; + return self.bad("unknown compression method\0"); + } + + self.bit_reader.drop_bits(4); + let len = self.bit_reader.bits(4) as usize + 8; + + if self.wbits == 0 { + self.wbits = len; + } + + if len > MAX_WBITS as usize || len > self.wbits { + self.mode = Mode::Bad; + return self.bad("invalid window size\0"); + } + + self.dmax = 1 << len; + self.flags = 0; // indicate zlib header + self.checksum = crate::ADLER32_INITIAL_VALUE as _; + + if self.bit_reader.hold() & 0x200 != 0 { + self.bit_reader.init_bits(); + + self.mode = Mode::DictId; + self.dict_id() + } else { + self.bit_reader.init_bits(); + + self.mode = Mode::Type; + self.type_() + } + } + + fn flags(&mut self) -> ReturnCode { + need_bits!(self, 16); + self.flags = self.bit_reader.hold() as i32; + + // Z_DEFLATED = 8 is the only supported method + if self.flags & 0xff != Z_DEFLATED { + self.mode = Mode::Bad; + return self.bad("unknown compression method\0"); + } + + if self.flags & 0xe000 != 0 { + self.mode = Mode::Bad; + return self.bad("unknown header flags set\0"); + } + + if let Some(head) = self.head.as_mut() { + head.text = ((self.bit_reader.hold() >> 8) & 1) as i32; + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + let b0 = self.bit_reader.bits(8) as u8; + let b1 = (self.bit_reader.hold() >> 8) as u8; + self.checksum = crc32(self.checksum, &[b0, b1]); + } + + self.bit_reader.init_bits(); + self.mode = Mode::Time; + self.time() + } + + fn time(&mut self) -> ReturnCode { + need_bits!(self, 32); + if let Some(head) = self.head.as_mut() { + head.time = self.bit_reader.hold() as z_size; + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + let bytes = (self.bit_reader.hold() as u32).to_le_bytes(); + self.checksum = crc32(self.checksum, &bytes); + } + + self.bit_reader.init_bits(); + self.mode = Mode::Os; + self.os() + } + + fn os(&mut self) -> ReturnCode { + need_bits!(self, 16); + if let Some(head) = self.head.as_mut() { + head.xflags = (self.bit_reader.hold() & 0xff) as i32; + head.os = (self.bit_reader.hold() >> 8) as i32; + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + let bytes = (self.bit_reader.hold() as u16).to_le_bytes(); + self.checksum = crc32(self.checksum, &bytes); + } + + self.bit_reader.init_bits(); + self.mode = Mode::ExLen; + self.ex_len() + } + + fn ex_len(&mut self) -> ReturnCode { + if (self.flags & 0x0400) != 0 { + need_bits!(self, 16); + + // self.length (and head.extra_len) represent the length of the extra field + self.length = self.bit_reader.hold() as usize; + if let Some(head) = self.head.as_mut() { + head.extra_len = self.length as u32; + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + let bytes = (self.bit_reader.hold() as u16).to_le_bytes(); + self.checksum = crc32(self.checksum, &bytes); + } + self.bit_reader.init_bits(); + } else if let Some(head) = self.head.as_mut() { + head.extra = core::ptr::null_mut(); + } + + self.mode = Mode::Extra; + self.extra() + } + + fn extra(&mut self) -> ReturnCode { + if (self.flags & 0x0400) != 0 { + // self.length is the number of remaining `extra` bytes. But they may not all be available + let extra_available = Ord::min(self.length, self.bit_reader.bytes_remaining()); + let extra_slice = &self.bit_reader.as_slice()[..extra_available]; + + if !extra_slice.is_empty() { + if let Some(head) = self.head.as_mut() { + if !head.extra.is_null() { + let written_so_far = head.extra_len as usize - self.length; + + let count = Ord::min( + (head.extra_max as usize).saturating_sub(written_so_far), + extra_slice.len(), + ); + + unsafe { + core::ptr::copy_nonoverlapping( + self.bit_reader.as_ptr(), + head.extra.add(written_so_far), + count, + ); + } + } + } + + // Checksum + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + self.checksum = crc32(self.checksum, extra_slice) + } + + self.in_available -= extra_available; + self.bit_reader.advance(extra_available); + self.length -= extra_available; + } + + // Checks for errors occur after returning + if self.length != 0 { + return self.inflate_leave(ReturnCode::Ok); + } + } + + self.length = 0; + self.mode = Mode::Name; + self.name() + } + + fn name(&mut self) -> ReturnCode { + if (self.flags & 0x0800) != 0 { + if self.in_available == 0 { + return self.inflate_leave(ReturnCode::Ok); + } + + // the name string will always be null-terminated, but might be longer than we have + // space for in the header struct. Nonetheless, we read the whole thing. + let slice = self.bit_reader.as_slice(); + let null_terminator_index = slice.iter().position(|c| *c == 0); + + // we include the null terminator if it exists + let name_slice = match null_terminator_index { + Some(i) => &slice[..=i], + None => slice, + }; + + // if the header has space, store as much as possible in there + if let Some(head) = self.head.as_mut() { + if !head.name.is_null() { + let remaining_name_bytes = (head.name_max as usize).saturating_sub(self.length); + let copy = Ord::min(name_slice.len(), remaining_name_bytes); + + unsafe { + core::ptr::copy_nonoverlapping( + name_slice.as_ptr(), + head.name.add(self.length), + copy, + ) + }; + + self.length += copy; + } + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + self.checksum = crc32(self.checksum, name_slice); + } + + let reached_end = name_slice.last() == Some(&0); + self.bit_reader.advance(name_slice.len()); + + if !reached_end && self.bit_reader.bytes_remaining() == 0 { + return self.inflate_leave(ReturnCode::Ok); + } + } else if let Some(head) = self.head.as_mut() { + head.name = core::ptr::null_mut(); + } + + self.length = 0; + self.mode = Mode::Comment; + self.comment() + } + + fn comment(&mut self) -> ReturnCode { + if (self.flags & 0x01000) != 0 { + if self.in_available == 0 { + return self.inflate_leave(ReturnCode::Ok); + } + + // the comment string will always be null-terminated, but might be longer than we have + // space for in the header struct. Nonetheless, we read the whole thing. + let slice = self.bit_reader.as_slice(); + let null_terminator_index = slice.iter().position(|c| *c == 0); + + // we include the null terminator if it exists + let comment_slice = match null_terminator_index { + Some(i) => &slice[..=i], + None => slice, + }; + + // if the header has space, store as much as possible in there + if let Some(head) = self.head.as_mut() { + if !head.comment.is_null() { + let remaining_comm_bytes = (head.comm_max as usize).saturating_sub(self.length); + let copy = Ord::min(comment_slice.len(), remaining_comm_bytes); + unsafe { + core::ptr::copy_nonoverlapping( + comment_slice.as_ptr(), + head.comment.add(self.length), + copy, + ) + }; + + self.length += copy; + } + } + + if (self.flags & 0x0200) != 0 && (self.wrap & 4) != 0 { + self.checksum = crc32(self.checksum, comment_slice); + } + + let reached_end = comment_slice.last() == Some(&0); + self.bit_reader.advance(comment_slice.len()); + + if !reached_end && self.bit_reader.bytes_remaining() == 0 { + return self.inflate_leave(ReturnCode::Ok); + } + } else if let Some(head) = self.head.as_mut() { + head.comment = core::ptr::null_mut(); + } + + self.mode = Mode::HCrc; + self.hcrc() + } + + fn hcrc(&mut self) -> ReturnCode { + if (self.flags & 0x0200) != 0 { + need_bits!(self, 16); + + if (self.wrap & 4) != 0 && self.bit_reader.hold() as u32 != (self.checksum & 0xffff) { + self.mode = Mode::Bad; + return self.bad("header crc mismatch\0"); + } + + self.bit_reader.init_bits(); + } + + if let Some(head) = self.head.as_mut() { + head.hcrc = (self.flags >> 9) & 1; + head.done = 1; + } + + // compute crc32 checksum if not in raw mode + if (self.wrap & 4 != 0) && self.flags != 0 { + self.crc_fold = Crc32Fold::new(); + self.checksum = crate::CRC32_INITIAL_VALUE; + } + + self.mode = Mode::Type; + self.type_() + } + + fn sync(&mut self) -> ReturnCode { + ReturnCode::StreamError + } + + fn lit(&mut self) -> ReturnCode { + if self.writer.remaining() == 0 { + #[cfg(all(test, feature = "std"))] + eprintln!("Ok: read_buf is full ({} bytes)", self.writer.capacity()); + return self.inflate_leave(ReturnCode::Ok); + } + + self.writer.push(self.length as u8); + + self.mode = Mode::Len; + + self.len() + } + + fn check(&mut self) -> ReturnCode { + if self.wrap != 0 { + need_bits!(self, 32); + + self.total += self.writer.len(); + + if self.wrap & 4 != 0 { + if self.flags != 0 { + self.crc_fold.fold(self.writer.filled(), self.checksum); + self.checksum = self.crc_fold.finish(); + } else { + self.checksum = adler32(self.checksum, self.writer.filled()); + } + } + + let given_checksum = if self.flags != 0 { + self.bit_reader.hold() as u32 + } else { + zswap32(self.bit_reader.hold() as u32) + }; + + self.out_available = self.writer.capacity() - self.writer.len(); + + if self.wrap & 4 != 0 && given_checksum != self.checksum { + self.mode = Mode::Bad; + return self.bad("incorrect data check\0"); + } + + self.bit_reader.init_bits(); + } + self.mode = Mode::Length; + self.length() + } + + fn length(&mut self) -> ReturnCode { + // for gzip, last bytes contain LENGTH + if self.wrap != 0 && self.flags != 0 { + need_bits!(self, 32); + if (self.wrap & 4) != 0 && self.bit_reader.hold() != self.total as u64 { + self.mode = Mode::Bad; + return self.bad("incorrect length check\0"); + } + + self.bit_reader.init_bits(); + } + + // inflate stream terminated properly + self.inflate_leave(ReturnCode::StreamEnd) + } + + fn type_(&mut self) -> ReturnCode { + use InflateFlush::*; + + match self.flush { + Block | Trees => self.inflate_leave(ReturnCode::Ok), + NoFlush | SyncFlush | Finish => self.type_do(), + } + } + + fn type_do(&mut self) -> ReturnCode { + if self.last { + self.bit_reader.next_byte_boundary(); + self.mode = Mode::Check; + return self.check(); + } + + need_bits!(self, 3); + self.last = self.bit_reader.bits(1) != 0; + self.bit_reader.drop_bits(1); + + match self.bit_reader.bits(2) { + 0 => { + // eprintln!("inflate: stored block (last = {last})"); + + self.bit_reader.drop_bits(2); + + self.mode = Mode::Stored; + self.stored() + } + 1 => { + // eprintln!("inflate: fixed codes block (last = {last})"); + + self.len_table = Table { + codes: Codes::Fixed(&self::inffixed_tbl::LENFIX), + bits: 9, + }; + + self.dist_table = Table { + codes: Codes::Fixed(&self::inffixed_tbl::DISTFIX), + bits: 5, + }; + + self.mode = Mode::Len_; + + self.bit_reader.drop_bits(2); + + if let InflateFlush::Trees = self.flush { + self.inflate_leave(ReturnCode::Ok) + } else { + self.len_() + } + } + 2 => { + // eprintln!("inflate: dynamic codes block (last = {last})"); + + self.bit_reader.drop_bits(2); + + self.mode = Mode::Table; + self.table() + } + 3 => { + // eprintln!("inflate: invalid block type"); + + self.bit_reader.drop_bits(2); + + self.mode = Mode::Bad; + self.bad("invalid block type\0") + } + _ => unsafe { core::hint::unreachable_unchecked() }, + } + } + + fn stored(&mut self) -> ReturnCode { + self.bit_reader.next_byte_boundary(); + + need_bits!(self, 32); + + let hold = self.bit_reader.bits(32) as u32; + + // eprintln!("hold {hold:#x}"); + + if hold as u16 != !((hold >> 16) as u16) { + self.mode = Mode::Bad; + return self.bad("invalid stored block lengths\0"); + } + + self.length = hold as usize & 0xFFFF; + // eprintln!("inflate: stored length {}", state.length); + + self.bit_reader.init_bits(); + + if let InflateFlush::Trees = self.flush { + self.inflate_leave(ReturnCode::Ok) + } else { + self.mode = Mode::CopyBlock; + self.copy_block() + } + } + + fn copy_block(&mut self) -> ReturnCode { + loop { + let mut copy = self.length; + + if copy == 0 { + break; + } + + copy = Ord::min(copy, self.writer.remaining()); + copy = Ord::min(copy, self.bit_reader.bytes_remaining()); + + if copy == 0 { + return self.inflate_leave(ReturnCode::Ok); + } + + self.writer.extend(&self.bit_reader.as_slice()[..copy]); + self.bit_reader.advance(copy); + + self.length -= copy; + } + + self.mode = Mode::Type; + self.type_() + } + + fn len_(&mut self) -> ReturnCode { + self.mode = Mode::Len; + self.len() + } + + fn len(&mut self) -> ReturnCode { + let avail_in = self.bit_reader.bytes_remaining(); + let avail_out = self.writer.remaining(); + + // INFLATE_FAST_MIN_LEFT is important. It makes sure there is at least 32 bytes of free + // space available. This means for many SIMD operations we don't need to process a + // remainder; we just copy blindly, and a later operation will overwrite the extra copied + // bytes + if avail_in >= INFLATE_FAST_MIN_HAVE && avail_out >= INFLATE_FAST_MIN_LEFT { + return inflate_fast_help(self, 0); + } + + self.back = 0; + + // get a literal, length, or end-of-block code + let mut here; + loop { + let bits = self.bit_reader.bits(self.len_table.bits); + here = self.len_table_get(bits as usize); + + if here.bits <= self.bit_reader.bits_in_buffer() { + break; + } + + pull_byte!(self); + } + + if here.op != 0 && here.op & 0xf0 == 0 { + let last = here; + loop { + let bits = self.bit_reader.bits((last.bits + last.op) as usize) as u16; + here = self.len_table_get((last.val + (bits >> last.bits)) as usize); + if last.bits + here.bits <= self.bit_reader.bits_in_buffer() { + break; + } + + pull_byte!(self); + } + + self.bit_reader.drop_bits(last.bits as usize); + self.back += last.bits as usize; + } + + self.bit_reader.drop_bits(here.bits as usize); + self.back += here.bits as usize; + self.length = here.val as usize; + + if here.op == 0 { + self.mode = Mode::Lit; + self.lit() + } else if here.op & 32 != 0 { + // end of block + + // eprintln!("inflate: end of block"); + + self.back = usize::MAX; + self.mode = Mode::Type; + self.type_() + } else if here.op & 64 != 0 { + self.mode = Mode::Bad; + self.bad("invalid literal/length code\0") + } else { + // length code + self.extra = (here.op & MAX_BITS) as usize; + self.mode = Mode::LenExt; + self.len_ext() + } + } + + fn len_ext(&mut self) -> ReturnCode { + let extra = self.extra; + + // get extra bits, if any + if extra != 0 { + need_bits!(self, extra); + self.length += self.bit_reader.bits(extra) as usize; + self.bit_reader.drop_bits(extra); + self.back += extra; + } + + // eprintln!("inflate: length {}", state.length); + + self.was = self.length; + self.mode = Mode::Dist; + self.dist() + } + + fn dist(&mut self) -> ReturnCode { + // get distance code + let mut here; + loop { + let bits = self.bit_reader.bits(self.dist_table.bits) as usize; + here = self.dist_table_get(bits); + if here.bits <= self.bit_reader.bits_in_buffer() { + break; + } + + pull_byte!(self); + } + + if here.op & 0xf0 == 0 { + let last = here; + + loop { + let bits = self.bit_reader.bits((last.bits + last.op) as usize); + here = self.dist_table_get(last.val as usize + ((bits as usize) >> last.bits)); + + if last.bits + here.bits <= self.bit_reader.bits_in_buffer() { + break; + } + + pull_byte!(self); + } + + self.bit_reader.drop_bits(last.bits as usize); + self.back += last.bits as usize; + } + + self.bit_reader.drop_bits(here.bits as usize); + + if here.op & 64 != 0 { + self.mode = Mode::Bad; + return self.bad("invalid distance code\0"); + } + + self.offset = here.val as usize; + + self.extra = (here.op & MAX_BITS) as usize; + self.mode = Mode::DistExt; + self.dist_ext() + } + + fn dist_ext(&mut self) -> ReturnCode { + let extra = self.extra; + + if extra > 0 { + need_bits!(self, extra); + self.offset += self.bit_reader.bits(extra) as usize; + self.bit_reader.drop_bits(extra); + self.back += extra; + } + + if self.offset > self.dmax { + self.mode = Mode::Bad; + return self.bad("invalid distance code too far back\0"); + } + + // eprintln!("inflate: distance {}", state.offset); + + self.mode = Mode::Match; + self.match_() + } + + /// copy match from window to output + + fn match_(&mut self) -> ReturnCode { + if self.writer.remaining() == 0 { + #[cfg(all(feature = "std", test))] + eprintln!( + "BufError: read_buf is full ({} bytes)", + self.writer.capacity() + ); + return self.inflate_leave(ReturnCode::Ok); + } + + // this is not quite right. not sure when that matters + let out = self.writer.remaining() + self.writer.len(); + let left = self.writer.remaining(); + + let copy = out - left; + + let copy = if self.offset > copy { + // copy from window to output + + let mut copy = self.offset - copy; + + if copy > self.window.have() { + if self.sane { + self.mode = Mode::Bad; + return self.bad("invalid distance too far back\0"); + } + + // TODO INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + panic!("INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR") + } + + let wnext = self.window.next(); + let wsize = self.window.size(); + + let from = if copy > wnext { + copy -= wnext; + wsize - copy + } else { + wnext - copy + }; + + copy = Ord::min(copy, self.length); + copy = Ord::min(copy, left); + + self.writer.extend(&self.window.as_slice()[from..][..copy]); + + copy + } else { + let copy = Ord::min(self.length, self.writer.remaining()); + self.writer.copy_match(self.offset, copy); + + copy + }; + + self.length -= copy; + + if self.length == 0 { + self.mode = Mode::Len; + self.len() + } else { + // otherwise it seems to recurse? + self.match_() + } + } + + /// get dynamic table entries descriptor + + fn table(&mut self) -> ReturnCode { + need_bits!(self, 14); + self.nlen = self.bit_reader.bits(5) as usize + 257; + self.bit_reader.drop_bits(5); + self.ndist = self.bit_reader.bits(5) as usize + 1; + self.bit_reader.drop_bits(5); + self.ncode = self.bit_reader.bits(4) as usize + 4; + self.bit_reader.drop_bits(4); + + // TODO pkzit_bug_workaround + if self.nlen > 286 || self.ndist > 30 { + self.mode = Mode::Bad; + return self.bad("too many length or distance symbols\0"); + } + + self.have = 0; + self.mode = Mode::LenLens; + self.len_lens() + } + + /// get code length code lengths (not a typo) + + fn len_lens(&mut self) -> ReturnCode { + // permutation of code lengths ; + const ORDER: [u16; 19] = [ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, + ]; + + while self.have < self.ncode { + need_bits!(self, 3); + self.lens[ORDER[self.have] as usize] = self.bit_reader.bits(3) as u16; + self.have += 1; + self.bit_reader.drop_bits(3); + } + + while self.have < 19 { + self.lens[ORDER[self.have] as usize] = 0; + self.have += 1; + } + + self.len_table.bits = 7; + + let InflateTable::Success(root) = inflate_table( + CodeType::Codes, + &self.lens, + 19, + &mut self.codes_codes, + self.len_table.bits, + &mut self.work, + ) else { + self.mode = Mode::Bad; + return self.bad("invalid code lengths set\0"); + }; + + self.len_table.codes = Codes::Codes; + self.len_table.bits = root; + + self.have = 0; + self.mode = Mode::CodeLens; + self.code_lens() + } + + /// get length and distance code code lengths + + fn code_lens(&mut self) -> ReturnCode { + while self.have < self.nlen + self.ndist { + let here = loop { + let bits = self.bit_reader.bits(self.len_table.bits); + let here = self.len_table_get(bits as usize); + if here.bits <= self.bit_reader.bits_in_buffer() { + break here; + } + + pull_byte!(self); + }; + + let here_bits = here.bits as usize; + + match here.val { + 0..=15 => { + self.bit_reader.drop_bits(here_bits); + self.lens[self.have] = here.val; + self.have += 1; + } + 16 => { + need_bits!(self, here_bits + 2); + self.bit_reader.drop_bits(here_bits); + if self.have == 0 { + self.mode = Mode::Bad; + return self.bad("invalid bit length repeat\0"); + } + + let len = self.lens[self.have - 1]; + let copy = 3 + self.bit_reader.bits(2) as usize; + self.bit_reader.drop_bits(2); + + if self.have + copy > self.nlen + self.ndist { + self.mode = Mode::Bad; + return self.bad("invalid bit length repeat\0"); + } + + for _ in 0..copy { + self.lens[self.have] = len; + self.have += 1; + } + } + 17 => { + need_bits!(self, here_bits + 3); + self.bit_reader.drop_bits(here_bits); + let len = 0; + let copy = 3 + self.bit_reader.bits(3) as usize; + self.bit_reader.drop_bits(3); + + if self.have + copy > self.nlen + self.ndist { + self.mode = Mode::Bad; + return self.bad("invalid bit length repeat\0"); + } + + for _ in 0..copy { + self.lens[self.have] = len as u16; + self.have += 1; + } + } + 18.. => { + need_bits!(self, here_bits + 7); + self.bit_reader.drop_bits(here_bits); + let len = 0; + let copy = 11 + self.bit_reader.bits(7) as usize; + self.bit_reader.drop_bits(7); + + if self.have + copy > self.nlen + self.ndist { + self.mode = Mode::Bad; + return self.bad("invalid bit length repeat\0"); + } + + for _ in 0..copy { + self.lens[self.have] = len as u16; + self.have += 1; + } + } + } + } + + // check for end-of-block code (better have one) + if self.lens[256] == 0 { + self.mode = Mode::Bad; + return self.bad("invalid code -- missing end-of-block\0"); + } + + // build code tables + + self.len_table.bits = 10; + + let InflateTable::Success(root) = inflate_table( + CodeType::Lens, + &self.lens, + self.nlen, + &mut self.len_codes, + self.len_table.bits, + &mut self.work, + ) else { + self.mode = Mode::Bad; + return self.bad("invalid literal/lengths set\0"); + }; + + self.len_table.codes = Codes::Len; + self.len_table.bits = root; + + self.dist_table.bits = 9; + + let InflateTable::Success(root) = inflate_table( + CodeType::Dists, + &self.lens[self.nlen..], + self.ndist, + &mut self.dist_codes, + self.dist_table.bits, + &mut self.work, + ) else { + self.mode = Mode::Bad; + return self.bad("invalid distances set\0"); + }; + + self.dist_table.bits = root; + self.dist_table.codes = Codes::Dist; + + self.mode = Mode::Len_; + + if matches!(self.flush, InflateFlush::Trees) { + return self.inflate_leave(ReturnCode::Ok); + } + + self.len_() + } + + fn dict_id(&mut self) -> ReturnCode { + need_bits!(self, 32); + + self.checksum = zswap32(self.bit_reader.hold() as u32); + + self.bit_reader.init_bits(); + + self.mode = Mode::Dict; + self.dict() + } + + fn dict(&mut self) -> ReturnCode { + if !self.havedict { + return self.inflate_leave(ReturnCode::NeedDict); + } + + self.checksum = crate::ADLER32_INITIAL_VALUE as _; + + self.mode = Mode::Type; + self.type_() + } + + fn mem(&mut self) -> ReturnCode { + self.inflate_leave(ReturnCode::MemError) + } + + fn bad(&mut self, msg: &'static str) -> ReturnCode { + #[cfg(all(feature = "std", test))] + dbg!(msg); + self.error_message = Some(msg); + self.inflate_leave(ReturnCode::DataError) + } + + // NOTE: it is crucial for the internal bookkeeping that this is the only route for actually + // leaving the inflate function call chain + fn inflate_leave(&mut self, return_code: ReturnCode) -> ReturnCode { + // actual logic is in `inflate` itself + return_code + } + + /// Stored in the `z_stream.data_type` field + fn decoding_state(&self) -> i32 { + let bit_reader_bits = self.bit_reader.bits_in_buffer() as i32; + debug_assert!(bit_reader_bits < 64); + + let last = if self.last { 64 } else { 0 }; + + let mode = match self.mode { + Mode::Type => 128, + Mode::Len_ | Mode::CopyBlock => 256, + _ => 0, + }; + + bit_reader_bits | last | mode + } +} + +fn inflate_fast_help(state: &mut State, _start: usize) -> ReturnCode { + let mut bit_reader = BitReader::new(&[]); + core::mem::swap(&mut bit_reader, &mut state.bit_reader); + + let mut writer = ReadBuf::new(&mut []); + core::mem::swap(&mut writer, &mut state.writer); + + let lcode = state.len_table_ref(); + let dcode = state.dist_table_ref(); + + // IDEA: use const generics for the bits here? + let lmask = (1u64 << state.len_table.bits) - 1; + let dmask = (1u64 << state.dist_table.bits) - 1; + + // TODO verify if this is relevant for us + let extra_safe = false; + + let window_size = state.window.size(); + + let mut bad = None; + + if bit_reader.bits_in_buffer() < 10 { + bit_reader.refill(); + } + + 'outer: loop { + let mut here = bit_reader.refill_and(|hold| lcode[(hold & lmask) as usize]); + + if here.op == 0 { + writer.push(here.val as u8); + bit_reader.drop_bits(here.bits as usize); + here = lcode[(bit_reader.hold() & lmask) as usize]; + + if here.op == 0 { + writer.push(here.val as u8); + bit_reader.drop_bits(here.bits as usize); + here = lcode[(bit_reader.hold() & lmask) as usize]; + } + } + + 'dolen: loop { + bit_reader.drop_bits(here.bits as usize); + let op = here.op; + + if op == 0 { + writer.push(here.val as u8); + } else if op & 16 != 0 { + let op = op & MAX_BITS; + let mut len = here.val + bit_reader.bits(op as usize) as u16; + bit_reader.drop_bits(op as usize); + + here = dcode[(bit_reader.hold() & dmask) as usize]; + + // we have two fast-path loads: 10+10 + 15+5 = 40, + // but we may need to refill here in the worst case + if bit_reader.bits_in_buffer() < MAX_BITS + MAX_DIST_EXTRA_BITS { + bit_reader.refill(); + } + + 'dodist: loop { + bit_reader.drop_bits(here.bits as usize); + let op = here.op; + + if op & 16 != 0 { + let op = op & MAX_BITS; + let dist = here.val + bit_reader.bits(op as usize) as u16; + + if dist as usize > state.dmax { + bad = Some("invalid distance too far back\0"); + state.mode = Mode::Bad; + break 'outer; + } + + bit_reader.drop_bits(op as usize); + + // max distance in output + let written = writer.len(); + + if dist as usize > written { + // copy fropm the window + if (dist as usize - written) > state.window.have() { + if state.sane { + bad = Some("invalid distance too far back\0"); + state.mode = Mode::Bad; + break 'outer; + } + + panic!("INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR") + } + + let mut op = dist as usize - written; + let mut from; + + let window_next = state.window.next(); + + if window_next == 0 { + // This case is hit when the window has just wrapped around + // by logic in `Window::extend`. It is special-cased because + // apparently this is quite common. + // + // the match is at the end of the window, even though the next + // position has now wrapped around. + from = window_size - op; + } else if window_next >= op { + // the standard case: a contiguous copy from the window, no wrapping + from = window_next - op; + } else { + // This case is hit when the window has recently wrapped around + // by logic in `Window::extend`. + // + // The match is (partially) at the end of the window + op -= window_next; + from = window_size - op; + + if op < len as usize { + // This case is hit when part of the match is at the end of the + // window, and part of it has wrapped around to the start. Copy + // the end section here, the start section will be copied below. + len -= op as u16; + writer.extend(&state.window.as_slice()[from..][..op]); + from = 0; + op = window_next; + } + } + + let copy = Ord::min(op, len as usize); + writer.extend(&state.window.as_slice()[from..][..copy]); + + if op < len as usize { + // here we need some bytes from the output itself + writer.copy_match(dist as usize, len as usize - op); + } + } else if extra_safe { + todo!() + } else { + writer.copy_match(dist as usize, len as usize) + } + } else if (op & 64) == 0 { + // 2nd level distance code + here = dcode[(here.val + bit_reader.bits(op as usize) as u16) as usize]; + continue 'dodist; + } else { + bad = Some("invalid distance code\0"); + state.mode = Mode::Bad; + break 'outer; + } + + break 'dodist; + } + } else if (op & 64) == 0 { + // 2nd level length code + here = lcode[(here.val + bit_reader.bits(op as usize) as u16) as usize]; + continue 'dolen; + } else if op & 32 != 0 { + // end of block + state.mode = Mode::Type; + break 'outer; + } else { + bad = Some("invalid literal/length code\0"); + state.mode = Mode::Bad; + break 'outer; + } + + break 'dolen; + } + + let remaining = bit_reader.bytes_remaining(); + if remaining.saturating_sub(INFLATE_FAST_MIN_LEFT - 1) > 0 + && writer.remaining() > INFLATE_FAST_MIN_LEFT + { + continue; + } + + break 'outer; + } + + // return unused bytes (on entry, bits < 8, so in won't go too far back) + bit_reader.return_unused_bytes(); + + state.bit_reader = bit_reader; + state.writer = writer; + + match state.mode { + Mode::Type => state.type_(), + Mode::Len => state.len(), + Mode::Bad => state.bad(bad.unwrap()), + _ => unreachable!(), + } +} + +pub fn prime(stream: &mut InflateStream, bits: i32, value: i32) -> ReturnCode { + if bits == 0 { + /* fall through */ + } else if bits < 0 { + stream.state.bit_reader.init_bits(); + } else if bits > 16 || stream.state.bit_reader.bits_in_buffer() + bits as u8 > 32 { + return ReturnCode::StreamError; + } else { + stream.state.bit_reader.prime(bits as u8, value as u64); + } + + ReturnCode::Ok +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +pub struct InflateConfig { + pub window_bits: i32, +} + +impl Default for InflateConfig { + fn default() -> Self { + Self { + window_bits: DEF_WBITS, + } + } +} + +/// Initialize the stream in an inflate state +pub fn init(stream: &mut z_stream, config: InflateConfig) -> ReturnCode { + stream.msg = core::ptr::null_mut(); + + // for safety we must really make sure that alloc and free are consistent + // this is a (slight) deviation from stock zlib. In this crate we pick the rust + // allocator as the default, but `libz-rs-sys` configures the C allocator + #[cfg(feature = "rust-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_rust_allocator() + } + + #[cfg(feature = "c-allocator")] + if stream.zalloc.is_none() || stream.zfree.is_none() { + stream.configure_default_c_allocator() + } + + if stream.zalloc.is_none() || stream.zfree.is_none() { + return ReturnCode::StreamError; + } + + let mut state = State::new(&[], ReadBuf::new(&mut [])); + + // TODO this can change depending on the used/supported SIMD instructions + state.chunksize = 32; + + let alloc = Allocator { + zalloc: stream.zalloc.unwrap(), + zfree: stream.zfree.unwrap(), + opaque: stream.opaque, + _marker: PhantomData, + }; + + // allocated here to have the same order as zlib + let Some(state_allocation) = alloc.allocate::() else { + return ReturnCode::MemError; + }; + + stream.state = state_allocation.write(state) as *mut _ as *mut internal_state; + + // SAFETY: we've correctly initialized the stream to be an InflateStream + let ret = if let Some(stream) = unsafe { InflateStream::from_stream_mut(stream) } { + reset_with_config(stream, config) + } else { + ReturnCode::StreamError + }; + + if ret != ReturnCode::Ok { + let ptr = stream.state; + stream.state = core::ptr::null_mut(); + // SAFETY: we assume deallocation does not cause UB + unsafe { alloc.deallocate(ptr, 1) }; + } + + ret +} + +pub fn reset_with_config(stream: &mut InflateStream, config: InflateConfig) -> ReturnCode { + let mut window_bits = config.window_bits; + let wrap; + + if window_bits < 0 { + wrap = 0; + + if window_bits < -MAX_WBITS { + return ReturnCode::StreamError; + } + + window_bits = -window_bits; + } else { + wrap = (window_bits >> 4) + 5; // TODO wth? + + if window_bits < 48 { + window_bits &= MAX_WBITS; + } + } + + if window_bits != 0 && !(MIN_WBITS..=MAX_WBITS).contains(&window_bits) { + #[cfg(feature = "std")] + eprintln!("invalid windowBits"); + return ReturnCode::StreamError; + } + + if stream.state.window.size() != 0 && stream.state.wbits != window_bits as usize { + let mut window = Window::empty(); + core::mem::swap(&mut window, &mut stream.state.window); + + let window = window.into_inner(); + assert!(!window.is_empty()); + unsafe { stream.alloc.deallocate(window.as_mut_ptr(), window.len()) }; + } + + stream.state.wrap = wrap as usize; + stream.state.wbits = window_bits as _; + + reset(stream) +} + +pub fn reset(stream: &mut InflateStream) -> ReturnCode { + // reset the state of the window + stream.state.window.clear(); + + stream.state.error_message = None; + + reset_keep(stream) +} + +pub fn reset_keep(stream: &mut InflateStream) -> ReturnCode { + stream.total_in = 0; + stream.total_out = 0; + stream.state.total = 0; + + stream.msg = core::ptr::null_mut(); + + let state = &mut stream.state; + + if state.wrap != 0 { + // to support ill-conceived Java test suite + stream.adler = (state.wrap & 1) as _; + } + + state.mode = Mode::Head; + state.checksum = crate::ADLER32_INITIAL_VALUE as u32; + + state.last = false; + state.havedict = false; + state.flags = -1; + state.dmax = 32768; + state.head = None; + state.bit_reader = BitReader::new(&[]); + + state.next = 0; + state.len_table = Table::default(); + state.dist_table = Table::default(); + + state.sane = true; + state.back = usize::MAX; + + ReturnCode::Ok +} + +pub unsafe fn inflate(stream: &mut InflateStream, flush: InflateFlush) -> ReturnCode { + if stream.next_out.is_null() || (stream.next_in.is_null() && stream.avail_in != 0) { + return ReturnCode::StreamError as _; + } + + let source_slice = core::slice::from_raw_parts(stream.next_in, stream.avail_in as usize); + let dest_slice = core::slice::from_raw_parts_mut(stream.next_out, stream.avail_out as usize); + + let state = &mut stream.state; + + // skip check + if let Mode::Type = state.mode { + state.mode = Mode::TypeDo; + } + + state.flush = flush; + + state.bit_reader.update_slice(source_slice); + state.writer = ReadBuf::new(dest_slice); + + state.in_available = stream.avail_in as _; + state.out_available = stream.avail_out as _; + + let mut err = state.dispatch(); + + let in_read = state.bit_reader.as_ptr() as usize - stream.next_in as usize; + let out_written = state.out_available - (state.writer.capacity() - state.writer.len()); + + stream.total_in += in_read as z_size; + state.total += out_written; + stream.total_out = state.total as _; + + stream.avail_in = state.bit_reader.bytes_remaining() as u32; + stream.next_in = state.bit_reader.as_ptr() as *mut u8; + + stream.avail_out = (state.writer.capacity() - state.writer.len()) as u32; + stream.next_out = state.writer.next_out() as *mut u8; + + stream.adler = state.checksum as z_checksum; + + let valid_mode = |mode| !matches!(mode, Mode::Bad | Mode::Mem | Mode::Sync); + let not_done = |mode| { + !matches!( + mode, + Mode::Check | Mode::Length | Mode::Bad | Mode::Mem | Mode::Sync + ) + }; + + let must_update_window = state.window.size() != 0 + || (out_written != 0 + && valid_mode(state.mode) + && (not_done(state.mode) || !matches!(state.flush, InflateFlush::Finish))); + + let update_checksum = state.wrap & 4 != 0; + + if must_update_window { + 'blk: { + // initialize the window if needed + if state.window.size() == 0 { + match Window::new_in(&stream.alloc, state.wbits) { + Some(window) => state.window = window, + None => { + state.mode = Mode::Mem; + err = ReturnCode::MemError; + break 'blk; + } + } + } + + state.window.extend( + &state.writer.filled()[..out_written], + state.flags, + update_checksum, + &mut state.checksum, + &mut state.crc_fold, + ); + } + } + + if let Some(msg) = state.error_message { + assert!(msg.ends_with(|c| c == '\0')); + stream.msg = msg.as_ptr() as *mut u8 as *mut core::ffi::c_char; + } + + stream.data_type = state.decoding_state(); + + if ((in_read == 0 && out_written == 0) || flush == InflateFlush::Finish as _) + && err == (ReturnCode::Ok as _) + { + ReturnCode::BufError as _ + } else { + err as _ + } +} + +fn syncsearch(mut got: usize, buf: &[u8]) -> (usize, usize) { + let len = buf.len(); + let mut next = 0; + + while next < len && got < 4 { + if buf[next] == if got < 2 { 0 } else { 0xff } { + got += 1; + } else if buf[next] != 0 { + got = 0; + } else { + got = 4 - got; + } + next += 1; + } + + (got, next) +} + +pub fn sync(stream: &mut InflateStream) -> ReturnCode { + let state = &mut stream.state; + + if stream.avail_in == 0 && state.bit_reader.bits_in_buffer() < 8 { + return ReturnCode::BufError; + } + /* if first time, start search in bit buffer */ + if !matches!(state.mode, Mode::Sync) { + state.mode = Mode::Sync; + + let (buf, len) = state.bit_reader.start_sync_search(); + + (state.have, _) = syncsearch(0, &buf[..len]); + } + + // search available input + let slice = unsafe { core::slice::from_raw_parts(stream.next_in, stream.avail_in as usize) }; + + let len; + (state.have, len) = syncsearch(state.have, slice); + stream.next_in = unsafe { stream.next_in.add(len) }; + stream.avail_in -= len as u32; + stream.total_in += len as z_size; + + /* return no joy or set up to restart inflate() on a new block */ + if state.have != 4 { + return ReturnCode::DataError; + } + + if state.flags == -1 { + state.wrap = 0; /* if no header yet, treat as raw */ + } else { + state.wrap &= !4; /* no point in computing a check value now */ + } + + let flags = state.flags; + let total_in = stream.total_in; + let total_out = stream.total_out; + + reset(stream); + + stream.total_in = total_in; + stream.total_out = total_out; + + stream.state.flags = flags; + stream.state.mode = Mode::Type; + + ReturnCode::Ok +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. +*/ +pub fn sync_point(stream: &mut InflateStream) -> bool { + matches!(stream.state.mode, Mode::Stored) && stream.state.bit_reader.bits_in_buffer() == 0 +} + +pub unsafe fn copy<'a>( + dest: &mut MaybeUninit>, + source: &InflateStream<'a>, +) -> ReturnCode { + if source.next_out.is_null() || (source.next_in.is_null() && source.avail_in != 0) { + return ReturnCode::StreamError; + } + + // Safety: source and dest are both mutable references, so guaranteed not to overlap. + // dest being a reference to maybe uninitialized memory makes a copy of 1 DeflateStream valid. + unsafe { + core::ptr::copy_nonoverlapping(source, dest.as_mut_ptr(), 1); + } + + // allocated here to have the same order as zlib + let Some(state_allocation) = source.alloc.allocate::() else { + return ReturnCode::MemError; + }; + + let state = &source.state; + + let writer: MaybeUninit = + unsafe { core::ptr::read(&state.writer as *const _ as *const MaybeUninit) }; + + let mut copy = State { + mode: state.mode, + last: state.last, + wrap: state.wrap, + len_table: state.len_table, + dist_table: state.dist_table, + wbits: state.wbits, + window: Window::empty(), + head: None, + ncode: state.ncode, + nlen: state.nlen, + ndist: state.ndist, + have: state.have, + next: state.next, + bit_reader: state.bit_reader, + writer: ReadBuf::new(&mut []), + total: state.total, + length: state.length, + offset: state.offset, + extra: state.extra, + sane: state.sane, + back: state.back, + was: state.was, + chunksize: state.chunksize, + in_available: state.in_available, + out_available: state.out_available, + lens: state.lens, + work: state.work, + error_message: state.error_message, + flush: state.flush, + checksum: state.checksum, + crc_fold: state.crc_fold, + havedict: state.havedict, + dmax: state.dmax, + flags: state.flags, + codes_codes: state.codes_codes, + len_codes: state.len_codes, + dist_codes: state.dist_codes, + }; + + if !state.window.is_empty() { + let Some(window) = state.window.clone_in(&source.alloc) else { + source.alloc.deallocate(state_allocation.as_mut_ptr(), 1); + return ReturnCode::MemError; + }; + + copy.window = window; + } + + // write the cloned state into state_ptr + let state_ptr = state_allocation.write(copy); + + // insert the state_ptr into `dest` + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state) }; + unsafe { core::ptr::write(field_ptr as *mut *mut State, state_ptr) }; + + // update the writer; it cannot be cloned so we need to use some shennanigans + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state.writer) }; + unsafe { core::ptr::copy(writer.as_ptr(), field_ptr, 1) }; + + // update the gzhead field (it contains a mutable reference so we need to be careful + let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state.head) }; + unsafe { core::ptr::copy(&source.state.head, field_ptr, 1) }; + + ReturnCode::Ok +} + +pub fn undermine(stream: &mut InflateStream, subvert: i32) -> ReturnCode { + stream.state.sane = (!subvert) != 0; + + ReturnCode::Ok +} + +pub fn mark(stream: &InflateStream) -> c_long { + if stream.next_out.is_null() || (stream.next_in.is_null() && stream.avail_in != 0) { + return c_long::MIN; + } + + let state = &stream.state; + + let length = match state.mode { + Mode::CopyBlock => state.length, + Mode::Match => state.was - state.length, + _ => 0, + }; + + (((state.back as c_long) as c_ulong) << 16) as c_long + length as c_long +} + +pub fn set_dictionary(stream: &mut InflateStream, dictionary: &[u8]) -> ReturnCode { + if stream.state.wrap != 0 && !matches!(stream.state.mode, Mode::Dict) { + return ReturnCode::StreamError; + } + + // check for correct dictionary identifier + if matches!(stream.state.mode, Mode::Dict) { + let dictid = adler32(1, dictionary); + + if dictid != stream.state.checksum { + return ReturnCode::DataError; + } + } + + let err = 'blk: { + // initialize the window if needed + if stream.state.window.size() == 0 { + match Window::new_in(&stream.alloc, stream.state.wbits) { + None => break 'blk ReturnCode::MemError, + Some(window) => stream.state.window = window, + } + } + + stream.state.window.extend( + dictionary, + stream.state.flags, + false, + &mut stream.state.checksum, + &mut stream.state.crc_fold, + ); + + ReturnCode::Ok + }; + + if err != ReturnCode::Ok { + stream.state.mode = Mode::Mem; + return ReturnCode::MemError; + } + + stream.state.havedict = true; + + ReturnCode::Ok +} + +pub fn end<'a>(stream: &'a mut InflateStream<'a>) -> &'a mut z_stream { + let alloc = stream.alloc; + + let mut window = Window::empty(); + core::mem::swap(&mut window, &mut stream.state.window); + + // safety: window is not used again + if !window.is_empty() { + let window = window.into_inner(); + unsafe { alloc.deallocate(window.as_mut_ptr(), window.len()) }; + } + + let stream = stream.as_z_stream_mut(); + + let state_ptr = core::mem::replace(&mut stream.state, core::ptr::null_mut()); + + // safety: state_ptr is not used again + unsafe { alloc.deallocate(state_ptr as *mut State, 1) }; + + stream +} + +pub fn get_header<'a>( + stream: &mut InflateStream<'a>, + head: Option<&'a mut gz_header>, +) -> ReturnCode { + if (stream.state.wrap & 2) == 0 { + return ReturnCode::StreamError; + } + + stream.state.head = head.map(|head| { + head.done = 0; + head + }); + ReturnCode::Ok +} +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn uncompress_buffer_overflow() { + let mut output = [0; 1 << 13]; + let input = [ + 72, 137, 58, 0, 3, 39, 255, 255, 255, 255, 255, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 184, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14, + 14, 14, 14, 14, 14, 63, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14, 255, 14, 103, 14, + 14, 14, 14, 14, 14, 61, 14, 255, 255, 63, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14, + 255, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 6, 14, 14, 14, 14, 14, 14, 14, 14, 71, + 4, 137, 106, + ]; + + let config = InflateConfig { window_bits: 15 }; + + let (_decompressed, err) = uncompress_slice(&mut output, &input, config); + assert_eq!(err, ReturnCode::DataError); + } +} diff --git a/third_party/rust/zlib-rs/src/inflate/bitreader.rs b/third_party/rust/zlib-rs/src/inflate/bitreader.rs new file mode 100644 index 0000000000..2b2fa5fd17 --- /dev/null +++ b/third_party/rust/zlib-rs/src/inflate/bitreader.rs @@ -0,0 +1,203 @@ +use core::marker::PhantomData; + +use crate::ReturnCode; + +#[derive(Debug, Clone, Copy)] +pub(crate) struct BitReader<'a> { + ptr: *const u8, + end: *const u8, + bit_buffer: u64, + bits_used: u8, + _marker: PhantomData<&'a [u8]>, +} + +impl<'a> BitReader<'a> { + pub fn new(slice: &'a [u8]) -> Self { + let range = slice.as_ptr_range(); + + Self { + ptr: range.start, + end: range.end, + bit_buffer: 0, + bits_used: 0, + _marker: PhantomData, + } + } + + #[inline(always)] + pub fn update_slice(&mut self, slice: &[u8]) { + let range = slice.as_ptr_range(); + + *self = Self { + ptr: range.start, + end: range.end, + bit_buffer: self.bit_buffer, + bits_used: self.bits_used, + _marker: PhantomData, + }; + } + + #[inline(always)] + pub fn advance(&mut self, bytes: usize) { + self.ptr = Ord::min(unsafe { self.ptr.add(bytes) }, self.end); + } + + #[inline(always)] + pub fn as_ptr(&self) -> *const u8 { + self.ptr + } + + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + let len = self.bytes_remaining(); + unsafe { core::slice::from_raw_parts(self.ptr, len) } + } + + #[inline(always)] + pub fn bits_in_buffer(&self) -> u8 { + self.bits_used + } + + #[inline(always)] + pub fn hold(&self) -> u64 { + self.bit_buffer + } + + #[inline(always)] + pub fn bytes_remaining(&self) -> usize { + self.end as usize - self.ptr as usize + } + + #[inline(always)] + pub fn need_bits(&mut self, n: usize) -> Result<(), ReturnCode> { + while (self.bits_used as usize) < n { + self.pull_byte()?; + } + + Ok(()) + } + + /// Remove zero to seven bits as needed to go to a byte boundary + #[inline(always)] + pub fn next_byte_boundary(&mut self) { + self.bit_buffer >>= self.bits_used & 0b0111; + self.bits_used -= self.bits_used & 0b0111; + } + + #[inline(always)] + pub fn pull_byte(&mut self) -> Result { + if self.ptr == self.end { + return Err(ReturnCode::Ok); + } + + let byte = unsafe { *self.ptr }; + self.ptr = unsafe { self.ptr.add(1) }; + + self.bit_buffer |= (byte as u64) << self.bits_used; + self.bits_used += 8; + + Ok(byte) + } + + #[inline(always)] + pub fn refill(&mut self) { + debug_assert!(self.bytes_remaining() >= 8); + + let read = unsafe { core::ptr::read_unaligned(self.ptr.cast::()) }.to_le(); + self.bit_buffer |= read << self.bits_used; + let increment = (63 - self.bits_used) >> 3; + self.ptr = self.ptr.wrapping_add(increment as usize); + self.bits_used |= 56; + } + + #[inline(always)] + pub fn refill_and(&mut self, f: impl Fn(u64) -> T) -> T { + debug_assert!(self.bytes_remaining() >= 8); + + // the trick of this function is that the read can happen concurrently + // with the arithmetic below. That makes the read effectively free. + let read = unsafe { core::ptr::read_unaligned(self.ptr.cast::()) }.to_le(); + let next_bit_buffer = self.bit_buffer | read << self.bits_used; + + let increment = (63 - self.bits_used) >> 3; + self.ptr = self.ptr.wrapping_add(increment as usize); + self.bits_used |= 56; + + let result = f(self.bit_buffer); + + self.bit_buffer = next_bit_buffer; + + result + } + + #[inline(always)] + pub fn bits(&mut self, n: usize) -> u64 { + // debug_assert!( n <= self.bits_used, "{n} bits requested, but only {} avaliable", self.bits_used); + + let lowest_n_bits = (1 << n) - 1; + self.bit_buffer & lowest_n_bits + } + + #[inline(always)] + pub fn drop_bits(&mut self, n: usize) { + self.bit_buffer >>= n; + self.bits_used -= n as u8; + } + + #[inline(always)] + pub fn start_sync_search(&mut self) -> ([u8; 4], usize) { + let mut buf = [0u8; 4]; + + self.bit_buffer <<= self.bits_used & 7; + self.bits_used -= self.bits_used & 7; + + let mut len = 0; + while self.bits_used >= 8 { + buf[len] = self.bit_buffer as u8; + len += 1; + self.bit_buffer >>= 8; + self.bits_used -= 8; + } + + (buf, len) + } + + #[inline(always)] + pub fn init_bits(&mut self) { + self.bit_buffer = 0; + self.bits_used = 0; + } + + #[inline(always)] + pub fn prime(&mut self, bits: u8, value: u64) { + let value = value & ((1 << bits) - 1); + self.bit_buffer += value << self.bits_used; + self.bits_used += bits; + } + + #[inline(always)] + pub fn return_unused_bytes(&mut self) { + let len = self.bits_used >> 3; + self.ptr = unsafe { self.ptr.sub(len as usize) }; + self.bits_used -= len << 3; + self.bit_buffer &= (1u64 << self.bits_used) - 1u64; + + assert!(self.bits_used <= 32); + } +} + +#[cfg(feature = "std")] +impl std::io::Read for BitReader<'_> { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + assert_eq!(self.bits_used, 0, "bit buffer not cleared before read"); + + let number_of_bytes = Ord::min(buf.len(), self.bytes_remaining()); + + // safety: `buf` is a mutable (exclusive) reference, so it cannot overlap the memory that + // the reader contains + unsafe { core::ptr::copy_nonoverlapping(self.ptr, buf.as_mut_ptr(), number_of_bytes) } + + self.ptr = unsafe { self.ptr.add(number_of_bytes) }; + Ok(number_of_bytes) + } +} diff --git a/third_party/rust/zlib-rs/src/inflate/inffixed_tbl.rs b/third_party/rust/zlib-rs/src/inflate/inffixed_tbl.rs new file mode 100644 index 0000000000..4bb2a9eac8 --- /dev/null +++ b/third_party/rust/zlib-rs/src/inflate/inffixed_tbl.rs @@ -0,0 +1,555 @@ +use crate::Code; + +const fn code(op: u8, bits: u8, val: u16) -> Code { + Code { op, bits, val } +} + +pub(crate) const LENFIX: [Code; 512] = [ + code(96, 7, 0), + code(0, 8, 80), + code(0, 8, 16), + code(20, 8, 115), + code(18, 7, 31), + code(0, 8, 112), + code(0, 8, 48), + code(0, 9, 192), + code(16, 7, 10), + code(0, 8, 96), + code(0, 8, 32), + code(0, 9, 160), + code(0, 8, 0), + code(0, 8, 128), + code(0, 8, 64), + code(0, 9, 224), + code(16, 7, 6), + code(0, 8, 88), + code(0, 8, 24), + code(0, 9, 144), + code(19, 7, 59), + code(0, 8, 120), + code(0, 8, 56), + code(0, 9, 208), + code(17, 7, 17), + code(0, 8, 104), + code(0, 8, 40), + code(0, 9, 176), + code(0, 8, 8), + code(0, 8, 136), + code(0, 8, 72), + code(0, 9, 240), + code(16, 7, 4), + code(0, 8, 84), + code(0, 8, 20), + code(21, 8, 227), + code(19, 7, 43), + code(0, 8, 116), + code(0, 8, 52), + code(0, 9, 200), + code(17, 7, 13), + code(0, 8, 100), + code(0, 8, 36), + code(0, 9, 168), + code(0, 8, 4), + code(0, 8, 132), + code(0, 8, 68), + code(0, 9, 232), + code(16, 7, 8), + code(0, 8, 92), + code(0, 8, 28), + code(0, 9, 152), + code(20, 7, 83), + code(0, 8, 124), + code(0, 8, 60), + code(0, 9, 216), + code(18, 7, 23), + code(0, 8, 108), + code(0, 8, 44), + code(0, 9, 184), + code(0, 8, 12), + code(0, 8, 140), + code(0, 8, 76), + code(0, 9, 248), + code(16, 7, 3), + code(0, 8, 82), + code(0, 8, 18), + code(21, 8, 163), + code(19, 7, 35), + code(0, 8, 114), + code(0, 8, 50), + code(0, 9, 196), + code(17, 7, 11), + code(0, 8, 98), + code(0, 8, 34), + code(0, 9, 164), + code(0, 8, 2), + code(0, 8, 130), + code(0, 8, 66), + code(0, 9, 228), + code(16, 7, 7), + code(0, 8, 90), + code(0, 8, 26), + code(0, 9, 148), + code(20, 7, 67), + code(0, 8, 122), + code(0, 8, 58), + code(0, 9, 212), + code(18, 7, 19), + code(0, 8, 106), + code(0, 8, 42), + code(0, 9, 180), + code(0, 8, 10), + code(0, 8, 138), + code(0, 8, 74), + code(0, 9, 244), + code(16, 7, 5), + code(0, 8, 86), + code(0, 8, 22), + code(64, 8, 0), + code(19, 7, 51), + code(0, 8, 118), + code(0, 8, 54), + code(0, 9, 204), + code(17, 7, 15), + code(0, 8, 102), + code(0, 8, 38), + code(0, 9, 172), + code(0, 8, 6), + code(0, 8, 134), + code(0, 8, 70), + code(0, 9, 236), + code(16, 7, 9), + code(0, 8, 94), + code(0, 8, 30), + code(0, 9, 156), + code(20, 7, 99), + code(0, 8, 126), + code(0, 8, 62), + code(0, 9, 220), + code(18, 7, 27), + code(0, 8, 110), + code(0, 8, 46), + code(0, 9, 188), + code(0, 8, 14), + code(0, 8, 142), + code(0, 8, 78), + code(0, 9, 252), + code(96, 7, 0), + code(0, 8, 81), + code(0, 8, 17), + code(21, 8, 131), + code(18, 7, 31), + code(0, 8, 113), + code(0, 8, 49), + code(0, 9, 194), + code(16, 7, 10), + code(0, 8, 97), + code(0, 8, 33), + code(0, 9, 162), + code(0, 8, 1), + code(0, 8, 129), + code(0, 8, 65), + code(0, 9, 226), + code(16, 7, 6), + code(0, 8, 89), + code(0, 8, 25), + code(0, 9, 146), + code(19, 7, 59), + code(0, 8, 121), + code(0, 8, 57), + code(0, 9, 210), + code(17, 7, 17), + code(0, 8, 105), + code(0, 8, 41), + code(0, 9, 178), + code(0, 8, 9), + code(0, 8, 137), + code(0, 8, 73), + code(0, 9, 242), + code(16, 7, 4), + code(0, 8, 85), + code(0, 8, 21), + code(16, 8, 258), + code(19, 7, 43), + code(0, 8, 117), + code(0, 8, 53), + code(0, 9, 202), + code(17, 7, 13), + code(0, 8, 101), + code(0, 8, 37), + code(0, 9, 170), + code(0, 8, 5), + code(0, 8, 133), + code(0, 8, 69), + code(0, 9, 234), + code(16, 7, 8), + code(0, 8, 93), + code(0, 8, 29), + code(0, 9, 154), + code(20, 7, 83), + code(0, 8, 125), + code(0, 8, 61), + code(0, 9, 218), + code(18, 7, 23), + code(0, 8, 109), + code(0, 8, 45), + code(0, 9, 186), + code(0, 8, 13), + code(0, 8, 141), + code(0, 8, 77), + code(0, 9, 250), + code(16, 7, 3), + code(0, 8, 83), + code(0, 8, 19), + code(21, 8, 195), + code(19, 7, 35), + code(0, 8, 115), + code(0, 8, 51), + code(0, 9, 198), + code(17, 7, 11), + code(0, 8, 99), + code(0, 8, 35), + code(0, 9, 166), + code(0, 8, 3), + code(0, 8, 131), + code(0, 8, 67), + code(0, 9, 230), + code(16, 7, 7), + code(0, 8, 91), + code(0, 8, 27), + code(0, 9, 150), + code(20, 7, 67), + code(0, 8, 123), + code(0, 8, 59), + code(0, 9, 214), + code(18, 7, 19), + code(0, 8, 107), + code(0, 8, 43), + code(0, 9, 182), + code(0, 8, 11), + code(0, 8, 139), + code(0, 8, 75), + code(0, 9, 246), + code(16, 7, 5), + code(0, 8, 87), + code(0, 8, 23), + code(64, 8, 0), + code(19, 7, 51), + code(0, 8, 119), + code(0, 8, 55), + code(0, 9, 206), + code(17, 7, 15), + code(0, 8, 103), + code(0, 8, 39), + code(0, 9, 174), + code(0, 8, 7), + code(0, 8, 135), + code(0, 8, 71), + code(0, 9, 238), + code(16, 7, 9), + code(0, 8, 95), + code(0, 8, 31), + code(0, 9, 158), + code(20, 7, 99), + code(0, 8, 127), + code(0, 8, 63), + code(0, 9, 222), + code(18, 7, 27), + code(0, 8, 111), + code(0, 8, 47), + code(0, 9, 190), + code(0, 8, 15), + code(0, 8, 143), + code(0, 8, 79), + code(0, 9, 254), + code(96, 7, 0), + code(0, 8, 80), + code(0, 8, 16), + code(20, 8, 115), + code(18, 7, 31), + code(0, 8, 112), + code(0, 8, 48), + code(0, 9, 193), + code(16, 7, 10), + code(0, 8, 96), + code(0, 8, 32), + code(0, 9, 161), + code(0, 8, 0), + code(0, 8, 128), + code(0, 8, 64), + code(0, 9, 225), + code(16, 7, 6), + code(0, 8, 88), + code(0, 8, 24), + code(0, 9, 145), + code(19, 7, 59), + code(0, 8, 120), + code(0, 8, 56), + code(0, 9, 209), + code(17, 7, 17), + code(0, 8, 104), + code(0, 8, 40), + code(0, 9, 177), + code(0, 8, 8), + code(0, 8, 136), + code(0, 8, 72), + code(0, 9, 241), + code(16, 7, 4), + code(0, 8, 84), + code(0, 8, 20), + code(21, 8, 227), + code(19, 7, 43), + code(0, 8, 116), + code(0, 8, 52), + code(0, 9, 201), + code(17, 7, 13), + code(0, 8, 100), + code(0, 8, 36), + code(0, 9, 169), + code(0, 8, 4), + code(0, 8, 132), + code(0, 8, 68), + code(0, 9, 233), + code(16, 7, 8), + code(0, 8, 92), + code(0, 8, 28), + code(0, 9, 153), + code(20, 7, 83), + code(0, 8, 124), + code(0, 8, 60), + code(0, 9, 217), + code(18, 7, 23), + code(0, 8, 108), + code(0, 8, 44), + code(0, 9, 185), + code(0, 8, 12), + code(0, 8, 140), + code(0, 8, 76), + code(0, 9, 249), + code(16, 7, 3), + code(0, 8, 82), + code(0, 8, 18), + code(21, 8, 163), + code(19, 7, 35), + code(0, 8, 114), + code(0, 8, 50), + code(0, 9, 197), + code(17, 7, 11), + code(0, 8, 98), + code(0, 8, 34), + code(0, 9, 165), + code(0, 8, 2), + code(0, 8, 130), + code(0, 8, 66), + code(0, 9, 229), + code(16, 7, 7), + code(0, 8, 90), + code(0, 8, 26), + code(0, 9, 149), + code(20, 7, 67), + code(0, 8, 122), + code(0, 8, 58), + code(0, 9, 213), + code(18, 7, 19), + code(0, 8, 106), + code(0, 8, 42), + code(0, 9, 181), + code(0, 8, 10), + code(0, 8, 138), + code(0, 8, 74), + code(0, 9, 245), + code(16, 7, 5), + code(0, 8, 86), + code(0, 8, 22), + code(64, 8, 0), + code(19, 7, 51), + code(0, 8, 118), + code(0, 8, 54), + code(0, 9, 205), + code(17, 7, 15), + code(0, 8, 102), + code(0, 8, 38), + code(0, 9, 173), + code(0, 8, 6), + code(0, 8, 134), + code(0, 8, 70), + code(0, 9, 237), + code(16, 7, 9), + code(0, 8, 94), + code(0, 8, 30), + code(0, 9, 157), + code(20, 7, 99), + code(0, 8, 126), + code(0, 8, 62), + code(0, 9, 221), + code(18, 7, 27), + code(0, 8, 110), + code(0, 8, 46), + code(0, 9, 189), + code(0, 8, 14), + code(0, 8, 142), + code(0, 8, 78), + code(0, 9, 253), + code(96, 7, 0), + code(0, 8, 81), + code(0, 8, 17), + code(21, 8, 131), + code(18, 7, 31), + code(0, 8, 113), + code(0, 8, 49), + code(0, 9, 195), + code(16, 7, 10), + code(0, 8, 97), + code(0, 8, 33), + code(0, 9, 163), + code(0, 8, 1), + code(0, 8, 129), + code(0, 8, 65), + code(0, 9, 227), + code(16, 7, 6), + code(0, 8, 89), + code(0, 8, 25), + code(0, 9, 147), + code(19, 7, 59), + code(0, 8, 121), + code(0, 8, 57), + code(0, 9, 211), + code(17, 7, 17), + code(0, 8, 105), + code(0, 8, 41), + code(0, 9, 179), + code(0, 8, 9), + code(0, 8, 137), + code(0, 8, 73), + code(0, 9, 243), + code(16, 7, 4), + code(0, 8, 85), + code(0, 8, 21), + code(16, 8, 258), + code(19, 7, 43), + code(0, 8, 117), + code(0, 8, 53), + code(0, 9, 203), + code(17, 7, 13), + code(0, 8, 101), + code(0, 8, 37), + code(0, 9, 171), + code(0, 8, 5), + code(0, 8, 133), + code(0, 8, 69), + code(0, 9, 235), + code(16, 7, 8), + code(0, 8, 93), + code(0, 8, 29), + code(0, 9, 155), + code(20, 7, 83), + code(0, 8, 125), + code(0, 8, 61), + code(0, 9, 219), + code(18, 7, 23), + code(0, 8, 109), + code(0, 8, 45), + code(0, 9, 187), + code(0, 8, 13), + code(0, 8, 141), + code(0, 8, 77), + code(0, 9, 251), + code(16, 7, 3), + code(0, 8, 83), + code(0, 8, 19), + code(21, 8, 195), + code(19, 7, 35), + code(0, 8, 115), + code(0, 8, 51), + code(0, 9, 199), + code(17, 7, 11), + code(0, 8, 99), + code(0, 8, 35), + code(0, 9, 167), + code(0, 8, 3), + code(0, 8, 131), + code(0, 8, 67), + code(0, 9, 231), + code(16, 7, 7), + code(0, 8, 91), + code(0, 8, 27), + code(0, 9, 151), + code(20, 7, 67), + code(0, 8, 123), + code(0, 8, 59), + code(0, 9, 215), + code(18, 7, 19), + code(0, 8, 107), + code(0, 8, 43), + code(0, 9, 183), + code(0, 8, 11), + code(0, 8, 139), + code(0, 8, 75), + code(0, 9, 247), + code(16, 7, 5), + code(0, 8, 87), + code(0, 8, 23), + code(64, 8, 0), + code(19, 7, 51), + code(0, 8, 119), + code(0, 8, 55), + code(0, 9, 207), + code(17, 7, 15), + code(0, 8, 103), + code(0, 8, 39), + code(0, 9, 175), + code(0, 8, 7), + code(0, 8, 135), + code(0, 8, 71), + code(0, 9, 239), + code(16, 7, 9), + code(0, 8, 95), + code(0, 8, 31), + code(0, 9, 159), + code(20, 7, 99), + code(0, 8, 127), + code(0, 8, 63), + code(0, 9, 223), + code(18, 7, 27), + code(0, 8, 111), + code(0, 8, 47), + code(0, 9, 191), + code(0, 8, 15), + code(0, 8, 143), + code(0, 8, 79), + code(0, 9, 255), +]; + +pub(crate) const DISTFIX: [Code; 32] = [ + code(16, 5, 1), + code(23, 5, 257), + code(19, 5, 17), + code(27, 5, 4097), + code(17, 5, 5), + code(25, 5, 1025), + code(21, 5, 65), + code(29, 5, 16385), + code(16, 5, 3), + code(24, 5, 513), + code(20, 5, 33), + code(28, 5, 8193), + code(18, 5, 9), + code(26, 5, 2049), + code(22, 5, 129), + code(64, 5, 0), + code(16, 5, 2), + code(23, 5, 385), + code(19, 5, 25), + code(27, 5, 6145), + code(17, 5, 7), + code(25, 5, 1537), + code(21, 5, 97), + code(29, 5, 24577), + code(16, 5, 4), + code(24, 5, 769), + code(20, 5, 49), + code(28, 5, 12289), + code(18, 5, 13), + code(26, 5, 3073), + code(22, 5, 193), + code(64, 5, 0), +]; diff --git a/third_party/rust/zlib-rs/src/inflate/inftrees.rs b/third_party/rust/zlib-rs/src/inflate/inftrees.rs new file mode 100644 index 0000000000..64a958e147 --- /dev/null +++ b/third_party/rust/zlib-rs/src/inflate/inftrees.rs @@ -0,0 +1,358 @@ +#![forbid(unsafe_code)] + +use crate::{Code, ENOUGH_DISTS, ENOUGH_LENS}; + +pub(crate) enum CodeType { + Codes, + Lens, + Dists, +} + +const MAX_BITS: usize = 15; + +fn min_max(count: [u16; N]) -> (usize, usize) { + let mut max = MAX_BITS; + while max >= 1 { + if count[max] != 0 { + break; + } + max -= 1; + } + + let mut min = 1; + while min < max { + if count[min] != 0 { + break; + } + min += 1; + } + + (min, max) +} + +/// Length codes 257..285 base +const LBASE: [u16; 31] = [ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, + 163, 195, 227, 258, 0, 0, +]; +/// Length codes 257..285 extra +const LEXT: [u16; 31] = [ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, + 21, 21, 21, 21, 16, 77, 202, +]; +/// Distance codes 0..29 base +const DBASE: [u16; 32] = [ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, + 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0, +]; +/// Distance codes 0..29 extra +const DEXT: [u16; 32] = [ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, + 27, 27, 28, 28, 29, 29, 64, 64, +]; + +#[repr(i32)] +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum InflateTable { + EnoughIsNotEnough = 1, + Success(usize) = 0, + InvalidCode = -1, +} + +pub(crate) fn inflate_table( + codetype: CodeType, + lens: &[u16], + codes: usize, + table: &mut [Code], + bits: usize, + work: &mut [u16], +) -> InflateTable { + // number of codes of each length + let mut count = [0u16; MAX_BITS + 1]; + + for len in lens[0..codes].iter().copied() { + count[len as usize] += 1; + } + + let mut root = bits; + + let (min, max) = min_max(count); + root = Ord::min(root, max); + root = Ord::max(root, min); + + if max == 0 { + // no symbols to code at all + let code = Code { + op: 64, + bits: 1, + val: 0, + }; + + table[0] = code; + table[1] = code; + + return InflateTable::Success(1); + } + + /* check for an over-subscribed or incomplete set of lengths */ + let mut left = 1i32; + let mut len = 1; + while len <= MAX_BITS { + left <<= 1; + left -= count[len] as i32; + if left < 0 { + // over-subscribed + return InflateTable::InvalidCode; + } + len += 1; + } + + if left > 0 && (matches!(codetype, CodeType::Codes) || max != 1) { + // incomplete set + return InflateTable::InvalidCode; + } + + /* generate offsets into symbol table for each length for sorting */ + + // offsets in table for each length + let mut offs = [0u16; MAX_BITS + 1]; + for len in 1..MAX_BITS { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym, len) in lens[0..codes].iter().copied().enumerate() { + if len != 0 { + let offset = offs[len as usize]; + offs[len as usize] += 1; + work[offset as usize] = sym as u16; + } + } + + let (base, extra, match_) = match codetype { + CodeType::Codes => (&[] as &[_], &[] as &[_], 20), + CodeType::Lens => (&LBASE[..], &LEXT[..], 257), + CodeType::Dists => (&DBASE[..], &DEXT[..], 0), + }; + + let used = 1 << root; + + /* check available table space */ + if matches!(codetype, CodeType::Lens) && used > ENOUGH_LENS { + return InflateTable::EnoughIsNotEnough; + } + + if matches!(codetype, CodeType::Dists) && used > ENOUGH_DISTS { + return InflateTable::EnoughIsNotEnough; + } + + let mut huff = 0; // starting code + let mut reversed_huff = 0u32; // starting code, reversed + let mut sym = 0; + let mut len = min; + let mut next = 0usize; // index into `table` + let mut curr = root; + let mut drop_ = 0; + let mut low = usize::MAX; // trigger new subtable when len > root + let mut used = 1 << root; + let mask = used - 1; /* mask for comparing low */ + + // process all codes and make table entries + 'outer: loop { + // create table entry + let here = if work[sym] >= match_ { + Code { + bits: (len - drop_) as u8, + op: extra[(work[sym] - match_) as usize] as u8, + val: base[(work[sym] - match_) as usize], + } + } else if work[sym] + 1 < match_ { + Code { + bits: (len - drop_) as u8, + op: 0, + val: work[sym], + } + } else { + Code { + bits: (len - drop_) as u8, + op: 0b01100000, + val: 0, + } + }; + + // replicate for those indices with low len bits equal to huff + let incr = 1 << (len - drop_); + let min = 1 << curr; // also has the name 'fill' in the C code + + let base = &mut table[next + (huff >> drop_)..]; + for fill in (0..min).step_by(incr) { + base[fill] = here; + } + + // backwards increment the len-bit code huff + reversed_huff = reversed_huff.wrapping_add(0x80000000u32 >> (len - 1)); + huff = reversed_huff.reverse_bits() as usize; + + // go to next symbol, update count, len + sym += 1; + count[len] -= 1; + if count[len] == 0 { + if len == max { + break 'outer; + } + len = lens[work[sym] as usize] as usize; + } + + // create new sub-table if needed + if len > root && (huff & mask) != low { + /* if first time, transition to sub-tables */ + if drop_ == 0 { + drop_ = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop_; + let mut left = 1 << curr; + while curr + drop_ < max { + left -= count[curr + drop_] as i32; + if left <= 0 { + break; + } + curr += 1; + left <<= 1; + } + + /* check for enough space */ + used += 1usize << curr; + + if matches!(codetype, CodeType::Lens) && used > ENOUGH_LENS { + return InflateTable::EnoughIsNotEnough; + } + + if matches!(codetype, CodeType::Dists) && used > ENOUGH_DISTS { + return InflateTable::EnoughIsNotEnough; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + table[low] = Code { + op: curr as u8, + bits: root as u8, + val: next as u16, + }; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if huff != 0 { + let here = Code { + op: 64, + bits: (len - drop_) as u8, + val: 0, + }; + + table[next..][huff] = here; + } + + /* set return parameters */ + InflateTable::Success(root) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn not_enough_errors() { + // we need to call inflate_table() directly in order to manifest + // not-enough errors, since zlib insures that enough is always enough + + let table = [Code::default(); crate::ENOUGH_DISTS]; + + let mut work = [0; 16]; + let mut lens: [_; 16] = core::array::from_fn(|i| (i + 1) as u16); + lens[15] = 15; + + let mut next = table; + let bits = 15; + let ret = inflate_table(CodeType::Dists, &lens, 16, &mut next, bits, &mut work); + assert_eq!(ret, InflateTable::EnoughIsNotEnough); + + let mut next = table; + let bits = 1; + let ret = inflate_table(CodeType::Dists, &lens, 16, &mut next, bits, &mut work); + assert_eq!(ret, InflateTable::EnoughIsNotEnough); + } + + fn build_fixed_length_table(work: &mut [u16]) -> [Code; 512] { + let mut lens = [0; 288]; + + // literal/length table + let mut sym = 0usize; + while sym < 144 { + lens[sym] = 8; + sym += 1; + } + while sym < 256 { + lens[sym] = 9; + sym += 1; + } + while sym < 280 { + lens[sym] = 7; + sym += 1; + } + while sym < 288 { + lens[sym] = 8; + sym += 1; + } + + let mut next = [Code::default(); 512]; + let bits = 9; + inflate_table(CodeType::Lens, &lens, 288, &mut next, bits, work); + + core::array::from_fn(|i| { + let mut code = next[i]; + + code.op = if i & 0b0111_1111 == 99 { 64 } else { code.op }; + + code + }) + } + + #[test] + fn generate_fixed_length_table() { + let mut work = [0; 512]; + let generated = build_fixed_length_table(&mut work); + + assert_eq!(generated, crate::inflate::inffixed_tbl::LENFIX); + } + + fn build_fixed_distance_table(work: &mut [u16]) -> [Code; 32] { + let mut lens = [0; 288]; + + let mut sym = 0; + while sym < 32 { + lens[sym] = 5; + sym += 1; + } + + let mut next = [Code::default(); 32]; + let bits = 5; + inflate_table(CodeType::Dists, &lens, 32, &mut next, bits, work); + + next + } + + #[test] + fn generate_fixed_distance_table() { + let mut work = [0; 512]; + let generated = build_fixed_distance_table(&mut work); + + assert_eq!(generated, crate::inflate::inffixed_tbl::DISTFIX); + } +} diff --git a/third_party/rust/zlib-rs/src/inflate/window.rs b/third_party/rust/zlib-rs/src/inflate/window.rs new file mode 100644 index 0000000000..535aa01afe --- /dev/null +++ b/third_party/rust/zlib-rs/src/inflate/window.rs @@ -0,0 +1,267 @@ +use crate::{ + adler32::{adler32, adler32_fold_copy}, + allocate::Allocator, + crc32::Crc32Fold, +}; +use core::mem::MaybeUninit; + +// translation guide: +// +// wsize -> buf.capacity() +// wnext -> buf.ptr +// whave -> buf.filled.len() +#[derive(Debug)] +pub struct Window<'a> { + buf: &'a mut [MaybeUninit], + + have: usize, // number of bytes logically written to the window. this can be higher than + // buf.len() if we run out of space in the window + next: usize, // write head +} + +impl<'a> Window<'a> { + pub fn into_inner(self) -> &'a mut [MaybeUninit] { + self.buf + } + + pub fn is_empty(&self) -> bool { + self.size() == 0 + } + + pub fn size(&self) -> usize { + if self.buf.is_empty() { + // an empty `buf` is used when the window has not yet been allocated, + // or when it has been deallocated. + 0 + } else { + self.buf.len() - Self::padding() + } + } + + /// number of bytes in the window. Saturates at `Self::capacity`. + pub fn have(&self) -> usize { + self.have + } + + /// Position where the next byte will be written + pub fn next(&self) -> usize { + self.next + } + + pub fn empty() -> Self { + Self { + buf: &mut [], + have: 0, + next: 0, + } + } + + pub fn clear(&mut self) { + self.have = 0; + self.next = 0; + } + + pub fn as_slice(&self) -> &[u8] { + // safety: the slice is always from the initialized part of buf + unsafe { slice_assume_init(&self.buf[..self.have]) } + } + + #[cfg(test)] + fn extend_adler32(&mut self, slice: &[u8], checksum: &mut u32) { + self.extend(slice, 0, true, checksum, &mut Crc32Fold::new()); + } + + pub fn extend( + &mut self, + slice: &[u8], + flags: i32, + update_checksum: bool, + checksum: &mut u32, + crc_fold: &mut Crc32Fold, + ) { + let len = slice.len(); + let wsize = self.size(); + + if len >= wsize { + // We have to split the checksum over non-copied and copied bytes + let pos = len.saturating_sub(self.size()); + let (non_window_slice, window_slice) = slice.split_at(pos); + + if update_checksum { + if flags != 0 { + crc_fold.fold(non_window_slice, 0); + crc_fold.fold_copy(&mut self.buf[..wsize], window_slice); + } else { + *checksum = adler32(*checksum, non_window_slice); + *checksum = adler32_fold_copy(*checksum, self.buf, window_slice); + } + } else { + self.buf[..wsize].copy_from_slice(unsafe { slice_to_uninit(window_slice) }); + } + + self.next = 0; + self.have = self.size(); + } else { + let dist = Ord::min(wsize - self.next, slice.len()); + + // the end part goes onto the end of the window. The start part wraps around and is + // written to the start of the window. + let (end_part, start_part) = slice.split_at(dist); + + if update_checksum { + let dst = &mut self.buf[self.next..][..end_part.len()]; + if flags != 0 { + crc_fold.fold_copy(dst, end_part); + } else { + *checksum = adler32_fold_copy(*checksum, dst, end_part); + } + } else { + let end_part = unsafe { slice_to_uninit(end_part) }; + self.buf[self.next..][..end_part.len()].copy_from_slice(end_part); + } + + if !start_part.is_empty() { + if update_checksum { + let dst = &mut self.buf[..start_part.len()]; + if flags != 0 { + crc_fold.fold_copy(dst, start_part); + } else { + *checksum = adler32_fold_copy(*checksum, dst, start_part); + } + } else { + let start_part = unsafe { slice_to_uninit(start_part) }; + self.buf[..start_part.len()].copy_from_slice(start_part); + } + + self.next = start_part.len(); + self.have = self.size(); + } else { + self.next += dist; + if self.next == self.size() { + self.next = 0; + } + if self.have < self.size() { + self.have += dist; + } + } + } + } + + pub fn new_in(alloc: &Allocator<'a>, window_bits: usize) -> Option { + let buf = alloc.allocate_slice::((1 << window_bits) + Self::padding())?; + + Some(Self { + buf, + have: 0, + next: 0, + }) + } + + pub fn clone_in(&self, alloc: &Allocator<'a>) -> Option { + let buf = alloc.allocate_slice::(self.buf.len())?; + + Some(Self { + buf, + have: self.have, + next: self.next, + }) + } + + // padding required so that SIMD operations going out-of-bounds are not a problem + pub fn padding() -> usize { + 64 // very conservative + } +} + +unsafe fn slice_to_uninit(slice: &[u8]) -> &[MaybeUninit] { + &*(slice as *const [u8] as *const [MaybeUninit]) +} + +// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable. +unsafe fn slice_assume_init(slice: &[MaybeUninit]) -> &[u8] { + &*(slice as *const [MaybeUninit] as *const [u8]) +} + +#[cfg(test)] +mod test { + use super::*; + + use crate::allocate::Allocator; + + fn init_window(window_bits_log2: usize) -> Window<'static> { + let mut window = Window::new_in(&Allocator::RUST, window_bits_log2).unwrap(); + window.buf.fill(MaybeUninit::new(0)); + window.have = 0; + window.next = 0; + window + } + + #[test] + fn extend_in_bounds() { + let mut checksum = 0; + + let mut window = init_window(4); + + window.extend_adler32(&[1; 5], &mut checksum); + assert_eq!(window.have, 5); + assert_eq!(window.next, 5); + + let slice = unsafe { slice_assume_init(&window.buf[..window.size()]) }; + assert_eq!(&[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], slice); + + window.extend_adler32(&[2; 7], &mut checksum); + assert_eq!(window.have, 12); + assert_eq!(window.next, 12); + + let slice = unsafe { slice_assume_init(&window.buf[..window.size()]) }; + assert_eq!(&[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0], slice); + + assert_eq!(checksum, 6946835); + + unsafe { Allocator::RUST.deallocate(window.buf.as_mut_ptr(), window.buf.len()) } + } + + #[test] + fn extend_crosses_bounds() { + let mut checksum = 0; + + let mut window = init_window(2); + + window.extend_adler32(&[1; 3], &mut checksum); + assert_eq!(window.have, 3); + assert_eq!(window.next, 3); + + let slice = unsafe { slice_assume_init(&window.buf[..window.size()]) }; + assert_eq!(&[1, 1, 1, 0], slice); + + window.extend_adler32(&[2; 3], &mut checksum); + assert_eq!(window.have, 4); + assert_eq!(window.next, 2); + + let slice = unsafe { slice_assume_init(&window.buf[..window.size()]) }; + assert_eq!(&[2, 2, 1, 2], slice); + + assert_eq!(checksum, 1769481); + + unsafe { Allocator::RUST.deallocate(window.buf.as_mut_ptr(), window.buf.len()) } + } + + #[test] + fn extend_out_of_bounds() { + let mut checksum = 0; + + let mut window = init_window(3); + + // adds 9 numbers, that won't fit into a window of size 8 + window.extend_adler32(&[1, 2, 3, 4, 5, 6, 7, 8, 9], &mut checksum); + assert_eq!(window.have, 8); + assert_eq!(window.next, 0); + + let slice = unsafe { slice_assume_init(&window.buf[..window.size()]) }; + assert_eq!(&[2, 3, 4, 5, 6, 7, 8, 9], slice); + + assert_eq!(checksum, 10813485); + + unsafe { Allocator::RUST.deallocate(window.buf.as_mut_ptr(), window.buf.len()) } + } +} diff --git a/third_party/rust/zlib-rs/src/lib.rs b/third_party/rust/zlib-rs/src/lib.rs new file mode 100644 index 0000000000..922a9b8b2a --- /dev/null +++ b/third_party/rust/zlib-rs/src/lib.rs @@ -0,0 +1,223 @@ +#![doc = core::include_str!("../README.md")] +#![cfg_attr(not(any(test, feature = "rust-allocator")), no_std)] + +#[cfg(any(feature = "rust-allocator", feature = "c-allocator"))] +extern crate alloc; + +mod adler32; +pub mod allocate; +pub mod c_api; +mod cpu_features; +pub mod crc32; +pub mod deflate; +pub mod inflate; +pub mod read_buf; + +pub use adler32::{adler32, adler32_combine}; +pub use crc32::{crc32, crc32_combine}; + +#[macro_export] +macro_rules! trace { + ($($arg:tt)*) => { + #[cfg(feature = "ZLIB_DEBUG")] + { + eprint!($($arg)*) + } + }; +} + +/// Maximum size of the dynamic table. The maximum number of code structures is +/// 1924, which is the sum of 1332 for literal/length codes and 592 for distance +/// codes. These values were found by exhaustive searches using the program +/// examples/enough.c found in the zlib distributions. The arguments to that +/// program are the number of symbols, the initial root table size, and the +/// maximum bit length of a code. "enough 286 10 15" for literal/length codes +/// returns 1332, and "enough 30 9 15" for distance codes returns 592. +/// The initial root table size (10 or 9) is found in the fifth argument of the +/// inflate_table() calls in inflate.c and infback.c. If the root table size is +/// changed, then these maximum sizes would be need to be recalculated and +/// updated. +#[allow(unused)] +pub(crate) const ENOUGH: usize = ENOUGH_LENS + ENOUGH_DISTS; +pub(crate) const ENOUGH_LENS: usize = 1332; +pub(crate) const ENOUGH_DISTS: usize = 592; + +/// initial adler-32 hash value +pub(crate) const ADLER32_INITIAL_VALUE: usize = 1; +/// initial crc-32 hash value +pub(crate) const CRC32_INITIAL_VALUE: u32 = 0; + +pub const MIN_WBITS: i32 = 8; // 256b LZ77 window +pub const MAX_WBITS: i32 = 15; // 32kb LZ77 window +pub(crate) const DEF_WBITS: i32 = MAX_WBITS; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum DeflateFlush { + #[default] + /// if flush is set to `NoFlush`, that allows deflate to decide how much data + /// to accumulate before producing output, in order to maximize compression. + NoFlush = 0, + + /// If flush is set to `PartialFlush`, all pending output is flushed to the + /// output buffer, but the output is not aligned to a byte boundary. All of the + /// input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + /// This completes the current deflate block and follows it with an empty fixed + /// codes block that is 10 bits long. This assures that enough bytes are output + /// in order for the decompressor to finish the block before the empty fixed + /// codes block. + PartialFlush = 1, + + /// If the parameter flush is set to `SyncFlush`, all pending output is + /// flushed to the output buffer and the output is aligned on a byte boundary, so + /// that the decompressor can get all input data available so far. (In + /// particular avail_in is zero after the call if enough output space has been + /// provided before the call.) Flushing may degrade compression for some + /// compression algorithms and so it should be used only when necessary. This + /// completes the current deflate block and follows it with an empty stored block + /// that is three bits plus filler bits to the next byte, followed by four bytes + /// (00 00 ff ff). + SyncFlush = 2, + + /// If flush is set to `FullFlush`, all output is flushed as with + /// Z_SYNC_FLUSH, and the compression state is reset so that decompression can + /// restart from this point if previous compressed data has been damaged or if + /// random access is desired. Using `FullFlush` too often can seriously degrade + /// compression. + FullFlush = 3, + + /// If the parameter flush is set to `Finish`, pending input is processed, + /// pending output is flushed and deflate returns with `StreamEnd` if there was + /// enough output space. If deflate returns with `Ok` or `BufError`, this + /// function must be called again with `Finish` and more output space (updated + /// avail_out) but no more input data, until it returns with `StreamEnd` or an + /// error. After deflate has returned `StreamEnd`, the only possible operations + /// on the stream are deflateReset or deflateEnd. + /// + /// `Finish` can be used in the first deflate call after deflateInit if all the + /// compression is to be done in a single step. In order to complete in one + /// call, avail_out must be at least the value returned by deflateBound (see + /// below). Then deflate is guaranteed to return `StreamEnd`. If not enough + /// output space is provided, deflate will not return `StreamEnd`, and it must + /// be called again as described above. + Finish = 4, + + /// If flush is set to `Block`, a deflate block is completed and emitted, as + /// for `SyncFlush`, but the output is not aligned on a byte boundary, and up to + /// seven bits of the current block are held to be written as the next byte after + /// the next deflate block is completed. In this case, the decompressor may not + /// be provided enough bits at this point in order to complete decompression of + /// the data provided so far to the compressor. It may need to wait for the next + /// block to be emitted. This is for advanced applications that need to control + /// the emission of deflate blocks. + Block = 5, +} + +impl TryFrom for DeflateFlush { + type Error = (); + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Self::NoFlush), + 1 => Ok(Self::PartialFlush), + 2 => Ok(Self::SyncFlush), + 3 => Ok(Self::FullFlush), + 4 => Ok(Self::Finish), + 5 => Ok(Self::Block), + _ => Err(()), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum InflateFlush { + #[default] + NoFlush = 0, + SyncFlush = 2, + Finish = 4, + Block = 5, + Trees = 6, +} + +impl TryFrom for InflateFlush { + type Error = (); + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Self::NoFlush), + 2 => Ok(Self::SyncFlush), + 4 => Ok(Self::Finish), + 5 => Ok(Self::Block), + 6 => Ok(Self::Trees), + _ => Err(()), + } + } +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub(crate) struct Code { + /// operation, extra bits, table bits + pub op: u8, + /// bits in this part of the code + pub bits: u8, + /// offset in table or code value + pub val: u16, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(i32)] +pub enum ReturnCode { + Ok = 0, + StreamEnd = 1, + NeedDict = 2, + ErrNo = -1, + StreamError = -2, + DataError = -3, + MemError = -4, + BufError = -5, + VersionError = -6, +} + +impl From for ReturnCode { + fn from(value: i32) -> Self { + match Self::try_from_c_int(value) { + Some(value) => value, + None => panic!("invalid return code {value}"), + } + } +} + +impl ReturnCode { + const fn error_message_str(self) -> &'static str { + match self { + ReturnCode::Ok => "\0", + ReturnCode::StreamEnd => "stream end\0", + ReturnCode::NeedDict => "need dictionary\0", + ReturnCode::ErrNo => "file error\0", + ReturnCode::StreamError => "stream error\0", + ReturnCode::DataError => "data error\0", + ReturnCode::MemError => "insufficient memory\0", + ReturnCode::BufError => "buffer error\0", + ReturnCode::VersionError => "incompatible version\0", + } + } + + pub const fn error_message(self) -> *const core::ffi::c_char { + let msg = self.error_message_str(); + msg.as_ptr().cast::() + } + + pub const fn try_from_c_int(err: core::ffi::c_int) -> Option { + match err { + 0 => Some(Self::Ok), + 1 => Some(Self::StreamEnd), + 2 => Some(Self::NeedDict), + -1 => Some(Self::ErrNo), + -2 => Some(Self::StreamError), + -3 => Some(Self::DataError), + -4 => Some(Self::MemError), + -5 => Some(Self::BufError), + -6 => Some(Self::VersionError), + _ => None, + } + } +} diff --git a/third_party/rust/zlib-rs/src/read_buf.rs b/third_party/rust/zlib-rs/src/read_buf.rs new file mode 100644 index 0000000000..04304c1588 --- /dev/null +++ b/third_party/rust/zlib-rs/src/read_buf.rs @@ -0,0 +1,409 @@ +// taken from https://docs.rs/tokio/latest/src/tokio/io/read_buf.rs.html#23-27 +// based on https://rust-lang.github.io/rfcs/2930-read-buf.html +use core::fmt; +use core::mem::MaybeUninit; + +use crate::allocate::Allocator; + +/// A wrapper around a byte buffer that is incrementally filled and initialized. +/// +/// This type is a sort of "double cursor". It tracks three regions in the +/// buffer: a region at the beginning of the buffer that has been logically +/// filled with data, a region that has been initialized at some point but not +/// yet logically filled, and a region at the end that may be uninitialized. +/// The filled region is guaranteed to be a subset of the initialized region. +/// +/// In summary, the contents of the buffer can be visualized as: +/// +/// ```not_rust +/// [ capacity ] +/// [ filled | unfilled ] +/// [ initialized | uninitialized ] +/// ``` +/// +/// It is undefined behavior to de-initialize any bytes from the uninitialized +/// region, since it is merely unknown whether this region is uninitialized or +/// not, and if part of it turns out to be initialized, it must stay initialized. +pub struct ReadBuf<'a> { + buf: &'a mut [MaybeUninit], + filled: usize, + initialized: usize, +} + +impl<'a> ReadBuf<'a> { + /// Creates a new `ReadBuf` from a fully initialized buffer. + #[inline] + pub fn new(buf: &'a mut [u8]) -> ReadBuf<'a> { + let initialized = buf.len(); + let buf = unsafe { slice_to_uninit_mut(buf) }; + ReadBuf { + buf, + filled: 0, + initialized, + } + } + + /// Pointer to where the next byte will be written + #[inline] + pub fn next_out(&mut self) -> *mut MaybeUninit { + self.buf[self.filled..].as_mut_ptr() + } + + /// Pointer to the start of the `ReadBuf` + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut MaybeUninit { + self.buf.as_mut_ptr() + } + + /// Returns the total capacity of the buffer. + #[inline] + pub fn capacity(&self) -> usize { + self.buf.len() + } + + /// Returns the length of the filled part of the buffer + #[inline] + pub fn len(&self) -> usize { + self.filled + } + + /// Returns true if there are no bytes in this ReadBuf + #[inline] + pub fn is_empty(&self) -> bool { + self.filled == 0 + } + + /// Returns a shared reference to the filled portion of the buffer. + #[inline] + pub fn filled(&self) -> &[u8] { + let slice = &self.buf[..self.filled]; + // safety: filled describes how far into the buffer that the + // user has filled with bytes, so it's been initialized. + unsafe { slice_assume_init(slice) } + } + + /// Returns a mutable reference to the entire buffer, without ensuring that it has been fully + /// initialized. + /// + /// The elements between 0 and `self.len()` are filled, and those between 0 and + /// `self.initialized().len()` are initialized (and so can be converted to a `&mut [u8]`). + /// + /// The caller of this method must ensure that these invariants are upheld. For example, if the + /// caller initializes some of the uninitialized section of the buffer, it must call + /// [`assume_init`](Self::assume_init) with the number of bytes initialized. + /// + /// # Safety + /// + /// The caller must not de-initialize portions of the buffer that have already been initialized. + /// This includes any bytes in the region marked as uninitialized by `ReadBuf`. + #[inline] + pub unsafe fn inner_mut(&mut self) -> &mut [MaybeUninit] { + self.buf + } + + /// Returns the number of bytes at the end of the slice that have not yet been filled. + #[inline] + pub fn remaining(&self) -> usize { + self.capacity() - self.filled + } + + /// Clears the buffer, resetting the filled region to empty. + /// + /// The number of initialized bytes is not changed, and the contents of the buffer are not modified. + #[inline] + pub fn clear(&mut self) { + self.filled = 0; + } + + /// Advances the size of the filled region of the buffer. + /// + /// The number of initialized bytes is not changed. + /// + /// # Panics + /// + /// Panics if the filled region of the buffer would become larger than the initialized region. + #[inline] + #[track_caller] + pub fn advance(&mut self, n: usize) { + let new = self.filled.checked_add(n).expect("filled overflow"); + self.set_filled(new); + } + + /// Sets the size of the filled region of the buffer. + /// + /// The number of initialized bytes is not changed. + /// + /// Note that this can be used to *shrink* the filled region of the buffer in addition to growing it (for + /// example, by a `AsyncRead` implementation that compresses data in-place). + /// + /// # Panics + /// + /// Panics if the filled region of the buffer would become larger than the initialized region. + #[inline] + #[track_caller] + pub fn set_filled(&mut self, n: usize) { + assert!( + n <= self.initialized, + "filled must not become larger than initialized" + ); + self.filled = n; + } + + /// Asserts that the first `n` unfilled bytes of the buffer are initialized. + /// + /// `ReadBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer + /// bytes than are already known to be initialized. + /// + /// # Safety + /// + /// The caller must ensure that `n` unfilled bytes of the buffer have already been initialized. + #[inline] + pub unsafe fn assume_init(&mut self, n: usize) { + self.initialized = Ord::max(self.initialized, self.filled + n); + } + + #[track_caller] + pub fn push(&mut self, byte: u8) { + assert!( + self.remaining() >= 1, + "read_buf is full ({} bytes)", + self.capacity() + ); + + self.buf[self.filled] = MaybeUninit::new(byte); + + self.initialized = Ord::max(self.initialized, self.filled + 1); + self.filled += 1; + } + + /// Appends data to the buffer, advancing the written position and possibly also the initialized position. + /// + /// # Panics + /// + /// Panics if `self.remaining()` is less than `buf.len()`. + #[inline(always)] + #[track_caller] + pub fn extend(&mut self, buf: &[u8]) { + assert!( + self.remaining() >= buf.len(), + "buf.len() must fit in remaining()" + ); + + // using simd here (on x86_64) was not fruitful + self.buf[self.filled..][..buf.len()].copy_from_slice(slice_to_uninit(buf)); + + let end = self.filled + buf.len(); + self.initialized = Ord::max(self.initialized, end); + self.filled = end; + } + + #[inline(always)] + pub fn copy_match(&mut self, offset_from_end: usize, length: usize) { + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx512() { + return self.copy_match_help::(offset_from_end, length); + } + + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_avx2() { + return self.copy_match_help::(offset_from_end, length); + } + + #[cfg(target_arch = "x86_64")] + if crate::cpu_features::is_enabled_sse() { + return self.copy_match_help::(offset_from_end, length); + } + + self.copy_match_help::(offset_from_end, length) + } + + fn copy_match_help(&mut self, offset_from_end: usize, length: usize) { + let current = self.filled; + + let start = current.checked_sub(offset_from_end).expect("in bounds"); + let end = start.checked_add(length).expect("in bounds"); + + // Note also that the referenced string may overlap the current + // position; for example, if the last 2 bytes decoded have values + // X and Y, a string reference with + // adds X,Y,X,Y,X to the output stream. + + if end > current { + if offset_from_end == 1 { + // this will just repeat this value many times + let element = self.buf[current - 1]; + self.buf[current..][..length].fill(element); + } else { + for i in 0..length { + self.buf[current + i] = self.buf[start + i]; + } + } + } else { + Self::copy_chunked_within::(self.buf, current, start, end) + } + + // safety: we just copied length initialized bytes right beyond self.filled + unsafe { self.assume_init(length) }; + + self.advance(length); + } + + #[inline(always)] + fn copy_chunked_within( + buf: &mut [MaybeUninit], + current: usize, + start: usize, + end: usize, + ) { + if (end - start).next_multiple_of(core::mem::size_of::()) <= (buf.len() - current) { + unsafe { + Self::copy_chunk_unchecked::( + buf.as_ptr().add(start), + buf.as_mut_ptr().add(current), + buf.as_ptr().add(end), + ) + } + } else { + // a full simd copy does not fit in the output buffer + buf.copy_within(start..end, current); + } + } + + /// # Safety + /// + /// `src` must be safe to perform unaligned reads in `core::mem::size_of::()` chunks until + /// `end` is reached. `dst` must be safe to (unalingned) write that number of chunks. + #[inline(always)] + unsafe fn copy_chunk_unchecked( + mut src: *const MaybeUninit, + mut dst: *mut MaybeUninit, + end: *const MaybeUninit, + ) { + while src < end { + let chunk = C::load_chunk(src); + C::store_chunk(dst, chunk); + + src = src.add(core::mem::size_of::()); + dst = dst.add(core::mem::size_of::()); + } + } + + pub(crate) fn new_in(alloc: &Allocator<'a>, len: usize) -> Option { + let buf = alloc.allocate_slice::(len)?; + + Some(Self { + buf, + filled: 0, + initialized: 0, + }) + } + + pub(crate) fn clone_in(&self, alloc: &Allocator<'a>) -> Option { + let mut clone = Self::new_in(alloc, self.buf.len())?; + + clone.buf.copy_from_slice(self.buf); + clone.filled = self.filled; + clone.initialized = self.initialized; + + Some(clone) + } + + pub(crate) unsafe fn drop_in(&mut self, alloc: &Allocator<'a>) { + if !self.buf.is_empty() { + let buf = core::mem::take(&mut self.buf); + alloc.deallocate(buf.as_mut_ptr(), buf.len()); + } + } +} + +impl fmt::Debug for ReadBuf<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ReadBuf") + .field("filled", &self.filled) + .field("initialized", &self.initialized) + .field("capacity", &self.capacity()) + .finish() + } +} + +fn slice_to_uninit(slice: &[u8]) -> &[MaybeUninit] { + unsafe { &*(slice as *const [u8] as *const [MaybeUninit]) } +} + +unsafe fn slice_to_uninit_mut(slice: &mut [u8]) -> &mut [MaybeUninit] { + &mut *(slice as *mut [u8] as *mut [MaybeUninit]) +} + +// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable. +unsafe fn slice_assume_init(slice: &[MaybeUninit]) -> &[u8] { + &*(slice as *const [MaybeUninit] as *const [u8]) +} + +trait Chunk { + /// Safety: must be valid to read a `Self::Chunk` value from `from` with an unaligned read. + unsafe fn load_chunk(from: *const MaybeUninit) -> Self; + + /// Safety: must be valid to write a `Self::Chunk` value to `out` with an unaligned write. + unsafe fn store_chunk(out: *mut MaybeUninit, chunk: Self); +} + +impl Chunk for u64 { + unsafe fn load_chunk(from: *const MaybeUninit) -> Self { + u64::to_le(core::ptr::read_unaligned(from.cast())) + } + + unsafe fn store_chunk(out: *mut MaybeUninit, chunk: Self) { + core::ptr::copy_nonoverlapping( + chunk.to_le_bytes().as_ptr().cast(), + out, + core::mem::size_of::(), + ) + } +} + +#[cfg(target_arch = "x86_64")] +impl Chunk for core::arch::x86_64::__m128i { + #[inline(always)] + unsafe fn load_chunk(from: *const MaybeUninit) -> Self { + core::arch::x86_64::_mm_loadu_si128(from.cast()) + } + + #[inline(always)] + unsafe fn store_chunk(out: *mut MaybeUninit, chunk: Self) { + core::arch::x86_64::_mm_storeu_si128(out as *mut Self, chunk); + } +} + +#[cfg(target_arch = "x86_64")] +impl Chunk for core::arch::x86_64::__m256i { + #[inline(always)] + unsafe fn load_chunk(from: *const MaybeUninit) -> Self { + core::arch::x86_64::_mm256_loadu_si256(from.cast()) + } + + #[inline(always)] + unsafe fn store_chunk(out: *mut MaybeUninit, chunk: Self) { + core::arch::x86_64::_mm256_storeu_si256(out as *mut Self, chunk); + } +} + +#[cfg(target_arch = "x86_64")] +impl Chunk for core::arch::x86_64::__m512i { + #[inline(always)] + unsafe fn load_chunk(from: *const MaybeUninit) -> Self { + // TODO AVX-512 is effectively unstable. + // We cross our fingers that LLVM optimizes this into a vmovdqu32 + // + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_loadu_si512&expand=3420&ig_expand=4110 + core::ptr::read_unaligned(from.cast()) + } + + #[inline(always)] + unsafe fn store_chunk(out: *mut MaybeUninit, chunk: Self) { + // TODO AVX-512 is effectively unstable. + // We cross our fingers that LLVM optimizes this into a vmovdqu32 + // + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_storeu_si512&expand=3420&ig_expand=4110,6550 + core::ptr::write_unaligned(out.cast(), chunk) + } +}