libflate-2.1.0/.cargo_vcs_info.json0000644000000001360000000000100126160ustar { "git": { "sha1": "6676d36d381eec60f376337e528d658b16c87c7a" }, "path_in_vcs": "" }libflate-2.1.0/.github/actions-rs/grcov.yml000064400000000000000000000000551046102023000166730ustar 00000000000000ignore-not-existing: true ignore: - "../*" libflate-2.1.0/.github/workflows/ci.yml000064400000000000000000000062021046102023000161210ustar 00000000000000# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md name: CI on: [push, pull_request] jobs: check: name: Check runs-on: ubuntu-latest strategy: matrix: toolchain: [stable, beta, nightly] features: [--no-default-features, --all-features] steps: - name: Checkout sources uses: actions/checkout@v1 - name: Install ${{ matrix.toolchain }} toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.toolchain }} override: true - name: Run cargo check uses: actions-rs/cargo@v1 with: command: check args: ${{ matrix.features }} --workspace no-std: name: no_std Check runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v1 - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: nightly override: true - name: Install cargo no-std-check uses: actions-rs/cargo@v1 with: command: install args: cargo-no-std-check # https://github.com/mystor/cargo-no-std-check/issues/2 # `--no-default-features` doesn't work with `--workspace` correctly. - name: Run cargo no-std-check on libflate crate uses: actions-rs/cargo@v1 with: command: no-std-check args: --no-default-features - name: Run cargo no-std-check on libflate_lz77 crate uses: actions-rs/cargo@v1 with: command: no-std-check args: --no-default-features --manifest-path libflate_lz77/Cargo.toml test: name: Test Suite runs-on: ubuntu-latest strategy: matrix: toolchain: [stable, beta, nightly] features: [--no-default-features, --all-features] steps: - name: Checkout sources uses: actions/checkout@v1 - name: Install ${{ matrix.toolchain }} toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.toolchain }} override: true - name: Run cargo test uses: actions-rs/cargo@v1 with: command: test args: ${{ matrix.features }} --workspace lints: name: Lints runs-on: ubuntu-latest strategy: matrix: toolchain: [stable, beta, nightly] features: [--no-default-features, --all-features] steps: - name: Checkout sources uses: actions/checkout@v1 - name: Install ${{ matrix.toolchain }} toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.toolchain }} override: true components: rustfmt, clippy - name: Run cargo fmt uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check - name: Run cargo clippy if: matrix.toolchain != 'beta' uses: actions-rs/cargo@v1 with: command: clippy args: ${{ matrix.features }} --workspace -- -D warnings libflate-2.1.0/.github/workflows/coverage.yml000064400000000000000000000023551046102023000173260ustar 00000000000000# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md name: Coverage on: push: branches: - master jobs: grcov: name: Coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Install toolchain uses: actions-rs/toolchain@v1 with: toolchain: nightly override: true - name: Execute tests uses: actions-rs/cargo@v1 with: command: test args: --all --all-features env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off" - name: Gather coverage data id: coverage uses: actions-rs/grcov@v0.1 - name: Coveralls upload uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel: true path-to-lcov: ${{ steps.coverage.outputs.report }} grcov_finalize: runs-on: ubuntu-latest needs: grcov steps: - name: Coveralls finalization uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true libflate-2.1.0/.gitignore000064400000000000000000000000221046102023000133700ustar 00000000000000target Cargo.lock libflate-2.1.0/Cargo.lock0000644000000226150000000000100105770ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "adler32" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "ahash" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", "zerocopy", ] [[package]] name = "allocator-api2" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", "windows-sys", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "core2" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" dependencies = [ "memchr", ] [[package]] name = "crc32fast" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "dary_heap" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", ] [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "libflate" version = "2.1.0" dependencies = [ "adler32", "clap", "core2", "crc32fast", "dary_heap", "libflate_lz77", ] [[package]] name = "libflate_lz77" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" dependencies = [ "core2", "hashbrown", "rle-decode-fast", ] [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "proc-macro2" version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rle-decode-fast" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] name = "windows_i686_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "zerocopy" version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", "syn", ] libflate-2.1.0/Cargo.toml0000644000000026250000000000100106210ustar # 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. [package] edition = "2021" name = "libflate" version = "2.1.0" authors = ["Takeru Ohta "] description = "A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP)" homepage = "https://github.com/sile/libflate" readme = "README.md" keywords = [ "deflate", "gzip", "zlib", ] categories = [ "compression", "no-std", ] license = "MIT" repository = "https://github.com/sile/libflate" [dependencies.adler32] version = "1" default-features = false [dependencies.core2] version = "0.4" features = ["alloc"] default-features = false [dependencies.crc32fast] version = "1.1.1" default-features = false [dependencies.dary_heap] version = "0.3.5" [dependencies.libflate_lz77] version = "2.1.0" default-features = false [dev-dependencies.clap] version = "4" features = ["derive"] [features] default = ["std"] std = [ "libflate_lz77/std", "core2/std", ] [badges.coveralls] repository = "sile/libflate" libflate-2.1.0/Cargo.toml.orig000064400000000000000000000017301046102023000142760ustar 00000000000000[package] name = "libflate" version = "2.1.0" authors = ["Takeru Ohta "] description = "A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP)" homepage = "https://github.com/sile/libflate" repository = "https://github.com/sile/libflate" readme = "README.md" keywords = ["deflate", "gzip", "zlib"] categories = ["compression", "no-std"] license = "MIT" edition = "2021" [badges] coveralls = {repository = "sile/libflate"} [dependencies] adler32 = { version = "1", default-features = false } crc32fast = { version = "1.1.1", default-features = false } dary_heap = "0.3.5" libflate_lz77 = { path = "libflate_lz77", version = "2.1.0", default-features = false } core2 = { version = "0.4", default-features = false, features = ["alloc"] } [features] default = ["std"] std = ["libflate_lz77/std", "core2/std"] [dev-dependencies] clap = { version = "4", features = ["derive"] } [workspace] members = ["libflate_lz77"] exclude = ["flate_bench"] libflate-2.1.0/LICENSE000064400000000000000000000021051046102023000124110ustar 00000000000000The MIT License Copyright (c) 2016 Takeru Ohta Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libflate-2.1.0/README.md000064400000000000000000000042501046102023000126660ustar 00000000000000libflate ======== [![libflate](https://img.shields.io/crates/v/libflate.svg)](https://crates.io/crates/libflate) [![Documentation](https://docs.rs/libflate/badge.svg)](https://docs.rs/libflate) [![Actions Status](https://github.com/sile/libflate/workflows/CI/badge.svg)](https://github.com/sile/libflate/actions) [![Coverage Status](https://coveralls.io/repos/github/sile/libflate/badge.svg?branch=master)](https://coveralls.io/github/sile/libflate?branch=master) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP). Documentation ------------- See [RustDoc Documentation](https://docs.rs/libflate). The documentation includes some examples. Installation ------------ Add following lines to your `Cargo.toml`: ```toml [dependencies] libflate = "2" ``` An Example ---------- Below is a command to decode GZIP stream that is read from the standard input: ```rust extern crate libflate; use std::io; use libflate::gzip::Decoder; fn main() { let mut input = io::stdin(); let mut decoder = Decoder::new(&mut input).unwrap(); io::copy(&mut decoder, &mut io::stdout()).unwrap(); } ``` An Informal Benchmark --------------------- A brief comparison with [flate2](https://github.com/alexcrichton/flate2-rs) and [inflate](https://github.com/PistonDevelopers/inflate): ```bash $ cd libflate/flate_bench/ $ curl -O https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-all-titles-in-ns0.gz $ gzip -d enwiki-latest-all-titles-in-ns0.gz > ls -lh enwiki-latest-all-titles-in-ns0 -rw-rw-r-- 1 foo foo 265M May 18 05:19 enwiki-latest-all-titles-in-ns0 $ cargo run --release -- enwiki-latest-all-titles-in-ns0 # ENCODE (input_size=277303937) - libflate: elapsed=8.137013s, size=83259010 - flate2: elapsed=9.814607s, size=74692153 # DECODE (input_size=74217004) - libflate: elapsed=1.354556s, size=277303937 - flate2: elapsed=0.960907s, size=277303937 - inflate: elapsed=1.926142s, size=277303937 ``` References ---------- - DEFLATE: [RFC-1951](https://tools.ietf.org/html/rfc1951) - ZLIB: [RFC-1950](https://tools.ietf.org/html/rfc1950) - GZIP: [RFC-1952](https://tools.ietf.org/html/rfc1952) libflate-2.1.0/data/issues_16/crash-1bb6d408475a5bd57247ee40f290830adfe2086e000064400000000000000000000024421046102023000225410ustar 00000000000000x^)*~~~~~~~~~~~Kt<<<<<:<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<3<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<3<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<3<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<3<<<<<<<<<<<<<<<<<<<<<<<<<5 u!z@͕Guݢm)&?{i=Qaj8tU^C*HCl$M;|;m7zFps_+j[ E)Pl@7qQs&KDgyErnuc¡V~pEͷ/A,i-kKfEwE55 u!z@͕Guݢm)&?{i=Qaj8tU^C*HCl$M;|;m7zFps_+j[ E)Pl@7qQs&KDgyErnuc¡V~pEͷ/A,i-kKfEwE5 = if input_filename == "-" { Box::new(io::stdin()) } else { Box::new( fs::File::open(input_filename).expect(&format!("Can't open file: {}", input_filename)), ) }; let mut input = io::BufReader::new(input); let output_filename = &args.output; let output: Box = if output_filename == "-" { Box::new(io::stdout()) } else if output_filename == "/dev/null" { Box::new(io::sink()) } else { Box::new( fs::File::create(output_filename) .expect(&format!("Can't create file: {}", output_filename)), ) }; let mut output = io::BufWriter::new(output); let verbose = args.verbose; match args.command { Command::Copy => { io::copy(&mut input, &mut output).expect("Coyping failed"); } Command::ByteRead { unit } => { let mut buf = vec![0; unit]; let mut reader = input; let mut count = 0; while let Ok(size) = reader.read(&mut buf) { if size == 0 { break; } count += size; } println!("COUNT: {}", count); } Command::GzipDecode => { let mut decoder = gzip::Decoder::new(input).expect("Read GZIP header failed"); if verbose { let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header()); } io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed"); } Command::GzipDecodeMulti => { let mut decoder = gzip::MultiDecoder::new(input).expect("Read GZIP header failed"); io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed"); } Command::GzipEncode => { let mut encoder = gzip::Encoder::new(output).unwrap(); io::copy(&mut input, &mut encoder).expect("Encoding GZIP stream failed"); encoder.finish().into_result().unwrap(); } Command::ZlibDecode => { let mut decoder = zlib::Decoder::new(input).expect("Read ZLIB header failed"); if verbose { let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header()); } io::copy(&mut decoder, &mut output).expect("Decoding ZLIB stream failed"); } Command::ZlibEncode => { let mut encoder = zlib::Encoder::new(output).unwrap(); io::copy(&mut input, &mut encoder).expect("Encoding ZLIB stream failed"); encoder.finish().into_result().unwrap(); } } } libflate-2.1.0/src/bit.rs000064400000000000000000000130101046102023000133140ustar 00000000000000use core2::io; #[derive(Debug)] pub struct BitWriter { inner: W, buf: u32, end: u8, } impl BitWriter where W: io::Write, { pub fn new(inner: W) -> Self { BitWriter { inner, buf: 0, end: 0, } } #[inline(always)] pub fn write_bit(&mut self, bit: bool) -> io::Result<()> { self.write_bits(1, bit as u16) } #[inline(always)] pub fn write_bits(&mut self, bitwidth: u8, bits: u16) -> io::Result<()> { debug_assert!(bitwidth < 16); debug_assert!(self.end + bitwidth <= 32); self.buf |= u32::from(bits) << self.end; self.end += bitwidth; self.flush_if_needed() } pub fn flush(&mut self) -> io::Result<()> { while self.end > 0 { self.inner.write_all(&[self.buf as u8])?; self.buf >>= 8; self.end = self.end.saturating_sub(8); } self.inner.flush()?; Ok(()) } #[inline(always)] fn flush_if_needed(&mut self) -> io::Result<()> { if self.end >= 16 { self.inner.write_all(&(self.buf as u16).to_le_bytes())?; self.end -= 16; self.buf >>= 16; } Ok(()) } } impl BitWriter { pub fn as_inner_ref(&self) -> &W { &self.inner } pub fn as_inner_mut(&mut self) -> &mut W { &mut self.inner } pub fn into_inner(self) -> W { self.inner } } #[derive(Debug)] pub struct BitReader { inner: R, last_read: u32, offset: u8, last_error: Option, } impl BitReader where R: io::Read, { pub fn new(inner: R) -> Self { BitReader { inner, last_read: 0, offset: 32, last_error: None, } } #[inline(always)] pub fn set_last_error(&mut self, e: io::Error) { self.last_error = Some(e); } #[inline(always)] pub fn check_last_error(&mut self) -> io::Result<()> { if let Some(e) = self.last_error.take() { Err(e) } else { Ok(()) } } #[inline(always)] pub fn read_bit(&mut self) -> io::Result { self.read_bits(1).map(|b| b != 0) } #[inline(always)] pub fn read_bits(&mut self, bitwidth: u8) -> io::Result { let v = self.read_bits_unchecked(bitwidth); self.check_last_error().map(|_| v) } #[inline(always)] pub fn read_bits_unchecked(&mut self, bitwidth: u8) -> u16 { let bits = self.peek_bits_unchecked(bitwidth); self.skip_bits(bitwidth); bits } #[inline(always)] pub fn peek_bits_unchecked(&mut self, bitwidth: u8) -> u16 { debug_assert!(bitwidth <= 16); while 32 < self.offset + bitwidth { if self.last_error.is_some() { return 0; } if let Err(e) = self.fill_next_u8() { self.last_error = Some(e); return 0; } } debug_assert!(self.offset < 32 || bitwidth == 0); let bits = self.last_read.wrapping_shr(u32::from(self.offset)) as u16; bits & ((1 << bitwidth) - 1) } #[inline(always)] pub fn skip_bits(&mut self, bitwidth: u8) { debug_assert!(self.last_error.is_some() || 32 - self.offset >= bitwidth); self.offset += bitwidth; } #[inline(always)] fn fill_next_u8(&mut self) -> io::Result<()> { self.offset -= 8; self.last_read >>= 8; let mut buf = [0; 1]; self.inner.read_exact(&mut buf)?; let next = u32::from(buf[0]); self.last_read |= next << (32 - 8); Ok(()) } #[inline] pub(crate) fn state(&self) -> BitReaderState { BitReaderState { last_read: self.last_read, offset: self.offset, } } #[inline] pub(crate) fn restore_state(&mut self, state: BitReaderState) { self.last_read = state.last_read; self.offset = state.offset; } } impl BitReader { pub fn reset(&mut self) { self.offset = 32; } pub fn as_inner_ref(&self) -> &R { &self.inner } pub fn as_inner_mut(&mut self) -> &mut R { &mut self.inner } pub fn into_inner(self) -> R { self.inner } } #[derive(Debug, Clone, Copy)] pub(crate) struct BitReaderState { last_read: u32, offset: u8, } #[cfg(test)] mod tests { use super::*; use alloc::vec::Vec; use core2::io; #[test] fn writer_works() { let mut writer = BitWriter::new(Vec::new()); writer.write_bit(true).unwrap(); writer.write_bits(3, 0b010).unwrap(); writer.write_bits(11, 0b10101011010).unwrap(); writer.flush().unwrap(); writer.write_bit(true).unwrap(); writer.flush().unwrap(); let buf = writer.into_inner(); assert_eq!(buf, [0b10100101, 0b01010101, 0b00000001]); } #[test] fn reader_works() { let buf = [0b10100101, 0b11010101]; let mut reader = BitReader::new(&buf[..]); assert_eq!(reader.read_bit().unwrap(), true); assert_eq!(reader.read_bit().unwrap(), false); assert_eq!(reader.read_bits(8).unwrap(), 0b01101001); assert_eq!(reader.peek_bits_unchecked(3), 0b101); assert_eq!(reader.peek_bits_unchecked(3), 0b101); reader.skip_bits(1); assert_eq!(reader.peek_bits_unchecked(3), 0b010); assert_eq!( reader.read_bits(8).map_err(|e| e.kind()), Err(io::ErrorKind::UnexpectedEof) ); } } libflate-2.1.0/src/checksum.rs000064400000000000000000000023031046102023000143430ustar 00000000000000use adler32::RollingAdler32; use core::fmt; pub struct Adler32(RollingAdler32); impl Adler32 { pub fn new() -> Self { Adler32(RollingAdler32::new()) } pub fn value(&self) -> u32 { self.0.hash() } pub fn update(&mut self, buf: &[u8]) { self.0.update_buffer(buf); } } impl fmt::Debug for Adler32 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Adler32(_)") } } pub struct Crc32(crc32fast::Hasher); impl Crc32 { pub fn new() -> Self { Crc32(crc32fast::Hasher::new()) } pub fn value(&self) -> u32 { self.0.clone().finalize() } pub fn update(&mut self, buf: &[u8]) { self.0.update(buf); } } impl fmt::Debug for Crc32 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Crc32(_)") } } #[cfg(test)] mod tests { use super::*; #[test] fn crc32_works() { let mut crc32 = Crc32::new(); crc32.update(b"abcde"); assert_eq!(crc32.value(), 0x8587D865); } #[test] fn adler32_works() { let mut adler32 = Adler32::new(); adler32.update(b"abcde"); assert_eq!(adler32.value(), 0x05C801F0); } } libflate-2.1.0/src/deflate/decode.rs000064400000000000000000000170701046102023000153770ustar 00000000000000use super::symbol; use crate::bit; use crate::lz77; use core2::io::{self, Read}; /// DEFLATE decoder. #[derive(Debug)] pub struct Decoder { bit_reader: bit::BitReader, lz77_decoder: lz77::Lz77Decoder, eos: bool, } impl Decoder where R: Read, { /// Makes a new decoder instance. /// /// `inner` is to be decoded DEFLATE stream. /// /// # Examples /// ``` /// # extern crate alloc; /// # use alloc::vec::Vec; /// use core2::io::{Cursor, Read}; /// use libflate::deflate::Decoder; /// /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; /// let mut decoder = Decoder::new(&encoded_data[..]); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(inner: R) -> Self { Decoder { bit_reader: bit::BitReader::new(inner), lz77_decoder: lz77::Lz77Decoder::new(), eos: false, } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.bit_reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.bit_reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::deflate::Decoder; /// /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; /// let decoder = Decoder::new(Cursor::new(&encoded_data)); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data); /// ``` pub fn into_inner(self) -> R { self.bit_reader.into_inner() } /// Returns the data that has been decoded but has not yet been read. /// /// This method is useful to retrieve partial decoded data when the decoding process is failed. pub fn unread_decoded_data(&self) -> &[u8] { self.lz77_decoder.buffer() } pub(crate) fn reset(&mut self) { self.bit_reader.reset(); self.lz77_decoder.clear(); self.eos = false } fn read_non_compressed_block(&mut self) -> io::Result<()> { self.bit_reader.reset(); let mut buf = [0; 2]; self.bit_reader.as_inner_mut().read_exact(&mut buf)?; let len = u16::from_le_bytes(buf); self.bit_reader.as_inner_mut().read_exact(&mut buf)?; let nlen = u16::from_le_bytes(buf); if !len != nlen { Err(invalid_data_error!( "LEN={} is not the one's complement of NLEN={}", len, nlen )) } else { self.lz77_decoder .extend_from_reader(self.bit_reader.as_inner_mut().take(len.into())) .and_then(|used| { if used != len.into() { Err(io::Error::new( io::ErrorKind::UnexpectedEof, #[cfg(feature = "std")] format!("The reader has incorrect length: expected {len}, read {used}"), #[cfg(not(feature = "std"))] "The reader has incorrect length", )) } else { Ok(()) } }) } } fn read_compressed_block(&mut self, huffman: &H) -> io::Result<()> where H: symbol::HuffmanCodec, { let symbol_decoder = huffman.load(&mut self.bit_reader)?; loop { let s = symbol_decoder.decode_unchecked(&mut self.bit_reader); self.bit_reader.check_last_error()?; match s { symbol::Symbol::Code(code) => { self.lz77_decoder.decode(code)?; } symbol::Symbol::EndOfBlock => { break; } } } Ok(()) } } impl Read for Decoder where R: Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { if !self.lz77_decoder.buffer().is_empty() { self.lz77_decoder.read(buf) } else if self.eos { Ok(0) } else { let bfinal = self.bit_reader.read_bit()?; let btype = self.bit_reader.read_bits(2)?; self.eos = bfinal; match btype { 0b00 => { self.read_non_compressed_block()?; self.read(buf) } 0b01 => { self.read_compressed_block(&symbol::FixedHuffmanCodec)?; self.read(buf) } 0b10 => { self.read_compressed_block(&symbol::DynamicHuffmanCodec)?; self.read(buf) } 0b11 => Err(invalid_data_error!( "btype 0x11 of DEFLATE is reserved(error) value" )), _ => unreachable!(), } } } } #[cfg(test)] mod tests { #[cfg(feature = "std")] use super::*; use crate::deflate::symbol::{DynamicHuffmanCodec, HuffmanCodec}; #[cfg(feature = "std")] use std::io; #[test] fn test_issues_3() { // see: https://github.com/sile/libflate/issues/3 let input = [ 180, 253, 73, 143, 28, 201, 150, 46, 8, 254, 150, 184, 139, 75, 18, 69, 247, 32, 157, 51, 27, 141, 132, 207, 78, 210, 167, 116, 243, 160, 223, 136, 141, 66, 205, 76, 221, 76, 195, 213, 84, 236, 234, 224, 78, 227, 34, 145, 221, 139, 126, 232, 69, 173, 170, 208, 192, 219, 245, 67, 3, 15, 149, 120, 171, 70, 53, 106, 213, 175, 23, 21, 153, 139, 254, 27, 249, 75, 234, 124, 71, 116, 56, 71, 68, 212, 204, 121, 115, 64, 222, 160, 203, 119, 142, 170, 169, 138, 202, 112, 228, 140, 38, ]; let mut bit_reader = crate::bit::BitReader::new(&input[..]); assert_eq!(bit_reader.read_bit().unwrap(), false); // not final block assert_eq!(bit_reader.read_bits(2).unwrap(), 0b10); // DynamicHuffmanCodec DynamicHuffmanCodec.load(&mut bit_reader).unwrap(); } #[test] #[cfg(feature = "std")] fn it_works() { let input = [ 180, 253, 73, 143, 28, 201, 150, 46, 8, 254, 150, 184, 139, 75, 18, 69, 247, 32, 157, 51, 27, 141, 132, 207, 78, 210, 167, 116, 243, 160, 223, 136, 141, 66, 205, 76, 221, 76, 195, 213, 84, 236, 234, 224, 78, 227, 34, 145, 221, 139, 126, 232, 69, 173, 170, 208, 192, 219, 245, 67, 3, 15, 149, 120, 171, 70, 53, 106, 213, 175, 23, 21, 153, 139, 254, 27, 249, 75, 234, 124, 71, 116, 56, 71, 68, 212, 204, 121, 115, 64, 222, 160, 203, 119, 142, 170, 169, 138, 202, 112, 228, 140, 38, 171, 162, 88, 212, 235, 56, 136, 231, 233, 239, 113, 249, 163, 252, 16, 42, 138, 49, 226, 108, 73, 28, 153, ]; let mut decoder = Decoder::new(&input[..]); let result = io::copy(&mut decoder, &mut io::sink()); assert!(result.is_err()); let error = result.err().unwrap(); assert_eq!(error.kind(), io::ErrorKind::InvalidData); assert!(error.to_string().starts_with("Too long backword reference")); } #[test] #[cfg(feature = "std")] fn test_issue_64() { let input = b"\x04\x04\x04\x05:\x1az*\xfc\x06\x01\x90\x01\x06\x01"; let mut decoder = Decoder::new(&input[..]); assert!(io::copy(&mut decoder, &mut io::sink()).is_err()); } } libflate-2.1.0/src/deflate/encode.rs000064400000000000000000000325271046102023000154150ustar 00000000000000use super::symbol; use super::BlockType; use crate::bit; use crate::finish::{Complete, Finish}; use crate::lz77; use alloc::vec::Vec; use core::cmp; use core2::io; /// The default size of a DEFLATE block. pub const DEFAULT_BLOCK_SIZE: usize = 1024 * 1024; const MAX_NON_COMPRESSED_BLOCK_SIZE: usize = 0xFFFF; /// Options for a DEFLATE encoder. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EncodeOptions { block_size: usize, dynamic_huffman: bool, lz77: Option, } impl Default for EncodeOptions { fn default() -> Self { Self::new() } } impl EncodeOptions { /// Makes a default instance. /// /// # Examples /// ``` /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new(); /// let encoder = Encoder::with_options(Vec::new(), options); /// ``` pub fn new() -> Self { EncodeOptions { block_size: DEFAULT_BLOCK_SIZE, dynamic_huffman: true, lz77: Some(lz77::DefaultLz77Encoder::new()), } } } impl EncodeOptions where E: lz77::Lz77Encode, { /// Specifies the LZ77 encoder used to compress input data. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::with_lz77(DefaultLz77Encoder::new()); /// let encoder = Encoder::with_options(Vec::new(), options); /// ``` pub fn with_lz77(lz77: E) -> Self { EncodeOptions { block_size: DEFAULT_BLOCK_SIZE, dynamic_huffman: true, lz77: Some(lz77), } } /// Disables LZ77 compression. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().no_compression(); /// let encoder = Encoder::with_options(Vec::new(), options); /// ``` pub fn no_compression(mut self) -> Self { self.lz77 = None; self } /// Specifies the hint of the size of a DEFLATE block. /// /// The default value is `DEFAULT_BLOCK_SIZE`. /// /// # Example /// ``` /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().block_size(512 * 1024); /// let encoder = Encoder::with_options(Vec::new(), options); /// ``` pub fn block_size(mut self, size: usize) -> Self { self.block_size = size; self } /// Specifies to compress with fixed huffman codes. /// /// # Example /// ``` /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().fixed_huffman_codes(); /// let encoder = Encoder::with_options(Vec::new(), options); /// ``` pub fn fixed_huffman_codes(mut self) -> Self { self.dynamic_huffman = false; self } fn get_block_type(&self) -> BlockType { if self.lz77.is_none() { BlockType::Raw } else if self.dynamic_huffman { BlockType::Dynamic } else { BlockType::Fixed } } fn get_block_size(&self) -> usize { if self.lz77.is_none() { cmp::min(self.block_size, MAX_NON_COMPRESSED_BLOCK_SIZE) } else { self.block_size } } } /// DEFLATE encoder. #[derive(Debug)] pub struct Encoder { writer: bit::BitWriter, block: Block, } impl Encoder where W: io::Write, { /// Makes a new encoder instance. /// /// Encoded DEFLATE stream is written to `inner`. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::deflate::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()); /// encoder.write_all(b"Hello World!".as_ref()).unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// [5, 192, 49, 13, 0, 0, 8, 3, 65, 43, 224, 6, 7, 24, 128, 237, /// 147, 38, 245, 63, 244, 230, 65, 181, 50, 215, 1]); /// ``` pub fn new(inner: W) -> Self { Self::with_options(inner, EncodeOptions::default()) } } impl Encoder where W: io::Write, E: lz77::Lz77Encode, { /// Makes a new encoder instance with specified options. /// /// Encoded DEFLATE stream is written to `inner`. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::deflate::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().no_compression(); /// let mut encoder = Encoder::with_options(Vec::new(), options); /// encoder.write_all(b"Hello World!".as_ref()).unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// [1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, /// 114, 108, 100, 33]); /// ``` pub fn with_options(inner: W, options: EncodeOptions) -> Self { Encoder { writer: bit::BitWriter::new(inner), block: Block::new(options), } } /// Flushes internal buffer and returns the inner stream. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::deflate::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()); /// encoder.write_all(b"Hello World!".as_ref()).unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// [5, 192, 49, 13, 0, 0, 8, 3, 65, 43, 224, 6, 7, 24, 128, 237, /// 147, 38, 245, 63, 244, 230, 65, 181, 50, 215, 1]); /// ``` pub fn finish(mut self) -> Finish { match self.block.finish(&mut self.writer) { Ok(_) => Finish::new(self.writer.into_inner(), None), Err(e) => Finish::new(self.writer.into_inner(), Some(e)), } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &W { self.writer.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut W { self.writer.as_inner_mut() } /// Unwraps the `Encoder`, returning the inner stream. pub fn into_inner(self) -> W { self.writer.into_inner() } pub(crate) fn zlib_sync_flush(&mut self) -> io::Result<()> { self.block.flush(&mut self.writer, false)?; self.writer.write_bit(false)?; self.writer.write_bits(2, BlockType::Raw as u16)?; self.writer.flush()?; self.writer.as_inner_mut().write_all(&[0, 0, 255, 255])?; self.writer.as_inner_mut().flush() } } impl io::Write for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn write(&mut self, buf: &[u8]) -> io::Result { self.block.write(&mut self.writer, buf)?; Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { self.block.flush(&mut self.writer, false)?; self.writer.as_inner_mut().flush() } } impl Complete for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn complete(self) -> io::Result<()> { self.finish().into_result().map(|_| ()) } } #[derive(Debug)] struct Block { block_type: BlockType, block_size: usize, block_buf: BlockBuf, } impl Block where E: lz77::Lz77Encode, { fn new(options: EncodeOptions) -> Self { Block { block_type: options.get_block_type(), block_size: options.get_block_size(), block_buf: BlockBuf::new(options.lz77, options.dynamic_huffman), } } fn write(&mut self, writer: &mut bit::BitWriter, buf: &[u8]) -> io::Result<()> where W: io::Write, { self.block_buf.append(buf); while self.block_buf.len() >= self.block_size { self.flush(writer, false)?; } Ok(()) } fn flush(&mut self, writer: &mut bit::BitWriter, is_final: bool) -> io::Result<()> where W: io::Write, { writer.write_bit(is_final)?; writer.write_bits(2, self.block_type as u16)?; self.block_buf.flush(writer)?; Ok(()) } fn finish(mut self, writer: &mut bit::BitWriter) -> io::Result<()> where W: io::Write, { self.flush(writer, true)?; writer.flush()?; Ok(()) } } #[derive(Debug)] enum BlockBuf { Raw(RawBuf), Fixed(CompressBuf), Dynamic(CompressBuf), } impl BlockBuf where E: lz77::Lz77Encode, { fn new(lz77: Option, dynamic: bool) -> Self { if let Some(lz77) = lz77 { if dynamic { BlockBuf::Dynamic(CompressBuf::new(symbol::DynamicHuffmanCodec, lz77)) } else { BlockBuf::Fixed(CompressBuf::new(symbol::FixedHuffmanCodec, lz77)) } } else { BlockBuf::Raw(RawBuf::new()) } } fn append(&mut self, buf: &[u8]) { match *self { BlockBuf::Raw(ref mut b) => b.append(buf), BlockBuf::Fixed(ref mut b) => b.append(buf), BlockBuf::Dynamic(ref mut b) => b.append(buf), } } fn len(&self) -> usize { match *self { BlockBuf::Raw(ref b) => b.len(), BlockBuf::Fixed(ref b) => b.len(), BlockBuf::Dynamic(ref b) => b.len(), } } fn flush(&mut self, writer: &mut bit::BitWriter) -> io::Result<()> where W: io::Write, { match *self { BlockBuf::Raw(ref mut b) => b.flush(writer), BlockBuf::Fixed(ref mut b) => b.flush(writer), BlockBuf::Dynamic(ref mut b) => b.flush(writer), } } } #[derive(Debug)] struct RawBuf { buf: Vec, } impl RawBuf { fn new() -> Self { RawBuf { buf: Vec::new() } } fn append(&mut self, buf: &[u8]) { self.buf.extend_from_slice(buf); } fn len(&self) -> usize { self.buf.len() } fn flush(&mut self, writer: &mut bit::BitWriter) -> io::Result<()> where W: io::Write, { let size = cmp::min(self.buf.len(), MAX_NON_COMPRESSED_BLOCK_SIZE); writer.flush()?; writer .as_inner_mut() .write_all(&(size as u16).to_le_bytes())?; writer .as_inner_mut() .write_all(&(!size as u16).to_le_bytes())?; writer.as_inner_mut().write_all(&self.buf[..size])?; self.buf.drain(0..size); Ok(()) } } #[derive(Debug)] struct CompressBuf { huffman: H, lz77: E, buf: Vec, original_size: usize, } impl CompressBuf where H: symbol::HuffmanCodec, E: lz77::Lz77Encode, { fn new(huffman: H, lz77: E) -> Self { CompressBuf { huffman, lz77, buf: Vec::new(), original_size: 0, } } fn append(&mut self, buf: &[u8]) { self.original_size += buf.len(); self.lz77.encode(buf, &mut self.buf); } fn len(&self) -> usize { self.original_size } fn flush(&mut self, writer: &mut bit::BitWriter) -> io::Result<()> where W: io::Write, { self.lz77.flush(&mut self.buf); self.buf.push(symbol::Symbol::EndOfBlock); let symbol_encoder = self.huffman.build(&self.buf)?; self.huffman.save(writer, &symbol_encoder)?; for s in self.buf.drain(..) { symbol_encoder.encode(writer, &s)?; } self.original_size = 0; Ok(()) } } #[cfg(test)] mod tests { use super::super::Decoder; use super::*; use core2::io::{Read as _, Write as _}; #[test] fn test_issues_52() { // see: https://github.com/sile/libflate/issues/52 let input = crate::deflate::test_data::ISSUE_52_INPUT; const LIMIT_1: usize = 16_031; const LIMIT_2: usize = LIMIT_1 + 1; // Attempt 1 (should succeed) // let mut encoder = Encoder::new(Vec::new()); encoder.write_all(&input[0..LIMIT_1]).unwrap(); let compressed: Vec = encoder.finish().into_result().unwrap(); assert!(LIMIT_1 > compressed.len()); // Attempt 2 (will fail without patch) // let mut encoder = Encoder::new(Vec::new()); encoder.write_all(&input[0..LIMIT_2]).unwrap(); let compressed: Vec = encoder.finish().into_result().unwrap(); assert!(LIMIT_2 > compressed.len()); } #[test] fn test_issue_27() { // See: https://github.com/sile/libflate/issues/27 let writes = ["fooooooooooooooooo", "bar", "baz"]; let mut encoder = Encoder::new(Vec::new()); for _ in 0..2 { for string in &writes { encoder.write(string.as_bytes()).expect("Write failed"); } encoder.flush().expect("Flush failed"); } let finished = encoder.finish().unwrap(); #[cfg(feature = "std")] println!("{:?}", finished.0); let mut output = Vec::new(); Decoder::new(&finished.0[..]) .read_to_end(&mut output) .unwrap(); assert_eq!( output, "fooooooooooooooooobarbazfooooooooooooooooobarbaz".as_bytes() ); } } libflate-2.1.0/src/deflate/mod.rs000064400000000000000000000032351046102023000147310ustar 00000000000000//! The encoder and decoder of the DEFLATE format and algorithm. //! //! The DEFLATE is defined in [RFC-1951](https://tools.ietf.org/html/rfc1951). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::deflate::{Encoder, Decoder}; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()); //! encoder.write_all(b"Hello World!".as_ref()).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` pub use self::decode::Decoder; pub use self::encode::EncodeOptions; pub use self::encode::Encoder; pub use self::encode::DEFAULT_BLOCK_SIZE; mod decode; mod encode; pub(crate) mod symbol; #[cfg(test)] pub(crate) mod test_data; #[derive(Debug, Clone, Copy)] enum BlockType { Raw = 0b00, Fixed = 0b01, Dynamic = 0b10, } #[cfg(test)] mod tests { use super::*; use crate::lz77; use alloc::vec::Vec; use core2::io::{Read, Write}; #[test] fn encode_and_decode_works() { let plain = (0..lz77::MAX_DISTANCE as u32 * 32) .map(|i| i as u8) .collect::>(); let buffer = Vec::new(); let mut encoder = Encoder::new(buffer); encoder.write_all(&plain[..]).expect("encode"); let encoded = encoder.finish().into_result().unwrap(); let mut buffer = Vec::new(); let mut decoder = Decoder::new(&encoded[..]); decoder.read_to_end(&mut buffer).expect("decode"); assert_eq!(buffer, plain); } } libflate-2.1.0/src/deflate/symbol.rs000064400000000000000000000412331046102023000154570ustar 00000000000000use crate::bit; use crate::huffman; use crate::huffman::Builder; use crate::lz77; use alloc::{boxed::Box, vec::Vec}; use core::{cmp, iter, ops::Range}; use core2::io; const FIXED_LITERAL_OR_LENGTH_CODE_TABLE: [(u8, Range, u16); 4] = [ (8, 000..144, 0b0_0011_0000), (9, 144..256, 0b1_1001_0000), (7, 256..280, 0b0_0000_0000), (8, 280..288, 0b0_1100_0000), ]; const BITWIDTH_CODE_ORDER: [usize; 19] = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, ]; const END_OF_BLOCK: u16 = 256; const LENGTH_TABLE: [(u16, u8); 29] = [ (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), (11, 1), (13, 1), (15, 1), (17, 1), (19, 2), (23, 2), (27, 2), (31, 2), (35, 3), (43, 3), (51, 3), (59, 3), (67, 4), (83, 4), (99, 4), (115, 4), (131, 5), (163, 5), (195, 5), (227, 5), (258, 0), ]; const MAX_DISTANCE_CODE_COUNT: usize = 30; const DISTANCE_TABLE: [(u16, u8); 30] = [ (1, 0), (2, 0), (3, 0), (4, 0), (5, 1), (7, 1), (9, 2), (13, 2), (17, 3), (25, 3), (33, 4), (49, 4), (65, 5), (97, 5), (129, 6), (193, 6), (257, 7), (385, 7), (513, 8), (769, 8), (1025, 9), (1537, 9), (2049, 10), (3073, 10), (4097, 11), (6145, 11), (8193, 12), (12_289, 12), (16_385, 13), (24_577, 13), ]; #[derive(Debug, PartialEq, Eq)] pub enum Symbol { EndOfBlock, Code(lz77::Code), } impl Symbol { pub fn code(&self) -> u16 { match *self { Symbol::Code(lz77::Code::Literal(b)) => u16::from(b), Symbol::EndOfBlock => 256, Symbol::Code(lz77::Code::Pointer { length, .. }) => match length { 3..=10 => 257 + length - 3, 11..=18 => 265 + (length - 11) / 2, 19..=34 => 269 + (length - 19) / 4, 35..=66 => 273 + (length - 35) / 8, 67..=130 => 277 + (length - 67) / 16, 131..=257 => 281 + (length - 131) / 32, 258 => 285, _ => unreachable!(), }, } } pub fn extra_lengh(&self) -> Option<(u8, u16)> { if let Symbol::Code(lz77::Code::Pointer { length, .. }) = *self { match length { 3..=10 | 258 => None, 11..=18 => Some((1, (length - 11) % 2)), 19..=34 => Some((2, (length - 19) % 4)), 35..=66 => Some((3, (length - 35) % 8)), 67..=130 => Some((4, (length - 67) % 16)), 131..=257 => Some((5, (length - 131) % 32)), _ => unreachable!(), } } else { None } } pub fn distance(&self) -> Option<(u8, u8, u16)> { if let Symbol::Code(lz77::Code::Pointer { backward_distance: distance, .. }) = *self { if distance <= 4 { Some((distance as u8 - 1, 0, 0)) } else { let mut extra_bits = 1; let mut code = 4; let mut base = 4; while base * 2 < distance { extra_bits += 1; code += 2; base *= 2; } let half = base / 2; let delta = distance - base - 1; if distance <= base + half { Some((code, extra_bits, delta % half)) } else { Some((code + 1, extra_bits, delta % half)) } } } else { None } } } impl From for Symbol { fn from(code: lz77::Code) -> Self { Symbol::Code(code) } } #[derive(Debug)] pub struct Encoder { literal: huffman::Encoder, distance: huffman::Encoder, } impl Encoder { pub fn encode(&self, writer: &mut bit::BitWriter, symbol: &Symbol) -> io::Result<()> where W: io::Write, { self.literal.encode(writer, symbol.code())?; if let Some((bits, extra)) = symbol.extra_lengh() { writer.write_bits(bits, extra)?; } if let Some((code, bits, extra)) = symbol.distance() { self.distance.encode(writer, u16::from(code))?; if bits > 0 { writer.write_bits(bits, extra)?; } } Ok(()) } } #[derive(Debug)] pub struct Decoder { literal: huffman::Decoder, distance: huffman::Decoder, } impl Decoder { #[inline(always)] pub fn decode_unchecked(&self, reader: &mut bit::BitReader) -> Symbol where R: io::Read, { let mut symbol = self.decode_literal_or_length(reader); if let Symbol::Code(lz77::Code::Pointer { ref mut backward_distance, .. }) = symbol { *backward_distance = self.decode_distance(reader); } symbol } #[inline(always)] fn decode_literal_or_length(&self, reader: &mut bit::BitReader) -> Symbol where R: io::Read, { let decoded = self.literal.decode_unchecked(reader); match decoded { 0..=255 => Symbol::Code(lz77::Code::Literal(decoded as u8)), 256 => Symbol::EndOfBlock, 286 | 287 => { #[cfg(feature = "std")] let message = format!("The value {decoded} must not occur in compressed data"); #[cfg(not(feature = "std"))] let message = "The value(s) [286, 287] must not occur in compressed data"; reader.set_last_error(io::Error::new(io::ErrorKind::InvalidData, message)); Symbol::EndOfBlock // dummy value } length_code => { let (base, extra_bits) = LENGTH_TABLE[length_code as usize - 257]; let extra = reader.read_bits_unchecked(extra_bits); Symbol::Code(lz77::Code::Pointer { length: base + extra, backward_distance: 0, }) } } } #[inline(always)] fn decode_distance(&self, reader: &mut bit::BitReader) -> u16 where R: io::Read, { let decoded = self.distance.decode_unchecked(reader) as usize; let (base, extra_bits) = DISTANCE_TABLE[decoded]; let extra = reader.read_bits_unchecked(extra_bits); base + extra } } pub trait HuffmanCodec { fn build(&self, symbols: &[Symbol]) -> io::Result; fn save(&self, writer: &mut bit::BitWriter, codec: &Encoder) -> io::Result<()> where W: io::Write; fn load(&self, reader: &mut bit::BitReader) -> io::Result where R: io::Read; } #[derive(Debug)] pub struct FixedHuffmanCodec; impl HuffmanCodec for FixedHuffmanCodec { #[allow(unused_variables)] fn build(&self, symbols: &[Symbol]) -> io::Result { let mut literal_builder = huffman::EncoderBuilder::new(288); for &(bitwidth, ref symbols, code_base) in &FIXED_LITERAL_OR_LENGTH_CODE_TABLE { for (code, symbol) in symbols .clone() .enumerate() .map(|(i, s)| (code_base + i as u16, s)) { literal_builder.set_mapping(symbol, huffman::Code::new(bitwidth, code))?; } } let mut distance_builder = huffman::EncoderBuilder::new(30); for i in 0..30 { distance_builder.set_mapping(i, huffman::Code::new(5, i))?; } Ok(Encoder { literal: literal_builder.finish(), distance: distance_builder.finish(), }) } #[allow(unused_variables)] fn save(&self, writer: &mut bit::BitWriter, codec: &Encoder) -> io::Result<()> where W: io::Write, { Ok(()) } #[allow(unused_variables)] fn load(&self, reader: &mut bit::BitReader) -> io::Result where R: io::Read, { let mut literal_builder = huffman::DecoderBuilder::new(9, None, Some(END_OF_BLOCK)); for &(bitwidth, ref symbols, code_base) in &FIXED_LITERAL_OR_LENGTH_CODE_TABLE { for (code, symbol) in symbols .clone() .enumerate() .map(|(i, s)| (code_base + i as u16, s)) { literal_builder.set_mapping(symbol, huffman::Code::new(bitwidth, code))?; } } let mut distance_builder = huffman::DecoderBuilder::new(5, literal_builder.safely_peek_bitwidth(), None); for i in 0..30 { distance_builder.set_mapping(i, huffman::Code::new(5, i))?; } Ok(Decoder { literal: literal_builder.finish(), distance: distance_builder.finish(), }) } } #[derive(Debug)] pub struct DynamicHuffmanCodec; impl HuffmanCodec for DynamicHuffmanCodec { fn build(&self, symbols: &[Symbol]) -> io::Result { let mut literal_counts = [0; 286]; let mut distance_counts = [0; 30]; let mut empty_distance_table = true; for s in symbols { literal_counts[s.code() as usize] += 1; if let Some((d, _, _)) = s.distance() { empty_distance_table = false; distance_counts[d as usize] += 1; } } if empty_distance_table { // Sets a dummy value because an empty distance table causes decoding error on Windows. // // See https://github.com/sile/libflate/issues/23 for more details. distance_counts[0] = 1; } Ok(Encoder { literal: huffman::EncoderBuilder::from_frequencies(&literal_counts, 15)?, distance: huffman::EncoderBuilder::from_frequencies(&distance_counts, 15)?, }) } fn save(&self, writer: &mut bit::BitWriter, codec: &Encoder) -> io::Result<()> where W: io::Write, { let literal_code_count = cmp::max(257, codec.literal.used_max_symbol().unwrap_or(0) + 1); let distance_code_count = cmp::max(1, codec.distance.used_max_symbol().unwrap_or(0) + 1); let codes = build_bitwidth_codes(codec, literal_code_count, distance_code_count); let mut code_counts = [0; 19]; for x in &codes { code_counts[x.0 as usize] += 1; } let bitwidth_encoder = huffman::EncoderBuilder::from_frequencies(&code_counts, 7)?; let bitwidth_code_count = cmp::max( 4, BITWIDTH_CODE_ORDER .iter() .rev() .position(|&i| code_counts[i] != 0 && bitwidth_encoder.lookup(i as u16).width > 0) .map_or(0, |trailing_zeros| 19 - trailing_zeros), ) as u16; writer.write_bits(5, literal_code_count - 257)?; writer.write_bits(5, distance_code_count - 1)?; writer.write_bits(4, bitwidth_code_count - 4)?; for &i in BITWIDTH_CODE_ORDER .iter() .take(bitwidth_code_count as usize) { let width = if code_counts[i] == 0 { 0 } else { u16::from(bitwidth_encoder.lookup(i as u16).width) }; writer.write_bits(3, width)?; } for &(code, bits, extra) in &codes { bitwidth_encoder.encode(writer, u16::from(code))?; if bits > 0 { writer.write_bits(bits, u16::from(extra))?; } } Ok(()) } fn load(&self, reader: &mut bit::BitReader) -> io::Result where R: io::Read, { let literal_code_count = reader.read_bits(5)? + 257; let distance_code_count = reader.read_bits(5)? + 1; let bitwidth_code_count = reader.read_bits(4)? + 4; if distance_code_count as usize > MAX_DISTANCE_CODE_COUNT { #[cfg(feature = "std")] let message = format!( "The value of HDIST is too big: max={MAX_DISTANCE_CODE_COUNT}, actual={distance_code_count}" ); #[cfg(not(feature = "std"))] let message = "The value of HDIST is too big: max={MAX_DISTANCE_CODE_COUNT}"; return Err(io::Error::new(io::ErrorKind::InvalidData, message)); } let mut bitwidth_code_bitwidthes = [0; 19]; for &i in BITWIDTH_CODE_ORDER .iter() .take(bitwidth_code_count as usize) { bitwidth_code_bitwidthes[i] = reader.read_bits(3)? as u8; } let bitwidth_decoder = huffman::DecoderBuilder::from_bitwidthes(&bitwidth_code_bitwidthes, Some(1), None)?; let mut literal_code_bitwidthes = Vec::with_capacity(literal_code_count as usize); while literal_code_bitwidthes.len() < literal_code_count as usize { let c = bitwidth_decoder.decode(reader)?; let last = literal_code_bitwidthes.last().cloned(); literal_code_bitwidthes.extend(load_bitwidthes(reader, c, last)?); } let mut distance_code_bitwidthes = literal_code_bitwidthes .drain(literal_code_count as usize..) .collect::>(); while distance_code_bitwidthes.len() < distance_code_count as usize { let c = bitwidth_decoder.decode(reader)?; let last = distance_code_bitwidthes .last() .cloned() .or_else(|| literal_code_bitwidthes.last().cloned()); distance_code_bitwidthes.extend(load_bitwidthes(reader, c, last)?); } if distance_code_bitwidthes.len() > distance_code_count as usize { #[cfg(feature = "std")] let message = format!( "The length of `distance_code_bitwidthes` is too large: actual={}, expected={}", distance_code_bitwidthes.len(), distance_code_count ); #[cfg(not(feature = "std"))] let message = "The length of `distance_code_bitwidthes` is too large"; return Err(io::Error::new(io::ErrorKind::InvalidData, message)); } let literal = huffman::DecoderBuilder::from_bitwidthes( &literal_code_bitwidthes, None, Some(END_OF_BLOCK), )?; let distance = huffman::DecoderBuilder::from_bitwidthes( &distance_code_bitwidthes, Some(literal.safely_peek_bitwidth()), None, )?; Ok(Decoder { literal, distance }) } } fn load_bitwidthes( reader: &mut bit::BitReader, code: u16, last: Option, ) -> io::Result>> where R: io::Read, { Ok(match code { 0..=15 => Box::new(iter::once(code as u8)), 16 => { let count = reader.read_bits(2)? + 3; let last = last.ok_or_else(|| invalid_data_error!("No preceding value"))?; Box::new(iter::repeat(last).take(count as usize)) } 17 => { let zeros = reader.read_bits(3)? + 3; Box::new(iter::repeat(0).take(zeros as usize)) } 18 => { let zeros = reader.read_bits(7)? + 11; Box::new(iter::repeat(0).take(zeros as usize)) } _ => unreachable!(), }) } fn build_bitwidth_codes( codec: &Encoder, literal_code_count: u16, distance_code_count: u16, ) -> Vec<(u8, u8, u8)> { struct RunLength { value: u8, count: usize, } let mut run_lens: Vec = Vec::new(); for &(e, size) in &[ (&codec.literal, literal_code_count), (&codec.distance, distance_code_count), ] { for (i, c) in (0..size).map(|x| e.lookup(x).width).enumerate() { if i > 0 && run_lens.last().map_or(false, |s| s.value == c) { run_lens.last_mut().unwrap().count += 1; } else { run_lens.push(RunLength { value: c, count: 1 }) } } } let mut codes: Vec<(u8, u8, u8)> = Vec::new(); for r in run_lens { if r.value == 0 { let mut c = r.count; while c >= 11 { let n = cmp::min(138, c) as u8; codes.push((18, 7, n - 11)); c -= n as usize; } if c >= 3 { codes.push((17, 3, c as u8 - 3)); c = 0; } for _ in 0..c { codes.push((0, 0, 0)); } } else { codes.push((r.value, 0, 0)); let mut c = r.count - 1; while c >= 3 { let n = cmp::min(6, c) as u8; codes.push((16, 2, n - 3)); c -= n as usize; } for _ in 0..c { codes.push((r.value, 0, 0)); } } } codes } libflate-2.1.0/src/deflate/test_data.rs000064400000000000000000001703161046102023000161270ustar 00000000000000//! Seperate module for large regression test data, to keep the test code readable. pub const ISSUE_52_INPUT: [u8; 16_052] = [ 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 111, 18, 131, 60, 2, 154, 153, 156, 67, 2, 154, 153, 156, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 48, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 244, 253, 84, 60, 2, 10, 151, 161, 67, 2, 10, 151, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 131, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 56, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 35, 60, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 53, 50, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 184, 30, 146, 67, 2, 184, 30, 146, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 66, 96, 101, 60, 2, 61, 42, 158, 67, 2, 61, 42, 158, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 54, 56, 57, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 149, 67, 2, 0, 128, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 188, 116, 19, 60, 2, 0, 64, 151, 67, 2, 0, 64, 151, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 229, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 57, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 51, 211, 162, 67, 2, 51, 211, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 88, 57, 52, 60, 2, 174, 199, 160, 67, 2, 174, 199, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 49, 8, 172, 60, 2, 195, 149, 152, 67, 2, 195, 149, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 50, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 10, 215, 163, 59, 2, 49, 8, 44, 61, 2, 143, 2, 148, 67, 2, 143, 2, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 54, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 72, 1, 149, 67, 2, 72, 1, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 152, 67, 2, 0, 128, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 56, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 111, 18, 3, 59, 2, 166, 155, 196, 60, 2, 154, 121, 159, 67, 2, 154, 121, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 72, 225, 159, 67, 2, 72, 225, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 215, 195, 161, 67, 2, 215, 195, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 53, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 0, 0, 160, 67, 2, 0, 0, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 0, 160, 160, 67, 2, 0, 160, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 143, 194, 117, 60, 2, 61, 42, 154, 67, 2, 61, 42, 154, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 50, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 166, 155, 68, 59, 2, 143, 194, 245, 60, 2, 184, 158, 148, 67, 2, 184, 158, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 111, 18, 131, 60, 2, 154, 153, 156, 67, 2, 154, 153, 156, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 48, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 244, 253, 84, 60, 2, 10, 151, 161, 67, 2, 10, 151, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 131, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 56, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 35, 60, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 53, 50, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 184, 30, 146, 67, 2, 184, 30, 146, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 66, 96, 101, 60, 2, 61, 42, 158, 67, 2, 61, 42, 158, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 55, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 149, 67, 2, 0, 128, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 188, 116, 19, 60, 2, 0, 64, 151, 67, 2, 0, 64, 151, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 229, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 57, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 51, 211, 162, 67, 2, 51, 211, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 88, 57, 52, 60, 2, 174, 199, 160, 67, 2, 174, 199, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 49, 8, 172, 60, 2, 195, 149, 152, 67, 2, 195, 149, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 50, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 10, 215, 163, 59, 2, 49, 8, 44, 61, 2, 143, 2, 148, 67, 2, 143, 2, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 54, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 72, 1, 149, 67, 2, 72, 1, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 152, 67, 2, 0, 128, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 56, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 111, 18, 3, 59, 2, 166, 155, 196, 60, 2, 154, 121, 159, 67, 2, 154, 121, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 72, 225, 159, 67, 2, 72, 225, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 215, 195, 161, 67, 2, 215, 195, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 53, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 0, 0, 160, 67, 2, 0, 0, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 0, 160, 160, 67, 2, 0, 160, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 143, 194, 117, 60, 2, 61, 42, 154, 67, 2, 61, 42, 154, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 50, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 166, 155, 68, 59, 2, 143, 194, 245, 60, 2, 184, 158, 148, 67, 2, 184, 158, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 111, 18, 131, 60, 2, 154, 153, 156, 67, 2, 154, 153, 156, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 48, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 244, 253, 84, 60, 2, 10, 151, 161, 67, 2, 10, 151, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 131, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 56, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 35, 60, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 53, 50, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 184, 30, 146, 67, 2, 184, 30, 146, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 66, 96, 101, 60, 2, 61, 42, 158, 67, 2, 61, 42, 158, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 56, 56, 54, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 149, 67, 2, 0, 128, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 188, 116, 19, 60, 2, 0, 64, 151, 67, 2, 0, 64, 151, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 229, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 57, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 51, 211, 162, 67, 2, 51, 211, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 88, 57, 52, 60, 2, 174, 199, 160, 67, 2, 174, 199, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 49, 8, 172, 60, 2, 195, 149, 152, 67, 2, 195, 149, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 50, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 10, 215, 163, 59, 2, 49, 8, 44, 61, 2, 143, 2, 148, 67, 2, 143, 2, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 54, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 72, 1, 149, 67, 2, 72, 1, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 52, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 152, 67, 2, 0, 128, 152, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 56, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 111, 18, 3, 59, 2, 166, 155, 196, 60, 2, 154, 121, 159, 67, 2, 154, 121, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 72, 225, 159, 67, 2, 72, 225, 159, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 68, 60, 2, 215, 195, 161, 67, 2, 215, 195, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 53, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 66, 96, 101, 60, 2, 0, 0, 160, 67, 2, 0, 0, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 52, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 0, 160, 160, 67, 2, 0, 160, 160, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 143, 194, 117, 60, 2, 61, 42, 154, 67, 2, 61, 42, 154, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 50, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 166, 155, 68, 59, 2, 143, 194, 245, 60, 2, 184, 158, 148, 67, 2, 184, 158, 148, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 111, 18, 131, 60, 2, 154, 153, 156, 67, 2, 154, 153, 156, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 49, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 166, 155, 196, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 50, 53, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 61, 42, 149, 67, 2, 61, 42, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 48, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 244, 253, 84, 60, 2, 10, 151, 161, 67, 2, 10, 151, 161, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 111, 18, 131, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 51, 56, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 52, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 35, 60, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 57, 48, 53, 50, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 150, 67, 139, 60, 2, 184, 30, 146, 67, 2, 184, 30, 146, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 52, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 166, 155, 68, 59, 2, 0, 128, 142, 67, 2, 0, 128, 142, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 48, 56, 0, 0, 0, 0, 2, 111, 18, 3, 59, 2, 111, 18, 3, 59, 2, 66, 96, 101, 60, 2, 61, 42, 158, 67, 2, 61, 42, 158, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 51, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 0, 0, 0, 0, 2, 10, 215, 163, 59, 2, 0, 128, 162, 67, 2, 0, 128, 162, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 48, 48, 48, 48, 48, 48, 48, 48, 50, 48, 48, 48, 48, 48, 51, 57, 56, 57, 48, 49, 54, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 50, 48, 48, 49, 55, 0, 0, 0, 0, 2, 111, 18, 131, 58, 2, 111, 18, 131, 58, 2, 10, 215, 163, 59, 2, 0, 128, 149, 67, 2, 0, 128, 149, 67, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 49, 54, 0, 0, 0, 0, 2, 49, 8, 144, 64, 2, 96, 229, 144, 64, 2, 172, 28, 230, 64, 2, 113, 61, 46, 66, 2, 92, 143, 52, 66, 0, 2, 0, 0, 192, 65, 0, 0, 0, 2, 47, 221, 12, 65, 2, 219, 249, 20, 65, 2, 8, 172, 14, 65, 2, 8, 172, 22, 65, 2, 0, 0, 128, 65, 2, 0, 0, 128, 63, 2, 8, 172, 14, 65, 2, 0, 0, 144, 65, 2, 0, 0, 112, 65, 2, 0, 0, 0, 64, 2, 0, 0, 48, 65, 2, 0, 0, 224, 64, 0, 0, 0, 0, 2, 47, 221, 12, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 49, 0, 0, 0, 0, 2, 160, 26, 155, 64, 2, 233, 38, 157, 64, 2, 156, 196, 232, 64, 2, 72, 225, 70, 66, 2, 205, 204, 82, 66, 0, 2, 0, 0, 168, 65, 0, 0, 0, 2, 33, 176, 150, 64, 2, 27, 47, 205, 63, 2, 10, 215, 163, 64, 2, 12, 2, 3, 64, 2, 0, 0, 48, 65, 2, 0, 0, 128, 63, 2, 248, 83, 167, 64, 2, 0, 0, 144, 65, 2, 0, 0, 80, 65, 2, 0, 0, 128, 63, 2, 0, 0, 32, 65, 2, 0, 0, 64, 64, 0, 0, 0, 0, 2, 33, 176, 150, 64, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 53, 0, 0, 0, 0, 2, 125, 63, 153, 64, 2, 72, 225, 158, 64, 2, 209, 34, 243, 64, 2, 61, 10, 63, 66, 2, 61, 10, 76, 66, 0, 2, 0, 0, 168, 65, 0, 0, 0, 2, 96, 229, 168, 64, 2, 68, 139, 200, 64, 2, 201, 118, 182, 64, 2, 164, 112, 209, 64, 2, 0, 0, 64, 65, 2, 0, 0, 64, 64, 2, 61, 10, 167, 64, 2, 0, 0, 160, 65, 2, 0, 0, 96, 65, 2, 0, 0, 0, 0, 2, 0, 0, 64, 65, 2, 0, 0, 192, 64, 0, 0, 0, 0, 2, 96, 229, 168, 64, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 50, 57, 0, 0, 0, 0, 2, 84, 227, 169, 64, 2, 180, 200, 174, 64, 2, 98, 16, 248, 64, 2, 236, 81, 50, 66, 2, 51, 51, 59, 66, 0, 2, 0, 0, 144, 65, 0, 0, 0, 2, 111, 18, 227, 64, 2, 80, 141, 223, 64, 2, 184, 30, 237, 64, 2, 106, 188, 224, 64, 2, 0, 0, 64, 65, 2, 0, 0, 64, 64, 2, 174, 71, 1, 65, 2, 0, 0, 128, 65, 2, 0, 0, 112, 65, 2, 0, 0, 0, 64, 2, 0, 0, 64, 65, 2, 0, 0, 48, 65, 0, 0, 0, 0, 2, 111, 18, 227, 64, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 52, 0, 0, 0, 0, 2, 217, 206, 163, 64, 2, 109, 231, 171, 64, 2, 135, 22, 3, 65, 2, 61, 10, 71, 66, 2, 51, 51, 86, 66, 0, 2, 0, 0, 168, 65, 0, 0, 0, 2, 156, 196, 10, 65, 2, 10, 215, 203, 64, 2, 170, 241, 18, 65, 2, 88, 57, 220, 64, 2, 0, 0, 96, 65, 2, 0, 0, 0, 64, 2, 27, 47, 19, 65, 2, 0, 0, 136, 65, 2, 0, 0, 128, 65, 2, 0, 0, 0, 0, 2, 0, 0, 16, 65, 2, 0, 0, 192, 64, 0, 0, 0, 0, 2, 156, 196, 10, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 51, 56, 0, 0, 0, 0, 2, 23, 217, 166, 64, 2, 23, 217, 178, 64, 2, 152, 110, 4, 65, 2, 72, 225, 65, 66, 2, 236, 81, 84, 66, 0, 2, 0, 0, 200, 65, 0, 0, 0, 2, 178, 157, 243, 64, 2, 80, 141, 131, 64, 2, 219, 249, 254, 64, 2, 215, 163, 136, 64, 2, 0, 0, 160, 65, 2, 0, 0, 128, 63, 2, 184, 30, 1, 65, 2, 0, 0, 176, 65, 2, 0, 0, 152, 65, 2, 0, 0, 0, 0, 2, 0, 0, 48, 65, 2, 0, 0, 32, 65, 0, 0, 0, 0, 2, 178, 157, 243, 64, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 51, 0, 0, 0, 0, 2, 113, 61, 138, 64, 2, 86, 14, 149, 64, 2, 178, 157, 227, 64, 2, 82, 184, 70, 66, 2, 61, 10, 90, 66, 0, 2, 0, 0, 192, 65, 0, 0, 0, 2, 162, 69, 28, 65, 2, 45, 178, 241, 64, 2, 6, 129, 33, 65, 2, 213, 120, 249, 64, 2, 0, 0, 112, 65, 2, 0, 0, 128, 64, 2, 39, 49, 36, 65, 2, 0, 0, 168, 65, 2, 0, 0, 152, 65, 2, 0, 0, 64, 64, 2, 0, 0, 96, 65, 2, 0, 0, 0, 65, 0, 0, 0, 0, 2, 162, 69, 28, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 52, 55, 0, 0, 0, 0, 2, 147, 24, 140, 64, 2, 78, 98, 148, 64, 2, 121, 233, 218, 64, 2, 154, 153, 65, 66, 2, 92, 143, 80, 66, 0, 2, 0, 0, 216, 65, 0, 0, 0, 2, 123, 20, 58, 65, 2, 78, 98, 240, 64, 2, 27, 47, 63, 65, 2, 199, 75, 247, 64, 2, 0, 0, 152, 65, 2, 0, 0, 128, 63, 2, 6, 129, 67, 65, 2, 0, 0, 168, 65, 2, 0, 0, 168, 65, 2, 0, 0, 0, 0, 2, 0, 0, 96, 65, 2, 0, 0, 16, 65, 0, 0, 0, 0, 2, 123, 20, 58, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 55, 48, 53, 49, 0, 0, 0, 0, 2, 211, 77, 150, 64, 2, 109, 231, 159, 64, 2, 129, 149, 227, 64, 2, 164, 112, 59, 66, 2, 123, 20, 75, 66, 0, 2, 0, 0, 216, 65, 0, 0, 0, 2, 92, 143, 92, 65, 2, 51, 51, 235, 64, 2, 121, 233, 94, 65, 2, 16, 88, 237, 64, 2, 0, 0, 136, 65, 2, 0, 0, 0, 64, 2, 113, 61, 100, 65, 2, 0, 0, 168, 65, 2, 0, 0, 168, 65, 2, 0, 0, 0, 64, 2, 0, 0, 128, 65, 2, 0, 0, 224, 64, 0, 0, 0, 0, 2, 92, 143, 92, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 52, 0, 0, 0, 0, 2, 109, 231, 163, 64, 2, 133, 235, 173, 64, 2, 168, 198, 243, 64, 2, 72, 225, 54, 66, 2, 246, 40, 69, 66, 0, 2, 0, 0, 224, 65, 0, 0, 0, 2, 154, 153, 89, 65, 2, 4, 86, 178, 64, 2, 211, 77, 90, 65, 2, 170, 241, 182, 64, 2, 0, 0, 112, 65, 2, 0, 0, 0, 64, 2, 43, 135, 90, 65, 2, 0, 0, 216, 65, 2, 0, 0, 184, 65, 2, 0, 0, 128, 63, 2, 0, 0, 168, 65, 2, 0, 0, 32, 65, 0, 0, 0, 0, 2, 154, 153, 89, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 48, 56, 0, 0, 0, 0, 2, 195, 245, 160, 64, 2, 117, 147, 172, 64, 2, 55, 137, 1, 65, 2, 51, 51, 68, 66, 2, 82, 184, 85, 66, 0, 2, 0, 0, 240, 65, 0, 0, 0, 2, 49, 8, 42, 65, 2, 88, 57, 4, 64, 2, 180, 200, 42, 65, 2, 61, 10, 23, 64, 2, 0, 0, 160, 65, 2, 0, 0, 160, 64, 2, 47, 221, 42, 65, 2, 0, 0, 232, 65, 2, 0, 0, 192, 65, 2, 0, 0, 64, 64, 2, 0, 0, 160, 65, 2, 0, 0, 48, 65, 0, 0, 0, 0, 2, 49, 8, 42, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 50, 0, 0, 0, 0, 2, 117, 147, 168, 64, 2, 135, 22, 177, 64, 2, 20, 174, 255, 64, 2, 31, 133, 58, 66, 2, 20, 174, 70, 66, 0, 2, 0, 0, 0, 66, 0, 0, 0, 2, 119, 190, 77, 65, 2, 182, 243, 253, 64, 2, 221, 36, 78, 65, 2, 6, 129, 3, 65, 2, 0, 0, 216, 65, 2, 0, 0, 0, 64, 2, 193, 202, 83, 65, 2, 0, 0, 224, 65, 2, 0, 0, 184, 65, 2, 0, 0, 0, 0, 2, 0, 0, 136, 65, 2, 0, 0, 80, 65, 0, 0, 0, 0, 2, 119, 190, 77, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 49, 54, 0, 0, 0, 0, 2, 133, 235, 165, 64, 2, 117, 147, 172, 64, 2, 111, 18, 223, 64, 2, 164, 112, 48, 66, 2, 154, 153, 58, 66, 0, 2, 0, 0, 4, 66, 0, 0, 0, 2, 182, 243, 39, 65, 2, 131, 192, 98, 64, 2, 238, 124, 41, 65, 2, 213, 120, 113, 64, 2, 0, 0, 128, 65, 2, 0, 0, 128, 63, 2, 223, 79, 47, 65, 2, 0, 0, 224, 65, 2, 0, 0, 184, 65, 2, 0, 0, 0, 0, 2, 0, 0, 128, 65, 2, 0, 0, 0, 65, 0, 0, 0, 0, 2, 182, 243, 39, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 50, 49, 0, 0, 0, 0, 2, 6, 129, 137, 64, 2, 244, 253, 144, 64, 2, 119, 190, 203, 64, 2, 205, 204, 58, 66, 2, 61, 10, 72, 66, 0, 2, 0, 0, 240, 65, 0, 0, 0, 2, 166, 155, 42, 65, 2, 47, 221, 200, 64, 2, 207, 247, 41, 65, 2, 233, 38, 201, 64, 2, 0, 0, 144, 65, 2, 0, 0, 64, 64, 2, 80, 141, 43, 65, 2, 0, 0, 232, 65, 2, 0, 0, 184, 65, 2, 0, 0, 128, 63, 2, 0, 0, 128, 65, 2, 0, 0, 64, 65, 0, 0, 0, 0, 2, 166, 155, 42, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 50, 53, 0, 0, 0, 0, 2, 236, 81, 192, 64, 2, 8, 172, 196, 64, 2, 25, 4, 246, 64, 2, 31, 133, 41, 66, 2, 102, 102, 49, 66, 0, 2, 0, 0, 8, 66, 0, 0, 0, 2, 238, 124, 43, 65, 2, 82, 184, 242, 64, 2, 205, 204, 42, 65, 2, 90, 100, 247, 64, 2, 0, 0, 136, 65, 2, 0, 0, 128, 63, 2, 141, 151, 46, 65, 2, 0, 0, 0, 66, 2, 0, 0, 176, 65, 2, 0, 0, 0, 0, 2, 0, 0, 144, 65, 2, 0, 0, 224, 64, 0, 0, 0, 0, 2, 238, 124, 43, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 48, 0, 0, 0, 0, 2, 119, 190, 143, 64, 2, 16, 88, 145, 64, 2, 115, 104, 181, 64, 2, 154, 153, 32, 66, 2, 72, 225, 36, 66, 0, 2, 0, 0, 248, 65, 0, 0, 0, 2, 172, 28, 30, 65, 2, 94, 186, 25, 64, 2, 244, 253, 30, 65, 2, 156, 196, 32, 64, 2, 0, 0, 32, 65, 2, 0, 0, 64, 64, 2, 209, 34, 33, 65, 2, 0, 0, 232, 65, 2, 0, 0, 176, 65, 2, 0, 0, 64, 64, 2, 0, 0, 136, 65, 2, 0, 0, 224, 64, 0, 0, 0, 0, 2, 172, 28, 30, 65, 0, 0, 0, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 56, 50, 49, 53, 56, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 51, 48, 52, 51, 52, 54, 52, 48, 50, 50, 10, 77, 82, 87, 86, 65, 16, 77, 50, 48, 49, 56, 48, 51, 52, 0, 0, 0, 0, 2, 29, 90, 92, 64, 2, 231, 251, 97, 64, 2, 102, 102, 146, 64, 2, 246, 40, 48, 66, 2, 61, 10, 56, 66, 0, 2, 0, 0, 240, 65, 0, 0, 0, 2, 14, 45, 174, 64, 2, 141, 151, 14, 63, 2, 18, 131, 176, 64, 2, 6, 129, 21, 63, 2, 0, 0, 0, 65, 2, 0, 0, 160, 64, 2, 147, 24, 208, 64, 2, 0, 0, 184, 65, 2, 0, 0, 152, 65, 2, 0, 0, 192, 64, 2, 0, 0, 48, 65, 2, 0, 0, 192, 64, 0, 0, 0, 0, 2, 14, 45, 174, 64, 0, 0, 0, ]; libflate-2.1.0/src/finish.rs000064400000000000000000000145221046102023000140270ustar 00000000000000//! `Finish` and related types. use core::ops::{Deref, DerefMut}; use core2::io::{self, Write}; /// `Finish` is a type that represents a value which /// may have an error occurred during the computation. /// /// Logically, `Finish` is equivalent to `Result`. #[derive(Debug, Default, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct Finish { value: T, error: Option, } impl Finish { /// Makes a new instance. /// /// # Examples /// ``` /// use libflate::Finish; /// /// // The result value of a succeeded computation /// let succeeded = Finish::new("value", None as Option<()>); /// assert_eq!(succeeded.into_result(), Ok("value")); /// /// // The result value of a failed computation /// let failed = Finish::new("value", Some("error")); /// assert_eq!(failed.into_result(), Err("error")); /// ``` pub fn new(value: T, error: Option) -> Self { Finish { value, error } } /// Unwraps the instance. /// /// # Examples /// ``` /// use libflate::Finish; /// /// let succeeded = Finish::new("value", None as Option<()>); /// assert_eq!(succeeded.unwrap(), ("value", None)); /// /// let failed = Finish::new("value", Some("error")); /// assert_eq!(failed.unwrap(), ("value", Some("error"))); /// ``` pub fn unwrap(self) -> (T, Option) { (self.value, self.error) } /// Converts from `Finish` to `Result`. /// /// # Examples /// ``` /// use libflate::Finish; /// /// let succeeded = Finish::new("value", None as Option<()>); /// assert_eq!(succeeded.into_result(), Ok("value")); /// /// let failed = Finish::new("value", Some("error")); /// assert_eq!(failed.into_result(), Err("error")); /// ``` pub fn into_result(self) -> Result { if let Some(e) = self.error { Err(e) } else { Ok(self.value) } } /// Converts from `Finish` to `Result<&T, &E>`. /// /// # Examples /// ``` /// use libflate::Finish; /// /// let succeeded = Finish::new("value", None as Option<()>); /// assert_eq!(succeeded.as_result(), Ok(&"value")); /// /// let failed = Finish::new("value", Some("error")); /// assert_eq!(failed.as_result(), Err(&"error")); /// ``` pub fn as_result(&self) -> Result<&T, &E> { if let Some(ref e) = self.error { Err(e) } else { Ok(&self.value) } } } /// A wrapper struct that completes the processing of the underlying instance when drops. /// /// This calls `Complete:::complete` method of `T` when drops. /// /// # Panics /// /// If the invocation of `Complete::complete(T)` returns an error, `AutoFinish::drop()` will panic. #[derive(Debug)] pub struct AutoFinish { inner: Option, } impl AutoFinish { /// Makes a new `AutoFinish` instance. /// /// # Examples /// /// ``` /// use core2::io::Write; /// use libflate::finish::AutoFinish; /// use libflate::gzip::Encoder; /// /// let plain = b"Hello World!"; /// let mut buf = Vec::new(); /// let mut encoder = AutoFinish::new(Encoder::new(&mut buf).unwrap()); /// encoder.write_all(plain.as_ref()).unwrap(); /// ``` pub fn new(inner: T) -> Self { AutoFinish { inner: Some(inner) } } /// Unwraps this `AutoFinish` instance, returning the underlying instance. pub fn into_inner(mut self) -> T { self.inner.take().expect("Never fails") } } impl Drop for AutoFinish { fn drop(&mut self) { if let Some(inner) = self.inner.take() { if let Err(e) = inner.complete() { panic!("{}", e); } } } } impl Deref for AutoFinish { type Target = T; fn deref(&self) -> &Self::Target { self.inner.as_ref().expect("Never fails") } } impl DerefMut for AutoFinish { fn deref_mut(&mut self) -> &mut Self::Target { self.inner.as_mut().expect("Never fails") } } impl Write for AutoFinish { fn write(&mut self, buf: &[u8]) -> io::Result { self.deref_mut().write(buf) } fn flush(&mut self) -> io::Result<()> { self.deref_mut().flush() } } /// A wrapper struct that completes the processing of the underlying instance when drops. /// /// This calls `Complete:::complete` method of `T` when drops. /// /// Note that this ignores the result of the invocation of `Complete::complete(T)`. #[derive(Debug)] pub struct AutoFinishUnchecked { inner: Option, } impl AutoFinishUnchecked { /// Makes a new `AutoFinishUnchecked` instance. /// /// # Examples /// /// ``` /// use core2::io::Write; /// use libflate::finish::AutoFinishUnchecked; /// use libflate::gzip::Encoder; /// /// let plain = b"Hello World!"; /// let mut buf = Vec::new(); /// let mut encoder = AutoFinishUnchecked::new(Encoder::new(&mut buf).unwrap()); /// encoder.write_all(plain.as_ref()).unwrap(); /// ``` pub fn new(inner: T) -> Self { AutoFinishUnchecked { inner: Some(inner) } } /// Unwraps this `AutoFinishUnchecked` instance, returning the underlying instance. pub fn into_inner(mut self) -> T { self.inner.take().expect("Never fails") } } impl Drop for AutoFinishUnchecked { fn drop(&mut self) { if let Some(inner) = self.inner.take() { let _ = inner.complete(); } } } impl Deref for AutoFinishUnchecked { type Target = T; fn deref(&self) -> &Self::Target { self.inner.as_ref().expect("Never fails") } } impl DerefMut for AutoFinishUnchecked { fn deref_mut(&mut self) -> &mut Self::Target { self.inner.as_mut().expect("Never fails") } } impl Write for AutoFinishUnchecked { fn write(&mut self, buf: &[u8]) -> io::Result { self.deref_mut().write(buf) } fn flush(&mut self) -> io::Result<()> { self.deref_mut().flush() } } /// This trait allows to complete an I/O related processing. pub trait Complete { /// Completes the current processing and returns the result. fn complete(self) -> io::Result<()>; } libflate-2.1.0/src/gzip.rs000064400000000000000000001141621046102023000135210ustar 00000000000000//! The encoder and decoder of the GZIP format. //! //! The GZIP format is defined in [RFC-1952](https://tools.ietf.org/html/rfc1952). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::gzip::{Encoder, Decoder}; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()).unwrap(); //! encoder.write_all(b"Hello World!".as_ref()).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]).unwrap(); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` use crate::checksum; use crate::deflate; use crate::finish::{Complete, Finish}; use crate::lz77; use alloc::{ffi::CString, vec::Vec}; use core2::io; #[cfg(feature = "std")] use std::time; const GZIP_ID: [u8; 2] = [31, 139]; const COMPRESSION_METHOD_DEFLATE: u8 = 8; const OS_FAT: u8 = 0; const OS_AMIGA: u8 = 1; const OS_VMS: u8 = 2; const OS_UNIX: u8 = 3; const OS_VM_CMS: u8 = 4; const OS_ATARI_TOS: u8 = 5; const OS_HPFS: u8 = 6; const OS_MACINTOSH: u8 = 7; const OS_Z_SYSTEM: u8 = 8; const OS_CPM: u8 = 9; const OS_TOPS20: u8 = 10; const OS_NTFS: u8 = 11; const OS_QDOS: u8 = 12; const OS_ACORN_RISCOS: u8 = 13; const OS_UNKNOWN: u8 = 255; const F_TEXT: u8 = 0b00_0001; const F_HCRC: u8 = 0b00_0010; const F_EXTRA: u8 = 0b00_0100; const F_NAME: u8 = 0b00_1000; const F_COMMENT: u8 = 0b01_0000; /// Compression levels defined by the GZIP format. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum CompressionLevel { /// Compressor used fastest algorithm. Fastest, /// Compressor used maximum compression, slowest algorithm. Slowest, /// No information about compression method. Unknown, } impl CompressionLevel { fn to_u8(&self) -> u8 { match *self { CompressionLevel::Fastest => 4, CompressionLevel::Slowest => 2, CompressionLevel::Unknown => 0, } } fn from_u8(x: u8) -> Self { match x { 4 => CompressionLevel::Fastest, 2 => CompressionLevel::Slowest, _ => CompressionLevel::Unknown, } } } impl From for CompressionLevel { fn from(f: lz77::CompressionLevel) -> Self { match f { lz77::CompressionLevel::Fast => CompressionLevel::Fastest, lz77::CompressionLevel::Best => CompressionLevel::Slowest, _ => CompressionLevel::Unknown, } } } #[derive(Debug, Clone)] pub(crate) struct Trailer { crc32: u32, input_size: u32, } impl Trailer { pub fn crc32(&self) -> u32 { self.crc32 } pub fn read_from(mut reader: R) -> io::Result where R: io::Read, { let mut buf = [0; 4]; reader.read_exact(&mut buf)?; let crc32 = u32::from_le_bytes(buf); reader.read_exact(&mut buf)?; let input_size = u32::from_le_bytes(buf); Ok(Trailer { crc32, input_size }) } fn write_to(&self, mut writer: W) -> io::Result<()> where W: io::Write, { writer.write_all(&self.crc32.to_le_bytes())?; writer.write_all(&self.input_size.to_le_bytes())?; Ok(()) } } /// GZIP header builder. #[derive(Debug, Clone)] pub struct HeaderBuilder { header: Header, } impl HeaderBuilder { /// Makes a new builder instance. /// /// # Examples /// ``` /// use libflate::gzip::{HeaderBuilder, CompressionLevel, Os}; /// /// let header = HeaderBuilder::new().finish(); /// assert_eq!(header.compression_level(), CompressionLevel::Unknown); /// assert_eq!(header.os(), Os::Unix); /// assert_eq!(header.is_text(), false); /// assert_eq!(header.is_verified(), false); /// assert_eq!(header.extra_field(), None); /// assert_eq!(header.filename(), None); /// assert_eq!(header.comment(), None); /// ``` pub fn new() -> Self { // wasm-unknown-unknown does not implement the time module #[cfg(all(not(target_arch = "wasm32"), feature = "std"))] let modification_time = time::UNIX_EPOCH .elapsed() .map(|d| d.as_secs() as u32) .unwrap_or(0); #[cfg(any(target_arch = "wasm32", not(feature = "std")))] let modification_time = 0; let header = Header { modification_time, compression_level: CompressionLevel::Unknown, os: Os::Unix, is_text: false, is_verified: false, extra_field: None, filename: None, comment: None, }; HeaderBuilder { header } } /// Sets the modification time (UNIX timestamp). /// /// # Examples /// ``` /// use libflate::gzip::HeaderBuilder; /// /// let header = HeaderBuilder::new().modification_time(10).finish(); /// assert_eq!(header.modification_time(), 10); /// ``` pub fn modification_time(&mut self, modification_time: u32) -> &mut Self { self.header.modification_time = modification_time; self } /// Sets the OS type. /// /// ``` /// use libflate::gzip::{HeaderBuilder, Os}; /// /// let header = HeaderBuilder::new().os(Os::Ntfs).finish(); /// assert_eq!(header.os(), Os::Ntfs); /// ``` pub fn os(&mut self, os: Os) -> &mut Self { self.header.os = os; self } /// Indicates the encoding data is a ASCII text. /// /// # Examples /// ``` /// use libflate::gzip::HeaderBuilder; /// /// let header = HeaderBuilder::new().text().finish(); /// assert_eq!(header.is_text(), true); /// ``` pub fn text(&mut self) -> &mut Self { self.header.is_text = true; self } /// Specifies toe verify header bytes using CRC-16. /// /// # Examples /// ``` /// use libflate::gzip::HeaderBuilder; /// /// let header = HeaderBuilder::new().verify().finish(); /// assert_eq!(header.is_verified(), true); /// ``` pub fn verify(&mut self) -> &mut Self { self.header.is_verified = true; self } /// Sets the extra field. /// /// # Examples /// ``` /// use libflate::gzip::{HeaderBuilder, ExtraField, ExtraSubField}; /// /// let subfield = ExtraSubField{id: [0, 1], data: vec![2, 3, 4]}; /// let extra = ExtraField{subfields: vec![subfield]}; /// let header = HeaderBuilder::new().extra_field(extra.clone()).finish(); /// assert_eq!(header.extra_field(), Some(&extra)); /// ``` pub fn extra_field(&mut self, extra: ExtraField) -> &mut Self { self.header.extra_field = Some(extra); self } /// Sets the file name. /// /// # Examples /// ``` /// #[cfg(not(feature = "std"))] /// extern crate alloc; /// #[cfg(not(feature = "std"))] /// use alloc::ffi::CString; /// #[cfg(feature = "std")] /// use std::ffi::CString; /// use libflate::gzip::HeaderBuilder; /// /// let header = HeaderBuilder::new().filename(CString::new("foo").unwrap()).finish(); /// assert_eq!(header.filename(), Some(&CString::new("foo").unwrap())); /// ``` pub fn filename(&mut self, filename: CString) -> &mut Self { self.header.filename = Some(filename); self } /// Sets the comment. /// /// # Examples /// ``` /// #[cfg(not(feature = "std"))] /// extern crate alloc; /// #[cfg(not(feature = "std"))] /// use alloc::ffi::CString; /// #[cfg(feature = "std")] /// use std::ffi::CString; /// use libflate::gzip::HeaderBuilder; /// /// let header = HeaderBuilder::new().comment(CString::new("foo").unwrap()).finish(); /// assert_eq!(header.comment(), Some(&CString::new("foo").unwrap())); /// ``` pub fn comment(&mut self, comment: CString) -> &mut Self { self.header.comment = Some(comment); self } /// Returns the result header. pub fn finish(&self) -> Header { self.header.clone() } } impl Default for HeaderBuilder { fn default() -> Self { Self::new() } } /// GZIP Header. #[derive(Debug, Clone)] pub struct Header { modification_time: u32, compression_level: CompressionLevel, os: Os, is_text: bool, is_verified: bool, extra_field: Option, filename: Option, comment: Option, } impl Header { /// Returns the modification time (UNIX timestamp). pub fn modification_time(&self) -> u32 { self.modification_time } /// Returns the compression level. pub fn compression_level(&self) -> CompressionLevel { self.compression_level.clone() } /// Returns the OS type. pub fn os(&self) -> Os { self.os.clone() } /// Returns `true` if the stream is probably ASCII text, `false` otherwise. pub fn is_text(&self) -> bool { self.is_text } /// Returns `true` if the header bytes is verified by CRC-16, `false` otherwise. pub fn is_verified(&self) -> bool { self.is_verified } /// Returns the extra field. pub fn extra_field(&self) -> Option<&ExtraField> { self.extra_field.as_ref() } /// Returns the file name. pub fn filename(&self) -> Option<&CString> { self.filename.as_ref() } /// Returns the comment. pub fn comment(&self) -> Option<&CString> { self.comment.as_ref() } fn flags(&self) -> u8 { [ (F_TEXT, self.is_text), (F_HCRC, self.is_verified), (F_EXTRA, self.extra_field.is_some()), (F_NAME, self.filename.is_some()), (F_COMMENT, self.comment.is_some()), ] .iter() .filter(|e| e.1) .map(|e| e.0) .sum() } fn crc16(&self) -> u16 { let mut crc = checksum::Crc32::new(); let mut buf = Vec::new(); Header { is_verified: false, ..self.clone() } .write_to(&mut buf) .unwrap(); crc.update(&buf); crc.value() as u16 } fn write_to(&self, mut writer: W) -> io::Result<()> where W: io::Write, { writer.write_all(&GZIP_ID)?; writer.write_all(&[COMPRESSION_METHOD_DEFLATE, self.flags()])?; writer.write_all(&self.modification_time.to_le_bytes())?; writer.write_all(&[self.compression_level.to_u8(), self.os.to_u8()])?; if let Some(ref x) = self.extra_field { x.write_to(&mut writer)?; } if let Some(ref x) = self.filename { writer.write_all(x.as_bytes_with_nul())?; } if let Some(ref x) = self.comment { writer.write_all(x.as_bytes_with_nul())?; } if self.is_verified { writer.write_all(&self.crc16().to_le_bytes())?; } Ok(()) } pub(crate) fn read_from(mut reader: R) -> io::Result where R: io::Read, { let mut this = HeaderBuilder::new().finish(); let mut buf = [0; 2 + 1 + 1 + 4 + 1 + 1]; reader.read_exact(&mut buf)?; let id = &buf[0..2]; if id != GZIP_ID { return Err(invalid_data_error!( "Unexpected GZIP ID: value={:?}, \ expected={:?}", id, GZIP_ID )); } let compression_method = buf[2]; if compression_method != COMPRESSION_METHOD_DEFLATE { return Err(invalid_data_error!( "Compression methods other than DEFLATE(8) are \ unsupported: method={}", compression_method )); } let flags = buf[3]; this.modification_time = u32::from_le_bytes([buf[4], buf[5], buf[6], buf[7]]); this.compression_level = CompressionLevel::from_u8(buf[8]); this.os = Os::from_u8(buf[9]); if flags & F_EXTRA != 0 { this.extra_field = Some(ExtraField::read_from(&mut reader)?); } if flags & F_NAME != 0 { this.filename = Some(read_cstring(&mut reader)?); } if flags & F_COMMENT != 0 { this.comment = Some(read_cstring(&mut reader)?); } // Checksum verification is skipped during fuzzing // so that random data from fuzzer can reach actually interesting code. // Compilation flag 'fuzzing' is automatically set by all 3 Rust fuzzers. if flags & F_HCRC != 0 && cfg!(not(fuzzing)) { let mut buf = [0; 2]; reader.read_exact(&mut buf)?; let crc = u16::from_le_bytes(buf); let expected = this.crc16(); if crc != expected { return Err(invalid_data_error!( "CRC16 of GZIP header mismatched: value={}, \ expected={}", crc, expected )); } this.is_verified = true; } Ok(this) } } fn read_cstring(mut reader: R) -> io::Result where R: io::Read, { let mut buf = Vec::new(); loop { let mut cbuf = [0; 1]; reader.read_exact(&mut cbuf)?; if cbuf[0] == 0 { return Ok(CString::new(buf).unwrap()); } buf.push(cbuf[0]); } } /// Extra field of a GZIP header. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ExtraField { /// Data of the extra field. pub subfields: Vec, } impl ExtraField { fn read_from(mut reader: R) -> io::Result where R: io::Read, { let mut subfields = Vec::new(); let mut buf = [0; 2]; reader.read_exact(&mut buf)?; let data_size = u16::from_le_bytes(buf) as usize; let mut reader = reader.take(data_size as u64); while reader.limit() > 0 { subfields.push(ExtraSubField::read_from(&mut reader)?); } Ok(ExtraField { subfields }) } fn write_to(&self, mut writer: W) -> io::Result<()> where W: io::Write, { let len = self.subfields.iter().map(|f| f.write_len()).sum::(); if len > 0xFFFF { return Err(invalid_data_error!("extra field too long: {}", len)); } writer.write_all(&(len as u16).to_le_bytes())?; for f in &self.subfields { f.write_to(&mut writer)?; } Ok(()) } } /// A sub field in the extra field of a GZIP header. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ExtraSubField { /// ID of the field. pub id: [u8; 2], /// Data of the field. pub data: Vec, } impl ExtraSubField { fn read_from(mut reader: R) -> io::Result where R: io::Read, { let mut field = ExtraSubField { id: [0; 2], data: Vec::new(), }; reader.read_exact(&mut field.id)?; let mut buf = [0; 2]; reader.read_exact(&mut buf)?; let data_size = u16::from_le_bytes(buf) as usize; field.data.resize(data_size, 0); reader.read_exact(&mut field.data)?; Ok(field) } fn write_to(&self, mut writer: W) -> io::Result<()> where W: io::Write, { writer.write_all(&self.id)?; writer.write_all(&(self.data.len() as u16).to_le_bytes())?; writer.write_all(&self.data)?; Ok(()) } fn write_len(&self) -> usize { 4 + self.data.len() } } /// OS type. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Os { /// FAT filesystem (MS-DOS, OS/2, NT/Win32) Fat, /// Amiga Amiga, /// VMS (or OpenVMS) Vms, /// Unix Unix, /// VM/CMS VmCms, /// Atari TOS AtariTos, /// HPFS filesystem (OS/2, NT) Hpfs, /// Macintosh Macintosh, /// Z-System ZSystem, /// CP/M CpM, /// TOPS-20 Tops20, /// NTFS filesystem (NT) Ntfs, /// QDOS Qdos, /// Acorn RISCOS AcornRiscos, /// Unknown Unknown, /// Undefined value in RFC-1952 Undefined(u8), } impl Os { fn to_u8(&self) -> u8 { match *self { Os::Fat => OS_FAT, Os::Amiga => OS_AMIGA, Os::Vms => OS_VMS, Os::Unix => OS_UNIX, Os::VmCms => OS_VM_CMS, Os::AtariTos => OS_ATARI_TOS, Os::Hpfs => OS_HPFS, Os::Macintosh => OS_MACINTOSH, Os::ZSystem => OS_Z_SYSTEM, Os::CpM => OS_CPM, Os::Tops20 => OS_TOPS20, Os::Ntfs => OS_NTFS, Os::Qdos => OS_QDOS, Os::AcornRiscos => OS_ACORN_RISCOS, Os::Unknown => OS_UNKNOWN, Os::Undefined(os) => os, } } fn from_u8(x: u8) -> Self { match x { OS_FAT => Os::Fat, OS_AMIGA => Os::Amiga, OS_VMS => Os::Vms, OS_UNIX => Os::Unix, OS_VM_CMS => Os::VmCms, OS_ATARI_TOS => Os::AtariTos, OS_HPFS => Os::Hpfs, OS_MACINTOSH => Os::Macintosh, OS_Z_SYSTEM => Os::ZSystem, OS_CPM => Os::CpM, OS_TOPS20 => Os::Tops20, OS_NTFS => Os::Ntfs, OS_QDOS => Os::Qdos, OS_ACORN_RISCOS => Os::AcornRiscos, OS_UNKNOWN => Os::Unknown, os => Os::Undefined(os), } } } /// Options for a GZIP encoder. #[derive(Debug)] pub struct EncodeOptions where E: lz77::Lz77Encode, { header: Header, options: deflate::EncodeOptions, } impl Default for EncodeOptions { fn default() -> Self { EncodeOptions { header: HeaderBuilder::new().finish(), options: Default::default(), } } } impl EncodeOptions { /// Makes a default instance. /// /// # Examples /// ``` /// use libflate::gzip::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn new() -> Self { Self::default() } } impl EncodeOptions where E: lz77::Lz77Encode, { /// Specifies the LZ77 encoder used to compress input data. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::gzip::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::with_lz77(DefaultLz77Encoder::new()); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn with_lz77(lz77: E) -> Self { let mut header = HeaderBuilder::new().finish(); header.compression_level = From::from(lz77.compression_level()); EncodeOptions { header, options: deflate::EncodeOptions::with_lz77(lz77), } } /// Disables LZ77 compression. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::gzip::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().no_compression(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn no_compression(mut self) -> Self { self.options = self.options.no_compression(); self.header.compression_level = CompressionLevel::Unknown; self } /// Sets the GZIP header which will be written to the output stream. /// /// # Example /// ``` /// use libflate::gzip::{Encoder, EncodeOptions, HeaderBuilder}; /// /// let header = HeaderBuilder::new().text().modification_time(100).finish(); /// let options = EncodeOptions::new().header(header); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn header(mut self, header: Header) -> Self { self.header = header; self } /// Specifies the hint of the size of a DEFLATE block. /// /// The default value is `deflate::DEFAULT_BLOCK_SIZE`. /// /// # Example /// ``` /// use libflate::gzip::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().block_size(512 * 1024); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn block_size(mut self, size: usize) -> Self { self.options = self.options.block_size(size); self } /// Specifies to compress with fixed huffman codes. /// /// # Example /// ``` /// use libflate::gzip::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().fixed_huffman_codes(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn fixed_huffman_codes(mut self) -> Self { self.options = self.options.fixed_huffman_codes(); self } } /// GZIP encoder. pub struct Encoder { header: Header, crc32: checksum::Crc32, input_size: u32, writer: deflate::Encoder, } impl Encoder where W: io::Write, { /// Makes a new encoder instance. /// /// Encoded GZIP stream is written to `inner`. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::gzip::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()).unwrap(); /// encoder.write_all(&b"Hello World!"[..]).unwrap(); /// encoder.finish().into_result().unwrap(); /// ``` pub fn new(inner: W) -> io::Result { Self::with_options(inner, EncodeOptions::new()) } } impl Encoder where W: io::Write, E: lz77::Lz77Encode, { /// Makes a new encoder instance with specified options. /// /// Encoded GZIP stream is written to `inner`. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::gzip::{Encoder, EncodeOptions, HeaderBuilder}; /// /// let header = HeaderBuilder::new().modification_time(123).finish(); /// let options = EncodeOptions::new().no_compression().header(header); /// let mut encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// encoder.write_all(&b"Hello World!"[..]).unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// &[31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, 72, 101, 108, 108, /// 111, 32, 87, 111, 114, 108, 100, 33, 163, 28, 41, 28, 12, 0, 0, 0][..]); /// ``` pub fn with_options(mut inner: W, options: EncodeOptions) -> io::Result { options.header.write_to(&mut inner)?; Ok(Encoder { header: options.header.clone(), crc32: checksum::Crc32::new(), input_size: 0, writer: deflate::Encoder::with_options(inner, options.options), }) } /// Returns the header of the GZIP stream. /// /// # Examples /// ``` /// use libflate::gzip::{Encoder, Os}; /// /// let encoder = Encoder::new(Vec::new()).unwrap(); /// assert_eq!(encoder.header().os(), Os::Unix); /// ``` pub fn header(&self) -> &Header { &self.header } /// Writes the GZIP trailer and returns the inner stream. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::gzip::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()).unwrap(); /// encoder.write_all(&b"Hello World!"[..]).unwrap(); /// /// assert!(encoder.finish().as_result().is_ok()) /// ``` /// /// # Note /// /// If you are not concerned the result of this encoding, /// it may be convenient to use `AutoFinishUnchecked` instead of the explicit invocation of this method. /// /// ``` /// use core2::io::Write; /// use libflate::finish::AutoFinishUnchecked; /// use libflate::gzip::Encoder; /// /// let plain = b"Hello World!"; /// let mut buf = Vec::new(); /// let mut encoder = AutoFinishUnchecked::new(Encoder::new(&mut buf).unwrap()); /// #[cfg(not(feature = "std"))] /// encoder.write_all(plain.as_ref()).unwrap(); /// #[cfg(feature = "std")] /// std::io::copy(&mut &plain[..], &mut encoder).unwrap(); /// ``` pub fn finish(self) -> Finish { let trailer = Trailer { crc32: self.crc32.value(), input_size: self.input_size, }; let mut inner = finish_try!(self.writer.finish()); match trailer.write_to(&mut inner).and_then(|_| inner.flush()) { Ok(_) => Finish::new(inner, None), Err(e) => Finish::new(inner, Some(e)), } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &W { self.writer.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut W { self.writer.as_inner_mut() } /// Unwraps the `Encoder`, returning the inner stream. pub fn into_inner(self) -> W { self.writer.into_inner() } } impl io::Write for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn write(&mut self, buf: &[u8]) -> io::Result { let written_size = self.writer.write(buf)?; self.crc32.update(&buf[..written_size]); self.input_size = self.input_size.wrapping_add(written_size as u32); Ok(written_size) } fn flush(&mut self) -> io::Result<()> { self.writer.flush() } } impl Complete for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn complete(self) -> io::Result<()> { self.finish().into_result().map(|_| ()) } } /// GZIP decoder. #[derive(Debug)] pub struct Decoder { header: Header, reader: deflate::Decoder, crc32: checksum::Crc32, eos: bool, } impl Decoder where R: io::Read, { /// Makes a new decoder instance. /// /// `inner` is to be decoded GZIP stream. /// /// # Examples /// ``` /// use core2::io::Read; /// use libflate::gzip::Decoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let mut decoder = Decoder::new(&encoded_data[..]).unwrap(); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(mut inner: R) -> io::Result { let header = Header::read_from(&mut inner)?; Ok(Self::with_header(inner, header)) } /// Returns the header of the GZIP stream. /// /// # Examples /// ``` /// use libflate::gzip::{Decoder, Os}; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let decoder = Decoder::new(&encoded_data[..]).unwrap(); /// assert_eq!(decoder.header().os(), Os::Unix); /// ``` pub fn header(&self) -> &Header { &self.header } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::gzip::Decoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let decoder = Decoder::new(Cursor::new(&encoded_data[..])).unwrap(); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data[..]); /// ``` pub fn into_inner(self) -> R { self.reader.into_inner() } /// Returns the data that has been decoded but has not yet been read. /// /// This method is useful to retrieve partial decoded data when the decoding process is failed. pub fn unread_decoded_data(&self) -> &[u8] { self.reader.unread_decoded_data() } fn with_header(inner: R, header: Header) -> Self { Decoder { header, reader: deflate::Decoder::new(inner), crc32: checksum::Crc32::new(), eos: false, } } fn reset(&mut self, header: Header) { self.header = header; self.reader.reset(); self.crc32 = checksum::Crc32::new(); self.eos = false; } } impl io::Read for Decoder where R: io::Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.eos { Ok(0) } else { let read_size = self.reader.read(buf)?; self.crc32.update(&buf[..read_size]); if read_size == 0 { if buf.is_empty() { return Ok(0); } self.eos = true; let trailer = Trailer::read_from(self.reader.as_inner_mut())?; // checksum verification is skipped during fuzzing // so that random data from fuzzer can reach actually interesting code // Compilation flag 'fuzzing' is automatically set by all 3 Rust fuzzers. if cfg!(not(fuzzing)) && trailer.crc32 != self.crc32.value() { Err(invalid_data_error!( "CRC32 mismatched: value={}, expected={}", self.crc32.value(), trailer.crc32 )) } else { Ok(0) } } else { Ok(read_size) } } } } /// A decoder that decodes all members in a GZIP stream. #[derive(Debug)] pub struct MultiDecoder { decoder: Decoder, eos: bool, } impl MultiDecoder where R: io::Read, { /// Makes a new decoder instance. /// /// `inner` is to be decoded GZIP stream. /// /// # Examples /// ``` /// use core2::io::Read; /// use libflate::gzip::MultiDecoder; /// /// let mut encoded_data = Vec::new(); /// /// // Add a member (a GZIP binary that represents "Hello ") /// encoded_data.extend(&[31, 139, 8, 0, 51, 206, 75, 90, 0, 3, 5, 128, 49, 9, 0, 0, 0, 194, 170, 24, /// 199, 34, 126, 3, 251, 127, 163, 131, 71, 192, 252, 45, 234, 6, 0, 0, 0][..]); /// /// // Add another member (a GZIP binary that represents "World!") /// encoded_data.extend(&[31, 139, 8, 0, 227, 207, 75, 90, 0, 3, 5, 128, 49, 9, 0, 0, 0, 194, 178, 152, /// 202, 2, 158, 130, 96, 255, 99, 120, 111, 4, 222, 157, 40, 118, 6, 0, 0, 0][..]); /// /// let mut decoder = MultiDecoder::new(&encoded_data[..]).unwrap(); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(inner: R) -> io::Result { let decoder = Decoder::new(inner)?; Ok(MultiDecoder { decoder, eos: false, }) } /// Returns the header of the current member in the GZIP stream. /// /// # Examples /// ``` /// use libflate::gzip::{MultiDecoder, Os}; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let decoder = MultiDecoder::new(&encoded_data[..]).unwrap(); /// assert_eq!(decoder.header().os(), Os::Unix); /// ``` pub fn header(&self) -> &Header { self.decoder.header() } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.decoder.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.decoder.as_inner_mut() } /// Unwraps this `MultiDecoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::gzip::MultiDecoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let decoder = MultiDecoder::new(Cursor::new(&encoded_data[..])).unwrap(); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data[..]); /// ``` pub fn into_inner(self) -> R { self.decoder.into_inner() } } impl io::Read for MultiDecoder where R: io::Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.eos { return Ok(0); } let read_size = self.decoder.read(buf)?; if read_size == 0 { match Header::read_from(self.as_inner_mut()) { Err(e) => { if e.kind() == io::ErrorKind::UnexpectedEof { self.eos = true; Ok(0) } else { Err(e) } } Ok(header) => { self.decoder.reset(header); self.read(buf) } } } else { Ok(read_size) } } } #[cfg(test)] mod tests { use super::*; use crate::finish::AutoFinish; use alloc::{vec, vec::Vec}; use core2::io::{Read, Write}; fn decode(buf: &[u8]) -> io::Result> { let mut decoder = Decoder::new(buf).unwrap(); let mut buf = Vec::with_capacity(buf.len()); decoder.read_to_end(&mut buf)?; Ok(buf) } fn decode_multi(buf: &[u8]) -> io::Result> { let mut decoder = MultiDecoder::new(buf).unwrap(); let mut buf = Vec::with_capacity(buf.len()); decoder.read_to_end(&mut buf).unwrap(); Ok(buf) } fn encode(text: &[u8]) -> io::Result> { let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(text).unwrap(); encoder.finish().into_result() } #[test] fn encode_works() { let plain = b"Hello World! Hello GZIP!!"; let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode(&encoded).unwrap(), plain); } #[test] fn encoder_auto_finish_works() { let plain = b"Hello World! Hello GZIP!!"; let mut buf = Vec::new(); { let mut encoder = AutoFinish::new(Encoder::new(&mut buf).unwrap()); encoder.write_all(plain.as_ref()).unwrap(); } assert_eq!(decode(&buf).unwrap(), plain); } #[test] fn multi_decode_works() { use core::iter; let text = b"Hello World!"; let encoded: Vec = iter::repeat(encode(text).unwrap()) .take(2) .flat_map(|b| b) .collect(); assert_eq!(decode(&encoded).unwrap(), b"Hello World!"); assert_eq!(decode_multi(&encoded).unwrap(), b"Hello World!Hello World!"); } #[test] /// See: https://github.com/sile/libflate/issues/15 and https://github.com/RazrFalcon/usvg/issues/20 fn issue_15_1() { let data = b"\x1F\x8B\x08\xC1\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x7B\x80\x80\x80\x80\x7B\x7B\x7B\x7B\x7B\x7B\x97\x7B\x7B\x7B\x86\x27\xEB\x60\xA7\xA8\x46\x6E\x1F\x33\x51\x5C\x34\xE0\xD2\x2E\xE8\x0C\x19\x1D\x3D\x3C\xFD\x3B\x6A\xFA\x63\xDF\x28\x87\x86\xF2\xA6\xAC\x87\x86\xF2\xA6\xAC\xD5"; assert!(decode(&data[..]).is_err()); } #[test] /// See: https://github.com/sile/libflate/issues/15 and https://github.com/RazrFalcon/usvg/issues/21 fn issue_15_2() { let data = b"\x1F\x8B\x08\xC1\x7B\x7B\x7B\x7B\x7B\xFC\x5D\x2D\xDC\x08\xC1\x7B\x7B\x7B\x7B\x7B\xFC\x5D\x2D\xDC\x08\xC1\x7B\x7F\x7B\x7B\x7B\xFC\x5D\x2D\xDC\x69\x32\x48\x22\x5A\x81\x81\x42\x42\x81\x7E\x81\x81\x81\x81\xF2\x17"; assert!(decode(&data[..]).is_err()); } #[test] /// See: https://github.com/sile/libflate/issues/15 and https://github.com/RazrFalcon/usvg/issues/22 fn issue_15_3() { let data = b"\x1F\x8B\x08\xC1\x91\x28\x71\xDC\xF2\x2D\x34\x35\x31\x35\x34\x30\x70\x6E\x60\x35\x31\x32\x32\x33\x32\x33\x37\x32\x36\x38\xDD\x1C\xE5\x2A\xDD\xDD\xDD\x22\xDD\xDD\xDD\xDC\x88\x13\xC9\x40\x60\xA7"; assert!(decode(&data[..]).is_err()); } #[test] /// See: https://github.com/sile/libflate/issues/61 fn issue_61() { let data = encode(b"Hello World").unwrap(); let mut decoder = Decoder::new(&data[..]).unwrap(); let mut buf = Vec::new(); decoder.read(&mut buf).unwrap(); decoder.read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"Hello World"); } #[test] fn extra_field() { let f = ExtraField { subfields: vec![ExtraSubField { id: [0, 0x42], data: "abc".into(), }], }; let mut buf = Vec::new(); f.write_to(&mut buf).unwrap(); assert_eq!(ExtraField::read_from(&buf[..]).unwrap(), f); } #[test] #[cfg(feature = "std")] fn encode_with_extra_field() { use std::io; let mut buf = Vec::new(); let extra_field = ExtraField { subfields: vec![ExtraSubField { id: [0, 0x42], data: "abc".into(), }], }; { // encode let header = HeaderBuilder::new() .extra_field(extra_field.clone()) .finish(); let ops = EncodeOptions::new().header(header); let mut encoder = Encoder::with_options(&mut buf, ops).unwrap(); write!(encoder, "hello world").unwrap(); encoder.finish().as_result().unwrap(); } { // decode let mut decoder = Decoder::new(&buf[..]).unwrap(); io::copy(&mut decoder, &mut io::sink()).unwrap(); assert_eq!(decoder.header().extra_field(), Some(&extra_field)); } } } libflate-2.1.0/src/huffman.rs000064400000000000000000000256221046102023000141760ustar 00000000000000//! Length-limited Huffman Codes. use crate::bit; use alloc::{vec, vec::Vec}; use core::cmp; use core2::io; const MAX_BITWIDTH: u8 = 15; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Code { pub width: u8, pub bits: u16, } impl Code { pub fn new(width: u8, bits: u16) -> Self { debug_assert!(width <= MAX_BITWIDTH); Code { width, bits } } fn inverse_endian(&self) -> Self { let mut f = self.bits; let mut t = 0; for _ in 0..self.width { t <<= 1; t |= f & 1; f >>= 1; } Code::new(self.width, t) } } pub trait Builder: Sized { type Instance; fn set_mapping(&mut self, symbol: u16, code: Code) -> io::Result<()>; fn finish(self) -> Self::Instance; fn restore_canonical_huffman_codes(mut self, bitwidthes: &[u8]) -> io::Result { debug_assert!(!bitwidthes.is_empty()); let mut symbols = bitwidthes .iter() .enumerate() .filter(|&(_, &code_bitwidth)| code_bitwidth > 0) .map(|(symbol, &code_bitwidth)| (symbol as u16, code_bitwidth)) .collect::>(); symbols.sort_by_key(|x| x.1); let mut code = 0; let mut prev_width = 0; for (symbol, bitwidth) in symbols { code <<= bitwidth - prev_width; self.set_mapping(symbol, Code::new(bitwidth, code))?; code += 1; prev_width = bitwidth; } Ok(self.finish()) } } pub struct DecoderBuilder { table: Vec, eob_symbol: Option, safely_peek_bitwidth: Option, max_bitwidth: u8, } impl DecoderBuilder { pub fn new( max_bitwidth: u8, safely_peek_bitwidth: Option, eob_symbol: Option, ) -> Self { debug_assert!(max_bitwidth <= MAX_BITWIDTH); DecoderBuilder { table: vec![u16::from(MAX_BITWIDTH) + 1; 1 << max_bitwidth], eob_symbol, safely_peek_bitwidth, max_bitwidth, } } pub fn from_bitwidthes( bitwidthes: &[u8], safely_peek_bitwidth: Option, eob_symbol: Option, ) -> io::Result { let builder = Self::new( bitwidthes.iter().cloned().max().unwrap_or(0), safely_peek_bitwidth, eob_symbol, ); builder.restore_canonical_huffman_codes(bitwidthes) } pub fn safely_peek_bitwidth(&self) -> Option { self.safely_peek_bitwidth } } impl Builder for DecoderBuilder { type Instance = Decoder; fn set_mapping(&mut self, symbol: u16, code: Code) -> io::Result<()> { debug_assert!(code.width <= self.max_bitwidth); if Some(symbol) == self.eob_symbol { self.safely_peek_bitwidth = Some(code.width); } // `bitwidth` encoded `to` value let value = (symbol << 5) | u16::from(code.width); // Sets the mapping to all possible indices let code_be = code.inverse_endian(); for padding in 0..(1 << (self.max_bitwidth - code.width)) { let i = ((padding << code.width) | code_be.bits) as usize; if self.table[i] != u16::from(MAX_BITWIDTH) + 1 { #[cfg(feature = "std")] let message = format!( "Bit region conflict: i={}, old_value={}, new_value={}, symbol={}, code={:?}", i, self.table[i], value, symbol, code ); #[cfg(not(feature = "std"))] let message = "Bit region conflict"; return Err(io::Error::new(io::ErrorKind::InvalidData, message)); } self.table[i] = value; } Ok(()) } fn finish(self) -> Self::Instance { Decoder { table: self.table, safely_peek_bitwidth: cmp::min( self.max_bitwidth, self.safely_peek_bitwidth.unwrap_or(1), ), max_bitwidth: self.max_bitwidth, } } } #[derive(Debug)] pub struct Decoder { table: Vec, safely_peek_bitwidth: u8, max_bitwidth: u8, } impl Decoder { pub fn safely_peek_bitwidth(&self) -> u8 { self.safely_peek_bitwidth } #[inline(always)] pub fn decode(&self, reader: &mut bit::BitReader) -> io::Result where R: io::Read, { let v = self.decode_unchecked(reader); reader.check_last_error()?; Ok(v) } #[inline(always)] pub fn decode_unchecked(&self, reader: &mut bit::BitReader) -> u16 where R: io::Read, { let mut value; let mut bitwidth; let mut peek_bitwidth = self.safely_peek_bitwidth; loop { let code = reader.peek_bits_unchecked(peek_bitwidth); value = self.table[code as usize]; bitwidth = (value & 0b1_1111) as u8; if bitwidth <= peek_bitwidth { break; } if bitwidth > self.max_bitwidth { reader.set_last_error(invalid_data_error!("Invalid huffman coded stream")); break; } peek_bitwidth = bitwidth; } reader.skip_bits(bitwidth); value >> 5 } } #[derive(Debug)] pub struct EncoderBuilder { table: Vec, } impl EncoderBuilder { pub fn new(symbol_count: usize) -> Self { EncoderBuilder { table: vec![Code::new(0, 0); symbol_count], } } pub fn from_bitwidthes(bitwidthes: &[u8]) -> io::Result { let symbol_count = bitwidthes .iter() .enumerate() .filter(|e| *e.1 > 0) .last() .map_or(0, |e| e.0) + 1; let builder = Self::new(symbol_count); builder.restore_canonical_huffman_codes(bitwidthes) } pub fn from_frequencies(symbol_frequencies: &[usize], max_bitwidth: u8) -> io::Result { let max_bitwidth = cmp::min( max_bitwidth, ordinary_huffman_codes::calc_optimal_max_bitwidth(symbol_frequencies), ); let code_bitwidthes = length_limited_huffman_codes::calc(max_bitwidth, symbol_frequencies); Self::from_bitwidthes(&code_bitwidthes) } } impl Builder for EncoderBuilder { type Instance = Encoder; fn set_mapping(&mut self, symbol: u16, code: Code) -> io::Result<()> { debug_assert_eq!(self.table[symbol as usize], Code::new(0, 0)); self.table[symbol as usize] = code.inverse_endian(); Ok(()) } fn finish(self) -> Self::Instance { Encoder { table: self.table } } } #[derive(Debug, Clone)] pub struct Encoder { table: Vec, } impl Encoder { #[inline(always)] pub fn encode(&self, writer: &mut bit::BitWriter, symbol: u16) -> io::Result<()> where W: io::Write, { let code = self.lookup(symbol); debug_assert_ne!(code, Code::new(0, 0)); writer.write_bits(code.width, code.bits) } #[inline(always)] pub fn lookup(&self, symbol: u16) -> Code { debug_assert!( symbol < self.table.len() as u16, "symbol:{}, table:{}", symbol, self.table.len() ); self.table[symbol as usize].clone() } pub fn used_max_symbol(&self) -> Option { self.table .iter() .rev() .position(|x| x.width > 0) .map(|trailing_zeros| (self.table.len() - 1 - trailing_zeros) as u16) } } #[allow(dead_code)] mod ordinary_huffman_codes { use core::cmp; use dary_heap::BinaryHeap; pub fn calc_optimal_max_bitwidth(frequencies: &[usize]) -> u8 { let mut heap = BinaryHeap::new(); for &freq in frequencies.iter().filter(|&&f| f > 0) { let weight = -(freq as isize); heap.push((weight, 0_u8)); } while heap.len() > 1 { let (weight1, width1) = heap.pop().unwrap(); let (weight2, width2) = heap.pop().unwrap(); heap.push((weight1 + weight2, 1 + cmp::max(width1, width2))); } let max_bitwidth = heap.pop().map_or(0, |x| x.1); cmp::max(1, max_bitwidth) } } mod length_limited_huffman_codes { use alloc::{vec, vec::Vec}; use core::mem; #[derive(Debug, Clone)] struct Node { symbols: Vec, weight: usize, } impl Node { pub fn empty() -> Self { Node { symbols: vec![], weight: 0, } } pub fn single(symbol: u16, weight: usize) -> Self { Node { symbols: vec![symbol], weight, } } pub fn merge(&mut self, other: Self) { self.weight += other.weight; self.symbols.extend(other.symbols); } } /// Reference: [A Fast Algorithm for Optimal Length-Limited Huffman Codes][LenLimHuff.pdf] /// /// [LenLimHuff.pdf]: https://www.ics.uci.edu/~dan/pubs/LenLimHuff.pdf pub fn calc(max_bitwidth: u8, frequencies: &[usize]) -> Vec { // NOTE: unoptimized implementation let mut source = frequencies .iter() .enumerate() .filter(|&(_, &f)| f > 0) .map(|(symbol, &weight)| Node::single(symbol as u16, weight)) .collect::>(); source.sort_by_key(|o| o.weight); let weighted = (0..max_bitwidth - 1).fold(source.clone(), |w, _| merge(package(w), source.clone())); let mut code_bitwidthes = vec![0; frequencies.len()]; for symbol in package(weighted) .into_iter() .flat_map(|n| n.symbols.into_iter()) { code_bitwidthes[symbol as usize] += 1; } code_bitwidthes } fn merge(x: Vec, y: Vec) -> Vec { let mut z = Vec::with_capacity(x.len() + y.len()); let mut x = x.into_iter().peekable(); let mut y = y.into_iter().peekable(); loop { let x_weight = x.peek().map(|s| s.weight); let y_weight = y.peek().map(|s| s.weight); if x_weight.is_none() { z.extend(y); break; } else if y_weight.is_none() { z.extend(x); break; } else if x_weight < y_weight { z.push(x.next().unwrap()); } else { z.push(y.next().unwrap()); } } z } fn package(mut nodes: Vec) -> Vec { if nodes.len() >= 2 { let new_len = nodes.len() / 2; for i in 0..new_len { nodes[i] = mem::replace(&mut nodes[i * 2], Node::empty()); let other = mem::replace(&mut nodes[i * 2 + 1], Node::empty()); nodes[i].merge(other); } nodes.truncate(new_len); } nodes } } #[cfg(test)] mod tests { #[test] fn it_works() {} } libflate-2.1.0/src/lib.rs000064400000000000000000000014251046102023000133130ustar 00000000000000//! A Rust implementation of DEFLATE algorithm and related formats (ZLIB, GZIP). #![forbid(unsafe_code)] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use finish::Finish; extern crate alloc; macro_rules! invalid_data_error { ($fmt:expr) => { invalid_data_error!($fmt, "") }; ($fmt:expr, $($arg:tt)*) => { ::core2::io::Error::new(::core2::io::ErrorKind::InvalidData, $fmt) }; } macro_rules! finish_try { ($e:expr) => { match $e.unwrap() { (inner, None) => inner, (inner, error) => return crate::finish::Finish::new(inner, error), } }; } pub mod deflate; pub mod finish; pub mod gzip; pub mod lz77; pub mod non_blocking; pub mod zlib; mod bit; mod checksum; mod huffman; mod util; libflate-2.1.0/src/lz77.rs000064400000000000000000000015011046102023000133430ustar 00000000000000//! The interface and implementations of LZ77 compression algorithm. //! //! LZ77 is a compression algorithm used in [DEFLATE](https://tools.ietf.org/html/rfc1951). pub use libflate_lz77::*; #[cfg(test)] mod tests { use super::*; use crate::deflate::symbol::Symbol; use alloc::{vec, vec::Vec}; #[test] // See: https://github.com/sile/libflate/issues/21 fn issue21() { let mut enc = DefaultLz77Encoder::new(); let mut sink = Vec::::new(); enc.encode(b"aaaaa", &mut sink); enc.flush(&mut sink); assert_eq!( sink, vec![ Symbol::Code(Code::Literal(97)), Symbol::Code(Code::Pointer { length: 4, backward_distance: 1 }) ] ); } } libflate-2.1.0/src/non_blocking/deflate/decode.rs000064400000000000000000000242541046102023000200430ustar 00000000000000use crate::deflate::symbol::{self, HuffmanCodec}; use crate::lz77; use crate::non_blocking::transaction::TransactionalBitReader; use core::cmp; use core2::io::{self, Read}; /// DEFLATE decoder which supports non-blocking I/O. #[derive(Debug)] pub struct Decoder { state: DecoderState, eos: bool, bit_reader: TransactionalBitReader, block_decoder: BlockDecoder, } impl Decoder { /// Makes a new decoder instance. /// /// `inner` is to be decoded DEFLATE stream. /// /// # Examples /// ``` /// use core2::io::{Cursor, Read}; /// use libflate::non_blocking::deflate::Decoder; /// /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; /// let mut decoder = Decoder::new(&encoded_data[..]); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(inner: R) -> Self { Decoder { state: DecoderState::ReadBlockHeader, eos: false, bit_reader: TransactionalBitReader::new(inner), block_decoder: BlockDecoder::new(), } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.bit_reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.bit_reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::non_blocking::deflate::Decoder; /// /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0]; /// let decoder = Decoder::new(Cursor::new(&encoded_data)); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data); /// ``` pub fn into_inner(self) -> R { self.bit_reader.into_inner() } pub(crate) fn bit_reader_mut(&mut self) -> &mut TransactionalBitReader { &mut self.bit_reader } } impl Read for Decoder { fn read(&mut self, buf: &mut [u8]) -> io::Result { let mut read_size; loop { let next = match self.state { DecoderState::ReadBlockHeader => { let (bfinal, btype) = self.bit_reader.transaction(|r| { let bfinal = r.read_bit()?; let btype = r.read_bits(2)?; Ok((bfinal, btype)) })?; self.eos = bfinal; self.block_decoder.enter_new_block(); match btype { 0b00 => DecoderState::ReadNonCompressedBlockLen, 0b01 => DecoderState::LoadFixedHuffmanCode, 0b10 => DecoderState::LoadDynamicHuffmanCode, 0b11 => { return Err(invalid_data_error!( "btype 0x11 of DEFLATE is reserved(error) value" )); } _ => unreachable!(), } } DecoderState::ReadNonCompressedBlockLen => { let len = self.bit_reader.transaction(|r| { r.reset(); let mut buf = [0; 2]; r.as_inner_mut().read_exact(&mut buf)?; let len = u16::from_le_bytes(buf); r.as_inner_mut().read_exact(&mut buf)?; let nlen = u16::from_le_bytes(buf); if !len != nlen { Err(invalid_data_error!( "LEN={} is not the one's complement of NLEN={}", len, nlen )) } else { Ok(len) } })?; DecoderState::ReadNonCompressedBlock { len } } DecoderState::ReadNonCompressedBlock { len: 0 } => { if self.eos { read_size = 0; break; } else { DecoderState::ReadBlockHeader } } DecoderState::ReadNonCompressedBlock { ref mut len } => { let buf_len = buf.len(); let buf = &mut buf[..cmp::min(buf_len, *len as usize)]; read_size = self.bit_reader.as_inner_mut().read(buf)?; self.block_decoder.extend(&buf[..read_size]); *len -= read_size as u16; break; } DecoderState::LoadFixedHuffmanCode => { let symbol_decoder = self .bit_reader .transaction(|r| symbol::FixedHuffmanCodec.load(r))?; DecoderState::DecodeBlock(symbol_decoder) } DecoderState::LoadDynamicHuffmanCode => { let symbol_decoder = self .bit_reader .transaction(|r| symbol::DynamicHuffmanCodec.load(r))?; DecoderState::DecodeBlock(symbol_decoder) } DecoderState::DecodeBlock(ref mut symbol_decoder) => { self.block_decoder .decode(&mut self.bit_reader, symbol_decoder)?; read_size = self.block_decoder.read(buf)?; if read_size == 0 && !buf.is_empty() && !self.eos { DecoderState::ReadBlockHeader } else { break; } } }; self.state = next; } Ok(read_size) } } #[derive(Debug)] enum DecoderState { ReadBlockHeader, ReadNonCompressedBlockLen, ReadNonCompressedBlock { len: u16 }, LoadFixedHuffmanCode, LoadDynamicHuffmanCode, DecodeBlock(symbol::Decoder), } #[derive(Debug)] struct BlockDecoder { lz77_decoder: lz77::Lz77Decoder, eob: bool, } impl BlockDecoder { pub fn new() -> Self { BlockDecoder { lz77_decoder: lz77::Lz77Decoder::new(), eob: false, } } pub fn enter_new_block(&mut self) { self.eob = false; } pub fn decode( &mut self, bit_reader: &mut TransactionalBitReader, symbol_decoder: &mut symbol::Decoder, ) -> io::Result<()> { if self.eob { return Ok(()); } while let Some(s) = self.decode_symbol(bit_reader, symbol_decoder)? { match s { symbol::Symbol::Code(code) => { self.lz77_decoder.decode(code)?; } symbol::Symbol::EndOfBlock => { self.eob = true; break; } } } Ok(()) } fn extend(&mut self, buf: &[u8]) { self.lz77_decoder.extend_from_slice(buf); } fn decode_symbol( &mut self, bit_reader: &mut TransactionalBitReader, symbol_decoder: &mut symbol::Decoder, ) -> io::Result> { let result = bit_reader.transaction(|bit_reader| { let s = symbol_decoder.decode_unchecked(bit_reader); bit_reader.check_last_error().map(|()| s) }); match result { Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(None), Err(e) => Err(e), Ok(s) => Ok(Some(s)), } } } impl Read for BlockDecoder { fn read(&mut self, buf: &mut [u8]) -> io::Result { if !self.lz77_decoder.buffer().is_empty() { self.lz77_decoder.read(buf) } else if self.eob { Ok(0) } else { Err(io::Error::new(io::ErrorKind::WouldBlock, "Would block")) } } } #[cfg(test)] mod tests { use super::*; use crate::deflate::{EncodeOptions, Encoder}; use crate::util::{nb_read_to_end, WouldBlockReader}; use alloc::{format, string::String, vec::Vec}; use core2::io::{Read, Write}; #[test] fn it_works() { let mut encoder = Encoder::new(Vec::new()); encoder.write_all(b"Hello World!".as_ref()).unwrap(); let encoded_data = encoder.finish().into_result().unwrap(); let mut decoder = Decoder::new(&encoded_data[..]); let mut decoded_data = Vec::new(); decoder.read_to_end(&mut decoded_data).unwrap(); assert_eq!(decoded_data, b"Hello World!"); } #[test] fn non_blocking_io_works() { let mut encoder = Encoder::new(Vec::new()); encoder.write_all(b"Hello World!".as_ref()).unwrap(); let encoded_data = encoder.finish().into_result().unwrap(); let decoder = Decoder::new(WouldBlockReader::new(&encoded_data[..])); let decoded_data = nb_read_to_end(decoder).unwrap(); assert_eq!(decoded_data, b"Hello World!"); } #[test] fn non_blocking_io_for_large_text_works() { let text: String = (0..10000) .into_iter() .map(|i| format!("test {}", i)) .collect(); let mut encoder = crate::deflate::Encoder::new(Vec::new()); encoder.write_all(text.as_bytes()).unwrap(); let encoded_data = encoder.finish().into_result().unwrap(); let decoder = Decoder::new(WouldBlockReader::new(&encoded_data[..])); let decoded_data = nb_read_to_end(decoder).unwrap(); assert_eq!(decoded_data, text.as_bytes()); } #[test] fn non_compressed_non_blocking_io_works() { let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()); encoder.write_all(b"Hello World!".as_ref()).unwrap(); let encoded_data = encoder.finish().into_result().unwrap(); let decoder = Decoder::new(WouldBlockReader::new(&encoded_data[..])); let decoded_data = nb_read_to_end(decoder).unwrap(); assert_eq!(decoded_data, b"Hello World!"); } } libflate-2.1.0/src/non_blocking/deflate/mod.rs000064400000000000000000000013471046102023000173750ustar 00000000000000//! The decoder of the DEFLATE format and algorithm. //! //! The DEFLATE is defined in [RFC-1951](https://tools.ietf.org/html/rfc1951). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::deflate::Encoder; //! use libflate::non_blocking::deflate::Decoder; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()); //! encoder.write_all(b"Hello World!".as_ref()).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` pub use self::decode::Decoder; mod decode; libflate-2.1.0/src/non_blocking/gzip.rs000064400000000000000000000137301046102023000161620ustar 00000000000000//! The encoder and decoder of the GZIP format. //! //! The GZIP format is defined in [RFC-1952](https://tools.ietf.org/html/rfc1952). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::gzip::Encoder; //! use libflate::non_blocking::gzip::Decoder; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()).unwrap(); //! encoder.write_all(&b"Hello World!".as_ref()).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` use crate::checksum; use crate::gzip::{Header, Trailer}; use crate::non_blocking::deflate; use core2::io::{self, Read}; /// GZIP decoder which supports non-blocking I/O. #[derive(Debug)] pub struct Decoder { header: Option
, reader: deflate::Decoder, crc32: checksum::Crc32, eos: bool, } impl Decoder { /// Makes a new decoder instance. /// /// `inner` is to be decoded GZIP stream. /// /// # Examples /// ``` /// use core2::io::Read; /// use libflate::non_blocking::gzip::Decoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let mut decoder = Decoder::new(&encoded_data[..]); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(inner: R) -> Self { Decoder { header: None, reader: deflate::Decoder::new(inner), crc32: checksum::Crc32::new(), eos: false, } } /// Returns the header of the GZIP stream. /// /// # Examples /// ``` /// use libflate::gzip::Os; /// use libflate::non_blocking::gzip::Decoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let mut decoder = Decoder::new(&encoded_data[..]); /// assert_eq!(decoder.header().unwrap().os(), Os::Unix); /// ``` pub fn header(&mut self) -> io::Result<&Header> { if let Some(ref header) = self.header { Ok(header) } else { let header = self .reader .bit_reader_mut() .transaction(|r| Header::read_from(r.as_inner_mut()))?; self.header = Some(header); self.header() } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::non_blocking::gzip::Decoder; /// /// let encoded_data = [31, 139, 8, 0, 123, 0, 0, 0, 0, 3, 1, 12, 0, 243, 255, /// 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, /// 163, 28, 41, 28, 12, 0, 0, 0]; /// /// let decoder = Decoder::new(Cursor::new(&encoded_data[..])); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data[..]); /// ``` pub fn into_inner(self) -> R { self.reader.into_inner() } } impl Read for Decoder { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.header.is_none() { self.header()?; } if self.eos { Ok(0) } else { let read_size = self.reader.read(buf)?; if read_size == 0 { let trailer = self .reader .bit_reader_mut() .transaction(|r| Trailer::read_from(r.as_inner_mut()))?; self.eos = true; // checksum verification is skipped during fuzzing // so that random data from fuzzer can reach actually interesting code // Compilation flag 'fuzzing' is automatically set by all 3 Rust fuzzers. if cfg!(not(fuzzing)) && trailer.crc32() != self.crc32.value() { Err(invalid_data_error!( "CRC32 mismatched: value={}, expected={}", self.crc32.value(), trailer.crc32() )) } else { Ok(0) } } else { self.crc32.update(&buf[..read_size]); Ok(read_size) } } } } #[cfg(test)] mod tests { use super::*; use crate::gzip::Encoder; use crate::util::{nb_read_to_end, WouldBlockReader}; use alloc::vec::Vec; use core2::io::Write; fn decode_all(buf: &[u8]) -> io::Result> { let decoder = Decoder::new(WouldBlockReader::new(buf)); nb_read_to_end(decoder) } #[test] fn encode_works() { let plain = b"Hello World! Hello GZIP!!"; let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode_all(&encoded).unwrap(), plain); } #[test] fn decode_works_noncompressed_block_offset_sync() { let encoded = include_bytes!("../../data/noncompressed_block_offset_sync/offset.gz"); let decoded = include_bytes!("../../data/noncompressed_block_offset_sync/offset"); // decode_all(encoded).unwrap(); assert_eq!(decode_all(encoded).unwrap(), decoded.to_vec()); } } libflate-2.1.0/src/non_blocking/mod.rs000064400000000000000000000014471046102023000157720ustar 00000000000000//! Implementations that can handle non-blocking I/O. //! //! The implementations in this module can handle non-blocking //! `Reader`s and `Writer`s which will return `ErrorKind::WouldBlock` error //! when I/O operations would block. //! //! If inner `Reader`s and `Writer`s return `ErrorKind::WouldBlock` error, //! `Decoder`s and `Encoder`s in this module will also return `ErrorKind::WouldBlock`. //! //! If retrying the operation after the inner I/O become available, it will proceed successfully. //! //! # NOTICE //! //! There is some performance penalty for non-blocking implementations //! against those that do not consider nonblocking I / O. //! So, it is recommended to use the latter if you are not need to handle non-blocking I/O. pub mod deflate; pub mod gzip; pub mod zlib; mod transaction; libflate-2.1.0/src/non_blocking/transaction.rs000064400000000000000000000057521046102023000175430ustar 00000000000000use crate::bit; use alloc::vec::Vec; use core::cmp; use core2::io::{self, Read}; #[derive(Debug)] pub struct TransactionalBitReader { inner: bit::BitReader>, savepoint: bit::BitReaderState, } impl TransactionalBitReader { pub fn new(inner: R) -> Self { let inner = bit::BitReader::new(TransactionalReader::new(inner)); let savepoint = inner.state(); TransactionalBitReader { inner, savepoint } } #[inline] pub fn transaction(&mut self, f: F) -> io::Result where F: FnOnce(&mut bit::BitReader>) -> io::Result, { self.start_transaction(); let result = f(&mut self.inner); if result.is_ok() { self.commit_transaction(); } else { self.abort_transaction(); } result } #[inline] pub fn start_transaction(&mut self) { self.inner.as_inner_mut().start_transaction(); self.savepoint = self.inner.state(); } #[inline] pub fn abort_transaction(&mut self) { self.inner.as_inner_mut().abort_transaction(); self.inner.restore_state(self.savepoint); } #[inline] pub fn commit_transaction(&mut self) { self.inner.as_inner_mut().commit_transaction(); } } impl TransactionalBitReader { pub fn as_inner_ref(&self) -> &R { &self.inner.as_inner_ref().inner } pub fn as_inner_mut(&mut self) -> &mut R { &mut self.inner.as_inner_mut().inner } pub fn into_inner(self) -> R { self.inner.into_inner().inner } } #[derive(Debug)] pub struct TransactionalReader { inner: R, in_transaction: bool, buffer: Vec, offset: usize, } impl TransactionalReader { pub fn new(inner: R) -> Self { TransactionalReader { inner, buffer: Vec::new(), in_transaction: false, offset: 0, } } #[inline] pub fn start_transaction(&mut self) { assert!(!self.in_transaction); self.in_transaction = true; } #[inline] pub fn commit_transaction(&mut self) { self.in_transaction = false; self.offset = 0; self.buffer.clear(); } #[inline] pub fn abort_transaction(&mut self) { self.in_transaction = false; self.offset = 0; } } impl Read for TransactionalReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.offset < self.buffer.len() { let unread_buf_size = self.buffer.len() - self.offset; let size = cmp::min(buf.len(), unread_buf_size); buf[0..size].copy_from_slice(&self.buffer[self.offset..self.offset + size]); self.offset += size; return Ok(size); } let size = self.inner.read(buf)?; if self.in_transaction { self.buffer.extend_from_slice(&buf[0..size]); self.offset += size; } Ok(size) } } libflate-2.1.0/src/non_blocking/zlib.rs000064400000000000000000000207111046102023000161460ustar 00000000000000//! The encoder and decoder of the ZLIB format. //! //! The ZLIB format is defined in [RFC-1950](https://tools.ietf.org/html/rfc1950). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::zlib::Encoder; //! use libflate::non_blocking::zlib::Decoder; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()).unwrap(); //! encoder.write_all(b"Hello World!".as_ref()).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` use crate::checksum; use crate::non_blocking::deflate; use crate::zlib::Header; use core2::io::{self, Read}; /// ZLIB decoder which supports non-blocking I/O. #[derive(Debug)] pub struct Decoder { header: Option
, reader: deflate::Decoder, adler32: checksum::Adler32, eos: bool, } impl Decoder { /// Makes a new decoder instance. /// /// `inner` is to be decoded ZLIB stream. /// /// # Examples /// ``` /// use core2::io::Read; /// use libflate::non_blocking::zlib::Decoder; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let mut decoder = Decoder::new(&encoded_data[..]); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(inner: R) -> Self { Decoder { header: None, reader: deflate::Decoder::new(inner), adler32: checksum::Adler32::new(), eos: false, } } /// Returns the header of the ZLIB stream. /// /// # Examples /// ``` /// use libflate::zlib::CompressionLevel; /// use libflate::non_blocking::zlib::Decoder; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let mut decoder = Decoder::new(&encoded_data[..]); /// assert_eq!(decoder.header().unwrap().compression_level(), /// CompressionLevel::Default); /// ``` pub fn header(&mut self) -> io::Result<&Header> { if let Some(ref header) = self.header { Ok(header) } else { let header = self .reader .bit_reader_mut() .transaction(|r| Header::read_from(r.as_inner_mut()))?; self.header = Some(header); self.header() } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::non_blocking::zlib::Decoder; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let decoder = Decoder::new(Cursor::new(&encoded_data)); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data); /// ``` pub fn into_inner(self) -> R { self.reader.into_inner() } } impl Read for Decoder { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.header.is_none() { self.header()?; } if self.eos { Ok(0) } else { let read_size = self.reader.read(buf)?; if read_size == 0 { let adler32 = self.reader.bit_reader_mut().transaction(|r| { let mut buf = [0; 4]; r.as_inner_mut() .read_exact(&mut buf) .and(Ok(u32::from_be_bytes(buf))) })?; self.eos = true; // checksum verification is skipped during fuzzing // so that random data from fuzzer can reach actually interesting code // Compilation flag 'fuzzing' is automatically set by all 3 Rust fuzzers. if cfg!(not(fuzzing)) && adler32 != self.adler32.value() { Err(invalid_data_error!( "Adler32 checksum mismatched: value={}, expected={}", self.adler32.value(), adler32 )) } else { Ok(0) } } else { self.adler32.update(&buf[..read_size]); Ok(read_size) } } } } #[cfg(test)] mod tests { use super::*; use crate::util::{nb_read_to_end, WouldBlockReader}; use crate::zlib::{EncodeOptions, Encoder}; use alloc::vec::Vec; use core2::io::Write; fn decode_all(buf: &[u8]) -> io::Result> { let decoder = Decoder::new(WouldBlockReader::new(buf)); nb_read_to_end(decoder) } #[cfg(feature = "std")] fn default_encode(buf: &[u8]) -> io::Result> { let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(buf.as_ref()).unwrap(); encoder.finish().into_result() } #[cfg(feature = "std")] macro_rules! assert_encode_decode { ($input:expr) => {{ let encoded = default_encode(&$input[..]).unwrap(); assert_eq!(decode_all(&encoded).unwrap(), &$input[..]); }}; } const DECODE_WORKS_TESTDATA: [u8; 20] = [ 120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0, 28, 73, 4, 62, ]; #[test] fn decode_works() { let encoded = DECODE_WORKS_TESTDATA; let buf = decode_all(&encoded[..]).unwrap(); let expected = b"Hello World!"; assert_eq!(buf, expected); } #[test] #[cfg(feature = "std")] fn default_encode_works() { let plain = b"Hello World! Hello ZLIB!!"; let mut encoder = Encoder::new(Vec::new()).unwrap(); io::copy(&mut &plain[..], &mut encoder).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode_all(&encoded).unwrap(), plain); } #[test] #[cfg(feature = "std")] fn best_speed_encode_works() { let plain = b"Hello World! Hello ZLIB!!"; let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::default().fixed_huffman_codes()) .unwrap(); io::copy(&mut &plain[..], &mut encoder).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode_all(&encoded).unwrap(), plain); } const RAW_ENCODE_WORKS_EXPECTED: [u8; 23] = [ 120, 1, 1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 28, 73, 4, 62, ]; #[test] fn raw_encode_works() { let plain = b"Hello World!"; let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()).unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); let expected = RAW_ENCODE_WORKS_EXPECTED; assert_eq!(encoded, expected); assert_eq!(decode_all(&encoded).unwrap(), plain); } #[test] #[cfg(feature = "std")] fn test_issue_2() { // See: https://github.com/sile/libflate/issues/2 assert_encode_decode!([ 163, 181, 167, 40, 62, 239, 41, 125, 189, 217, 61, 122, 20, 136, 160, 178, 119, 217, 217, 41, 125, 189, 97, 195, 101, 47, 170, ]); assert_encode_decode!([ 162, 58, 99, 211, 7, 64, 96, 36, 57, 155, 53, 166, 76, 14, 238, 66, 66, 148, 154, 124, 162, 58, 99, 188, 138, 131, 171, 189, 54, 229, 192, 38, 29, 240, 122, 28, ]); assert_encode_decode!([ 239, 238, 212, 42, 5, 46, 186, 67, 122, 247, 30, 61, 219, 62, 228, 202, 164, 205, 139, 109, 99, 181, 99, 181, 99, 122, 30, 12, 62, 46, 27, 145, 241, 183, 137, ]); assert_encode_decode!([ 88, 202, 64, 12, 125, 108, 153, 49, 164, 250, 71, 19, 4, 108, 111, 108, 237, 205, 208, 77, 217, 100, 118, 49, 10, 64, 12, 125, 51, 202, 69, 67, 181, 146, 86, ]); } } libflate-2.1.0/src/util.rs000064400000000000000000000034021046102023000135170ustar 00000000000000#[cfg(test)] pub(crate) mod testonly { use alloc::vec; use alloc::vec::Vec; use core2::io::{self, Read}; pub struct WouldBlockReader { inner: R, do_block: bool, } impl WouldBlockReader { pub fn new(inner: R) -> Self { WouldBlockReader { inner, do_block: false, } } } impl Read for WouldBlockReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.do_block = !self.do_block; if self.do_block { Err(io::Error::new(io::ErrorKind::WouldBlock, "Would block")) } else if buf.is_empty() { Ok(0) } else { let mut byte = [0; 1]; if self.inner.read(&mut byte[..])? == 1 { buf[0] = byte[0]; Ok(1) } else { Ok(0) } } } } pub fn nb_read_to_end(mut reader: R) -> io::Result> { let mut buf = vec![0; 1024]; let mut offset = 0; loop { match reader.read(&mut buf[offset..]) { Err(e) => { if e.kind() != io::ErrorKind::WouldBlock { return Err(e); } } Ok(0) => { buf.truncate(offset); break; } Ok(size) => { offset += size; if offset == buf.len() { buf.resize(offset * 2, 0); } } } } Ok(buf) } } #[cfg(test)] pub(crate) use testonly::*; libflate-2.1.0/src/zlib.rs000064400000000000000000000715361046102023000135170ustar 00000000000000//! The encoder and decoder of the ZLIB format. //! //! The ZLIB format is defined in [RFC-1950](https://tools.ietf.org/html/rfc1950). //! //! # Examples //! ``` //! use core2::io::{Read, Write}; //! use libflate::zlib::{Encoder, Decoder}; //! //! // Encoding //! let mut encoder = Encoder::new(Vec::new()).unwrap(); //! encoder.write_all(&b"Hello World!"[..]).unwrap(); //! let encoded_data = encoder.finish().into_result().unwrap(); //! //! // Decoding //! let mut decoder = Decoder::new(&encoded_data[..]).unwrap(); //! let mut decoded_data = Vec::new(); //! decoder.read_to_end(&mut decoded_data).unwrap(); //! //! assert_eq!(decoded_data, b"Hello World!"); //! ``` use crate::checksum; use crate::deflate; use crate::finish::{Complete, Finish}; use crate::lz77; use core2::io; const COMPRESSION_METHOD_DEFLATE: u8 = 8; /// Compression levels defined by the ZLIB format. #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum CompressionLevel { /// Compressor used fastest algorithm. Fastest = 0, /// Compressor used fast algorithm. Fast = 1, /// Compressor used default algorithm. Default = 2, /// Compressor used maximum compression, slowest algorithm. Slowest = 3, } impl CompressionLevel { fn from_u2(level: u8) -> Self { match level { 0 => CompressionLevel::Fastest, 1 => CompressionLevel::Fast, 2 => CompressionLevel::Default, 3 => CompressionLevel::Slowest, _ => unreachable!(), } } fn as_u2(&self) -> u8 { self.clone() as u8 } } impl From for CompressionLevel { fn from(f: lz77::CompressionLevel) -> Self { match f { lz77::CompressionLevel::None => CompressionLevel::Fastest, lz77::CompressionLevel::Fast => CompressionLevel::Fast, lz77::CompressionLevel::Balance => CompressionLevel::Default, lz77::CompressionLevel::Best => CompressionLevel::Slowest, } } } /// LZ77 Window sizes defined by the ZLIB format. #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] // TODO: Use `#[allow(clippy::upper_case_acronyms)]` instead once it gets available on the stable branch #[allow(clippy::all)] pub enum Lz77WindowSize { /// 256 bytes B256 = 0, /// 512 btyes B512 = 1, /// 1 kilobyte KB1 = 2, /// 2 kilobytes KB2 = 3, /// 4 kitobytes KB4 = 4, /// 8 kitobytes KB8 = 5, /// 16 kitobytes KB16 = 6, /// 32 kitobytes KB32 = 7, } impl Lz77WindowSize { fn from_u4(compression_info: u8) -> Option { match compression_info { 0 => Some(Lz77WindowSize::B256), 1 => Some(Lz77WindowSize::B512), 2 => Some(Lz77WindowSize::KB1), 3 => Some(Lz77WindowSize::KB2), 4 => Some(Lz77WindowSize::KB4), 5 => Some(Lz77WindowSize::KB8), 6 => Some(Lz77WindowSize::KB16), 7 => Some(Lz77WindowSize::KB32), _ => None, } } fn as_u4(&self) -> u8 { self.clone() as u8 } /// Converts from `u16` to Lz77WindowSize`. /// /// Fractions are rounded to next upper window size. /// If `size` exceeds maximum window size, /// `lz77::MAX_WINDOW_SIZE` will be used instead. /// /// # Examples /// ``` /// use libflate::zlib::Lz77WindowSize; /// /// assert_eq!(Lz77WindowSize::from_u16(15000), Lz77WindowSize::KB16); /// assert_eq!(Lz77WindowSize::from_u16(16384), Lz77WindowSize::KB16); /// assert_eq!(Lz77WindowSize::from_u16(16385), Lz77WindowSize::KB32); /// assert_eq!(Lz77WindowSize::from_u16(40000), Lz77WindowSize::KB32); /// ``` pub fn from_u16(size: u16) -> Self { use self::Lz77WindowSize::*; if 16_384 < size { KB32 } else if 8192 < size { KB16 } else if 4096 < size { KB8 } else if 2048 < size { KB4 } else if 1024 < size { KB2 } else if 512 < size { KB1 } else if 256 < size { B512 } else { B256 } } /// Converts from `Lz77WindowSize` to `u16`. /// /// # Examples /// ``` /// use libflate::zlib::Lz77WindowSize; /// /// assert_eq!(Lz77WindowSize::KB16.to_u16(), 16384u16); /// ``` pub fn to_u16(&self) -> u16 { use self::Lz77WindowSize::*; match *self { B256 => 256, B512 => 512, KB1 => 1024, KB2 => 2048, KB4 => 4096, KB8 => 8192, KB16 => 16_384, KB32 => 32_768, } } } /// [zlib] library specific parameter for defining behavior when `Write::flush` method is called. /// /// # References /// /// - [Zlib Manual](https://www.zlib.net/manual.html) /// - [Zlib Flush Modes](https://www.bolet.org/~pornin/deflate-flush.html) /// /// [zlib]: https://www.zlib.net/ #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum FlushMode { /// `Z_NO_FLUSH` (default). /// /// Note that when this parameter is specified, /// no `zlib` specific processing will not be executed but ordinal DEFLATE layer flushing will be performed. #[default] None = 0, /// `Z_SYNC_FLUSH`. Sync = 2, } /// ZLIB header. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Header { window_size: Lz77WindowSize, compression_level: CompressionLevel, } impl Header { /// Returns the LZ77 window size stored in the header. pub fn window_size(&self) -> Lz77WindowSize { self.window_size.clone() } /// Returns the compression level stored in the header. pub fn compression_level(&self) -> CompressionLevel { self.compression_level.clone() } fn from_lz77(lz77: &E) -> Self where E: lz77::Lz77Encode, { Header { compression_level: From::from(lz77.compression_level()), window_size: Lz77WindowSize::from_u16(lz77.window_size()), } } pub(crate) fn read_from(mut reader: R) -> io::Result where R: io::Read, { let mut buf = [0; 2]; reader.read_exact(&mut buf)?; let [cmf, flg] = buf; let check = (u16::from(cmf) << 8) + u16::from(flg); if check % 31 != 0 { return Err(invalid_data_error!( "Inconsistent ZLIB check bits: `CMF({}) * 256 + \ FLG({})` must be a multiple of 31", cmf, flg )); } let compression_method = cmf & 0b1111; let compression_info = cmf >> 4; if compression_method != COMPRESSION_METHOD_DEFLATE { return Err(invalid_data_error!( "Compression methods other than DEFLATE(8) are \ unsupported: method={}", compression_method )); } let window_size = Lz77WindowSize::from_u4(compression_info).ok_or_else(|| { invalid_data_error!("CINFO above 7 are not allowed: value={}", compression_info) })?; let dict_flag = (flg & 0b10_0000) != 0; if dict_flag { let mut buf = [0; 4]; reader.read_exact(&mut buf)?; return Err(invalid_data_error!( "Preset dictionaries are not supported: \ dictionary_id=0x{:X}", u32::from_be_bytes(buf) )); } let compression_level = CompressionLevel::from_u2(flg >> 6); Ok(Header { window_size, compression_level, }) } fn write_to(&self, mut writer: W) -> io::Result<()> where W: io::Write, { let cmf = (self.window_size.as_u4() << 4) | COMPRESSION_METHOD_DEFLATE; let mut flg = self.compression_level.as_u2() << 6; let check = (u16::from(cmf) << 8) + u16::from(flg); if check % 31 != 0 { flg += (31 - check % 31) as u8; } writer.write_all(&[cmf, flg])?; Ok(()) } } /// ZLIB decoder. #[derive(Debug)] pub struct Decoder { header: Header, reader: deflate::Decoder, adler32: checksum::Adler32, eos: bool, } impl Decoder where R: io::Read, { /// Makes a new decoder instance. /// /// `inner` is to be decoded ZLIB stream. /// /// # Examples /// ``` /// use core2::io::Read; /// use libflate::zlib::Decoder; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let mut decoder = Decoder::new(&encoded_data[..]).unwrap(); /// let mut buf = Vec::new(); /// decoder.read_to_end(&mut buf).unwrap(); /// /// assert_eq!(buf, b"Hello World!"); /// ``` pub fn new(mut inner: R) -> io::Result { let header = Header::read_from(&mut inner)?; Ok(Decoder { header, reader: deflate::Decoder::new(inner), adler32: checksum::Adler32::new(), eos: false, }) } /// Returns the header of the ZLIB stream. /// /// # Examples /// ``` /// use libflate::zlib::{Decoder, CompressionLevel}; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let decoder = Decoder::new(&encoded_data[..]).unwrap(); /// assert_eq!(decoder.header().compression_level(), /// CompressionLevel::Default); /// ``` pub fn header(&self) -> &Header { &self.header } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &R { self.reader.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut R { self.reader.as_inner_mut() } /// Unwraps this `Decoder`, returning the underlying reader. /// /// # Examples /// ``` /// use core2::io::Cursor; /// use libflate::zlib::Decoder; /// /// let encoded_data = [120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, /// 202, 73, 81, 4, 0, 28, 73, 4, 62]; /// /// let decoder = Decoder::new(Cursor::new(&encoded_data)).unwrap(); /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data); /// ``` pub fn into_inner(self) -> R { self.reader.into_inner() } /// Returns the data that has been decoded but has not yet been read. /// /// This method is useful to retrieve partial decoded data when the decoding process is failed. pub fn unread_decoded_data(&self) -> &[u8] { self.reader.unread_decoded_data() } } impl io::Read for Decoder where R: io::Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.eos { Ok(0) } else { let read_size = self.reader.read(buf)?; if read_size == 0 { if buf.is_empty() { return Ok(0); } self.eos = true; let mut buf = [0; 4]; self.reader.as_inner_mut().read_exact(&mut buf)?; let adler32 = u32::from_be_bytes(buf); // checksum verification is skipped during fuzzing // so that random data from fuzzer can reach actually interesting code // Compilation flag 'fuzzing' is automatically set by all 3 Rust fuzzers. if cfg!(not(fuzzing)) && adler32 != self.adler32.value() { Err(invalid_data_error!( "Adler32 checksum mismatched: value={}, expected={}", self.adler32.value(), adler32 )) } else { Ok(0) } } else { self.adler32.update(&buf[..read_size]); Ok(read_size) } } } } /// Options for a ZLIB encoder. #[derive(Debug)] pub struct EncodeOptions where E: lz77::Lz77Encode, { header: Header, options: deflate::EncodeOptions, flush_mode: FlushMode, } impl Default for EncodeOptions { fn default() -> Self { EncodeOptions { header: Header::from_lz77(&lz77::DefaultLz77Encoder::new()), options: Default::default(), flush_mode: FlushMode::None, } } } impl EncodeOptions { /// Makes a default instance. /// /// # Examples /// ``` /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn new() -> Self { Self::default() } } impl EncodeOptions where E: lz77::Lz77Encode, { /// Specifies the LZ77 encoder used to compress input data. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::with_lz77(DefaultLz77Encoder::new()); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn with_lz77(lz77: E) -> Self { EncodeOptions { header: Header::from_lz77(&lz77), options: deflate::EncodeOptions::with_lz77(lz77), flush_mode: FlushMode::None, } } /// Disables LZ77 compression. /// /// # Example /// ``` /// use libflate::lz77::DefaultLz77Encoder; /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().no_compression(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn no_compression(mut self) -> Self { self.options = self.options.no_compression(); self.header.compression_level = CompressionLevel::Fastest; self } /// Specifies the hint of the size of a DEFLATE block. /// /// The default value is `deflate::DEFAULT_BLOCK_SIZE`. /// /// # Example /// ``` /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().block_size(512 * 1024); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn block_size(mut self, size: usize) -> Self { self.options = self.options.block_size(size); self } /// Specifies to compress with fixed huffman codes. /// /// # Example /// ``` /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().fixed_huffman_codes(); /// let encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// ``` pub fn fixed_huffman_codes(mut self) -> Self { self.options = self.options.fixed_huffman_codes(); self } /// Specifies flush mode. pub fn flush_mode(mut self, mode: FlushMode) -> Self { self.flush_mode = mode; self } } /// ZLIB encoder. #[derive(Debug)] pub struct Encoder { header: Header, flush_mode: FlushMode, writer: deflate::Encoder, adler32: checksum::Adler32, } impl Encoder where W: io::Write, { /// Makes a new encoder instance. /// /// Encoded ZLIB stream is written to `inner`. /// /// # Examples /// ``` /// #[cfg(feature = "std")] /// use std::io::Write; /// #[cfg(not(feature = "std"))] /// use core2::io::Write; /// use libflate::zlib::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()).unwrap(); /// encoder.write_all(b"Hello World!").unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// vec![120, 156, 5, 192, 49, 13, 0, 0, 8, 3, 65, 43, 224, 6, 7, 24, 128, /// 237, 147, 38, 245, 63, 244, 230, 65, 181, 50, 215, 1, 28, 73, 4, 62]); /// ``` pub fn new(inner: W) -> io::Result { Self::with_options(inner, EncodeOptions::default()) } } impl Encoder where W: io::Write, E: lz77::Lz77Encode, { /// Makes a new encoder instance with specified options. /// /// Encoded ZLIB stream is written to `inner`. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::zlib::{Encoder, EncodeOptions}; /// /// let options = EncodeOptions::new().no_compression(); /// let mut encoder = Encoder::with_options(Vec::new(), options).unwrap(); /// encoder.write_all(b"Hello World!").unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// [120, 1, 1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, /// 114, 108, 100, 33, 28, 73, 4, 62]); /// ``` pub fn with_options(mut inner: W, options: EncodeOptions) -> io::Result { options.header.write_to(&mut inner)?; Ok(Encoder { header: options.header, flush_mode: options.flush_mode, writer: deflate::Encoder::with_options(inner, options.options), adler32: checksum::Adler32::new(), }) } /// Returns the header of the ZLIB stream. /// /// # Examples /// ``` /// use libflate::zlib::{Encoder, Lz77WindowSize}; /// /// let encoder = Encoder::new(Vec::new()).unwrap(); /// assert_eq!(encoder.header().window_size(), Lz77WindowSize::KB32); /// ``` pub fn header(&self) -> &Header { &self.header } /// Writes the ZLIB trailer and returns the inner stream. /// /// # Examples /// ``` /// use core2::io::Write; /// use libflate::zlib::Encoder; /// /// let mut encoder = Encoder::new(Vec::new()).unwrap(); /// encoder.write_all(b"Hello World!").unwrap(); /// /// assert_eq!(encoder.finish().into_result().unwrap(), /// vec![120, 156, 5, 192, 49, 13, 0, 0, 8, 3, 65, 43, 224, 6, 7, 24, 128, /// 237, 147, 38, 245, 63, 244, 230, 65, 181, 50, 215, 1, 28, 73, 4, 62]); /// ``` /// /// # Note /// /// If you are not concerned the result of this encoding, /// it may be convenient to use `AutoFinishUnchecked` instead of the explicit invocation of this method. /// /// ``` /// use core2::io::Write; /// use libflate::finish::AutoFinishUnchecked; /// use libflate::zlib::Encoder; /// /// let plain = b"Hello World!"; /// let mut buf = Vec::new(); /// let mut encoder = AutoFinishUnchecked::new(Encoder::new(&mut buf).unwrap()); /// encoder.write_all(plain.as_ref()).unwrap(); /// ``` pub fn finish(self) -> Finish { let mut inner = finish_try!(self.writer.finish()); match inner .write_all(&self.adler32.value().to_be_bytes()) .and_then(|_| inner.flush()) { Ok(_) => Finish::new(inner, None), Err(e) => Finish::new(inner, Some(e)), } } /// Returns the immutable reference to the inner stream. pub fn as_inner_ref(&self) -> &W { self.writer.as_inner_ref() } /// Returns the mutable reference to the inner stream. pub fn as_inner_mut(&mut self) -> &mut W { self.writer.as_inner_mut() } /// Unwraps the `Encoder`, returning the inner stream. pub fn into_inner(self) -> W { self.writer.into_inner() } } impl io::Write for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn write(&mut self, buf: &[u8]) -> io::Result { let written_size = self.writer.write(buf)?; self.adler32.update(&buf[..written_size]); Ok(written_size) } fn flush(&mut self) -> io::Result<()> { match self.flush_mode { FlushMode::None => self.writer.flush(), FlushMode::Sync => self.writer.zlib_sync_flush(), } } } impl Complete for Encoder where W: io::Write, E: lz77::Lz77Encode, { fn complete(self) -> io::Result<()> { self.finish().into_result().map(|_| ()) } } #[cfg(test)] mod tests { use super::*; use crate::finish::AutoFinish; use alloc::{borrow::ToOwned, string::ToString, vec, vec::Vec}; use core2::io::{Read as _, Write as _}; fn decode_all(buf: &[u8]) -> io::Result> { let mut decoder = Decoder::new(buf).unwrap(); let mut buf = Vec::with_capacity(buf.len()); decoder.read_to_end(&mut buf)?; Ok(buf) } fn default_encode(buf: &[u8]) -> io::Result> { let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(buf).unwrap(); encoder.finish().into_result() } macro_rules! assert_encode_decode { ($input:expr) => {{ let encoded = default_encode(&$input[..]).unwrap(); assert_eq!(decode_all(&encoded).unwrap(), &$input[..]); }}; } const DECODE_WORKS_TESTDATA: [u8; 20] = [ 120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0, 28, 73, 4, 62, ]; #[test] fn decode_works() { let encoded = DECODE_WORKS_TESTDATA; let mut decoder = Decoder::new(&encoded[..]).unwrap(); assert_eq!( *decoder.header(), Header { window_size: Lz77WindowSize::KB32, compression_level: CompressionLevel::Default, } ); let mut buf = Vec::new(); decoder.read_to_end(&mut buf).unwrap(); let expected = b"Hello World!"; assert_eq!(buf, expected); } #[test] fn default_encode_works() { let plain = b"Hello World! Hello ZLIB!!"; let mut encoder = Encoder::new(Vec::new()).unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode_all(&encoded).unwrap(), plain); } #[test] fn best_speed_encode_works() { let plain = b"Hello World! Hello ZLIB!!"; let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::default().fixed_huffman_codes()) .unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); assert_eq!(decode_all(&encoded).unwrap(), plain); } const RAW_ENCODE_WORKS_EXPECTED: [u8; 23] = [ 120, 1, 1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 28, 73, 4, 62, ]; #[test] fn raw_encode_works() { let plain = b"Hello World!"; let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()).unwrap(); encoder.write_all(plain.as_ref()).unwrap(); let encoded = encoder.finish().into_result().unwrap(); let expected = RAW_ENCODE_WORKS_EXPECTED; assert_eq!(encoded, expected); assert_eq!(decode_all(&encoded).unwrap(), plain); } #[test] fn encoder_auto_finish_works() { let plain = b"Hello World! Hello ZLIB!!"; let mut buf = Vec::new(); { let mut encoder = AutoFinish::new(Encoder::new(&mut buf).unwrap()); encoder.write_all(plain.as_ref()).unwrap(); } assert_eq!(decode_all(&buf).unwrap(), plain); } #[test] fn test_issue_2() { // See: https://github.com/sile/libflate/issues/2 assert_encode_decode!([ 163, 181, 167, 40, 62, 239, 41, 125, 189, 217, 61, 122, 20, 136, 160, 178, 119, 217, 217, 41, 125, 189, 97, 195, 101, 47, 170, ]); assert_encode_decode!([ 162, 58, 99, 211, 7, 64, 96, 36, 57, 155, 53, 166, 76, 14, 238, 66, 66, 148, 154, 124, 162, 58, 99, 188, 138, 131, 171, 189, 54, 229, 192, 38, 29, 240, 122, 28, ]); assert_encode_decode!([ 239, 238, 212, 42, 5, 46, 186, 67, 122, 247, 30, 61, 219, 62, 228, 202, 164, 205, 139, 109, 99, 181, 99, 181, 99, 122, 30, 12, 62, 46, 27, 145, 241, 183, 137, ]); assert_encode_decode!([ 88, 202, 64, 12, 125, 108, 153, 49, 164, 250, 71, 19, 4, 108, 111, 108, 237, 205, 208, 77, 217, 100, 118, 49, 10, 64, 12, 125, 51, 202, 69, 67, 181, 146, 86, ]); } #[test] fn test_issues_16() { // See: https://github.com/sile/libflate/issues/16 let encoded = include_bytes!("../data/issues_16/crash-1bb6d408475a5bd57247ee40f290830adfe2086e"); assert_eq!( &decode_all(&encoded[..]) .err() .map(|e| e.to_string()) .unwrap()[..31], "The value of HDIST is too big: max=30, actual=32"[..31] .to_owned() .as_str() ); let encoded = include_bytes!("../data/issues_16/crash-369e8509a0e76356f4549c292ceedee429cfe125"); assert_eq!( &decode_all(&encoded[..]) .err() .map(|e| e.to_string()) .unwrap()[..31], "The value of HDIST is too big: max=30, actual=32"[..31] .to_owned() .as_str() ); let encoded = include_bytes!("../data/issues_16/crash-e75959d935650306881140df7f6d1d73e33425cb"); assert_eq!( &decode_all(&encoded[..]) .err() .map(|e| e.to_string()) .unwrap()[..31], "The value of HDIST is too big: max=30, actual=32"[..31] .to_owned() .as_str() ); } #[test] fn test_issues_27() { // See: https://github.com/sile/libflate/issues/27 let writes = ["fooooooooooooooooo", "bar", "baz"]; // FlushMode::None let mut encoder = Encoder::new(Vec::new()).unwrap(); for _ in 0..2 { for string in &writes { encoder.write(string.as_bytes()).expect("Write failed"); } encoder.flush().expect("Flush failed"); } let finished = encoder.finish().unwrap(); let expected = vec![ 120, 156, // header 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162, 227, 2, 14, 141, 0, 0, 0, 8, 0, 206, 74, 80, 221, 137, 166, 215, 189, 252, 136, 16, 93, 1, 112, 32, 0, 0, 0, 0, 0, 228, 255, 26, 246, 95, 20, 111, ]; assert_eq!(finished.0, expected); let mut output = Vec::new(); Decoder::new(&finished.0[..]) .unwrap() .read_to_end(&mut output) .unwrap(); assert_eq!( output, "fooooooooooooooooobarbazfooooooooooooooooobarbaz".as_bytes() ); // FlushMode::Sync let mut encoder = Encoder::with_options(Vec::new(), EncodeOptions::new().flush_mode(FlushMode::Sync)) .unwrap(); for _ in 0..2 { for string in &writes { encoder.write(string.as_bytes()).expect("Write failed"); } encoder.flush().expect("Flush failed"); } let finished = encoder.finish().unwrap(); let expected = vec![ 120, 156, // header 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162, 3, 0, 0, 255, 255, // sync bytes 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162, 3, 0, 0, 255, 255, // sync bytes 5, 192, 129, 0, 0, 0, 0, 0, 144, 255, 107, 0, 246, 95, 20, 111, ]; assert_eq!(finished.0, expected); let mut output = Vec::new(); Decoder::new(&finished.0[..]) .unwrap() .read_to_end(&mut output) .unwrap(); assert_eq!( output, "fooooooooooooooooobarbazfooooooooooooooooobarbaz".as_bytes() ); } #[test] #[cfg(feature = "std")] /// See: https://github.com/sile/libflate/issues/61 fn issue_61() { let data = default_encode(b"Hello World").unwrap(); let mut decoder = Decoder::new(&data[..]).unwrap(); let mut buf = Vec::new(); decoder.read(&mut buf).unwrap(); decoder.read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"Hello World"); } #[test] fn issue71() { let encoded_data = [ 120, 218, 251, 255, 207, 144, 193, 138, 193, 151, 161, 146, 33, 143, 33, 149, 161, 156, 161, 24, 72, 38, 51, 148, 48, 100, 50, 228, 3, 69, 120, 25, 184, 24, ]; let mut decoder = Decoder::new(&encoded_data[..]).unwrap(); let mut buf = Vec::new(); let result = decoder.read_to_end(&mut buf); assert!(result.is_err()); buf.extend_from_slice(decoder.unread_decoded_data()); let decoded_data = [ 255, 254, 49, 0, 58, 0, 77, 0, 121, 0, 110, 0, 101, 0, 119, 0, 115, 0, 101, 0, 99, 0, 116, 0, 105, 0, 111, 0, 110, 0, 13, 0, 10, ]; assert_eq!(buf, decoded_data); } }