Showing preview only (586K chars total). Download the full file or copy to clipboard to get everything.
Repository: gyscos/zstd-rs
Branch: main
Commit: a9bbf0a981c0
Files: 82
Total size: 558.6 KB
Directory structure:
gitextract_z1p3b8qn/
├── .gitattributes
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── linux.yml
│ ├── macos.yml
│ ├── wasm.yml
│ └── windows.yml
├── .gitignore
├── .gitmodules
├── Cargo.toml
├── LICENSE
├── Readme.md
├── assets/
│ ├── example.txt
│ ├── example.txt.v5.zst
│ ├── example.txt.v6.zst
│ ├── example.txt.v7.zst
│ ├── example.txt.v8.zst
│ └── example.txt.zst
├── examples/
│ ├── basic.rs
│ ├── benchmark.rs
│ ├── stream.rs
│ ├── train.rs
│ ├── zstd.rs
│ └── zstdcat.rs
├── rustfmt.toml
├── src/
│ ├── bulk/
│ │ ├── compressor.rs
│ │ ├── decompressor.rs
│ │ ├── mod.rs
│ │ └── tests.rs
│ ├── dict.rs
│ ├── lib.rs
│ └── stream/
│ ├── functions.rs
│ ├── mod.rs
│ ├── raw.rs
│ ├── read/
│ │ ├── mod.rs
│ │ └── tests.rs
│ ├── tests.rs
│ ├── write/
│ │ ├── mod.rs
│ │ └── tests.rs
│ └── zio/
│ ├── mod.rs
│ ├── reader.rs
│ └── writer.rs
├── tests/
│ └── issue_182.rs
└── zstd-safe/
├── Cargo.toml
├── LICENSE
├── Readme.md
├── build.rs
├── fuzz/
│ ├── .gitignore
│ ├── Cargo.toml
│ └── fuzz_targets/
│ └── zstd_fuzzer.rs
├── src/
│ ├── constants.rs
│ ├── constants_experimental.rs
│ ├── constants_seekable.rs
│ ├── lib.rs
│ ├── seekable.rs
│ └── tests.rs
├── update_consts.sh
└── zstd-sys/
├── Cargo.toml
├── LICENSE
├── LICENSE.BSD-3-Clause
├── Readme.md
├── build.rs
├── examples/
│ └── it_work.rs
├── src/
│ ├── bindings_zdict.rs
│ ├── bindings_zdict_experimental.rs
│ ├── bindings_zdict_std_experimental.rs
│ ├── bindings_zstd.rs
│ ├── bindings_zstd_experimental.rs
│ ├── bindings_zstd_seekable.rs
│ ├── bindings_zstd_std_experimental.rs
│ ├── lib.rs
│ └── wasm_shim.rs
├── test_it.sh
├── update_bindings.sh
├── update_zstd.sh
├── wasm-shim/
│ ├── assert.h
│ ├── stdio.h
│ ├── stdlib.h
│ ├── string.h
│ └── time.h
├── zdict.h
├── zstd.h
└── zstd_seekable.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
/assets/* -text -crlf
================================================
FILE: .github/dependabot.yml
================================================
# Dependabot dependency version checks / updates
version: 2
updates:
- package-ecosystem: "github-actions"
# Workflow files stored in the
# default location of `.github/workflows`
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/zstd-safe"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/zstd-safe/zstd-sys"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/linux.yml
================================================
name: Linux
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Build with feature thin
run: cargo build --verbose --features thin
- name: Run tests
run: cargo test --verbose --features thin
- name: Build zstd-safe with feature seekable
run: cargo build --manifest-path zstd-safe/Cargo.toml --verbose --features seekable
- name: Run zstd-safe tests with feature seekable
run: cargo test --manifest-path zstd-safe/Cargo.toml --verbose --features seekable
- name: Build zstd-safe with features std and seekable
run: cargo build --manifest-path zstd-safe/Cargo.toml --verbose --features std,seekable
- name: Run zstd-safe tests with features std and seekable
run: cargo test --manifest-path zstd-safe/Cargo.toml --verbose --features std,seekable
================================================
FILE: .github/workflows/macos.yml
================================================
name: macOS
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
================================================
FILE: .github/workflows/wasm.yml
================================================
name: Wasm
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: self-hosted
steps:
- name: Wasm target
run: rustup target add wasm32-unknown-unknown
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Build
run: cargo build --verbose --target wasm32-unknown-unknown
- name: Build with feature thin
run: cargo build --verbose --features thin --target wasm32-unknown-unknown
================================================
FILE: .github/workflows/windows.yml
================================================
name: Windows
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
strategy:
matrix:
target:
#- i686-pc-windows-gnu
- i686-pc-windows-msvc
#- x86_64-pc-windows-gnu
- x86_64-pc-windows-msvc
channel: [ stable ]
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: setup
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.channel }}-${{ matrix.target }}
targets: ${{ matrix.target }}
- name: Add mingw32 to path for i686-gnu
run: |
echo "C:\msys64\mingw32\bin" >> $GITHUB_PATH
echo "C:\msys64\usr\bin" >> $GITHUB_PATH
if: matrix.target == 'i686-pc-windows-gnu'
shell: bash
- name: Add mingw64 to path for x86_64-gnu
run: |
echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH
echo "C:\msys64\usr\bin" >> $GITHUB_PATH
if: matrix.target == 'x86_64-pc-windows-gnu'
shell: bash
- name: Update gcc
if: matrix.target == 'x86_64-pc-windows-gnu'
run: pacman.exe -Sy --noconfirm mingw-w64-x86_64-toolchain
- name: Update gcc
if: matrix.target == 'i686-pc-windows-gnu'
run: pacman.exe -Sy --noconfirm mingw-w64-i686-toolchain
- name: Build
run: cargo build --verbose --verbose
- name: Run tests
run: cargo test --verbose
================================================
FILE: .gitignore
================================================
target
Cargo.lock
/silesia
/silesia.zip
================================================
FILE: .gitmodules
================================================
[submodule "zstd-safe/zstd-sys/zstd"]
path = zstd-safe/zstd-sys/zstd
url = https://github.com/facebook/zstd
================================================
FILE: Cargo.toml
================================================
[package]
authors = ["Alexandre Bury <alexandre.bury@gmail.com>"]
description = "Binding for the zstd compression library."
documentation = "https://docs.rs/zstd"
keywords = ["zstd", "zstandard", "compression"]
categories = ["compression", "api-bindings"]
license = "BSD-3-Clause"
name = "zstd"
repository = "https://github.com/gyscos/zstd-rs"
version = "0.13.3"
exclude = ["assets/*.zst", "/.github"]
readme = "Readme.md"
edition = "2018"
rust-version = "1.64"
[package.metadata.docs.rs]
features = ["experimental", "zstdmt", "zdict_builder", "doc-cfg"]
[badges]
travis-ci = { repository = "gyscos/zstd-rs" }
[dependencies]
zstd-safe = { path = "zstd-safe", version = "7.1.0", default-features = false, features = ["std"] }
[dev-dependencies]
clap = {version = "4.0", features=["derive"]}
humansize = "2.0"
partial-io = "0.5"
walkdir = "2.2"
[features]
default = ["legacy", "arrays", "zdict_builder"]
bindgen = ["zstd-safe/bindgen"]
debug = ["zstd-safe/debug"]
legacy = ["zstd-safe/legacy"]
pkg-config = ["zstd-safe/pkg-config"]
wasm = []
zstdmt = ["zstd-safe/zstdmt"]
experimental = ["zstd-safe/experimental"]
thin = ["zstd-safe/thin"]
arrays = ["zstd-safe/arrays"]
no_asm = ["zstd-safe/no_asm"]
doc-cfg = []
zdict_builder = ["zstd-safe/zdict_builder"]
# These two are for cross-language LTO.
# Will only work if `clang` is used to build the C library.
fat-lto = ["zstd-safe/fat-lto"]
thin-lto = ["zstd-safe/thin-lto"]
[[example]]
name = "train"
required-features = ["zdict_builder"]
================================================
FILE: LICENSE
================================================
BSD 3-Clause License
Copyright (c) 2026, Alexandre Bury
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: Readme.md
================================================
# zstd
[](https://crates.io/crates/zstd)
[](./LICENSE)
[](https://github.com/gyscos/zstd-rs/actions/workflows/linux.yml)
[](https://github.com/gyscos/zstd-rs/actions/workflows/windows.yml)
[](https://github.com/gyscos/zstd-rs/actions/workflows/macos.yml)
[](https://github.com/gyscos/zstd-rs/actions/workflows/wasm.yml)
This library is a rust binding for the [zstd compression library][zstd].
# [Documentation][doc]
## 1 - Add to `cargo.toml`
```bash
$ cargo add zstd
```
```toml
# Cargo.toml
[dependencies]
zstd = "0.13"
```
## 2 - Usage
This library provides `Read` and `Write` wrappers to handle (de)compression,
along with convenience functions to made common tasks easier.
For instance, `stream::copy_encode` and `stream::copy_decode` are easy-to-use
wrappers around `std::io::copy`. Check the [stream] example:
```rust
use std::io;
// This function use the convenient `copy_encode` method
fn compress(level: i32) {
zstd::stream::copy_encode(io::stdin(), io::stdout(), level).unwrap();
}
// This function does the same thing, directly using an `Encoder`:
fn compress_manually(level: i32) {
let mut encoder = zstd::stream::Encoder::new(io::stdout(), level).unwrap();
io::copy(&mut io::stdin(), &mut encoder).unwrap();
encoder.finish().unwrap();
}
fn decompress() {
zstd::stream::copy_decode(io::stdin(), io::stdout()).unwrap();
}
```
# Asynchronous support
The [`async-compression`](https://github.com/Nemo157/async-compression/) crate
provides an async-ready integration of various compression algorithms,
including `zstd-rs`.
# Compile it yourself
`zstd` is included as a submodule. To get everything during your clone, use:
```
git clone https://github.com/gyscos/zstd-rs --recursive
```
Or, if you cloned it without the `--recursive` flag,
call this from inside the repository:
```
git submodule update --init
```
Then, running `cargo build` should take care
of building the C library and linking to it.
# Build-time bindgen
This library includes a pre-generated `bindings.rs` file.
You can also generate new bindings at build-time, using the `bindgen` feature:
```
cargo build --features bindgen
```
# TODO
* Benchmarks, optimizations, ...
# Disclaimer
This implementation is largely inspired by bozaro's [lz4-rs].
# License
* The zstd C library is under a dual BSD/GPLv2 license.
* This zstd-rs binding library is under a [BSD-3-Clause](LICENSE) license.
[zstd]: https://github.com/facebook/zstd
[lz4-rs]: https://github.com/bozaro/lz4-rs
[cargo-edit]: https://github.com/killercup/cargo-edit#cargo-add
[doc]: https://docs.rs/zstd
[stream]: examples/stream.rs
[submodule]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
================================================
FILE: assets/example.txt
================================================
’Twas brillig, and the slithy toves
Did gyre and gimble in the wade;
All mimsy were the borogoves,
And the mome raths outgrabe.
"Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jubjub bird, and shun
The frumious Bandersnatch!"
He took his vorpal sword in hand:
Long time the manxome foe he sought—
So rested he by the Tumtum tree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wood,
And burbled as it came!
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
"And hast thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Callooh! Callay!"
He chortled in his joy.
’Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
================================================
FILE: examples/basic.rs
================================================
fn main() {
let some_content = "Something";
let compression_level = 3;
// Compress some text
let compressed =
zstd::encode_all(some_content.as_bytes(), compression_level).unwrap();
// Now uncompress it
let decoded: Vec<u8> = zstd::decode_all(compressed.as_slice()).unwrap();
// Convert it to text
let decoded_text = std::str::from_utf8(&decoded).unwrap();
assert_eq!(some_content, decoded_text);
}
================================================
FILE: examples/benchmark.rs
================================================
use clap::Parser;
use humansize::{format_size, DECIMAL};
use std::io::Read;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about=None)]
struct Args {
/// Directory containing the data to compress.
/// To use the silesia corpus, run the following commands:
///
/// ```
/// wget http://sun.aei.polsl.pl/~sdeor/corpus/silesia.zip
/// unzip silesia.zip -d silesia/
/// cargo run --example benchmark -- silesia/",
/// ```
dir: PathBuf,
/// First compression level to test.
#[arg(short, long)]
begin: i32,
/// Last compression level to test.
#[arg(short, long)]
end: i32,
}
fn main() {
let args = Args::parse();
// Step 1: load data in memory
let files: Vec<Vec<u8>> = std::fs::read_dir(args.dir)
.unwrap()
.map(|file| {
let file = file.unwrap();
let mut content = Vec::new();
std::fs::File::open(file.path())
.unwrap()
.read_to_end(&mut content)
.unwrap();
content
})
.collect();
let total_size: usize = files.iter().map(|data| data.len()).sum();
// Step 3: compress data
// Print tsv headers
println!(
"{}\t{}\t{}\t{}",
"Compression level",
"Compression ratio",
"Compression speed",
"Decompression speed"
);
for level in args.begin..args.end {
// Compress each sample sequentially.
let start = std::time::Instant::now();
let compressed: Vec<Vec<u8>> = files
.iter()
.map(|data| zstd::encode_all(&data[..], level).unwrap())
.collect();
let mid = std::time::Instant::now();
let uncompressed: Vec<Vec<u8>> = compressed
.iter()
.map(|data| zstd::decode_all(&data[..]).unwrap())
.collect();
let end = std::time::Instant::now();
for (original, processed) in files.iter().zip(uncompressed.iter()) {
assert_eq!(&original[..], &processed[..]);
}
let compress_time = mid - start;
let decompress_time = end - mid;
let compress_seconds = compress_time.as_secs() as f64
+ compress_time.subsec_nanos() as f64 * 1e-9;
let decompress_seconds = decompress_time.as_secs() as f64
+ decompress_time.subsec_nanos() as f64 * 1e-9;
let compressed_size: usize = compressed.iter().map(Vec::len).sum();
let speed = (total_size as f64 / compress_seconds) as usize;
let speed = format_size(speed, DECIMAL);
let d_speed = (total_size as f64 / decompress_seconds) as usize;
let d_speed = format_size(d_speed, DECIMAL);
let ratio = compressed_size as f64 / total_size as f64;
println!("{}\t{:.3}\t{}/s\t{}/s", level, 1.0 / ratio, speed, d_speed);
}
}
================================================
FILE: examples/stream.rs
================================================
use std::env;
use std::io::{self, Write};
use std::str::FromStr;
fn main() {
match env::args().nth(1) {
None => {
writeln!(
&mut io::stderr(),
"Invalid option. Usage: `stream [-d|-1..-22]`"
)
.unwrap();
}
Some(ref option) if option == "-d" => decompress(),
Some(ref option) => {
if option.starts_with('-') {
let level = match i32::from_str(&option[1..]) {
Ok(level) => level,
Err(e) => panic!("Error parsing compression level: {}", e),
};
compress(level);
} else {
writeln!(
&mut io::stderr(),
"Invalid option. Usage: `stream [-d|-1..-22]`"
)
.unwrap();
}
}
}
}
fn compress(level: i32) {
zstd::stream::copy_encode(io::stdin(), io::stdout(), level).unwrap();
}
fn decompress() {
zstd::stream::copy_decode(io::stdin(), io::stdout()).unwrap();
}
================================================
FILE: examples/train.rs
================================================
use clap::Parser;
use std::io;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about=None)]
/// This program trains a dictionary from one or more files,
/// to make future compression of similar small files more efficient.
///
/// The dictionary will need to be present during decompression,
/// but if you need to compress many small files individually,
/// it may be worth the trouble.
struct Args {
/// Maximum dictionary size in bytes.
#[arg(short, long)]
max_size: usize,
/// Files to use as input.
files: Vec<PathBuf>,
}
fn main() {
let args = Args::parse();
let dict = zstd::dict::from_files(&args.files, args.max_size).unwrap();
let mut dict_reader: &[u8] = &dict;
io::copy(&mut dict_reader, &mut io::stdout()).unwrap();
}
================================================
FILE: examples/zstd.rs
================================================
use zstd;
use std::env;
use std::fs;
use std::io;
const SUFFIX: &'static str = ".zst";
fn main() {
for arg in env::args().skip(1) {
if arg.ends_with(SUFFIX) {
match decompress(&arg) {
Ok(()) => println!("Decompressed {}", arg),
Err(e) => println!("Error decompressing {}: {}", arg, e),
}
} else {
match compress(&arg) {
Ok(()) => println!("Compressed {}", arg),
Err(e) => println!("Error compressing {}: {}", arg, e),
}
}
}
}
fn compress(source: &str) -> io::Result<()> {
let mut file = fs::File::open(source)?;
let mut encoder = {
let target = fs::File::create(source.to_string() + SUFFIX)?;
zstd::Encoder::new(target, 1)?
};
io::copy(&mut file, &mut encoder)?;
encoder.finish()?;
Ok(())
}
fn decompress(source: &str) -> io::Result<()> {
let mut decoder = {
let file = fs::File::open(source)?;
zstd::Decoder::new(file)?
};
let mut target = fs::File::create(source.trim_end_matches(SUFFIX))?;
io::copy(&mut decoder, &mut target)?;
Ok(())
}
================================================
FILE: examples/zstdcat.rs
================================================
use clap::Parser;
use std::fs;
use std::io;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about=None)]
struct Args {
/// Files to decompress. With no file, or when given -, read standard input.
file: Vec<String>,
}
fn main() {
// This will be a simple application:
// takes a single (repeatable and optional) argument.
let args = Args::parse();
// If nothing was given, act as if `-` was there.
if args.file.is_empty() {
decompress_file("-").unwrap();
} else {
for file in &args.file {
decompress_file(file).unwrap();
}
}
}
// Dispatch the source reader depending on the filename
fn decompress_file(file: &str) -> io::Result<()> {
match file {
"-" => decompress_from(io::stdin()),
other => decompress_from(io::BufReader::new(fs::File::open(other)?)),
}
}
// Decompress from a `Reader` into stdout
fn decompress_from<R: io::Read>(r: R) -> io::Result<()> {
let mut decoder = zstd::Decoder::new(r)?;
io::copy(&mut decoder, &mut io::stdout())?;
Ok(())
}
================================================
FILE: rustfmt.toml
================================================
max_width = 79
reorder_imports = true
use_try_shorthand = true
================================================
FILE: src/bulk/compressor.rs
================================================
use crate::map_error_code;
use std::io;
use zstd_safe;
/// Allows to compress independently multiple chunks of data.
///
/// Each job will be processed entirely in-memory without streaming, so this
/// is most fitting for many small jobs. To compress larger volume that don't
/// easily fit in memory, a streaming compression may be more appropriate.
///
/// It is more efficient than a streaming compressor for 2 reasons:
/// * It re-uses the zstd context between jobs to avoid re-allocations
/// * It avoids copying data from a `Read` into a temporary buffer before compression.
#[derive(Default)]
pub struct Compressor<'a> {
context: zstd_safe::CCtx<'a>,
}
impl Compressor<'static> {
/// Creates a new zstd compressor
pub fn new(level: i32) -> io::Result<Self> {
Self::with_dictionary(level, &[])
}
/// Creates a new zstd compressor, using the given dictionary.
///
/// Note that using a dictionary means that decompression will need to use
/// the same dictionary.
pub fn with_dictionary(level: i32, dictionary: &[u8]) -> io::Result<Self> {
let mut compressor = Self::default();
compressor.set_dictionary(level, dictionary)?;
Ok(compressor)
}
}
impl<'a> Compressor<'a> {
/// Creates a new compressor using an existing `EncoderDictionary`.
///
/// The compression level will be the one specified when creating the dictionary.
///
/// Note that using a dictionary means that decompression will need to use
/// the same dictionary.
pub fn with_prepared_dictionary<'b>(
dictionary: &'a crate::dict::EncoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let mut compressor = Self::default();
compressor.set_prepared_dictionary(dictionary)?;
Ok(compressor)
}
/// Changes the compression level used by this compressor.
///
/// *This will clear any dictionary previously registered.*
///
/// If you want to keep the existing dictionary, you will need to pass it again to
/// `Self::set_dictionary` instead of using this method.
pub fn set_compression_level(&mut self, level: i32) -> io::Result<()> {
self.set_dictionary(level, &[])
}
/// Changes the dictionary and compression level used by this compressor.
///
/// Will affect future compression jobs.
///
/// Note that using a dictionary means that decompression will need to use
/// the same dictionary.
pub fn set_dictionary(
&mut self,
level: i32,
dictionary: &[u8],
) -> io::Result<()> {
self.context
.set_parameter(zstd_safe::CParameter::CompressionLevel(level))
.map_err(map_error_code)?;
self.context
.load_dictionary(dictionary)
.map_err(map_error_code)?;
Ok(())
}
/// Changes the dictionary used by this compressor.
///
/// The compression level used when preparing the dictionary will be used.
///
/// Note that using a dictionary means that decompression will need to use
/// the same dictionary.
pub fn set_prepared_dictionary<'b>(
&mut self,
dictionary: &'a crate::dict::EncoderDictionary<'b>,
) -> io::Result<()>
where
'b: 'a,
{
self.context
.ref_cdict(dictionary.as_cdict())
.map_err(map_error_code)?;
Ok(())
}
/// Compress a single block of data to the given destination buffer.
///
/// Returns the number of bytes written, or an error if something happened
/// (for instance if the destination buffer was too small).
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn compress_to_buffer<C: zstd_safe::WriteBuf + ?Sized>(
&mut self,
source: &[u8],
destination: &mut C,
) -> io::Result<usize> {
self.context
.compress2(destination, source)
.map_err(map_error_code)
}
/// Compresses a block of data and returns the compressed result.
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn compress(&mut self, data: &[u8]) -> io::Result<Vec<u8>> {
// We allocate a big buffer, slightly larger than the input data.
let buffer_len = zstd_safe::compress_bound(data.len());
let mut buffer = Vec::with_capacity(buffer_len);
self.compress_to_buffer(data, &mut buffer)?;
// Should we shrink the vec? Meh, let the user do it if he wants.
Ok(buffer)
}
/// Gives mutable access to the internal context.
pub fn context_mut(&mut self) -> &mut zstd_safe::CCtx<'a> {
&mut self.context
}
/// Sets a compression parameter for this compressor.
pub fn set_parameter(
&mut self,
parameter: zstd_safe::CParameter,
) -> io::Result<()> {
self.context
.set_parameter(parameter)
.map_err(map_error_code)?;
Ok(())
}
/// Sets the expected size of the input.
///
/// This affects the compression effectiveness.
///
/// It is an error to give an incorrect size (an error will be returned when closing the
/// stream if the size does not match what was pledged).
///
/// Giving a `None` size means the size is unknown (this is the default).
pub fn set_pledged_src_size(
&mut self,
size: Option<u64>,
) -> io::Result<()> {
self.context
.set_pledged_src_size(size)
.map_err(map_error_code)?;
Ok(())
}
crate::encoder_parameters!();
}
fn _assert_traits() {
fn _assert_send<T: Send>(_: T) {}
_assert_send(Compressor::new(0));
}
================================================
FILE: src/bulk/decompressor.rs
================================================
use crate::map_error_code;
#[cfg(feature = "experimental")]
use std::convert::TryInto;
use std::io;
use zstd_safe;
/// Allows to decompress independently multiple blocks of data.
///
/// This reduces memory usage compared to calling `decompress` multiple times.
#[derive(Default)]
pub struct Decompressor<'a> {
context: zstd_safe::DCtx<'a>,
}
impl Decompressor<'static> {
/// Creates a new zstd decompressor.
pub fn new() -> io::Result<Self> {
Self::with_dictionary(&[])
}
/// Creates a new zstd decompressor, using the given dictionary.
pub fn with_dictionary(dictionary: &[u8]) -> io::Result<Self> {
let mut decompressor = Self::default();
decompressor.set_dictionary(dictionary)?;
Ok(decompressor)
}
}
impl<'a> Decompressor<'a> {
/// Creates a new decompressor using an existing `DecoderDictionary`.
///
/// Note that using a dictionary means that compression will need to use
/// the same dictionary.
pub fn with_prepared_dictionary<'b>(
dictionary: &'a crate::dict::DecoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let mut decompressor = Self::default();
decompressor.set_prepared_dictionary(dictionary)?;
Ok(decompressor)
}
/// Changes the dictionary used by this decompressor.
///
/// Will affect future compression jobs.
///
/// Note that using a dictionary means that compression will need to use
/// the same dictionary.
pub fn set_dictionary(&mut self, dictionary: &[u8]) -> io::Result<()> {
self.context
.load_dictionary(dictionary)
.map_err(map_error_code)?;
Ok(())
}
/// Changes the dictionary used by this decompressor.
///
/// Note that using a dictionary means that compression will need to use
/// the same dictionary.
pub fn set_prepared_dictionary<'b>(
&mut self,
dictionary: &'a crate::dict::DecoderDictionary<'b>,
) -> io::Result<()>
where
'b: 'a,
{
self.context
.ref_ddict(dictionary.as_ddict())
.map_err(map_error_code)?;
Ok(())
}
/// Deompress a single block of data to the given destination buffer.
///
/// Returns the number of bytes written, or an error if something happened
/// (for instance if the destination buffer was too small).
pub fn decompress_to_buffer<C: zstd_safe::WriteBuf + ?Sized>(
&mut self,
source: &[u8],
destination: &mut C,
) -> io::Result<usize> {
self.context
.decompress(destination, source)
.map_err(map_error_code)
}
/// Decompress a block of data, and return the result in a `Vec<u8>`.
///
/// The decompressed data should be at most `capacity` bytes,
/// or an error will be returned.
pub fn decompress(
&mut self,
data: &[u8],
capacity: usize,
) -> io::Result<Vec<u8>> {
let capacity =
Self::upper_bound(data).unwrap_or(capacity).min(capacity);
let mut buffer = Vec::with_capacity(capacity);
self.decompress_to_buffer(data, &mut buffer)?;
Ok(buffer)
}
/// Sets a decompression parameter for this decompressor.
pub fn set_parameter(
&mut self,
parameter: zstd_safe::DParameter,
) -> io::Result<()> {
self.context
.set_parameter(parameter)
.map_err(map_error_code)?;
Ok(())
}
crate::decoder_parameters!();
/// Get an upper bound on the decompressed size of data, if available
///
/// This can be used to pre-allocate enough capacity for `decompress_to_buffer`
/// and is used by `decompress` to ensure that it does not over-allocate if
/// you supply a large `capacity`.
///
/// Will return `None` if the upper bound cannot be determined or is larger than `usize::MAX`
///
/// Note that unless the `experimental` feature is enabled, this will always return `None`.
pub fn upper_bound(_data: &[u8]) -> Option<usize> {
#[cfg(feature = "experimental")]
{
let bound = zstd_safe::decompress_bound(_data).ok()?;
bound.try_into().ok()
}
#[cfg(not(feature = "experimental"))]
{
None
}
}
}
fn _assert_traits() {
fn _assert_send<T: Send>(_: T) {}
_assert_send(Decompressor::new());
}
================================================
FILE: src/bulk/mod.rs
================================================
//! Compress and decompress data in bulk.
//!
//! These methods process all the input data at once.
//! It is therefore best used with relatively small blocks
//! (like small network packets).
mod compressor;
mod decompressor;
#[cfg(test)]
mod tests;
pub use self::compressor::Compressor;
pub use self::decompressor::Decompressor;
use std::io;
/// Compresses a single block of data to the given destination buffer.
///
/// Returns the number of bytes written, or an error if something happened
/// (for instance if the destination buffer was too small).
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn compress_to_buffer(
source: &[u8],
destination: &mut [u8],
level: i32,
) -> io::Result<usize> {
Compressor::new(level)?.compress_to_buffer(source, destination)
}
/// Compresses a block of data and returns the compressed result.
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn compress(data: &[u8], level: i32) -> io::Result<Vec<u8>> {
Compressor::new(level)?.compress(data)
}
/// Deompress a single block of data to the given destination buffer.
///
/// Returns the number of bytes written, or an error if something happened
/// (for instance if the destination buffer was too small).
pub fn decompress_to_buffer(
source: &[u8],
destination: &mut [u8],
) -> io::Result<usize> {
Decompressor::new()?.decompress_to_buffer(source, destination)
}
/// Decompresses a block of data and returns the decompressed result.
///
/// The decompressed data should be at most `capacity` bytes,
/// or an error will be returned.
pub fn decompress(data: &[u8], capacity: usize) -> io::Result<Vec<u8>> {
Decompressor::new()?.decompress(data, capacity)
}
================================================
FILE: src/bulk/tests.rs
================================================
use super::{compress, decompress};
const TEXT: &str = include_str!("../../assets/example.txt");
#[test]
fn test_direct() {
// Can we include_str!("assets/example.txt")?
// It's excluded from the packaging step, so maybe not.
crate::test_cycle_unwrap(
TEXT.as_bytes(),
|data| compress(data, 1),
|data| decompress(data, TEXT.len()),
);
}
#[test]
fn test_stream_compat() {
// We can bulk-compress and stream-decode
crate::test_cycle_unwrap(
TEXT.as_bytes(),
|data| compress(data, 1),
|data| crate::decode_all(data),
);
// We can stream-encode and bulk-decompress
crate::test_cycle_unwrap(
TEXT.as_bytes(),
|data| crate::encode_all(data, 1),
|data| decompress(data, TEXT.len()),
);
}
#[test]
fn has_content_size() {
let compressed = compress(TEXT.as_bytes(), 1).unwrap();
// Bulk functions by default include the content size.
assert_eq!(
zstd_safe::get_frame_content_size(&compressed).unwrap(),
Some(TEXT.len() as u64)
);
}
================================================
FILE: src/dict.rs
================================================
//! Train a dictionary from various sources.
//!
//! A dictionary can help improve the compression of small files.
//! The dictionary must be present during decompression,
//! but can be shared across multiple "similar" files.
//!
//! Creating a dictionary using the `zstd` C library,
//! using the `zstd` command-line interface, using this library,
//! or using the `train` binary provided, should give the same result,
//! and are therefore completely compatible.
//!
//! To use, see [`Encoder::with_dictionary`] or [`Decoder::with_dictionary`].
//!
//! [`Encoder::with_dictionary`]: ../struct.Encoder.html#method.with_dictionary
//! [`Decoder::with_dictionary`]: ../struct.Decoder.html#method.with_dictionary
#[cfg(feature = "zdict_builder")]
use std::io::{self, Read};
pub use zstd_safe::{CDict, DDict};
/// Prepared dictionary for compression
///
/// A dictionary can include its own copy of the data (if it is `'static`), or it can merely point
/// to a separate buffer (if it has another lifetime).
pub struct EncoderDictionary<'a> {
cdict: CDict<'a>,
}
impl EncoderDictionary<'static> {
/// Creates a prepared dictionary for compression.
///
/// This will copy the dictionary internally.
pub fn copy(dictionary: &[u8], level: i32) -> Self {
Self {
cdict: zstd_safe::create_cdict(dictionary, level),
}
}
}
impl<'a> EncoderDictionary<'a> {
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
/// Create prepared dictionary for compression
///
/// A level of `0` uses zstd's default (currently `3`).
///
/// Only available with the `experimental` feature. Use `EncoderDictionary::copy` otherwise.
pub fn new(dictionary: &'a [u8], level: i32) -> Self {
Self {
cdict: zstd_safe::CDict::create_by_reference(dictionary, level),
}
}
/// Returns reference to `CDict` inner object
pub fn as_cdict(&self) -> &CDict<'a> {
&self.cdict
}
}
/// Prepared dictionary for decompression
pub struct DecoderDictionary<'a> {
ddict: DDict<'a>,
}
impl DecoderDictionary<'static> {
/// Create a prepared dictionary for decompression.
///
/// This will copy the dictionary internally.
pub fn copy(dictionary: &[u8]) -> Self {
Self {
ddict: zstd_safe::DDict::create(dictionary),
}
}
}
impl<'a> DecoderDictionary<'a> {
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
/// Create prepared dictionary for decompression
///
/// Only available with the `experimental` feature. Use `DecoderDictionary::copy` otherwise.
pub fn new(dict: &'a [u8]) -> Self {
Self {
ddict: zstd_safe::DDict::create_by_reference(dict),
}
}
/// Returns reference to `DDict` inner object
pub fn as_ddict(&self) -> &DDict<'a> {
&self.ddict
}
}
/// Train a dictionary from a big continuous chunk of data, with all samples
/// contiguous in memory.
///
/// This is the most efficient way to train a dictionary,
/// since this is directly fed into `zstd`.
///
/// * `sample_data` is the concatenation of all sample data.
/// * `sample_sizes` is the size of each sample in `sample_data`.
/// The sum of all `sample_sizes` should equal the length of `sample_data`.
/// * `max_size` is the maximum size of the dictionary to generate.
///
/// The result is the dictionary data. You can, for example, feed it to [`CDict::create`].
#[cfg(feature = "zdict_builder")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "zdict_builder")))]
pub fn from_continuous(
sample_data: &[u8],
sample_sizes: &[usize],
max_size: usize,
) -> io::Result<Vec<u8>> {
use crate::map_error_code;
// Complain if the lengths don't add up to the entire data.
if sample_sizes.iter().sum::<usize>() != sample_data.len() {
return Err(io::Error::new(
io::ErrorKind::Other,
"sample sizes don't add up".to_string(),
));
}
let mut result = Vec::with_capacity(max_size);
zstd_safe::train_from_buffer(&mut result, sample_data, sample_sizes)
.map_err(map_error_code)?;
Ok(result)
}
/// Train a dictionary from multiple samples.
///
/// The samples will internally be copied to a single continuous buffer,
/// so make sure you have enough memory available.
///
/// If you need to stretch your system's limits,
/// [`from_continuous`] directly uses the given slice.
///
/// [`from_continuous`]: ./fn.from_continuous.html
///
/// * `samples` is a list of individual samples to train on.
/// * `max_size` is the maximum size of the dictionary to generate.
///
/// The result is the dictionary data. You can, for example, feed it to [`CDict::create`].
#[cfg(feature = "zdict_builder")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "zdict_builder")))]
pub fn from_samples<S: AsRef<[u8]>>(
samples: &[S],
max_size: usize,
) -> io::Result<Vec<u8>> {
// Pre-allocate the entire required size.
let total_length: usize =
samples.iter().map(|sample| sample.as_ref().len()).sum();
let mut data = Vec::with_capacity(total_length);
// Copy every sample to a big chunk of memory
data.extend(samples.iter().flat_map(|s| s.as_ref()).cloned());
let sizes: Vec<_> = samples.iter().map(|s| s.as_ref().len()).collect();
from_continuous(&data, &sizes, max_size)
}
/// Train a dictionary from multiple samples.
///
/// Unlike [`from_samples`], this does not require having a list of all samples.
/// It also allows running into an error when iterating through the samples.
///
/// They will still be copied to a continuous array and fed to [`from_continuous`].
///
/// * `samples` is an iterator of individual samples to train on.
/// * `max_size` is the maximum size of the dictionary to generate.
///
/// The result is the dictionary data. You can, for example, feed it to [`CDict::create`].
///
/// # Examples
///
/// ```rust,no_run
/// // Train from a couple of json files.
/// let dict_buffer = zstd::dict::from_sample_iterator(
/// ["file_a.json", "file_b.json"]
/// .into_iter()
/// .map(|filename| std::fs::File::open(filename)),
/// 10_000, // 10kB dictionary
/// ).unwrap();
/// ```
///
/// ```rust,no_run
/// use std::io::BufRead as _;
/// // Treat each line from stdin as a separate sample.
/// let dict_buffer = zstd::dict::from_sample_iterator(
/// std::io::stdin().lock().lines().map(|line: std::io::Result<String>| {
/// // Transform each line into a `Cursor<Vec<u8>>` so they implement Read.
/// line.map(String::into_bytes)
/// .map(std::io::Cursor::new)
/// }),
/// 10_000, // 10kB dictionary
/// ).unwrap();
/// ```
#[cfg(feature = "zdict_builder")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "zdict_builder")))]
pub fn from_sample_iterator<I, R>(
samples: I,
max_size: usize,
) -> io::Result<Vec<u8>>
where
I: IntoIterator<Item = io::Result<R>>,
R: Read,
{
let mut data = Vec::new();
let mut sizes = Vec::new();
for sample in samples {
let mut sample = sample?;
let len = sample.read_to_end(&mut data)?;
sizes.push(len);
}
from_continuous(&data, &sizes, max_size)
}
/// Train a dict from a list of files.
///
/// * `filenames` is an iterator of files to load. Each file will be treated as an individual
/// sample.
/// * `max_size` is the maximum size of the dictionary to generate.
///
/// The result is the dictionary data. You can, for example, feed it to [`CDict::create`].
#[cfg(feature = "zdict_builder")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "zdict_builder")))]
pub fn from_files<I, P>(filenames: I, max_size: usize) -> io::Result<Vec<u8>>
where
P: AsRef<std::path::Path>,
I: IntoIterator<Item = P>,
{
from_sample_iterator(
filenames
.into_iter()
.map(|filename| std::fs::File::open(filename)),
max_size,
)
}
#[cfg(test)]
#[cfg(feature = "zdict_builder")]
mod tests {
use std::fs;
use std::io;
use std::io::Read;
use walkdir;
#[test]
fn test_dict_training() {
// Train a dictionary
let paths: Vec<_> = walkdir::WalkDir::new("src")
.into_iter()
.map(|entry| entry.unwrap())
.map(|entry| entry.into_path())
.filter(|path| path.to_str().unwrap().ends_with(".rs"))
.collect();
let dict = super::from_files(&paths, 4000).unwrap();
for path in paths {
let mut buffer = Vec::new();
let mut file = fs::File::open(path).unwrap();
let mut content = Vec::new();
file.read_to_end(&mut content).unwrap();
io::copy(
&mut &content[..],
&mut crate::stream::Encoder::with_dictionary(
&mut buffer,
1,
&dict,
)
.unwrap()
.auto_finish(),
)
.unwrap();
let mut result = Vec::new();
io::copy(
&mut crate::stream::Decoder::with_dictionary(
&buffer[..],
&dict[..],
)
.unwrap(),
&mut result,
)
.unwrap();
assert_eq!(&content, &result);
}
}
}
================================================
FILE: src/lib.rs
================================================
//! Rust binding to the [zstd library][zstd].
//!
//! This crate provides:
//!
//! * An [encoder](stream/write/struct.Encoder.html) to compress data using zstd
//! and send the output to another write.
//! * A [decoder](stream/read/struct.Decoder.html) to read input data from a `Read`
//! and decompress it.
//! * Convenient functions for common tasks.
//!
//! # Example
//!
//! ```no_run
//! use std::io;
//!
//! // Uncompress input and print the result.
//! zstd::stream::copy_decode(io::stdin(), io::stdout()).unwrap();
//! ```
//!
//! [zstd]: https://github.com/facebook/zstd
#![deny(missing_docs)]
#![cfg_attr(feature = "doc-cfg", feature(doc_cfg))]
// Re-export the zstd-safe crate.
pub use zstd_safe;
pub mod bulk;
pub mod dict;
#[macro_use]
pub mod stream;
use std::io;
/// Default compression level.
pub use zstd_safe::CLEVEL_DEFAULT as DEFAULT_COMPRESSION_LEVEL;
/// The accepted range of compression levels.
pub fn compression_level_range(
) -> std::ops::RangeInclusive<zstd_safe::CompressionLevel> {
zstd_safe::min_c_level()..=zstd_safe::max_c_level()
}
#[doc(no_inline)]
pub use crate::stream::{decode_all, encode_all, Decoder, Encoder};
/// Returns the error message as io::Error based on error_code.
fn map_error_code(code: usize) -> io::Error {
let msg = zstd_safe::get_error_name(code);
io::Error::new(io::ErrorKind::Other, msg.to_string())
}
// Some helper functions to write full-cycle tests.
#[cfg(test)]
fn test_cycle<F, G>(data: &[u8], f: F, g: G)
where
F: Fn(&[u8]) -> Vec<u8>,
G: Fn(&[u8]) -> Vec<u8>,
{
let mid = f(data);
let end = g(&mid);
assert_eq!(data, &end[..]);
}
#[cfg(test)]
fn test_cycle_unwrap<F, G>(data: &[u8], f: F, g: G)
where
F: Fn(&[u8]) -> io::Result<Vec<u8>>,
G: Fn(&[u8]) -> io::Result<Vec<u8>>,
{
test_cycle(data, |data| f(data).unwrap(), |data| g(data).unwrap())
}
#[test]
fn default_compression_level_in_range() {
assert!(compression_level_range().contains(&DEFAULT_COMPRESSION_LEVEL));
}
================================================
FILE: src/stream/functions.rs
================================================
use std::io;
use super::{Decoder, Encoder};
/// Decompress from the given source as if using a `Decoder`.
///
/// The input data must be in the zstd frame format.
pub fn decode_all<R: io::Read>(source: R) -> io::Result<Vec<u8>> {
let mut result = Vec::new();
copy_decode(source, &mut result)?;
Ok(result)
}
/// Decompress from the given source as if using a `Decoder`.
///
/// Decompressed data will be appended to `destination`.
pub fn copy_decode<R, W>(source: R, mut destination: W) -> io::Result<()>
where
R: io::Read,
W: io::Write,
{
let mut decoder = Decoder::new(source)?;
io::copy(&mut decoder, &mut destination)?;
Ok(())
}
/// Compress all data from the given source as if using an `Encoder`.
///
/// Result will be in the zstd frame format.
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn encode_all<R: io::Read>(source: R, level: i32) -> io::Result<Vec<u8>> {
let mut result = Vec::<u8>::new();
copy_encode(source, &mut result, level)?;
Ok(result)
}
/// Compress all data from the given source as if using an `Encoder`.
///
/// Compressed data will be appended to `destination`.
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn copy_encode<R, W>(
mut source: R,
destination: W,
level: i32,
) -> io::Result<()>
where
R: io::Read,
W: io::Write,
{
let mut encoder = Encoder::new(destination, level)?;
io::copy(&mut source, &mut encoder)?;
encoder.finish()?;
Ok(())
}
#[cfg(test)]
mod tests {}
================================================
FILE: src/stream/mod.rs
================================================
//! Compress and decompress Zstd streams.
//!
//! Zstd streams are the main way to compress and decompress data.
//! They are compatible with the `zstd` command-line tool.
//!
//! This module provides both `Read` and `Write` interfaces to compressing and
//! decompressing.
pub mod read;
pub mod write;
mod functions;
pub mod zio;
#[cfg(test)]
mod tests;
pub mod raw;
pub use self::functions::{copy_decode, copy_encode, decode_all, encode_all};
pub use self::read::Decoder;
pub use self::write::{AutoFinishEncoder, Encoder};
#[doc(hidden)]
#[macro_export]
/// Common functions for the decoder, both in read and write mode.
macro_rules! decoder_parameters {
() => {
/// Sets the maximum back-reference distance.
///
/// The actual maximum distance is going to be `2^log_distance`.
///
/// This will need to at least match the value set when compressing.
pub fn window_log_max(&mut self, log_distance: u32) -> io::Result<()> {
self.set_parameter(zstd_safe::DParameter::WindowLogMax(
log_distance,
))
}
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
/// Enables or disabled expecting the 4-byte magic header
///
/// Only available with the `experimental` feature.
///
/// This will need to match the settings used when compressing.
pub fn include_magicbytes(
&mut self,
include_magicbytes: bool,
) -> io::Result<()> {
self.set_parameter(zstd_safe::DParameter::Format(
if include_magicbytes {
zstd_safe::FrameFormat::One
} else {
zstd_safe::FrameFormat::Magicless
},
))
}
};
}
#[doc(hidden)]
#[macro_export]
/// Common functions for the decoder, both in read and write mode.
macro_rules! decoder_common {
($readwrite:ident) => {
/// Sets a decompression parameter on the decompression stream.
pub fn set_parameter(
&mut self,
parameter: zstd_safe::DParameter,
) -> io::Result<()> {
self.$readwrite.operation_mut().set_parameter(parameter)
}
$crate::decoder_parameters!();
};
}
#[doc(hidden)]
#[macro_export]
/// Parameter-setters for the encoder. Relies on a `set_parameter` method.
macro_rules! encoder_parameters {
() => {
/// Controls whether zstd should include a content checksum at the end
/// of each frame.
pub fn include_checksum(
&mut self,
include_checksum: bool,
) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::ChecksumFlag(
include_checksum,
))
}
/// Enables multithreaded compression
///
/// * If `n_workers == 0` (default), then multithreaded will be
/// disabled.
/// * If `n_workers >= 1`, then compression will be done in separate
/// threads.
///
/// So even `n_workers = 1` may increase performance by separating
/// IO and compression.
///
/// Note: This is only available if the `zstdmt` cargo feature is activated.
#[cfg(feature = "zstdmt")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "zstdmt")))]
pub fn multithread(&mut self, n_workers: u32) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::NbWorkers(n_workers))
}
/// Enables or disables storing of the dict id.
///
/// Defaults to true. If false, the behaviour of decoding with a wrong
/// dictionary is undefined.
pub fn include_dictid(
&mut self,
include_dictid: bool,
) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::DictIdFlag(
include_dictid,
))
}
/// Enables or disabled storing of the contentsize.
///
/// Note that this only has an effect if the size is given with `set_pledged_src_size`.
pub fn include_contentsize(
&mut self,
include_contentsize: bool,
) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::ContentSizeFlag(
include_contentsize,
))
}
/// Enables or disables long-distance matching
pub fn long_distance_matching(
&mut self,
long_distance_matching: bool,
) -> io::Result<()> {
self.set_parameter(
zstd_safe::CParameter::EnableLongDistanceMatching(
long_distance_matching,
),
)
}
/// Sets the target size for compressed blocks.
///
/// A lower block size may result in slightly lower speed (~2%) and compression ratio
/// (~0.1%), but may decrease end-to-end latency in low-bandwidth environments (time to
/// first decompressed byte).
///
/// No value, or a value of zero, results in no constraint for the block sizes.
pub fn set_target_cblock_size(
&mut self,
target_size: Option<u32>,
) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::TargetCBlockSize(
target_size.unwrap_or(0),
))
}
/// Sets the maximum back-reference distance.
///
/// The actual maximum distance is going to be `2^log_distance`.
///
/// Note that decompression will need to use at least the same setting.
pub fn window_log(&mut self, log_distance: u32) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::WindowLog(log_distance))
}
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
/// Enables or disable the magic bytes at the beginning of each frame.
///
/// If disabled, include_magicbytes must also be called on the decoder.
///
/// Only available with the `experimental` feature.
///
/// Note that decompression will need to use the same setting.
pub fn include_magicbytes(
&mut self,
include_magicbytes: bool,
) -> io::Result<()> {
self.set_parameter(zstd_safe::CParameter::Format(
if include_magicbytes {
zstd_safe::FrameFormat::One
} else {
zstd_safe::FrameFormat::Magicless
},
))
}
};
}
#[doc(hidden)]
#[macro_export]
/// Common functions for the encoder, both in read and write mode.
macro_rules! encoder_common {
($readwrite:ident) => {
/// Sets the given zstd compression parameter.
pub fn set_parameter(
&mut self,
parameter: zstd_safe::CParameter,
) -> io::Result<()> {
self.$readwrite.operation_mut().set_parameter(parameter)
}
/// Sets the expected size of the input.
///
/// This affects the compression effectiveness.
///
/// It is an error to give an incorrect size (an error will be returned when closing the
/// stream if the size does not match what was pledged).
///
/// Giving a `None` size means the size is unknown (this is the default).
pub fn set_pledged_src_size(
&mut self,
size: Option<u64>,
) -> io::Result<()> {
self.$readwrite.operation_mut().set_pledged_src_size(size)
}
$crate::encoder_parameters!();
};
}
================================================
FILE: src/stream/raw.rs
================================================
//! Raw in-memory stream compression/decompression.
//!
//! This module defines a `Decoder` and an `Encoder` to decode/encode streams
//! of data using buffers.
//!
//! They are mostly thin wrappers around `zstd_safe::{DCtx, CCtx}`.
use std::io;
pub use zstd_safe::{CParameter, DParameter, InBuffer, OutBuffer, WriteBuf};
use crate::dict::{DecoderDictionary, EncoderDictionary};
use crate::map_error_code;
/// Represents an abstract compression/decompression operation.
///
/// This trait covers both `Encoder` and `Decoder`.
pub trait Operation {
/// Performs a single step of this operation.
///
/// Should return a hint for the next input size.
///
/// If the result is `Ok(0)`, it may indicate that a frame was just
/// finished.
fn run<C: WriteBuf + ?Sized>(
&mut self,
input: &mut InBuffer<'_>,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize>;
/// Performs a single step of this operation.
///
/// This is a comvenience wrapper around `Operation::run` if you don't
/// want to deal with `InBuffer`/`OutBuffer`.
fn run_on_buffers(
&mut self,
input: &[u8],
output: &mut [u8],
) -> io::Result<Status> {
let mut input = InBuffer::around(input);
let mut output = OutBuffer::around(output);
let remaining = self.run(&mut input, &mut output)?;
Ok(Status {
remaining,
bytes_read: input.pos(),
bytes_written: output.pos(),
})
}
/// Flushes any internal buffer, if any.
///
/// Returns the number of bytes still in the buffer.
/// To flush entirely, keep calling until it returns `Ok(0)`.
fn flush<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
let _ = output;
Ok(0)
}
/// Prepares the operation for a new frame.
///
/// This is hopefully cheaper than creating a new operation.
fn reinit(&mut self) -> io::Result<()> {
Ok(())
}
/// Finishes the operation, writing any footer if necessary.
///
/// Returns the number of bytes still to write.
///
/// Keep calling this method until it returns `Ok(0)`,
/// and then don't ever call this method.
fn finish<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
finished_frame: bool,
) -> io::Result<usize> {
let _ = output;
let _ = finished_frame;
Ok(0)
}
}
/// Dummy operation that just copies its input to the output.
pub struct NoOp;
impl Operation for NoOp {
fn run<C: WriteBuf + ?Sized>(
&mut self,
input: &mut InBuffer<'_>,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
// Skip the prelude
let src = &input.src[input.pos..];
// Safe because `output.pos() <= output.capacity()`.
let output_pos = output.pos();
let dst = unsafe { output.as_mut_ptr().add(output_pos) };
// Ignore anything past the end
let len = usize::min(src.len(), output.capacity() - output_pos);
let src = &src[..len];
// Safe because:
// * `len` is less than either of the two lengths
// * `src` and `dst` do not overlap because we have `&mut` to each.
unsafe { std::ptr::copy_nonoverlapping(src.as_ptr(), dst, len) };
input.set_pos(input.pos() + len);
unsafe { output.set_pos(output_pos + len) };
Ok(0)
}
}
/// Describes the result of an operation.
pub struct Status {
/// Number of bytes expected for next input.
///
/// * If `remaining = 0`, then we are at the end of a frame.
/// * If `remaining > 0`, then it's just a hint for how much there is still
/// to read.
pub remaining: usize,
/// Number of bytes read from the input.
pub bytes_read: usize,
/// Number of bytes written to the output.
pub bytes_written: usize,
}
/// An in-memory decoder for streams of data.
pub struct Decoder<'a> {
context: MaybeOwnedDCtx<'a>,
}
impl Decoder<'static> {
/// Creates a new decoder.
pub fn new() -> io::Result<Self> {
Self::with_dictionary(&[])
}
/// Creates a new decoder initialized with the given dictionary.
pub fn with_dictionary(dictionary: &[u8]) -> io::Result<Self> {
let mut context = zstd_safe::DCtx::create();
context.init().map_err(map_error_code)?;
context
.load_dictionary(dictionary)
.map_err(map_error_code)?;
Ok(Decoder {
context: MaybeOwnedDCtx::Owned(context),
})
}
}
impl<'a> Decoder<'a> {
/// Creates a new decoder which employs the provided context for deserialization.
pub fn with_context(context: &'a mut zstd_safe::DCtx<'static>) -> Self {
Self {
context: MaybeOwnedDCtx::Borrowed(context),
}
}
/// Creates a new decoder, using an existing `DecoderDictionary`.
pub fn with_prepared_dictionary<'b>(
dictionary: &DecoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let mut context = zstd_safe::DCtx::create();
context
.ref_ddict(dictionary.as_ddict())
.map_err(map_error_code)?;
Ok(Decoder {
context: MaybeOwnedDCtx::Owned(context),
})
}
/// Creates a new decoder, using a ref prefix
pub fn with_ref_prefix<'b>(ref_prefix: &'b [u8]) -> io::Result<Self>
where
'b: 'a,
{
let mut context = zstd_safe::DCtx::create();
context.ref_prefix(ref_prefix).map_err(map_error_code)?;
Ok(Decoder {
context: MaybeOwnedDCtx::Owned(context),
})
}
/// Sets a decompression parameter for this decoder.
pub fn set_parameter(&mut self, parameter: DParameter) -> io::Result<()> {
match &mut self.context {
MaybeOwnedDCtx::Owned(x) => x.set_parameter(parameter),
MaybeOwnedDCtx::Borrowed(x) => x.set_parameter(parameter),
}
.map_err(map_error_code)?;
Ok(())
}
}
impl Operation for Decoder<'_> {
fn run<C: WriteBuf + ?Sized>(
&mut self,
input: &mut InBuffer<'_>,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
match &mut self.context {
MaybeOwnedDCtx::Owned(x) => x.decompress_stream(output, input),
MaybeOwnedDCtx::Borrowed(x) => x.decompress_stream(output, input),
}
.map_err(map_error_code)
}
fn flush<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
// To flush, we just offer no additional input.
self.run(&mut InBuffer::around(&[]), output)?;
// We don't _know_ how much (decompressed data) there is still in buffer.
if output.pos() < output.capacity() {
// We only know when there's none (the output buffer is not full).
Ok(0)
} else {
// Otherwise, pretend there's still "1 byte" remaining.
Ok(1)
}
}
fn reinit(&mut self) -> io::Result<()> {
match &mut self.context {
MaybeOwnedDCtx::Owned(x) => {
x.reset(zstd_safe::ResetDirective::SessionOnly)
}
MaybeOwnedDCtx::Borrowed(x) => {
x.reset(zstd_safe::ResetDirective::SessionOnly)
}
}
.map_err(map_error_code)?;
Ok(())
}
fn finish<C: WriteBuf + ?Sized>(
&mut self,
_output: &mut OutBuffer<'_, C>,
finished_frame: bool,
) -> io::Result<usize> {
if finished_frame {
Ok(0)
} else {
Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"incomplete frame",
))
}
}
}
/// An in-memory encoder for streams of data.
pub struct Encoder<'a> {
context: MaybeOwnedCCtx<'a>,
}
impl Encoder<'static> {
/// Creates a new encoder.
pub fn new(level: i32) -> io::Result<Self> {
Self::with_dictionary(level, &[])
}
/// Creates a new encoder initialized with the given dictionary.
pub fn with_dictionary(level: i32, dictionary: &[u8]) -> io::Result<Self> {
let mut context = zstd_safe::CCtx::create();
context
.set_parameter(CParameter::CompressionLevel(level))
.map_err(map_error_code)?;
context
.load_dictionary(dictionary)
.map_err(map_error_code)?;
Ok(Encoder {
context: MaybeOwnedCCtx::Owned(context),
})
}
}
impl<'a> Encoder<'a> {
/// Creates a new encoder that uses the provided context for serialization.
pub fn with_context(context: &'a mut zstd_safe::CCtx<'static>) -> Self {
Self {
context: MaybeOwnedCCtx::Borrowed(context),
}
}
/// Creates a new encoder using an existing `EncoderDictionary`.
pub fn with_prepared_dictionary<'b>(
dictionary: &EncoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let mut context = zstd_safe::CCtx::create();
context
.ref_cdict(dictionary.as_cdict())
.map_err(map_error_code)?;
Ok(Encoder {
context: MaybeOwnedCCtx::Owned(context),
})
}
/// Creates a new encoder initialized with the given ref prefix.
pub fn with_ref_prefix<'b>(
level: i32,
ref_prefix: &'b [u8],
) -> io::Result<Self>
where
'b: 'a,
{
let mut context = zstd_safe::CCtx::create();
context
.set_parameter(CParameter::CompressionLevel(level))
.map_err(map_error_code)?;
context.ref_prefix(ref_prefix).map_err(map_error_code)?;
Ok(Encoder {
context: MaybeOwnedCCtx::Owned(context),
})
}
/// Sets a compression parameter for this encoder.
pub fn set_parameter(&mut self, parameter: CParameter) -> io::Result<()> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => x.set_parameter(parameter),
MaybeOwnedCCtx::Borrowed(x) => x.set_parameter(parameter),
}
.map_err(map_error_code)?;
Ok(())
}
/// Sets the size of the input expected by zstd.
///
/// May affect compression ratio.
///
/// It is an error to give an incorrect size (an error _will_ be returned when closing the
/// stream).
///
/// If `None` is given, it assume the size is not known (default behaviour).
pub fn set_pledged_src_size(
&mut self,
pledged_src_size: Option<u64>,
) -> io::Result<()> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => {
x.set_pledged_src_size(pledged_src_size)
}
MaybeOwnedCCtx::Borrowed(x) => {
x.set_pledged_src_size(pledged_src_size)
}
}
.map_err(map_error_code)?;
Ok(())
}
}
impl<'a> Operation for Encoder<'a> {
fn run<C: WriteBuf + ?Sized>(
&mut self,
input: &mut InBuffer<'_>,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => x.compress_stream(output, input),
MaybeOwnedCCtx::Borrowed(x) => x.compress_stream(output, input),
}
.map_err(map_error_code)
}
fn flush<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
) -> io::Result<usize> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => x.flush_stream(output),
MaybeOwnedCCtx::Borrowed(x) => x.flush_stream(output),
}
.map_err(map_error_code)
}
fn finish<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
_finished_frame: bool,
) -> io::Result<usize> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => x.end_stream(output),
MaybeOwnedCCtx::Borrowed(x) => x.end_stream(output),
}
.map_err(map_error_code)
}
fn reinit(&mut self) -> io::Result<()> {
match &mut self.context {
MaybeOwnedCCtx::Owned(x) => {
x.reset(zstd_safe::ResetDirective::SessionOnly)
}
MaybeOwnedCCtx::Borrowed(x) => {
x.reset(zstd_safe::ResetDirective::SessionOnly)
}
}
.map_err(map_error_code)?;
Ok(())
}
}
enum MaybeOwnedCCtx<'a> {
Owned(zstd_safe::CCtx<'a>),
Borrowed(&'a mut zstd_safe::CCtx<'static>),
}
enum MaybeOwnedDCtx<'a> {
Owned(zstd_safe::DCtx<'a>),
Borrowed(&'a mut zstd_safe::DCtx<'static>),
}
#[cfg(test)]
mod tests {
// This requires impl for [u8; N] which is currently behind a feature.
#[cfg(feature = "arrays")]
#[test]
fn test_cycle() {
use super::{Decoder, Encoder, InBuffer, Operation, OutBuffer};
let mut encoder = Encoder::new(1).unwrap();
let mut decoder = Decoder::new().unwrap();
// Step 1: compress
let mut input = InBuffer::around(b"AbcdefAbcdefabcdef");
let mut output = [0u8; 128];
let mut output = OutBuffer::around(&mut output);
loop {
encoder.run(&mut input, &mut output).unwrap();
if input.pos == input.src.len() {
break;
}
}
encoder.finish(&mut output, true).unwrap();
let initial_data = input.src;
// Step 2: decompress
let mut input = InBuffer::around(output.as_slice());
let mut output = [0u8; 128];
let mut output = OutBuffer::around(&mut output);
loop {
decoder.run(&mut input, &mut output).unwrap();
if input.pos == input.src.len() {
break;
}
}
assert_eq!(initial_data, output.as_slice());
}
}
================================================
FILE: src/stream/read/mod.rs
================================================
//! Implement pull-based [`Read`] trait for both compressing and decompressing.
use std::io::{self, BufRead, BufReader, Read};
use crate::dict::{DecoderDictionary, EncoderDictionary};
use crate::stream::{raw, zio};
use zstd_safe;
#[cfg(test)]
mod tests;
/// A decoder that decompress input data from another `Read`.
///
/// This allows to read a stream of compressed data
/// (good for files or heavy network stream).
pub struct Decoder<'a, R> {
reader: zio::Reader<R, raw::Decoder<'a>>,
}
/// An encoder that compress input data from another `Read`.
pub struct Encoder<'a, R> {
reader: zio::Reader<R, raw::Encoder<'a>>,
}
impl<R: Read> Decoder<'static, BufReader<R>> {
/// Creates a new decoder.
pub fn new(reader: R) -> io::Result<Self> {
let buffer_size = zstd_safe::DCtx::in_size();
Self::with_buffer(BufReader::with_capacity(buffer_size, reader))
}
}
impl<R: BufRead> Decoder<'static, R> {
/// Creates a new decoder around a `BufRead`.
pub fn with_buffer(reader: R) -> io::Result<Self> {
Self::with_dictionary(reader, &[])
}
/// Creates a new decoder, using an existing dictionary.
///
/// The dictionary must be the same as the one used during compression.
pub fn with_dictionary(reader: R, dictionary: &[u8]) -> io::Result<Self> {
let decoder = raw::Decoder::with_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
}
impl<'a, R: BufRead> Decoder<'a, R> {
/// Creates a new decoder which employs the provided context for deserialization.
pub fn with_context(
reader: R,
context: &'a mut zstd_safe::DCtx<'static>,
) -> Self {
Self {
reader: zio::Reader::new(
reader,
raw::Decoder::with_context(context),
),
}
}
/// Sets this `Decoder` to stop after the first frame.
///
/// By default, it keeps concatenating frames until EOF is reached.
#[must_use]
pub fn single_frame(mut self) -> Self {
self.reader.set_single_frame();
self
}
/// Creates a new decoder, using an existing `DecoderDictionary`.
///
/// The dictionary must be the same as the one used during compression.
pub fn with_prepared_dictionary<'b>(
reader: R,
dictionary: &DecoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let decoder = raw::Decoder::with_prepared_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
/// Creates a new decoder, using a ref prefix.
///
/// The prefix must be the same as the one used during compression.
pub fn with_ref_prefix<'b>(
reader: R,
ref_prefix: &'b [u8],
) -> io::Result<Self>
where
'b: 'a,
{
let decoder = raw::Decoder::with_ref_prefix(ref_prefix)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
/// Recommendation for the size of the output buffer.
pub fn recommended_output_size() -> usize {
zstd_safe::DCtx::out_size()
}
/// Acquire a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.reader.reader()
}
/// Acquire a mutable reference to the underlying reader.
///
/// Note that mutation of the reader may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.reader.reader_mut()
}
/// Return the inner `Read`.
///
/// Calling `finish()` is not *required* after reading a stream -
/// just use it if you need to get the `Read` back.
pub fn finish(self) -> R {
self.reader.into_inner()
}
crate::decoder_common!(reader);
}
impl<R: BufRead> Read for Decoder<'_, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.reader.read(buf)
}
}
impl<R: Read> Encoder<'static, BufReader<R>> {
/// Creates a new encoder.
pub fn new(reader: R, level: i32) -> io::Result<Self> {
let buffer_size = zstd_safe::CCtx::in_size();
Self::with_buffer(BufReader::with_capacity(buffer_size, reader), level)
}
}
impl<R: BufRead> Encoder<'static, R> {
/// Creates a new encoder around a `BufRead`.
pub fn with_buffer(reader: R, level: i32) -> io::Result<Self> {
Self::with_dictionary(reader, level, &[])
}
/// Creates a new encoder, using an existing dictionary.
///
/// The dictionary must be the same as the one used during compression.
pub fn with_dictionary(
reader: R,
level: i32,
dictionary: &[u8],
) -> io::Result<Self> {
let encoder = raw::Encoder::with_dictionary(level, dictionary)?;
let reader = zio::Reader::new(reader, encoder);
Ok(Encoder { reader })
}
}
impl<'a, R: BufRead> Encoder<'a, R> {
/// Creates a new encoder which employs the provided context for serialization.
pub fn with_context(
reader: R,
context: &'a mut zstd_safe::CCtx<'static>,
) -> Self {
Self {
reader: zio::Reader::new(
reader,
raw::Encoder::with_context(context),
),
}
}
/// Creates a new encoder, using an existing `EncoderDictionary`.
///
/// The dictionary must be the same as the one used during compression.
pub fn with_prepared_dictionary<'b>(
reader: R,
dictionary: &EncoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let encoder = raw::Encoder::with_prepared_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, encoder);
Ok(Encoder { reader })
}
/// Recommendation for the size of the output buffer.
pub fn recommended_output_size() -> usize {
zstd_safe::CCtx::out_size()
}
/// Acquire a reference to the underlying reader.
pub fn get_ref(&self) -> &R {
self.reader.reader()
}
/// Acquire a mutable reference to the underlying reader.
///
/// Note that mutation of the reader may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut R {
self.reader.reader_mut()
}
/// Flush any internal buffer.
///
/// This ensures all input consumed so far is compressed.
///
/// Since it prevents bundling currently buffered data with future input,
/// it may affect compression ratio.
///
/// * Returns the number of bytes written to `out`.
/// * Returns `Ok(0)` when everything has been flushed.
pub fn flush(&mut self, out: &mut [u8]) -> io::Result<usize> {
self.reader.flush(out)
}
/// Return the inner `Read`.
///
/// Calling `finish()` is not *required* after reading a stream -
/// just use it if you need to get the `Read` back.
pub fn finish(self) -> R {
self.reader.into_inner()
}
crate::encoder_common!(reader);
}
impl<R: BufRead> Read for Encoder<'_, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.reader.read(buf)
}
}
fn _assert_traits() {
use std::io::Cursor;
fn _assert_send<T: Send>(_: T) {}
_assert_send(Decoder::new(Cursor::new(Vec::new())));
_assert_send(Encoder::new(Cursor::new(Vec::new()), 1));
}
================================================
FILE: src/stream/read/tests.rs
================================================
use crate::stream::read::{Decoder, Encoder};
use std::io::Read;
#[test]
fn test_error_handling() {
let invalid_input = b"Abcdefghabcdefgh";
let mut decoder = Decoder::new(&invalid_input[..]).unwrap();
let output = decoder.read_to_end(&mut Vec::new());
assert_eq!(output.is_err(), true);
}
#[test]
fn test_cycle() {
let input = b"Abcdefghabcdefgh";
let mut encoder = Encoder::new(&input[..], 1).unwrap();
let mut buffer = Vec::new();
encoder.read_to_end(&mut buffer).unwrap();
let mut decoder = Decoder::new(&buffer[..]).unwrap();
let mut buffer = Vec::new();
decoder.read_to_end(&mut buffer).unwrap();
assert_eq!(input, &buffer[..]);
}
================================================
FILE: src/stream/tests.rs
================================================
use super::{copy_encode, decode_all, encode_all};
use super::{Decoder, Encoder};
use partial_io::{PartialOp, PartialWrite};
use std::io;
use std::iter;
#[test]
fn test_end_of_frame() {
use std::io::{Read, Write};
let mut enc = Encoder::new(Vec::new(), 1).unwrap();
enc.write_all(b"foo").unwrap();
let mut compressed = enc.finish().unwrap();
// Add footer/whatever to underlying storage.
compressed.push(0);
// Drain zstd stream until end-of-frame.
let mut dec = Decoder::new(&compressed[..]).unwrap().single_frame();
let mut buf = Vec::new();
dec.read_to_end(&mut buf).unwrap();
assert_eq!(&buf, b"foo", "Error decoding a single frame.");
}
#[test]
fn test_concatenated_frames() {
let mut buffer = Vec::new();
copy_encode(&b"foo"[..], &mut buffer, 1).unwrap();
copy_encode(&b"bar"[..], &mut buffer, 2).unwrap();
copy_encode(&b"baz"[..], &mut buffer, 3).unwrap();
assert_eq!(
&decode_all(&buffer[..]).unwrap(),
b"foobarbaz",
"Error decoding concatenated frames."
);
}
#[test]
fn test_flush() {
use std::io::Write;
let buf = Vec::new();
let mut z = Encoder::new(buf, 19).unwrap();
z.write_all(b"hello").unwrap();
z.flush().unwrap(); // Might corrupt stream
let buf = z.finish().unwrap();
let s = decode_all(&buf[..]).unwrap();
assert_eq!(s, b"hello", "Error decoding after flush.");
}
#[test]
fn test_try_finish() {
use std::io::Write;
let mut z = setup_try_finish();
z.get_mut().set_ops(iter::repeat(PartialOp::Unlimited));
// flush() should continue to work even though write() doesn't.
z.flush().unwrap();
let buf = match z.try_finish() {
Ok(buf) => buf.into_inner(),
Err((_z, e)) => panic!("try_finish failed with {:?}", e),
};
// Make sure the multiple try_finish calls didn't screw up the internal
// buffer and continued to produce valid compressed data.
assert_eq!(&decode_all(&buf[..]).unwrap(), b"hello", "Error decoding");
}
#[test]
#[should_panic]
fn test_write_after_try_finish() {
use std::io::Write;
let mut z = setup_try_finish();
z.write_all(b"hello world").unwrap();
}
fn setup_try_finish() -> Encoder<'static, PartialWrite<Vec<u8>>> {
use std::io::Write;
let buf =
PartialWrite::new(Vec::new(), iter::repeat(PartialOp::Unlimited));
let mut z = Encoder::new(buf, 19).unwrap();
z.write_all(b"hello").unwrap();
z.get_mut()
.set_ops(iter::repeat(PartialOp::Err(io::ErrorKind::WouldBlock)));
let (z, err) = z.try_finish().unwrap_err();
assert_eq!(
err.kind(),
io::ErrorKind::WouldBlock,
"expected WouldBlock error"
);
z
}
#[test]
fn test_failing_write() {
use std::io::Write;
let buf = PartialWrite::new(
Vec::new(),
iter::repeat(PartialOp::Err(io::ErrorKind::WouldBlock)),
);
let mut z = Encoder::new(buf, 1).unwrap();
// Fill in enough data to make sure the buffer gets written out.
let input = vec![b'b'; 128 * 1024];
// This should work even though the inner writer rejects writes.
assert_eq!(
z.write(&input).unwrap(),
128 * 1024,
"did not write all input buffer"
);
// The next write would fail (the buffer still has some data in it).
assert_eq!(
z.write(b"abc").unwrap_err().kind(),
io::ErrorKind::WouldBlock,
"expected WouldBlock error"
);
z.get_mut().set_ops(iter::repeat(PartialOp::Unlimited));
// This shouldn't have led to any corruption.
let buf = z.finish().unwrap().into_inner();
assert_eq!(
&decode_all(&buf[..]).unwrap(),
&input,
"WouldBlock errors should not corrupt stream"
);
}
#[test]
fn test_invalid_frame() {
use std::io::Read;
// I really hope this data is invalid...
let data = &[1u8, 2u8, 3u8, 4u8, 5u8];
let mut dec = Decoder::new(&data[..]).unwrap();
assert_eq!(
dec.read_to_end(&mut Vec::new()).err().map(|e| e.kind()),
Some(io::ErrorKind::Other),
"did not encounter expected 'invalid frame' error"
);
}
#[test]
fn test_incomplete_frame() {
use std::io::{Read, Write};
let mut enc = Encoder::new(Vec::new(), 1).unwrap();
enc.write_all(b"This is a regular string").unwrap();
let mut compressed = enc.finish().unwrap();
let half_size = compressed.len() - 2;
compressed.truncate(half_size);
let mut dec = Decoder::new(&compressed[..]).unwrap();
assert_eq!(
dec.read_to_end(&mut Vec::new()).err().map(|e| e.kind()),
Some(io::ErrorKind::UnexpectedEof),
"did not encounter expected EOF error"
);
}
#[test]
fn test_cli_compatibility() {
let input = include_bytes!("../../assets/example.txt.zst");
let output = decode_all(&input[..]).unwrap();
let expected = include_bytes!("../../assets/example.txt");
assert_eq!(
&output[..],
&expected[..],
"error decoding cli-compressed data"
);
}
#[cfg(feature = "legacy")]
#[test]
fn test_legacy() {
use std::fs;
use std::io::Read;
// Read the content from that file
let expected = include_bytes!("../../assets/example.txt");
for version in &[5, 6, 7, 8] {
let filename = format!("assets/example.txt.v{}.zst", version);
let file = fs::File::open(filename).unwrap();
let mut decoder = Decoder::new(file).unwrap();
let mut buffer = Vec::new();
decoder.read_to_end(&mut buffer).unwrap();
assert_eq!(
&expected[..],
&buffer[..],
"error decompressing legacy version {}",
version
);
}
}
// Check that compressing+decompressing some data gives back the original
fn test_full_cycle(input: &[u8], level: i32) {
crate::test_cycle_unwrap(
input,
|data| encode_all(data, level),
|data| decode_all(data),
);
}
#[test]
fn test_empty() {
// Test compressing empty data
for level in 1..19 {
test_full_cycle(b"", level);
}
}
#[test]
fn test_ll_source() {
// Where could I find some long text?...
let data = include_bytes!("../../zstd-safe/zstd-sys/src/bindings_zstd.rs");
// Test a few compression levels.
// TODO: check them all?
for level in 1..5 {
// Test compressing actual data
test_full_cycle(data, level);
}
}
#[test]
fn reader_to_writer() {
use std::io::{Read, Write};
let clear = include_bytes!("../../assets/example.txt");
// Compress using reader
let mut encoder = super::read::Encoder::new(&clear[..], 1).unwrap();
let mut compressed_buffer = Vec::new();
encoder.read_to_end(&mut compressed_buffer).unwrap();
// eprintln!("Compressed Buffer: {:?}", compressed_buffer);
// Decompress using writer
let mut decompressed_buffer = Vec::new();
let mut decoder =
super::write::Decoder::new(&mut decompressed_buffer).unwrap();
decoder.write_all(&compressed_buffer[..]).unwrap();
decoder.flush().unwrap();
// eprintln!("{:?}", decompressed_buffer);
assert_eq!(clear, &decompressed_buffer[..]);
}
#[test]
fn test_finish_empty_encoder() {
use std::io::Write;
let mut enc = Encoder::new(Vec::new(), 0).unwrap();
enc.do_finish().unwrap();
enc.write_all(b"this should not work").unwrap_err();
enc.finish().unwrap();
}
================================================
FILE: src/stream/write/mod.rs
================================================
//! Implement push-based [`Write`] trait for both compressing and decompressing.
use std::io::{self, Write};
use zstd_safe;
use crate::dict::{DecoderDictionary, EncoderDictionary};
use crate::stream::{raw, zio};
#[cfg(test)]
mod tests;
/// An encoder that compress and forward data to another writer.
///
/// This allows to compress a stream of data
/// (good for files or heavy network stream).
///
/// Don't forget to call [`finish()`] before dropping it!
///
/// Alternatively, you can call [`auto_finish()`] to use an
/// [`AutoFinishEncoder`] that will finish on drop.
///
/// Note: The zstd library has its own internal input buffer (~128kb).
///
/// [`finish()`]: #method.finish
/// [`auto_finish()`]: #method.auto_finish
/// [`AutoFinishEncoder`]: AutoFinishEncoder
pub struct Encoder<'a, W: Write> {
// output writer (compressed data)
writer: zio::Writer<W, raw::Encoder<'a>>,
}
/// A decoder that decompress and forward data to another writer.
///
/// Note that you probably want to `flush()` after writing your stream content.
/// You can use [`auto_flush()`] to automatically flush the writer on drop.
///
/// [`auto_flush()`]: Decoder::auto_flush
pub struct Decoder<'a, W: Write> {
// output writer (decompressed data)
writer: zio::Writer<W, raw::Decoder<'a>>,
}
/// A wrapper around an `Encoder<W>` that finishes the stream on drop.
///
/// This can be created by the [`auto_finish()`] method on the [`Encoder`].
///
/// [`auto_finish()`]: Encoder::auto_finish
/// [`Encoder`]: Encoder
pub struct AutoFinishEncoder<
'a,
W: Write,
F: FnMut(io::Result<W>) = Box<dyn Send + FnMut(io::Result<W>)>,
> {
// We wrap this in an option to take it during drop.
encoder: Option<Encoder<'a, W>>,
on_finish: Option<F>,
}
/// A wrapper around a `Decoder<W>` that flushes the stream on drop.
///
/// This can be created by the [`auto_flush()`] method on the [`Decoder`].
///
/// [`auto_flush()`]: Decoder::auto_flush
/// [`Decoder`]: Decoder
pub struct AutoFlushDecoder<
'a,
W: Write,
F: FnMut(io::Result<()>) = Box<dyn Send + FnMut(io::Result<()>)>,
> {
// We wrap this in an option to take it during drop.
decoder: Option<Decoder<'a, W>>,
on_flush: Option<F>,
}
impl<'a, W: Write, F: FnMut(io::Result<()>)> AutoFlushDecoder<'a, W, F> {
fn new(decoder: Decoder<'a, W>, on_flush: F) -> Self {
AutoFlushDecoder {
decoder: Some(decoder),
on_flush: Some(on_flush),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.decoder.as_ref().unwrap().get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutation of the writer may result in surprising results if
/// this decoder is continued to be used.
///
/// Mostly used for testing purposes.
pub fn get_mut(&mut self) -> &mut W {
self.decoder.as_mut().unwrap().get_mut()
}
}
impl<W, F> Drop for AutoFlushDecoder<'_, W, F>
where
W: Write,
F: FnMut(io::Result<()>),
{
fn drop(&mut self) {
let mut decoder = self.decoder.take().unwrap();
let result = decoder.flush();
if let Some(mut on_finish) = self.on_flush.take() {
on_finish(result);
}
}
}
impl<W: Write, F: FnMut(io::Result<()>)> Write for AutoFlushDecoder<'_, W, F> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.decoder.as_mut().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.decoder.as_mut().unwrap().flush()
}
}
impl<'a, W: Write, F: FnMut(io::Result<W>)> AutoFinishEncoder<'a, W, F> {
fn new(encoder: Encoder<'a, W>, on_finish: F) -> Self {
AutoFinishEncoder {
encoder: Some(encoder),
on_finish: Some(on_finish),
}
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.encoder.as_ref().unwrap().get_ref()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutation of the writer may result in surprising results if
/// this encoder is continued to be used.
///
/// Mostly used for testing purposes.
pub fn get_mut(&mut self) -> &mut W {
self.encoder.as_mut().unwrap().get_mut()
}
}
impl<W: Write, F: FnMut(io::Result<W>)> Drop for AutoFinishEncoder<'_, W, F> {
fn drop(&mut self) {
let result = self.encoder.take().unwrap().finish();
if let Some(mut on_finish) = self.on_finish.take() {
on_finish(result);
}
}
}
impl<W: Write, F: FnMut(io::Result<W>)> Write for AutoFinishEncoder<'_, W, F> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.encoder.as_mut().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.encoder.as_mut().unwrap().flush()
}
}
impl<W: Write> Encoder<'static, W> {
/// Creates a new encoder.
///
/// `level`: compression level (1-22).
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn new(writer: W, level: i32) -> io::Result<Self> {
Self::with_dictionary(writer, level, &[])
}
/// Creates a new encoder, using an existing dictionary.
///
/// (Provides better compression ratio for small files,
/// but requires the dictionary to be present during decompression.)
///
/// A level of `0` uses zstd's default (currently `3`).
pub fn with_dictionary(
writer: W,
level: i32,
dictionary: &[u8],
) -> io::Result<Self> {
let encoder = raw::Encoder::with_dictionary(level, dictionary)?;
Ok(Self::with_encoder(writer, encoder))
}
}
impl<'a, W: Write> Encoder<'a, W> {
/// Creates a new encoder from a prepared zio writer.
pub fn with_writer(writer: zio::Writer<W, raw::Encoder<'a>>) -> Self {
Self { writer }
}
/// Creates a new encoder from the given `Write` and raw encoder.
pub fn with_encoder(writer: W, encoder: raw::Encoder<'a>) -> Self {
let writer = zio::Writer::new(writer, encoder);
Self::with_writer(writer)
}
/// Creates an encoder that uses the provided context to compress a stream.
pub fn with_context(
writer: W,
context: &'a mut zstd_safe::CCtx<'static>,
) -> Self {
let encoder = raw::Encoder::with_context(context);
Self::with_encoder(writer, encoder)
}
/// Creates a new encoder, using an existing prepared `EncoderDictionary`.
///
/// (Provides better compression ratio for small files,
/// but requires the dictionary to be present during decompression.)
pub fn with_prepared_dictionary<'b>(
writer: W,
dictionary: &EncoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let encoder = raw::Encoder::with_prepared_dictionary(dictionary)?;
Ok(Self::with_encoder(writer, encoder))
}
/// Creates a new encoder, using a ref prefix
pub fn with_ref_prefix<'b>(
writer: W,
level: i32,
ref_prefix: &'b [u8],
) -> io::Result<Self>
where
'b: 'a,
{
let encoder = raw::Encoder::with_ref_prefix(level, ref_prefix)?;
Ok(Self::with_encoder(writer, encoder))
}
/// Returns a wrapper around `self` that will finish the stream on drop.
pub fn auto_finish(self) -> AutoFinishEncoder<'a, W> {
AutoFinishEncoder {
encoder: Some(self),
on_finish: None,
}
}
/// Returns an encoder that will finish the stream on drop.
///
/// Calls the given callback with the result from `finish()`. This runs during drop so it's
/// important that the provided callback doesn't panic.
pub fn on_finish<F: FnMut(io::Result<W>)>(
self,
f: F,
) -> AutoFinishEncoder<'a, W, F> {
AutoFinishEncoder::new(self, f)
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.writer.writer()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutation of the writer may result in surprising results if
/// this encoder is continued to be used.
pub fn get_mut(&mut self) -> &mut W {
self.writer.writer_mut()
}
/// **Required**: Finishes the stream.
///
/// You *need* to finish the stream when you're done writing, either with
/// this method or with [`try_finish(self)`](#method.try_finish).
///
/// This returns the inner writer in case you need it.
///
/// To get back `self` in case an error happened, use `try_finish`.
///
/// **Note**: If you don't want (or can't) call `finish()` manually after
/// writing your data, consider using `auto_finish()` to get an
/// `AutoFinishEncoder`.
pub fn finish(self) -> io::Result<W> {
self.try_finish().map_err(|(_, err)| err)
}
/// **Required**: Attempts to finish the stream.
///
/// You *need* to finish the stream when you're done writing, either with
/// this method or with [`finish(self)`](#method.finish).
///
/// This returns the inner writer if the finish was successful, or the
/// object plus an error if it wasn't.
///
/// `write` on this object will panic after `try_finish` has been called,
/// even if it fails.
pub fn try_finish(mut self) -> Result<W, (Self, io::Error)> {
match self.writer.finish() {
// Return the writer, because why not
Ok(()) => Ok(self.writer.into_inner().0),
Err(e) => Err((self, e)),
}
}
/// Attempts to finish the stream.
///
/// You *need* to finish the stream when you're done writing, either with
/// this method or with [`finish(self)`](#method.finish).
pub fn do_finish(&mut self) -> io::Result<()> {
self.writer.finish()
}
/// Return a recommendation for the size of data to write at once.
pub fn recommended_input_size() -> usize {
zstd_safe::CCtx::in_size()
}
crate::encoder_common!(writer);
}
impl<'a, W: Write> Write for Encoder<'a, W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.writer.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}
impl<W: Write> Decoder<'static, W> {
/// Creates a new decoder.
pub fn new(writer: W) -> io::Result<Self> {
Self::with_dictionary(writer, &[])
}
/// Creates a new decoder, using an existing dictionary.
///
/// (Provides better compression ratio for small files,
/// but requires the dictionary to be present during decompression.)
pub fn with_dictionary(writer: W, dictionary: &[u8]) -> io::Result<Self> {
let decoder = raw::Decoder::with_dictionary(dictionary)?;
Ok(Self::with_decoder(writer, decoder))
}
}
impl<'a, W: Write> Decoder<'a, W> {
/// Creates a new decoder around the given prepared zio writer.
///
/// # Examples
///
/// ```rust
/// fn wrap<W: std::io::Write>(writer: W) -> zstd::stream::write::Decoder<'static, W> {
/// let decoder = zstd::stream::raw::Decoder::new().unwrap();
/// let writer = zstd::stream::zio::Writer::new(writer, decoder);
/// zstd::stream::write::Decoder::with_writer(writer)
/// }
/// ```
pub fn with_writer(writer: zio::Writer<W, raw::Decoder<'a>>) -> Self {
Decoder { writer }
}
/// Creates a new decoder around the given `Write` and raw decoder.
pub fn with_decoder(writer: W, decoder: raw::Decoder<'a>) -> Self {
let writer = zio::Writer::new(writer, decoder);
Decoder { writer }
}
/// Creates a decoder that uses the provided context to decompress a stream.
pub fn with_context(
writer: W,
context: &'a mut zstd_safe::DCtx<'static>,
) -> Self {
let encoder = raw::Decoder::with_context(context);
Self::with_decoder(writer, encoder)
}
/// Creates a new decoder, using an existing prepared `DecoderDictionary`.
///
/// (Provides better compression ratio for small files,
/// but requires the dictionary to be present during decompression.)
pub fn with_prepared_dictionary<'b>(
writer: W,
dictionary: &DecoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let decoder = raw::Decoder::with_prepared_dictionary(dictionary)?;
Ok(Self::with_decoder(writer, decoder))
}
/// Acquires a reference to the underlying writer.
pub fn get_ref(&self) -> &W {
self.writer.writer()
}
/// Acquires a mutable reference to the underlying writer.
///
/// Note that mutation of the writer may result in surprising results if
/// this decoder is continued to be used.
pub fn get_mut(&mut self) -> &mut W {
self.writer.writer_mut()
}
/// Returns the inner `Write`.
pub fn into_inner(self) -> W {
self.writer.into_inner().0
}
/// Return a recommendation for the size of data to write at once.
pub fn recommended_input_size() -> usize {
zstd_safe::DCtx::in_size()
}
/// Returns a wrapper around `self` that will flush the stream on drop.
pub fn auto_flush(self) -> AutoFlushDecoder<'a, W> {
AutoFlushDecoder {
decoder: Some(self),
on_flush: None,
}
}
/// Returns a decoder that will flush the stream on drop.
///
/// Calls the given callback with the result from `flush()`. This runs during drop so it's
/// important that the provided callback doesn't panic.
pub fn on_flush<F: FnMut(io::Result<()>)>(
self,
f: F,
) -> AutoFlushDecoder<'a, W, F> {
AutoFlushDecoder::new(self, f)
}
crate::decoder_common!(writer);
}
impl<W: Write> Write for Decoder<'_, W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.writer.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}
fn _assert_traits() {
fn _assert_send<T: Send>(_: T) {}
_assert_send(Decoder::new(Vec::new()));
_assert_send(Encoder::new(Vec::new(), 1));
_assert_send(Decoder::new(Vec::new()).unwrap().auto_flush());
_assert_send(Encoder::new(Vec::new(), 1).unwrap().auto_finish());
}
================================================
FILE: src/stream/write/tests.rs
================================================
use std::io::{Cursor, Write};
use std::iter;
use partial_io::{PartialOp, PartialWrite};
use crate::stream::decode_all;
use crate::stream::write::{Decoder, Encoder};
#[test]
fn test_cycle() {
let input = b"Abcdefghabcdefgh";
let buffer = Cursor::new(Vec::new());
let mut encoder = Encoder::new(buffer, 1).unwrap();
encoder.write_all(input).unwrap();
let encoded = encoder.finish().unwrap().into_inner();
// println!("Encoded: {:?}", encoded);
let buffer = Cursor::new(Vec::new());
let mut decoder = Decoder::new(buffer).unwrap();
decoder.write_all(&encoded).unwrap();
decoder.flush().unwrap();
let decoded = decoder.into_inner().into_inner();
assert_eq!(input, &decoded[..]);
}
/// Test that flush after a partial write works successfully without
/// corrupting the frame. This test is in this module because it checks
/// internal implementation details.
#[test]
fn test_partial_write_flush() {
let input = vec![b'b'; 128 * 1024];
let mut z = setup_partial_write(&input);
// flush shouldn't corrupt the stream
z.flush().unwrap();
let buf = z.finish().unwrap().into_inner();
assert_eq!(&decode_all(&buf[..]).unwrap(), &input);
}
/// Test that finish after a partial write works successfully without
/// corrupting the frame. This test is in this module because it checks
/// internal implementation details.
#[test]
fn test_partial_write_finish() {
let input = vec![b'b'; 128 * 1024];
let z = setup_partial_write(&input);
// finish shouldn't corrupt the stream
let buf = z.finish().unwrap().into_inner();
assert_eq!(&decode_all(&buf[..]).unwrap(), &input);
}
fn setup_partial_write(input_data: &[u8]) -> Encoder<PartialWrite<Vec<u8>>> {
let buf =
PartialWrite::new(Vec::new(), iter::repeat(PartialOp::Limited(1)));
let mut z = Encoder::new(buf, 1).unwrap();
// Fill in enough data to make sure the buffer gets written out.
z.write(input_data).unwrap();
{
let inner = &mut z.writer;
// At this point, the internal buffer in z should have some data.
assert_ne!(inner.offset(), inner.buffer().len());
}
z
}
================================================
FILE: src/stream/zio/mod.rs
================================================
//! Wrappers around raw operations implementing `std::io::{Read, Write}`.
mod reader;
mod writer;
pub use self::reader::Reader;
pub use self::writer::Writer;
================================================
FILE: src/stream/zio/reader.rs
================================================
use std::io::{self, BufRead, Read};
use crate::stream::raw::{InBuffer, Operation, OutBuffer};
// [ reader -> zstd ] -> output
/// Implements the [`Read`] API around an [`Operation`].
///
/// This can be used to wrap a raw in-memory operation in a read-focused API.
///
/// It can wrap either a compression or decompression operation, and pulls
/// input data from a wrapped `Read`.
pub struct Reader<R, D> {
reader: R,
operation: D,
state: State,
single_frame: bool,
finished_frame: bool,
}
enum State {
// Still actively reading from the inner `Read`
Reading,
// We reached EOF from the inner `Read`, now flushing.
PastEof,
// We are fully done, nothing can be read.
Finished,
}
impl<R, D> Reader<R, D> {
/// Creates a new `Reader`.
///
/// `reader` will be used to pull input data for the given operation.
pub fn new(reader: R, operation: D) -> Self {
Reader {
reader,
operation,
state: State::Reading,
single_frame: false,
finished_frame: false,
}
}
/// Sets `self` to stop after the first decoded frame.
pub fn set_single_frame(&mut self) {
self.single_frame = true;
}
/// Returns a mutable reference to the underlying operation.
pub fn operation_mut(&mut self) -> &mut D {
&mut self.operation
}
/// Returns a mutable reference to the underlying reader.
pub fn reader_mut(&mut self) -> &mut R {
&mut self.reader
}
/// Returns a reference to the underlying reader.
pub fn reader(&self) -> &R {
&self.reader
}
/// Returns the inner reader.
pub fn into_inner(self) -> R {
self.reader
}
/// Flush any internal buffer.
///
/// For encoders, this ensures all input consumed so far is compressed.
pub fn flush(&mut self, output: &mut [u8]) -> io::Result<usize>
where
D: Operation,
{
self.operation.flush(&mut OutBuffer::around(output))
}
}
// Read and retry on Interrupted errors.
fn fill_buf<R>(reader: &mut R) -> io::Result<&[u8]>
where
R: BufRead,
{
// This doesn't work right now because of the borrow-checker.
// When it can be made to compile, it would allow Reader to automatically
// retry on `Interrupted` error.
/*
loop {
match reader.fill_buf() {
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
otherwise => return otherwise,
}
}
*/
// Workaround for now
let res = reader.fill_buf()?;
// eprintln!("Filled buffer: {:?}", res);
Ok(res)
}
impl<R, D> Read for Reader<R, D>
where
R: BufRead,
D: Operation,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// Keep trying until _something_ has been written.
let mut first = true;
loop {
match self.state {
State::Reading => {
let (bytes_read, bytes_written) = {
// Start with a fresh pool of un-processed data.
// This is the only line that can return an interruption error.
let input = if first {
// eprintln!("First run, no input coming.");
b""
} else {
fill_buf(&mut self.reader)?
};
// eprintln!("Input = {:?}", input);
// It's possible we don't have any new data to read.
// (In this case we may still have zstd's own buffer to clear.)
if !first && input.is_empty() {
self.state = State::PastEof;
continue;
}
first = false;
let mut src = InBuffer::around(input);
let mut dst = OutBuffer::around(buf);
// We don't want empty input (from first=true) to cause a frame
// re-initialization.
if self.finished_frame && !input.is_empty() {
// eprintln!("!! Reigniting !!");
self.operation.reinit()?;
self.finished_frame = false;
}
// Phase 1: feed input to the operation
let hint = self.operation.run(&mut src, &mut dst)?;
// eprintln!(
// "Hint={} Just run our operation:\n In={:?}\n Out={:?}",
// hint, src, dst
// );
if hint == 0 {
// In practice this only happens when decoding, when we just finished
// reading a frame.
self.finished_frame = true;
if self.single_frame {
self.state = State::Finished;
}
}
// eprintln!("Output: {:?}", dst);
(src.pos(), dst.pos())
};
self.reader.consume(bytes_read);
if bytes_written > 0 {
return Ok(bytes_written);
}
// We need more data! Try again!
}
State::PastEof => {
let mut dst = OutBuffer::around(buf);
// We already sent all the input we could get to zstd. Time to flush out the
// buffer and be done with it.
// Phase 2: flush out the operation's buffer
// Keep calling `finish()` until the buffer is empty.
let hint = self
.operation
.finish(&mut dst, self.finished_frame)?;
// eprintln!("Hint: {} ; Output: {:?}", hint, dst);
if hint == 0 {
// This indicates that the footer is complete.
// This is the only way to terminate the stream cleanly.
self.state = State::Finished;
}
return Ok(dst.pos());
}
State::Finished => {
return Ok(0);
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::Reader;
use std::io::{Cursor, Read};
#[test]
fn test_noop() {
use crate::stream::raw::NoOp;
let input = b"AbcdefghAbcdefgh.";
// Test reader
let mut output = Vec::new();
{
let mut reader = Reader::new(Cursor::new(input), NoOp);
reader.read_to_end(&mut output).unwrap();
}
assert_eq!(&output, input);
}
#[test]
fn test_compress() {
use crate::stream::raw::Encoder;
let input = b"AbcdefghAbcdefgh.";
// Test reader
let mut output = Vec::new();
{
let mut reader =
Reader::new(Cursor::new(input), Encoder::new(1).unwrap());
reader.read_to_end(&mut output).unwrap();
}
// eprintln!("{:?}", output);
let decoded = crate::decode_all(&output[..]).unwrap();
assert_eq!(&decoded, input);
}
}
================================================
FILE: src/stream/zio/writer.rs
================================================
use std::io::{self, Write};
use crate::stream::raw::{InBuffer, Operation, OutBuffer};
// input -> [ zstd -> buffer -> writer ]
/// Implements the [`Write`] API around an [`Operation`].
///
/// This can be used to wrap a raw in-memory operation in a write-focused API.
///
/// It can be used with either compression or decompression, and forwards the
/// output to a wrapped `Write`.
pub struct Writer<W, D> {
/// Either an encoder or a decoder.
operation: D,
/// Where we send the output of the operation.
writer: W,
/// Offset into the buffer
///
/// Only things after this matter. Things before have already been sent to the writer.
offset: usize,
/// Output buffer
///
/// Where the operation writes, before it gets flushed to the writer
buffer: Vec<u8>,
// When `true`, indicates that nothing should be added to the buffer.
// All that's left if to empty the buffer.
finished: bool,
/// When `true`, the operation just finished a frame.
///
/// Only happens when decompressing.
/// The context needs to be re-initialized to process the next frame.
finished_frame: bool,
}
impl<W, D> Writer<W, D>
where
W: Write,
D: Operation,
{
/// Creates a new `Writer` with a fixed buffer capacity of 32KB
///
/// All output from the given operation will be forwarded to `writer`.
pub fn new(writer: W, operation: D) -> Self {
// 32KB buffer? That's what flate2 uses
Self::new_with_capacity(writer, operation, 32 * 1024)
}
/// Creates a new `Writer` with user defined capacity.
///
/// All output from the given operation will be forwarded to `writer`.
pub fn new_with_capacity(
writer: W,
operation: D,
capacity: usize,
) -> Self {
Self::with_output_buffer(
Vec::with_capacity(capacity),
writer,
operation,
)
}
/// Creates a new `Writer` using the given output buffer.
///
/// The output buffer _must_ have pre-allocated capacity (its capacity will not be changed after).
///
/// Usually you would use `Vec::with_capacity(desired_buffer_size)`.
pub fn with_output_buffer(
output_buffer: Vec<u8>,
writer: W,
operation: D,
) -> Self {
Writer {
writer,
operation,
offset: 0,
// 32KB buffer? That's what flate2 uses
buffer: output_buffer,
finished: false,
finished_frame: false,
}
}
/// Ends the stream.
///
/// This *must* be called after all data has been written to finish the
/// stream.
///
/// If you forget to call this and just drop the `Writer`, you *will* have
/// an incomplete output.
///
/// Keep calling it until it returns `Ok(())`, then don't call it again.
pub fn finish(&mut self) -> io::Result<()> {
loop {
// Keep trying until we're really done.
self.write_from_offset()?;
// At this point the buffer has been fully written out.
if self.finished {
return Ok(());
}
// Let's fill this buffer again!
let finished_frame = self.finished_frame;
let hint =
self.with_buffer(|dst, op| op.finish(dst, finished_frame));
self.offset = 0;
// println!("Hint: {:?}\nOut:{:?}", hint, &self.buffer);
// We return here if zstd had a problem.
// Could happen with invalid data, ...
let hint = hint?;
if hint != 0 && self.buffer.is_empty() {
// This happens if we are decoding an incomplete frame.
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"incomplete frame",
));
}
// println!("Finishing {}, {}", bytes_written, hint);
self.finished = hint == 0;
}
}
/// Run the given closure on `self.buffer`.
///
/// The buffer will be cleared, and made available wrapped in an `OutBuffer`.
fn with_buffer<F, T>(&mut self, f: F) -> T
where
F: FnOnce(&mut OutBuffer<'_, Vec<u8>>, &mut D) -> T,
{
self.buffer.clear();
let mut output = OutBuffer::around(&mut self.buffer);
// eprintln!("Output: {:?}", output);
f(&mut output, &mut self.operation)
}
/// Attempt to write `self.buffer` to the wrapped writer.
///
/// Returns `Ok(())` once all the buffer has been written.
fn write_from_offset(&mut self) -> io::Result<()> {
// The code looks a lot like `write_all`, but keeps track of what has
// been written in case we're interrupted.
while self.offset < self.buffer.len() {
match self.writer.write(&self.buffer[self.offset..]) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"writer will not accept any more data",
))
}
Ok(n) => self.offset += n,
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (),
Err(e) => return Err(e),
}
}
Ok(())
}
/// Return the wrapped `Writer` and `Operation`.
///
/// Careful: if you call this before calling [`Writer::finish()`], the
/// output may be incomplete.
pub fn into_inner(self) -> (W, D) {
(self.writer, self.operation)
}
/// Gives a reference to the inner writer.
pub fn writer(&self) -> &W {
&self.writer
}
/// Gives a mutable reference to the inner writer.
pub fn writer_mut(&mut self) -> &mut W {
&mut self.writer
}
/// Gives a reference to the inner operation.
pub fn operation(&self) -> &D {
&self.operation
}
/// Gives a mutable reference to the inner operation.
pub fn operation_mut(&mut self) -> &mut D {
&mut self.operation
}
/// Returns the offset in the current buffer. Only useful for debugging.
#[cfg(test)]
pub fn offset(&self) -> usize {
self.offset
}
/// Returns the current buffer. Only useful for debugging.
#[cfg(test)]
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
}
impl<W, D> Write for Writer<W, D>
where
W: Write,
D: Operation,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.finished {
return Err(io::Error::new(
io::ErrorKind::Other,
"encoder is finished",
));
}
// Keep trying until _something_ has been consumed.
// As soon as some input has been taken, we cannot afford
// to take any chance: if an error occurs, the user couldn't know
// that some data _was_ successfully written.
loop {
// First, write any pending data from `self.buffer`.
self.write_from_offset()?;
// At this point `self.buffer` can safely be discarded.
// Support writing concatenated frames by re-initializing the
// context.
if self.finished_frame {
self.operation.reinit()?;
self.finished_frame = false;
}
let mut src = InBuffer::around(buf);
let hint = self.with_buffer(|dst, op| op.run(&mut src, dst));
let bytes_read = src.pos;
// eprintln!(
// "Write Hint: {:?}\n src: {:?}\n dst: {:?}",
// hint, src, self.buffer
// );
self.offset = 0;
let hint = hint?;
if hint == 0 {
self.finished_frame = true;
}
// As we said, as soon as we've consumed something, return.
if bytes_read > 0 || buf.is_empty() {
// println!("Returning {}", bytes_read);
return Ok(bytes_read);
}
}
}
fn flush(&mut self) -> io::Result<()> {
let mut finished = self.finished;
loop {
// If the output is blocked or has an error, return now.
self.write_from_offset()?;
if finished {
break;
}
let hint = self.with_buffer(|dst, op| op.flush(dst));
self.offset = 0;
let hint = hint?;
finished = hint == 0;
}
self.writer.flush()
}
}
#[cfg(test)]
mod tests {
use super::Writer;
use std::io::Write;
#[test]
fn test_noop() {
use crate::stream::raw::NoOp;
let input = b"AbcdefghAbcdefgh.";
// Test writer
let mut output = Vec::new();
{
let mut writer = Writer::new(&mut output, NoOp);
writer.write_all(input).unwrap();
writer.finish().unwrap();
}
assert_eq!(&output, input);
}
#[test]
fn test_compress() {
use crate::stream::raw::Encoder;
let input = b"AbcdefghAbcdefgh.";
// Test writer
let mut output = Vec::new();
{
let mut writer =
Writer::new(&mut output, Encoder::new(1).unwrap());
writer.write_all(input).unwrap();
writer.finish().unwrap();
}
// println!("Output: {:?}", output);
let decoded = crate::decode_all(&output[..]).unwrap();
assert_eq!(&decoded, input);
}
#[test]
fn test_compress_with_capacity() {
use crate::stream::raw::Encoder;
let input = b"AbcdefghAbcdefgh.";
// Test writer
let mut output = Vec::new();
{
let mut writer = Writer::new_with_capacity(
&mut output,
Encoder::new(1).unwrap(),
64,
);
assert_eq!(writer.buffer.capacity(), 64);
writer.write_all(input).unwrap();
writer.finish().unwrap();
}
let decoded = crate::decode_all(&output[..]).unwrap();
assert_eq!(&decoded, input);
}
#[test]
fn test_decompress() {
use crate::stream::raw::Decoder;
let input = b"AbcdefghAbcdefgh.";
let compressed = crate::encode_all(&input[..], 1).unwrap();
// Test writer
let mut output = Vec::new();
{
let mut writer = Writer::new(&mut output, Decoder::new().unwrap());
writer.write_all(&compressed).unwrap();
writer.finish().unwrap();
}
// println!("Output: {:?}", output);
assert_eq!(&output, input);
}
#[test]
fn test_decompress_with_capacity() {
use crate::stream::raw::Decoder;
let input = b"AbcdefghAbcdefgh.";
let compressed = crate::encode_all(&input[..], 1).unwrap();
// Test writer
let mut output = Vec::new();
{
let mut writer = Writer::new_with_capacity(
&mut output,
Decoder::new().unwrap(),
64,
);
assert_eq!(writer.buffer.capacity(), 64);
writer.write_all(&compressed).unwrap();
writer.finish().unwrap();
}
assert_eq!(&output, input);
}
}
================================================
FILE: tests/issue_182.rs
================================================
const TEXT: &[u8] = include_bytes!("../assets/example.txt");
#[test]
#[should_panic]
fn test_issue_182() {
use std::io::BufRead;
let compressed = zstd::encode_all(TEXT, 3).unwrap();
let truncated = &compressed[..compressed.len() / 2];
let rdr = zstd::Decoder::new(truncated).unwrap();
let rdr = std::io::BufReader::new(rdr);
for line in rdr.lines() {
line.unwrap();
}
}
================================================
FILE: zstd-safe/Cargo.toml
================================================
[package]
authors = ["Alexandre Bury <alexandre.bury@gmail.com>"]
name = "zstd-safe"
build = "build.rs"
version = "7.2.4"
description = "Safe low-level bindings for the zstd compression library."
keywords = ["zstd", "zstandard", "compression"]
categories = ["api-bindings", "compression"]
repository = "https://github.com/gyscos/zstd-rs"
license = "BSD-3-Clause"
readme = "Readme.md"
edition = "2018"
rust-version = "1.64"
exclude = ["update_consts.sh"]
[package.metadata.docs.rs]
features = ["experimental", "arrays", "std", "zdict_builder", "doc-cfg"]
[dependencies]
zstd-sys = { path = "zstd-sys", version = "2.0.15", default-features = false }
[features]
default = ["legacy", "arrays", "zdict_builder"]
bindgen = ["zstd-sys/bindgen"]
debug = ["zstd-sys/debug"]
experimental = ["zstd-sys/experimental"]
legacy = ["zstd-sys/legacy"]
pkg-config = ["zstd-sys/pkg-config"]
std = ["zstd-sys/std"] # Implements WriteBuf for std types like Cursor and Vec.
zstdmt = ["zstd-sys/zstdmt"]
thin = ["zstd-sys/thin"]
arrays = []
no_asm = ["zstd-sys/no_asm"]
doc-cfg = []
zdict_builder = ["zstd-sys/zdict_builder"]
seekable = ["zstd-sys/seekable"]
# These two are for cross-language LTO.
# Will only work if `clang` is used to build the C library.
fat-lto = ["zstd-sys/fat-lto"]
thin-lto = ["zstd-sys/thin-lto"]
[lints.rust]
non_upper_case_globals = "allow"
================================================
FILE: zstd-safe/LICENSE
================================================
BSD 3-Clause License
Copyright (c) 2026, Alexandre Bury
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: zstd-safe/Readme.md
================================================
# zstd-safe
This is a thin, no-std, safe abstraction built on top of the bindings from [zstd-sys].
It is close to a 1-for-1 mapping to the C functions, but uses rust types like slices instead of pointers and lengths.
For a more comfortable higher-level library (with `Read`/`Write` implementations), see [zstd-rs].
[zstd-rs]: https://github.com/gyscos/zstd-rs/tree/main/zstd-safe/zstd-sys
[zstd-rs]: https://github.com/gyscos/zstd-rs
================================================
FILE: zstd-safe/build.rs
================================================
fn main() {
// Force the `std` feature in some cases
let target_arch =
std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
if target_arch == "wasm32" || target_os == "hermit" {
println!("cargo:rustc-cfg=feature=\"std\"");
}
}
================================================
FILE: zstd-safe/fuzz/.gitignore
================================================
target
corpus
artifacts
coverage
================================================
FILE: zstd-safe/fuzz/Cargo.toml
================================================
[package]
name = "zstd-safe-fuzz"
version = "0.0.0"
publish = false
edition = "2018"
[package.metadata]
cargo-fuzz = true
[package.metadata.docs.rs]
features = ["std"]
[dependencies]
libfuzzer-sys = "0.4"
zstd-sys = { path = "../zstd-sys", version = "2.0.10", default-features = false }
[features]
std = ["zstd-sys/std"]
[dependencies.zstd-safe]
path = ".."
[[bin]]
name = "zstd_fuzzer"
path = "fuzz_targets/zstd_fuzzer.rs"
test = false
doc = false
bench = false
================================================
FILE: zstd-safe/fuzz/fuzz_targets/zstd_fuzzer.rs
================================================
#![no_main]
extern crate zstd_safe;
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
// Generate random sized buffer
let buffer_size = std::cmp::min(data.len() * 2, 2048);
let mut buffer = vec![0u8; buffer_size];
// Fuzz compression and decompression
for level in 0..=20 {
if let Ok(written) = zstd_safe::compress(&mut buffer[..], data, level) {
let compressed = &buffer[..written];
let mut decompressed = vec![0u8; buffer_size];
let _ = zstd_safe::decompress(&mut decompressed[..], compressed).unwrap_or_else(|_| 0);
}
}
// Fuzz compression and decompression with CCtx
let mut cctx = zstd_safe::CCtx::default();
if let Ok(written) = cctx.compress(&mut buffer[..], data, 3) {
let compressed = &buffer[..written];
let mut dctx = zstd_safe::DCtx::default();
let mut decompressed = vec![0u8; buffer_size];
let _ = dctx.decompress(&mut decompressed[..], compressed).unwrap_or_else(|_| 0);
}
// Fuzz compression and decompression on dict
let dict = b"sample dictionary for zstd fuzzing";
let mut cctx_dict = zstd_safe::CCtx::default();
if let Ok(written) = cctx_dict.compress_using_dict(&mut buffer[..], data, dict, 3) {
let compressed = &buffer[..written];
let mut dctx_dict = zstd_safe::DCtx::default();
let mut decompressed = vec![0u8; buffer_size];
let _ = dctx_dict.decompress_using_dict(&mut decompressed[..], compressed, dict).unwrap_or_else(|_| 0);
}
// Fuzz compression and decompression with streaming
let mut cctx_stream = zstd_safe::CCtx::default();
let mut dctx_stream = zstd_safe::DCtx::default();
let mut in_buffer = zstd_safe::InBuffer::around(data);
let mut out_buffer = zstd_safe::OutBuffer::around(&mut buffer[..]);
if let Ok(_) = cctx_stream.compress_stream(&mut out_buffer, &mut in_buffer) {
let mut decompressed_stream = vec![0u8; buffer_size];
let mut out_buffer_stream = zstd_safe::OutBuffer::around(&mut decompressed_stream[..]);
let mut in_buffer_stream = zstd_safe::InBuffer::around(out_buffer.as_slice());
let _ = dctx_stream.decompress_stream(&mut out_buffer_stream, &mut in_buffer_stream).unwrap_or_else(|_| 0);
}
// Fuzz error handling and malformed input
let mut cctx_param = zstd_safe::CCtx::default();
if let Ok(_) = cctx_param.set_parameter(zstd_safe::CParameter::ChecksumFlag(true)) {
if let Ok(written) = cctx_param.compress2(&mut buffer[..], data) {
let compressed = &buffer[..written];
let mut dctx_param = zstd_safe::DCtx::default();
let mut decompressed = vec![0u8; buffer_size];
let _ = dctx_param.decompress(&mut decompressed[..], compressed).unwrap_or_else(|_| 0);
}
}
if let Ok(written) = zstd_safe::compress(&mut buffer[..], data, 3) {
let compressed = &mut buffer[..written];
for i in (0..compressed.len()).step_by(5) {
compressed[i] = compressed[i].wrapping_add(1);
}
let mut decompressed = vec![0u8; 2048];
let mut dctx = zstd_safe::DCtx::default();
let _ = dctx.decompress(&mut decompressed[..], compressed).unwrap_or_else(|_| 0);
}
});
================================================
FILE: zstd-safe/src/constants.rs
================================================
// This file has been generated by ./update_consts.sh
pub const BLOCKSIZELOG_MAX: u32 = zstd_sys::ZSTD_BLOCKSIZELOG_MAX;
pub const BLOCKSIZE_MAX: u32 = zstd_sys::ZSTD_BLOCKSIZE_MAX;
pub const CLEVEL_DEFAULT: CompressionLevel = zstd_sys::ZSTD_CLEVEL_DEFAULT as CompressionLevel;
pub const CONTENTSIZE_ERROR: u64 = zstd_sys::ZSTD_CONTENTSIZE_ERROR as u64;
pub const CONTENTSIZE_UNKNOWN: u64 = zstd_sys::ZSTD_CONTENTSIZE_UNKNOWN as u64;
pub const MAGIC_DICTIONARY: u32 = zstd_sys::ZSTD_MAGIC_DICTIONARY;
pub const MAGICNUMBER: u32 = zstd_sys::ZSTD_MAGICNUMBER;
pub const MAGIC_SKIPPABLE_MASK: u32 = zstd_sys::ZSTD_MAGIC_SKIPPABLE_MASK;
pub const MAGIC_SKIPPABLE_START: u32 = zstd_sys::ZSTD_MAGIC_SKIPPABLE_START;
pub const VERSION_MAJOR: u32 = zstd_sys::ZSTD_VERSION_MAJOR;
pub const VERSION_MINOR: u32 = zstd_sys::ZSTD_VERSION_MINOR;
pub const VERSION_NUMBER: u32 = zstd_sys::ZSTD_VERSION_NUMBER;
pub const VERSION_RELEASE: u32 = zstd_sys::ZSTD_VERSION_RELEASE;
================================================
FILE: zstd-safe/src/constants_experimental.rs
================================================
// This file has been generated by ./update_consts.sh
pub const BLOCKSIZE_MAX_MIN: u32 = zstd_sys::ZSTD_BLOCKSIZE_MAX_MIN;
pub const BLOCKSPLITTER_LEVEL_MAX: u32 = zstd_sys::ZSTD_BLOCKSPLITTER_LEVEL_MAX;
pub const CHAINLOG_MAX_32: u32 = zstd_sys::ZSTD_CHAINLOG_MAX_32;
pub const CHAINLOG_MAX_64: u32 = zstd_sys::ZSTD_CHAINLOG_MAX_64;
pub const CHAINLOG_MIN: u32 = zstd_sys::ZSTD_CHAINLOG_MIN;
pub const FRAMEHEADERSIZE_MAX: u32 = zstd_sys::ZSTD_FRAMEHEADERSIZE_MAX;
pub const HASHLOG_MIN: u32 = zstd_sys::ZSTD_HASHLOG_MIN;
pub const LDM_BUCKETSIZELOG_MAX: u32 = zstd_sys::ZSTD_LDM_BUCKETSIZELOG_MAX;
pub const LDM_BUCKETSIZELOG_MIN: u32 = zstd_sys::ZSTD_LDM_BUCKETSIZELOG_MIN;
pub const LDM_HASHLOG_MIN: u32 = zstd_sys::ZSTD_LDM_HASHLOG_MIN;
pub const LDM_HASHRATELOG_MIN: u32 = zstd_sys::ZSTD_LDM_HASHRATELOG_MIN;
pub const LDM_MINMATCH_MAX: u32 = zstd_sys::ZSTD_LDM_MINMATCH_MAX;
pub const LDM_MINMATCH_MIN: u32 = zstd_sys::ZSTD_LDM_MINMATCH_MIN;
pub const MINMATCH_MAX: u32 = zstd_sys::ZSTD_MINMATCH_MAX;
pub const MINMATCH_MIN: u32 = zstd_sys::ZSTD_MINMATCH_MIN;
pub const OVERLAPLOG_MAX: u32 = zstd_sys::ZSTD_OVERLAPLOG_MAX;
pub const OVERLAPLOG_MIN: u32 = zstd_sys::ZSTD_OVERLAPLOG_MIN;
pub const SEARCHLOG_MIN: u32 = zstd_sys::ZSTD_SEARCHLOG_MIN;
pub const SKIPPABLEHEADERSIZE: u32 = zstd_sys::ZSTD_SKIPPABLEHEADERSIZE;
pub const SRCSIZEHINT_MIN: u32 = zstd_sys::ZSTD_SRCSIZEHINT_MIN;
pub const TARGETCBLOCKSIZE_MAX: u32 = zstd_sys::ZSTD_TARGETCBLOCKSIZE_MAX;
pub const TARGETCBLOCKSIZE_MIN: u32 = zstd_sys::ZSTD_TARGETCBLOCKSIZE_MIN;
pub const TARGETLENGTH_MAX: u32 = zstd_sys::ZSTD_TARGETLENGTH_MAX;
pub const TARGETLENGTH_MIN: u32 = zstd_sys::ZSTD_TARGETLENGTH_MIN;
pub const WINDOWLOG_LIMIT_DEFAULT: u32 = zstd_sys::ZSTD_WINDOWLOG_LIMIT_DEFAULT;
pub const WINDOWLOG_MAX_32: u32 = zstd_sys::ZSTD_WINDOWLOG_MAX_32;
pub const WINDOWLOG_MAX_64: u32 = zstd_sys::ZSTD_WINDOWLOG_MAX_64;
pub const WINDOWLOG_MIN: u32 = zstd_sys::ZSTD_WINDOWLOG_MIN;
================================================
FILE: zstd-safe/src/constants_seekable.rs
================================================
// This file has been generated by ./update_consts.sh
pub const SEEKABLE_FRAMEINDEX_TOOLARGE: u64 = zstd_sys::ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE as u64;
pub const SEEKABLE_MAGICNUMBER: u32 = zstd_sys::ZSTD_SEEKABLE_MAGICNUMBER;
pub const SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE: u32 = zstd_sys::ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE;
pub const SEEKABLE_MAXFRAMES: u32 = zstd_sys::ZSTD_SEEKABLE_MAXFRAMES;
pub const seekTableFooterSize: u32 = zstd_sys::ZSTD_seekTableFooterSize;
================================================
FILE: zstd-safe/src/lib.rs
================================================
#![no_std]
//! Minimal safe wrapper around zstd-sys.
//!
//! This crates provides a minimal translation of the [zstd-sys] methods.
//! For a more comfortable high-level library, see the [zstd] crate.
//!
//! [zstd-sys]: https://crates.io/crates/zstd-sys
//! [zstd]: https://crates.io/crates/zstd
//!
//! Most of the functions here map 1-for-1 to a function from
//! [the C zstd library][zstd-c] mentioned in their descriptions.
//! Check the [source documentation][doc] for more information on their
//! behaviour.
//!
//! [doc]: https://facebook.github.io/zstd/zstd_manual.html
//! [zstd-c]: https://facebook.github.io/zstd/
//!
//! Features denoted as experimental in the C library are hidden behind an
//! `experimental` feature.
#![cfg_attr(feature = "doc-cfg", feature(doc_cfg))]
// TODO: Use alloc feature instead to implement stuff for Vec
// TODO: What about Cursor?
#[cfg(feature = "std")]
extern crate std;
#[cfg(test)]
mod tests;
#[cfg(feature = "seekable")]
pub mod seekable;
// Re-export zstd-sys
pub use zstd_sys;
/// How to compress data.
pub use zstd_sys::ZSTD_strategy as Strategy;
/// Frame progression state.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub use zstd_sys::ZSTD_frameProgression as FrameProgression;
/// Reset directive.
// pub use zstd_sys::ZSTD_ResetDirective as ResetDirective;
use core::ffi::{c_char, c_int, c_ulonglong, c_void};
use core::marker::PhantomData;
use core::num::{NonZeroU32, NonZeroU64};
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
use core::str;
include!("constants.rs");
#[cfg(feature = "experimental")]
include!("constants_experimental.rs");
#[cfg(feature = "seekable")]
include!("constants_seekable.rs");
/// Represents the compression level used by zstd.
pub type CompressionLevel = i32;
/// Represents a possible error from the zstd library.
pub type ErrorCode = usize;
/// Wrapper result around most zstd functions.
///
/// Either a success code (usually number of bytes written), or an error code.
pub type SafeResult = Result<usize, ErrorCode>;
/// Indicates an error happened when parsing the frame content size.
///
/// The stream may be corrupted, or the given frame prefix was too small.
#[derive(Debug)]
pub struct ContentSizeError;
impl core::fmt::Display for ContentSizeError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("Could not get content size")
}
}
/// Returns true if code represents error.
fn is_error(code: usize) -> bool {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_isError(code) != 0 }
}
/// Parse the result code
///
/// Returns the number of bytes written if the code represents success,
/// or the error message code otherwise.
fn parse_code(code: usize) -> SafeResult {
if !is_error(code) {
Ok(code)
} else {
Err(code)
}
}
/// Parse a content size value.
///
/// zstd uses 2 special content size values to indicate either unknown size or parsing error.
fn parse_content_size(
content_size: u64,
) -> Result<Option<u64>, ContentSizeError> {
match content_size {
CONTENTSIZE_ERROR => Err(ContentSizeError),
CONTENTSIZE_UNKNOWN => Ok(None),
other => Ok(Some(other)),
}
}
fn ptr_void(src: &[u8]) -> *const c_void {
src.as_ptr() as *const c_void
}
fn ptr_mut_void(dst: &mut (impl WriteBuf + ?Sized)) -> *mut c_void {
dst.as_mut_ptr() as *mut c_void
}
/// Returns the ZSTD version.
///
/// Returns `major * 10_000 + minor * 100 + patch`.
/// So 1.5.3 would be returned as `10_503`.
pub fn version_number() -> u32 {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_versionNumber() as u32 }
}
/// Returns a string representation of the ZSTD version.
///
/// For example "1.5.3".
pub fn version_string() -> &'static str {
// Safety: Assumes `ZSTD_versionString` returns a valid utf8 string.
unsafe { c_char_to_str(zstd_sys::ZSTD_versionString()) }
}
/// Returns the minimum (fastest) compression level supported.
///
/// This is likely going to be a _very_ large negative number.
pub fn min_c_level() -> CompressionLevel {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_minCLevel() as CompressionLevel }
}
/// Returns the maximum (slowest) compression level supported.
pub fn max_c_level() -> CompressionLevel {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_maxCLevel() as CompressionLevel }
}
/// Wraps the `ZSTD_compress` function.
///
/// This will try to compress `src` entirely and write the result to `dst`, returning the number of
/// bytes written. If `dst` is too small to hold the compressed content, an error will be returned.
///
/// For streaming operations that don't require to store the entire input/output in memory, see
/// `compress_stream`.
pub fn compress<C: WriteBuf + ?Sized>(
dst: &mut C,
src: &[u8],
compression_level: CompressionLevel,
) -> SafeResult {
// Safety: ZSTD_compress indeed returns how many bytes have been written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compress(
buffer,
capacity,
ptr_void(src),
src.len(),
compression_level,
))
})
}
}
/// Wraps the `ZSTD_decompress` function.
///
/// This is a one-step decompression (not streaming).
///
/// You will need to make sure `dst` is large enough to store all the decompressed content, or an
/// error will be returned.
///
/// If decompression was a success, the number of bytes written will be returned.
pub fn decompress<C: WriteBuf + ?Sized>(
dst: &mut C,
src: &[u8],
) -> SafeResult {
// Safety: ZSTD_decompress indeed returns how many bytes have been written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_decompress(
buffer,
capacity,
ptr_void(src),
src.len(),
))
})
}
}
/// Wraps the `ZSTD_getDecompressedSize` function.
///
/// Returns `None` if the size could not be found, or if the content is actually empty.
#[deprecated(note = "Use ZSTD_getFrameContentSize instead")]
pub fn get_decompressed_size(src: &[u8]) -> Option<NonZeroU64> {
// Safety: Just FFI
NonZeroU64::new(unsafe {
zstd_sys::ZSTD_getDecompressedSize(ptr_void(src), src.len()) as u64
})
}
/// Maximum compressed size in worst case single-pass scenario
pub fn compress_bound(src_size: usize) -> usize {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_compressBound(src_size) }
}
/// Compression context
///
/// It is recommended to allocate a single context per thread and re-use it
/// for many compression operations.
pub struct CCtx<'a>(NonNull<zstd_sys::ZSTD_CCtx>, PhantomData<&'a ()>);
impl Default for CCtx<'_> {
fn default() -> Self {
CCtx::create()
}
}
impl<'a> CCtx<'a> {
/// Tries to create a new context.
///
/// Returns `None` if zstd returns a NULL pointer - may happen if allocation fails.
pub fn try_create() -> Option<Self> {
// Safety: Just FFI
Some(CCtx(
NonNull::new(unsafe { zstd_sys::ZSTD_createCCtx() })?,
PhantomData,
))
}
/// Wrap `ZSTD_createCCtx`
///
/// # Panics
///
/// If zstd returns a NULL pointer.
pub fn create() -> Self {
Self::try_create()
.expect("zstd returned null pointer when creating new context")
}
/// Wraps the `ZSTD_compressCCtx()` function
pub fn compress<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
compression_level: CompressionLevel,
) -> SafeResult {
// Safety: ZSTD_compressCCtx returns how many bytes were written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compressCCtx(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
compression_level,
))
})
}
}
/// Wraps the `ZSTD_compress2()` function.
pub fn compress2<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
) -> SafeResult {
// Safety: ZSTD_compress2 returns how many bytes were written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compress2(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
))
})
}
}
/// Wraps the `ZSTD_compress_usingDict()` function.
pub fn compress_using_dict<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
dict: &[u8],
compression_level: CompressionLevel,
) -> SafeResult {
// Safety: ZSTD_compress_usingDict returns how many bytes were written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compress_usingDict(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
ptr_void(dict),
dict.len(),
compression_level,
))
})
}
}
/// Wraps the `ZSTD_compress_usingCDict()` function.
pub fn compress_using_cdict<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
cdict: &CDict<'_>,
) -> SafeResult {
// Safety: ZSTD_compress_usingCDict returns how many bytes were written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compress_usingCDict(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
cdict.0.as_ptr(),
))
})
}
}
/// Initializes the context with the given compression level.
///
/// This is equivalent to running:
/// * `reset()`
/// * `set_parameter(CompressionLevel, compression_level)`
pub fn init(&mut self, compression_level: CompressionLevel) -> SafeResult {
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_initCStream(self.0.as_ptr(), compression_level)
};
parse_code(code)
}
/// Wraps the `ZSTD_initCStream_srcSize()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
#[deprecated]
pub fn init_src_size(
&mut self,
compression_level: CompressionLevel,
pledged_src_size: u64,
) -> SafeResult {
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_initCStream_srcSize(
self.0.as_ptr(),
compression_level as c_int,
pledged_src_size as c_ulonglong,
)
};
parse_code(code)
}
/// Wraps the `ZSTD_initCStream_usingDict()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
#[deprecated]
pub fn init_using_dict(
&mut self,
dict: &[u8],
compression_level: CompressionLevel,
) -> SafeResult {
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_initCStream_usingDict(
self.0.as_ptr(),
ptr_void(dict),
dict.len(),
compression_level,
)
};
parse_code(code)
}
/// Wraps the `ZSTD_initCStream_usingCDict()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
#[deprecated]
pub fn init_using_cdict<'b>(&mut self, cdict: &CDict<'b>) -> SafeResult
where
'b: 'a, // Dictionary outlives the stream.
{
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_initCStream_usingCDict(
self.0.as_ptr(),
cdict.0.as_ptr(),
)
};
parse_code(code)
}
/// Tries to load a dictionary.
///
/// The dictionary content will be copied internally and does not need to be kept alive after
/// calling this function.
///
/// If you need to use the same dictionary for multiple contexts, it may be more efficient to
/// create a `CDict` first, then loads that.
///
/// The dictionary will apply to all compressed frames, until a new dictionary is set.
pub fn load_dictionary(&mut self, dict: &[u8]) -> SafeResult {
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_loadDictionary(
self.0.as_ptr(),
ptr_void(dict),
dict.len(),
)
})
}
/// Wraps the `ZSTD_CCtx_refCDict()` function.
///
/// Dictionary must outlive the context.
pub fn ref_cdict<'b>(&mut self, cdict: &CDict<'b>) -> SafeResult
where
'b: 'a,
{
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_refCDict(self.0.as_ptr(), cdict.0.as_ptr())
})
}
/// Return to "no-dictionary" mode.
///
/// This will disable any dictionary/prefix previously registered for future frames.
pub fn disable_dictionary(&mut self) -> SafeResult {
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_loadDictionary(
self.0.as_ptr(),
core::ptr::null(),
0,
)
})
}
/// Use some prefix as single-use dictionary for the next compressed frame.
///
/// Just like a dictionary, decompression will need to be given the same prefix.
///
/// This is best used if the "prefix" looks like the data to be compressed.
pub fn ref_prefix<'b>(&mut self, prefix: &'b [u8]) -> SafeResult
where
'b: 'a,
{
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_refPrefix(
self.0.as_ptr(),
ptr_void(prefix),
prefix.len(),
)
})
}
/// Performs a step of a streaming compression operation.
///
/// This will read some data from `input` and/or write some data to `output`.
///
/// # Returns
///
/// A hint for the "ideal" amount of input data to provide in the next call.
///
/// This hint is only for performance purposes.
///
/// Wraps the `ZSTD_compressStream()` function.
pub fn compress_stream<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
input: &mut InBuffer<'_>,
) -> SafeResult {
let mut output = output.wrap();
let mut input = input.wrap();
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_compressStream(
self.0.as_ptr(),
ptr_mut(&mut output),
ptr_mut(&mut input),
)
};
parse_code(code)
}
/// Performs a step of a streaming compression operation.
///
/// This will read some data from `input` and/or write some data to `output`.
///
/// The `end_op` directive can be used to specify what to do after: nothing special, flush
/// internal buffers, or end the frame.
///
/// # Returns
///
/// An lower bound for the amount of data that still needs to be flushed out.
///
/// This is useful when flushing or ending the frame: you need to keep calling this function
/// until it returns 0.
///
/// Wraps the `ZSTD_compressStream2()` function.
pub fn compress_stream2<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
input: &mut InBuffer<'_>,
end_op: zstd_sys::ZSTD_EndDirective,
) -> SafeResult {
let mut output = output.wrap();
let mut input = input.wrap();
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_compressStream2(
self.0.as_ptr(),
ptr_mut(&mut output),
ptr_mut(&mut input),
end_op,
)
})
}
/// Flush any intermediate buffer.
///
/// To fully flush, you should keep calling this function until it returns `Ok(0)`.
///
/// Wraps the `ZSTD_flushStream()` function.
pub fn flush_stream<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
) -> SafeResult {
let mut output = output.wrap();
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_flushStream(self.0.as_ptr(), ptr_mut(&mut output))
};
parse_code(code)
}
/// Ends the stream.
///
/// You should keep calling this function until it returns `Ok(0)`.
///
/// Wraps the `ZSTD_endStream()` function.
pub fn end_stream<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
) -> SafeResult {
let mut output = output.wrap();
// Safety: Just FFI
let code = unsafe {
zstd_sys::ZSTD_endStream(self.0.as_ptr(), ptr_mut(&mut output))
};
parse_code(code)
}
/// Returns the size currently used by this context.
///
/// This may change over time.
pub fn sizeof(&self) -> usize {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_sizeof_CCtx(self.0.as_ptr()) }
}
/// Resets the state of the context.
///
/// Depending on the reset mode, it can reset the session, the parameters, or both.
///
/// Wraps the `ZSTD_CCtx_reset()` function.
pub fn reset(&mut self, reset: ResetDirective) -> SafeResult {
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_reset(self.0.as_ptr(), reset.as_sys())
})
}
/// Sets a compression parameter.
///
/// Some of these parameters need to be set during de-compression as well.
pub fn set_parameter(&mut self, param: CParameter) -> SafeResult {
// TODO: Until bindgen properly generates a binding for this, we'll need to do it here.
#[cfg(feature = "experimental")]
use zstd_sys::ZSTD_cParameter::{
ZSTD_c_experimentalParam1 as ZSTD_c_rsyncable,
ZSTD_c_experimentalParam10 as ZSTD_c_stableOutBuffer,
ZSTD_c_experimentalParam11 as ZSTD_c_blockDelimiters,
ZSTD_c_experimentalParam12 as ZSTD_c_validateSequences,
ZSTD_c_experimentalParam13 as ZSTD_c_useBlockSplitter,
ZSTD_c_experimentalParam14 as ZSTD_c_useRowMatchFinder,
ZSTD_c_experimentalParam15 as ZSTD_c_deterministicRefPrefix,
ZSTD_c_experimentalParam16 as ZSTD_c_prefetchCDictTables,
ZSTD_c_experimentalParam17 as ZSTD_c_enableSeqProducerFallback,
ZSTD_c_experimentalParam18 as ZSTD_c_maxBlockSize,
ZSTD_c_experimentalParam19 as ZSTD_c_searchForExternalRepcodes,
ZSTD_c_experimentalParam2 as ZSTD_c_format,
ZSTD_c_experimentalParam3 as ZSTD_c_forceMaxWindow,
ZSTD_c_experimentalParam4 as ZSTD_c_forceAttachDict,
ZSTD_c_experimentalParam5 as ZSTD_c_literalCompressionMode,
ZSTD_c_experimentalParam7 as ZSTD_c_srcSizeHint,
ZSTD_c_experimentalParam8 as ZSTD_c_enableDedicatedDictSearch,
ZSTD_c_experimentalParam9 as ZSTD_c_stableInBuffer,
};
use zstd_sys::ZSTD_cParameter::*;
use CParameter::*;
let (param, value) = match param {
#[cfg(feature = "experimental")]
RSyncable(rsyncable) => (ZSTD_c_rsyncable, rsyncable as c_int),
#[cfg(feature = "experimental")]
Format(format) => (ZSTD_c_format, format as c_int),
#[cfg(feature = "experimental")]
ForceMaxWindow(force) => (ZSTD_c_forceMaxWindow, force as c_int),
#[cfg(feature = "experimental")]
ForceAttachDict(force) => (ZSTD_c_forceAttachDict, force as c_int),
#[cfg(feature = "experimental")]
LiteralCompressionMode(mode) => {
(ZSTD_c_literalCompressionMode, mode as c_int)
}
#[cfg(feature = "experimental")]
SrcSizeHint(value) => (ZSTD_c_srcSizeHint, value as c_int),
#[cfg(feature = "experimental")]
EnableDedicatedDictSearch(enable) => {
(ZSTD_c_enableDedicatedDictSearch, enable as c_int)
}
#[cfg(feature = "experimental")]
StableInBuffer(stable) => (ZSTD_c_stableInBuffer, stable as c_int),
#[cfg(feature = "experimental")]
StableOutBuffer(stable) => {
(ZSTD_c_stableOutBuffer, stable as c_int)
}
#[cfg(feature = "experimental")]
BlockDelimiters(value) => (ZSTD_c_blockDelimiters, value as c_int),
#[cfg(feature = "experimental")]
ValidateSequences(validate) => {
(ZSTD_c_validateSequences, validate as c_int)
}
#[cfg(feature = "experimental")]
UseBlockSplitter(split) => {
(ZSTD_c_useBlockSplitter, split as c_int)
}
#[cfg(feature = "experimental")]
UseRowMatchFinder(mode) => {
(ZSTD_c_useRowMatchFinder, mode as c_int)
}
#[cfg(feature = "experimental")]
DeterministicRefPrefix(deterministic) => {
(ZSTD_c_deterministicRefPrefix, deterministic as c_int)
}
#[cfg(feature = "experimental")]
PrefetchCDictTables(prefetch) => {
(ZSTD_c_prefetchCDictTables, prefetch as c_int)
}
#[cfg(feature = "experimental")]
EnableSeqProducerFallback(enable) => {
(ZSTD_c_enableSeqProducerFallback, enable as c_int)
}
#[cfg(feature = "experimental")]
MaxBlockSize(value) => (ZSTD_c_maxBlockSize, value as c_int),
#[cfg(feature = "experimental")]
SearchForExternalRepcodes(value) => {
(ZSTD_c_searchForExternalRepcodes, value as c_int)
}
TargetCBlockSize(value) => {
(ZSTD_c_targetCBlockSize, value as c_int)
}
CompressionLevel(level) => (ZSTD_c_compressionLevel, level),
WindowLog(value) => (ZSTD_c_windowLog, value as c_int),
HashLog(value) => (ZSTD_c_hashLog, value as c_int),
ChainLog(value) => (ZSTD_c_chainLog, value as c_int),
SearchLog(value) => (ZSTD_c_searchLog, value as c_int),
MinMatch(value) => (ZSTD_c_minMatch, value as c_int),
TargetLength(value) => (ZSTD_c_targetLength, value as c_int),
Strategy(strategy) => (ZSTD_c_strategy, strategy as c_int),
EnableLongDistanceMatching(flag) => {
(ZSTD_c_enableLongDistanceMatching, flag as c_int)
}
LdmHashLog(value) => (ZSTD_c_ldmHashLog, value as c_int),
LdmMinMatch(value) => (ZSTD_c_ldmMinMatch, value as c_int),
LdmBucketSizeLog(value) => {
(ZSTD_c_ldmBucketSizeLog, value as c_int)
}
LdmHashRateLog(value) => (ZSTD_c_ldmHashRateLog, value as c_int),
ContentSizeFlag(flag) => (ZSTD_c_contentSizeFlag, flag as c_int),
ChecksumFlag(flag) => (ZSTD_c_checksumFlag, flag as c_int),
DictIdFlag(flag) => (ZSTD_c_dictIDFlag, flag as c_int),
NbWorkers(value) => (ZSTD_c_nbWorkers, value as c_int),
JobSize(value) => (ZSTD_c_jobSize, value as c_int),
OverlapSizeLog(value) => (ZSTD_c_overlapLog, value as c_int),
};
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_setParameter(self.0.as_ptr(), param, value)
})
}
/// Guarantee that the input size will be this value.
///
/// If given `None`, assumes the size is unknown.
///
/// Unless explicitly disabled, this will cause the size to be written in the compressed frame
/// header.
///
/// If the actual data given to compress has a different size, an error will be returned.
pub fn set_pledged_src_size(
&mut self,
pledged_src_size: Option<u64>,
) -> SafeResult {
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_setPledgedSrcSize(
self.0.as_ptr(),
pledged_src_size.unwrap_or(CONTENTSIZE_UNKNOWN) as c_ulonglong,
)
})
}
/// Creates a copy of this context.
///
/// This only works before any data has been compressed. An error will be
/// returned otherwise.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn try_clone(
&self,
pledged_src_size: Option<u64>,
) -> Result<Self, ErrorCode> {
// Safety: Just FFI
let context = NonNull::new(unsafe { zstd_sys::ZSTD_createCCtx() })
.ok_or(0usize)?;
// Safety: Just FFI
parse_code(unsafe {
zstd_sys::ZSTD_copyCCtx(
context.as_ptr(),
self.0.as_ptr(),
pledged_src_size.unwrap_or(CONTENTSIZE_UNKNOWN),
)
})?;
Ok(CCtx(context, self.1))
}
/// Wraps the `ZSTD_getBlockSize()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn get_block_size(&self) -> usize {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_getBlockSize(self.0.as_ptr()) }
}
/// Wraps the `ZSTD_compressBlock()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn compress_block<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
) -> SafeResult {
// Safety: ZSTD_compressBlock returns the number of bytes written.
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_compressBlock(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
))
})
}
}
/// Returns the recommended input buffer size.
///
/// Using this size may result in minor performance boost.
pub fn in_size() -> usize {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_CStreamInSize() }
}
/// Returns the recommended output buffer size.
///
/// Using this may result in minor performance boost.
pub fn out_size() -> usize {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_CStreamOutSize() }
}
/// Use a shared thread pool for this context.
///
/// Thread pool must outlive the context.
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
pub fn ref_thread_pool<'b>(&mut self, pool: &'b ThreadPool) -> SafeResult
where
'b: 'a,
{
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_refThreadPool(self.0.as_ptr(), pool.0.as_ptr())
})
}
/// Return to using a private thread pool for this context.
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
pub fn disable_thread_pool(&mut self) -> SafeResult {
parse_code(unsafe {
zstd_sys::ZSTD_CCtx_refThreadPool(
self.0.as_ptr(),
core::ptr::null_mut(),
)
})
}
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn get_frame_progression(&self) -> FrameProgression {
// Safety: Just FFI
unsafe { zstd_sys::ZSTD_getFrameProgression(self.0.as_ptr()) }
}
}
impl<'a> Drop for CCtx<'a> {
fn drop(&mut self) {
// Safety: Just FFI
unsafe {
zstd_sys::ZSTD_freeCCtx(self.0.as_ptr());
}
}
}
unsafe impl Send for CCtx<'_> {}
// Non thread-safe methods already take `&mut self`, so it's fine to implement Sync here.
unsafe impl Sync for CCtx<'_> {}
unsafe fn c_char_to_str(text: *const c_char) -> &'static str {
core::ffi::CStr::from_ptr(text)
.to_str()
.expect("bad error message from zstd")
}
/// Returns the error string associated with an error code.
pub fn get_error_name(code: usize) -> &'static str {
unsafe {
// Safety: assumes ZSTD returns a well-formed utf8 string.
let name = zstd_sys::ZSTD_getErrorName(code);
c_char_to_str(name)
}
}
/// A Decompression Context.
///
/// The lifetime references the potential dictionary used for this context.
///
/// If no dictionary was used, it will most likely be `'static`.
///
/// Same as `DStream`.
pub struct DCtx<'a>(NonNull<zstd_sys::ZSTD_DCtx>, PhantomData<&'a ()>);
impl Default for DCtx<'_> {
fn default() -> Self {
DCtx::create()
}
}
impl<'a> DCtx<'a> {
/// Try to create a new decompression context.
///
/// Returns `None` if the operation failed (for example, not enough memory).
pub fn try_create() -> Option<Self> {
Some(DCtx(
NonNull::new(unsafe { zstd_sys::ZSTD_createDCtx() })?,
PhantomData,
))
}
/// Creates a new decoding context.
///
/// # Panics
///
/// If the context creation fails.
pub fn create() -> Self {
Self::try_create()
.expect("zstd returned null pointer when creating new context")
}
/// Fully decompress the given frame.
///
/// This decompress an entire frame in-memory. If you can have enough memory to store both the
/// input and output buffer, then it may be faster that streaming decompression.
///
/// Wraps the `ZSTD_decompressDCtx()` function.
pub fn decompress<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
) -> SafeResult {
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_decompressDCtx(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
))
})
}
}
/// Fully decompress the given frame using a dictionary.
///
/// Dictionary must be identical to the one used during compression.
///
/// If you plan on using the same dictionary multiple times, it is faster to create a `DDict`
/// first and use `decompress_using_ddict`.
///
/// Wraps `ZSTD_decompress_usingDict`
pub fn decompress_using_dict<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
dict: &[u8],
) -> SafeResult {
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_decompress_usingDict(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
ptr_void(dict),
dict.len(),
))
})
}
}
/// Fully decompress the given frame using a dictionary.
///
/// Dictionary must be identical to the one used during compression.
///
/// Wraps the `ZSTD_decompress_usingDDict()` function.
pub fn decompress_using_ddict<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
ddict: &DDict<'_>,
) -> SafeResult {
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_decompress_usingDDict(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
ddict.0.as_ptr(),
))
})
}
}
/// Initializes an existing `DStream` for decompression.
///
/// This is equivalent to calling:
/// * `reset(SessionOnly)`
/// * `disable_dictionary()`
///
/// Wraps the `ZSTD_initCStream()` function.
pub fn init(&mut self) -> SafeResult {
let code = unsafe { zstd_sys::ZSTD_initDStream(self.0.as_ptr()) };
parse_code(code)
}
/// Wraps the `ZSTD_initDStream_usingDict()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
#[deprecated]
pub fn init_using_dict(&mut self, dict: &[u8]) -> SafeResult {
let code = unsafe {
zstd_sys::ZSTD_initDStream_usingDict(
self.0.as_ptr(),
ptr_void(dict),
dict.len(),
)
};
parse_code(code)
}
/// Wraps the `ZSTD_initDStream_usingDDict()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
#[deprecated]
pub fn init_using_ddict<'b>(&mut self, ddict: &DDict<'b>) -> SafeResult
where
'b: 'a,
{
let code = unsafe {
zstd_sys::ZSTD_initDStream_usingDDict(
self.0.as_ptr(),
ddict.0.as_ptr(),
)
};
parse_code(code)
}
/// Resets the state of the context.
///
/// Depending on the reset mode, it can reset the session, the parameters, or both.
///
/// Wraps the `ZSTD_DCtx_reset()` function.
pub fn reset(&mut self, reset: ResetDirective) -> SafeResult {
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_reset(self.0.as_ptr(), reset.as_sys())
})
}
/// Loads a dictionary.
///
/// This will let this context decompress frames that were compressed using this dictionary.
///
/// The dictionary content will be copied internally and does not need to be kept alive after
/// calling this function.
///
/// If you need to use the same dictionary for multiple contexts, it may be more efficient to
/// create a `DDict` first, then loads that.
///
/// The dictionary will apply to all future frames, until a new dictionary is set.
pub fn load_dictionary(&mut self, dict: &[u8]) -> SafeResult {
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_loadDictionary(
self.0.as_ptr(),
ptr_void(dict),
dict.len(),
)
})
}
/// Return to "no-dictionary" mode.
///
/// This will disable any dictionary/prefix previously registered for future frames.
pub fn disable_dictionary(&mut self) -> SafeResult {
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_loadDictionary(
self.0.as_ptr(),
core::ptr::null(),
0,
)
})
}
/// References a dictionary.
///
/// This will let this context decompress frames compressed with the same dictionary.
///
/// It will apply to all frames decompressed by this context (until a new dictionary is set).
///
/// Wraps the `ZSTD_DCtx_refDDict()` function.
pub fn ref_ddict<'b>(&mut self, ddict: &DDict<'b>) -> SafeResult
where
'b: 'a,
{
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_refDDict(self.0.as_ptr(), ddict.0.as_ptr())
})
}
/// Use some prefix as single-use dictionary for the next frame.
///
/// Just like a dictionary, this only works if compression was done with the same prefix.
///
/// But unlike a dictionary, this only applies to the next frame.
///
/// Wraps the `ZSTD_DCtx_refPrefix()` function.
pub fn ref_prefix<'b>(&mut self, prefix: &'b [u8]) -> SafeResult
where
'b: 'a,
{
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_refPrefix(
self.0.as_ptr(),
ptr_void(prefix),
prefix.len(),
)
})
}
/// Sets a decompression parameter.
pub fn set_parameter(&mut self, param: DParameter) -> SafeResult {
#[cfg(feature = "experimental")]
use zstd_sys::ZSTD_dParameter::{
ZSTD_d_experimentalParam1 as ZSTD_d_format,
ZSTD_d_experimentalParam2 as ZSTD_d_stableOutBuffer,
ZSTD_d_experimentalParam3 as ZSTD_d_forceIgnoreChecksum,
ZSTD_d_experimentalParam4 as ZSTD_d_refMultipleDDicts,
};
use zstd_sys::ZSTD_dParameter::*;
use DParameter::*;
let (param, value) = match param {
#[cfg(feature = "experimental")]
Format(format) => (ZSTD_d_format, format as c_int),
#[cfg(feature = "experimental")]
StableOutBuffer(stable) => {
(ZSTD_d_stableOutBuffer, stable as c_int)
}
#[cfg(feature = "experimental")]
ForceIgnoreChecksum(force) => {
(ZSTD_d_forceIgnoreChecksum, force as c_int)
}
#[cfg(feature = "experimental")]
RefMultipleDDicts(value) => {
(ZSTD_d_refMultipleDDicts, value as c_int)
}
WindowLogMax(value) => (ZSTD_d_windowLogMax, value as c_int),
};
parse_code(unsafe {
zstd_sys::ZSTD_DCtx_setParameter(self.0.as_ptr(), param, value)
})
}
/// Performs a step of a streaming decompression operation.
///
/// This will read some data from `input` and/or write some data to `output`.
///
/// # Returns
///
/// * `Ok(0)` if the current frame just finished decompressing successfully.
/// * `Ok(hint)` with a hint for the "ideal" amount of input data to provide in the next call.
/// Can be safely ignored.
///
/// Wraps the `ZSTD_decompressStream()` function.
pub fn decompress_stream<C: WriteBuf + ?Sized>(
&mut self,
output: &mut OutBuffer<'_, C>,
input: &mut InBuffer<'_>,
) -> SafeResult {
let mut output = output.wrap();
let mut input = input.wrap();
let code = unsafe {
zstd_sys::ZSTD_decompressStream(
self.0.as_ptr(),
ptr_mut(&mut output),
ptr_mut(&mut input),
)
};
parse_code(code)
}
/// Wraps the `ZSTD_DStreamInSize()` function.
///
/// Returns a hint for the recommended size of the input buffer for decompression.
pub fn in_size() -> usize {
unsafe { zstd_sys::ZSTD_DStreamInSize() }
}
/// Wraps the `ZSTD_DStreamOutSize()` function.
///
/// Returns a hint for the recommended size of the output buffer for decompression.
pub fn out_size() -> usize {
unsafe { zstd_sys::ZSTD_DStreamOutSize() }
}
/// Wraps the `ZSTD_sizeof_DCtx()` function.
pub fn sizeof(&self) -> usize {
unsafe { zstd_sys::ZSTD_sizeof_DCtx(self.0.as_ptr()) }
}
/// Wraps the `ZSTD_decompressBlock()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn decompress_block<C: WriteBuf + ?Sized>(
&mut self,
dst: &mut C,
src: &[u8],
) -> SafeResult {
unsafe {
dst.write_from(|buffer, capacity| {
parse_code(zstd_sys::ZSTD_decompressBlock(
self.0.as_ptr(),
buffer,
capacity,
ptr_void(src),
src.len(),
))
})
}
}
/// Wraps the `ZSTD_insertBlock()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn insert_block(&mut self, block: &[u8]) -> usize {
unsafe {
zstd_sys::ZSTD_insertBlock(
self.0.as_ptr(),
ptr_void(block),
block.len(),
)
}
}
/// Creates a copy of this context.
///
/// This only works before any data has been decompressed. An error will be
/// returned otherwise.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn try_clone(&self) -> Result<Self, ErrorCode> {
let context = NonNull::new(unsafe { zstd_sys::ZSTD_createDCtx() })
.ok_or(0usize)?;
unsafe { zstd_sys::ZSTD_copyDCtx(context.as_ptr(), self.0.as_ptr()) };
Ok(DCtx(context, self.1))
}
}
impl Drop for DCtx<'_> {
fn drop(&mut self) {
unsafe {
zstd_sys::ZSTD_freeDCtx(self.0.as_ptr());
}
}
}
unsafe impl Send for DCtx<'_> {}
// Non thread-safe methods already take `&mut self`, so it's fine to implement Sync here.
unsafe impl Sync for DCtx<'_> {}
/// Compression dictionary.
pub struct CDict<'a>(NonNull<zstd_sys::ZSTD_CDict>, PhantomData<&'a ()>);
impl CDict<'static> {
/// Prepare a dictionary to compress data.
///
/// This will make it easier for compression contexts to load this dictionary.
///
/// The dictionary content will be copied internally, and does not need to be kept around.
///
/// # Panics
///
/// If loading this dictionary failed.
pub fn create(
dict_buffer: &[u8],
compression_level: CompressionLevel,
) -> Self {
Self::try_create(dict_buffer, compression_level)
.expect("zstd returned null pointer when creating dict")
}
/// Prepare a dictionary to compress data.
///
/// This will make it easier for compression contexts to load this dictionary.
///
/// The dictionary content will be copied internally, and does not need to be kept around.
pub fn try_create(
dict_buffer: &[u8],
compression_level: CompressionLevel,
) -> Option<Self> {
Some(CDict(
NonNull::new(unsafe {
zstd_sys::ZSTD_createCDict(
ptr_void(dict_buffer),
dict_buffer.len(),
compression_level,
)
})?,
PhantomData,
))
}
}
impl<'a> CDict<'a> {
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn create_by_reference(
dict_buffer: &'a [u8],
compression_level: CompressionLevel,
) -> Self {
CDict(
NonNull::new(unsafe {
zstd_sys::ZSTD_createCDict_byReference(
ptr_void(dict_buffer),
dict_buffer.len(),
compression_level,
)
})
.expect("zstd returned null pointer"),
PhantomData,
)
}
/// Returns the _current_ memory usage of this dictionary.
///
/// Note that this may change over time.
pub fn sizeof(&self) -> usize {
unsafe { zstd_sys::ZSTD_sizeof_CDict(self.0.as_ptr()) }
}
/// Returns the dictionary ID for this dict.
///
/// Returns `None` if this dictionary is empty or invalid.
pub fn get_dict_id(&self) -> Option<NonZeroU32> {
NonZeroU32::new(unsafe {
zstd_sys::ZSTD_getDictID_fromCDict(self.0.as_ptr()) as u32
})
}
}
/// Wraps the `ZSTD_createCDict()` function.
pub fn create_cdict(
dict_buffer: &[u8],
compression_level: CompressionLevel,
) -> CDict<'static> {
CDict::create(dict_buffer, compression_level)
}
impl<'a> Drop for CDict<'a> {
fn drop(&mut self) {
unsafe {
zstd_sys::ZSTD_freeCDict(self.0.as_ptr());
}
}
}
unsafe impl<'a> Send for CDict<'a> {}
unsafe impl<'a> Sync for CDict<'a> {}
/// Wraps the `ZSTD_compress_usingCDict()` function.
pub fn compress_using_cdict(
cctx: &mut CCtx<'_>,
dst: &mut [u8],
src: &[u8],
cdict: &CDict<'_>,
) -> SafeResult {
cctx.compress_using_cdict(dst, src, cdict)
}
/// A digested decompression dictionary.
pub struct DDict<'a>(NonNull<zstd_sys::ZSTD_DDict>, PhantomData<&'a ()>);
impl DDict<'static> {
pub fn create(dict_buffer: &[u8]) -> Self {
Self::try_create(dict_buffer)
.expect("zstd returned null pointer when creating dict")
}
pub fn try_create(dict_buffer: &[u8]) -> Option<Self> {
Some(DDict(
NonNull::new(unsafe {
zstd_sys::ZSTD_createDDict(
ptr_void(dict_buffer),
dict_buffer.len(),
)
})?,
PhantomData,
))
}
}
impl<'a> DDict<'a> {
pub fn sizeof(&self) -> usize {
unsafe { zstd_sys::ZSTD_sizeof_DDict(self.0.as_ptr()) }
}
/// Wraps the `ZSTD_createDDict_byReference()` function.
///
/// The dictionary will keep referencing `dict_buffer`.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn create_by_reference(dict_buffer: &'a [u8]) -> Self {
DDict(
NonNull::new(unsafe {
zstd_sys::ZSTD_createDDict_byReference(
ptr_void(dict_buffer),
dict_buffer.len(),
)
})
.expect("zstd returned null pointer"),
PhantomData,
)
}
/// Returns the dictionary ID for this dict.
///
/// Returns `None` if this dictionary is empty or invalid.
pub fn get_dict_id(&self) -> Option<NonZeroU32> {
NonZeroU32::new(unsafe {
zstd_sys::ZSTD_getDictID_fromDDict(self.0.as_ptr()) as u32
})
}
}
/// Wraps the `ZSTD_createDDict()` function.
///
/// It copies the dictionary internally, so the resulting `DDict` is `'static`.
pub fn create_ddict(dict_buffer: &[u8]) -> DDict<'static> {
DDict::create(dict_buffer)
}
impl<'a> Drop for DDict<'a> {
fn drop(&mut self) {
unsafe {
zstd_sys::ZSTD_freeDDict(self.0.as_ptr());
}
}
}
unsafe impl<'a> Send for DDict<'a> {}
unsafe impl<'a> Sync for DDict<'a> {}
/// A shared thread pool for one or more compression contexts
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
pub struct ThreadPool(NonNull<zstd_sys::ZSTD_threadPool>);
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
impl ThreadPool {
/// Create a thread pool with the specified number of threads.
///
/// # Panics
///
/// If creating the thread pool failed.
pub fn new(num_threads: usize) -> Self {
Self::try_new(num_threads)
.expect("zstd returned null pointer when creating thread pool")
}
/// Create a thread pool with the specified number of threads.
pub fn try_new(num_threads: usize) -> Option<Self> {
Some(Self(NonNull::new(unsafe {
zstd_sys::ZSTD_createThreadPool(num_threads)
})?))
}
}
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
impl Drop for ThreadPool {
fn drop(&mut self) {
unsafe {
zstd_sys::ZSTD_freeThreadPool(self.0.as_ptr());
}
}
}
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
unsafe impl Send for ThreadPool {}
#[cfg(all(feature = "experimental", feature = "zstdmt"))]
#[cfg_attr(
feature = "doc-cfg",
doc(cfg(all(feature = "experimental", feature = "zstdmt")))
)]
unsafe impl Sync for ThreadPool {}
/// Wraps the `ZSTD_decompress_usingDDict()` function.
pub fn decompress_using_ddict(
dctx: &mut DCtx<'_>,
dst: &mut [u8],
src: &[u8],
ddict: &DDict<'_>,
) -> SafeResult {
dctx.decompress_using_ddict(dst, src, ddict)
}
/// Compression stream.
///
/// Same as `CCtx`.
pub type CStream<'a> = CCtx<'a>;
// CStream can't be shared across threads, so it does not implement Sync.
/// Allocates a new `CStream`.
pub fn create_cstream<'a>() -> CStream<'a> {
CCtx::create()
}
/// Prepares an existing `CStream` for compression at the given level.
pub fn init_cstream(
zcs: &mut CStream<'_>,
compression_level: CompressionLevel,
) -> SafeResult {
zcs.init(compression_level)
}
#[derive(Debug)]
/// Wrapper around an input buffer.
///
/// Bytes will be read starting at `src[pos]`.
///
/// `pos` will be updated after reading.
pub struct InBuffer<'a> {
pub src: &'a [u8],
pub pos: usize,
}
/// Describe a bytes container, like `Vec<u8>`.
///
/// Represents a contiguous segment of allocated memory, a prefix of which is initialized.
///
/// It allows starting from an uninitializes chunk of memory and writing to it, progressively
/// initializing it. No re-allocation typically occur after the initial creation.
///
/// The main implementors are:
/// * `Vec<u8>` and similar structures. These hold both a length (initialized data) and a capacity
/// (allocated memory).
///
/// Use `Vec::with_capacity` to create an empty `Vec` with non-zero capacity, and the length
/// field will be updated to cover the data written to it (as long as it fits in the given
/// capacity).
/// * `[u8]` and `[u8; N]`. These must start already-initialized, and will not be resized. It will
/// be up to the caller to only use the part that was written (as returned by the various writing
/// operations).
/// * `std::io::Cursor<T: WriteBuf>`. This will ignore data before the cursor's position, and
/// append data after that.
pub unsafe trait WriteBuf {
/// Returns the valid data part of this container. Should only cover initialized data.
fn as_slice(&self) -> &[u8];
/// Returns the full capacity of this container. May include uninitialized data.
fn capacity(&self) -> usize;
/// Returns a pointer to the start of the data.
fn as_mut_ptr(&mut self) -> *mut u8;
/// Indicates that the first `n` bytes of the container have been written.
///
/// Safety: this should only be called if the `n` first bytes of this buffer have actually been
/// initialized.
unsafe fn filled_until(&mut self, n: usize);
/// Call the given closure using the pointer and capacity from `self`.
///
/// Assumes the given function returns a parseable code, which if valid, represents how many
/// bytes were written to `self`.
///
/// The given closure must treat its first argument as pointing to potentially uninitialized
/// memory, and should not read from it.
///
/// In addition, it must have written at least `n` bytes contiguously from this pointer, where
/// `n` is the returned value.
unsafe fn write_from<F>(&mut self, f: F) -> SafeResult
where
F: FnOnce(*mut c_void, usize) -> SafeResult,
{
let res = f(ptr_mut_void(self), self.capacity());
if let Ok(n) = res {
self.filled_until(n);
}
res
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "std")))]
unsafe impl<T> WriteBuf for std::io::Cursor<T>
where
T: WriteBuf,
{
fn as_slice(&self) -> &[u8] {
&self.get_ref().as_slice()[self.position() as usize..]
}
fn capacity(&self) -> usize {
self.get_ref()
.capacity()
.saturating_sub(self.position() as usize)
}
fn as_mut_ptr(&mut self) -> *mut u8 {
let start = self.position() as usize;
assert!(start <= self.get_ref().capacity());
// Safety: start is still in the same memory allocation
unsafe { self.get_mut().as_mut_ptr().add(start) }
}
unsafe fn filled_until(&mut self, n: usize) {
// Early exit: `n = 0` does not indicate anything.
if n == 0 {
return;
}
// Here we assume data _before_ self.position() was already initialized.
// Egh it's not actually guaranteed by Cursor? So let's guarantee it ourselves.
// Since the cursor wraps another `WriteBuf`, we know how much data is initialized there.
let position = self.position() as usize;
let initialized = self.get_ref().as_slice().len();
if let Some(uninitialized) = position.checked_sub(initialized) {
// Here, the cursor is further than the known-initialized part.
// Cursor's solution is to pad with zeroes, so let's do the same.
// We'll zero bytes from the end of valid data (as_slice().len()) to the cursor position.
// Safety:
// * We know `n > 0`
// * This means `self.capacity() > 0` (promise by the caller)
// * This means `self.get_ref().capacity() > self.position`
// * This means that `position` is within the nested pointer's allocation.
// * Finally, `initialized + uninitialized = position`, so the entire byte
// range here is within the allocation
unsafe {
self.get_mut()
.as_mut_ptr()
.add(initialized)
.write_bytes(0u8, uninitialized)
};
}
let start = self.position() as usize;
assert!(start + n <= self.get_ref().capacity());
self.get_mut().filled_until(start + n);
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "std")))]
unsafe impl<'a> WriteBuf for &'a mut std::vec::Vec<u8> {
fn as_slice(&self) -> &[u8] {
std::vec::Vec::as_slice(self)
}
fn capacity(&self) -> usize {
std::vec::Vec::capacity(self)
}
fn as_mut_ptr(&mut self) -> *mut u8 {
std::vec::Vec::as_mut_ptr(self)
}
unsafe fn filled_until(&mut self, n: usize) {
std::vec::Vec::set_len(self, n)
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "std")))]
unsafe impl WriteBuf for std::vec::Vec<u8> {
fn as_slice(&self) -> &[u8] {
&self[..]
}
fn capacity(&self) -> usize {
self.capacity()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.as_mut_ptr()
}
unsafe fn filled_until(&mut self, n: usize) {
self.set_len(n);
}
}
#[cfg(feature = "arrays")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "arrays")))]
unsafe impl<const N: usize> WriteBuf for [u8; N] {
fn as_slice(&self) -> &[u8] {
self
}
fn capacity(&self) -> usize {
self.len()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
(&mut self[..]).as_mut_ptr()
}
unsafe fn filled_until(&mut self, _n: usize) {
// Assume the slice is already initialized
}
}
unsafe impl WriteBuf for [u8] {
fn as_slice(&self) -> &[u8] {
self
}
fn capacity(&self) -> usize {
self.len()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.as_mut_ptr()
}
unsafe fn filled_until(&mut self, _n: usize) {
// Assume the slice is already initialized
}
}
/*
// This is possible, but... why?
unsafe impl<'a> WriteBuf for OutBuffer<'a, [u8]> {
fn as_slice(&self) -> &[u8] {
self.dst
}
fn capacity(&self) -> usize {
self.dst.len()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.dst.as_mut_ptr()
}
unsafe fn filled_until(&mut self, n: usize) {
self.pos = n;
}
}
*/
#[derive(Debug)]
/// Wrapper around an output buffer.
///
/// `C` is usually either `[u8]` or `Vec<u8>`.
///
/// Bytes will be written starting at `dst[pos]`.
///
/// `pos` will be updated after writing.
///
/// # Invariant
///
/// `pos <= dst.capacity()`
pub struct OutBuffer<'a, C: WriteBuf + ?Sized> {
dst: &'a mut C,
pos: usize,
}
/// Convenience method to get a mut pointer from a mut ref.
fn ptr_mut<B>(ptr_void: &mut B) -> *mut B {
ptr_void as *mut B
}
/// Interface between a C-level ZSTD_outBuffer and a rust-level `OutBuffer`.
///
/// Will update the parent buffer from the C buffer on drop.
struct OutBufferWrapper<'a, 'b, C: WriteBuf + ?Sized> {
buf: zstd_sys::ZSTD_outBuffer,
parent: &'a mut OutBuffer<'b, C>,
}
impl<'a, 'b: 'a, C: WriteBuf + ?Sized> Deref for OutBufferWrapper<'a, 'b, C> {
type Target = zstd_sys::ZSTD_outBuffer;
fn deref(&self) -> &Self::Target {
&self.buf
}
}
impl<'a, 'b: 'a, C: WriteBuf + ?Sized> DerefMut
for OutBufferWrapper<'a, 'b, C>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buf
}
}
impl<'a, C: WriteBuf + ?Sized> OutBuffer<'a, C> {
/// Returns a new `OutBuffer` around the given slice.
///
/// Starts with `pos = 0`.
pub fn around(dst: &'a mut C) -> Self {
OutBuffer { dst, pos: 0 }
}
/// Returns a new `OutBuffer` around the given slice, starting at the given position.
///
/// # Panics
///
/// If `pos > dst.capacity()`.
pub fn around_pos(dst: &'a mut C, pos: usize) -> Self {
if pos > dst.capacity() {
panic!("Given position outside of the buffer bounds.");
}
OutBuffer { dst, pos }
}
/// Returns the current cursor position.
///
/// Guaranteed to be <= self.capacity()
pub fn pos(&self) -> usize {
assert!(self.pos <= self.dst.capacity());
self.pos
}
/// Returns the capacity of the underlying buffer.
pub fn capacity(&self) -> usize {
self.dst.capacity()
}
/// Sets the new cursor position.
///
/// # Panics
///
/// If `pos > self.dst.capacity()`.
///
/// # Safety
///
/// Data up to `pos` must have actually been written to.
pub unsafe fn set_pos(&mut self, pos: usize) {
if pos > self.dst.capacity() {
panic!("Given position outside of the buffer bounds.");
}
self.dst.filled_until(pos);
self.pos = pos;
}
fn wrap<'b>(&'b mut self) -> OutBufferWrapper<'b, 'a, C> {
OutBufferWrapper {
buf: zstd_sys::ZSTD_outBuffer {
dst: ptr_mut_void(self.dst),
size: self.dst.capacity(),
pos: self.pos,
},
parent: self,
}
}
/// Returns the part of this buffer that was written to.
pub fn as_slice<'b>(&'b self) -> &'a [u8]
where
'b: 'a,
{
let pos = self.pos;
&self.dst.as_slice()[..pos]
}
/// Returns a pointer to the start of this buffer.
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.dst.as_mut_ptr()
}
}
impl<'a, 'b, C: WriteBuf + ?Sized> Drop for OutBufferWrapper<'a, 'b, C> {
fn drop(&mut self) {
// Safe because we guarantee that data until `self.buf.pos` has been written.
unsafe { self.parent.set_pos(self.buf.pos) };
}
}
struct InBufferWrapper<'a, 'b> {
buf: zstd_sys::ZSTD_inBuffer,
parent: &'a mut InBuffer<'b>,
}
impl<'a, 'b: 'a> Deref for InBufferWrapper<'a, 'b> {
type Target = zstd_sys::ZSTD_inBuffer;
fn deref(&self) -> &Self::Target {
&self.buf
}
}
impl<'a, 'b: 'a> DerefMut for InBufferWrapper<'a, 'b> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buf
}
}
impl<'a> InBuffer<'a> {
/// Returns a new `InBuffer` around the given slice.
///
/// Starts with `pos = 0`.
pub fn around(src: &'a [u8]) -> Self {
InBuffer { src, pos: 0 }
}
/// Returns the current cursor position.
pub fn pos(&self) -> usize {
self.pos
}
/// Sets the new cursor position.
///
/// # Panics
///
/// If `pos > self.src.len()`.
pub fn set_pos(&mut self, pos: usize) {
if pos > self.src.len() {
panic!("Given position outside of the buffer bounds.");
}
self.pos = pos;
}
fn wrap<'b>(&'b mut self) -> InBufferWrapper<'b, 'a> {
InBufferWrapper {
buf: zstd_sys::ZSTD_inBuffer {
src: ptr_void(self.src),
size: self.src.len(),
pos: self.pos,
},
parent: self,
}
}
}
impl<'a, 'b> Drop for InBufferWrapper<'a, 'b> {
fn drop(&mut self) {
self.parent.set_pos(self.buf.pos);
}
}
/// A Decompression stream.
///
/// Same as `DCtx`.
pub type DStream<'a> = DCtx<'a>;
// Some functions work on a "frame prefix".
// TODO: Define `struct FramePrefix(&[u8]);` and move these functions to it?
//
// Some other functions work on a dictionary (not CDict or DDict).
// Same thing?
/// Wraps the `ZSTD_findFrameCompressedSize()` function.
///
/// `src` should contain at least an entire frame.
pub fn find_frame_compressed_size(src: &[u8]) -> SafeResult {
let code = unsafe {
zstd_sys::ZSTD_findFrameCompressedSize(ptr_void(src), src.len())
};
parse_code(code)
}
/// Wraps the `ZSTD_getFrameContentSize()` function.
///
/// Args:
/// * `src`: A prefix of the compressed frame. It should at least include the frame header.
///
/// Returns:
/// * `Err(ContentSizeError)` if `src` is too small of a prefix, or if it appears corrupted.
/// * `Ok(None)` if the frame does not include a content size.
/// * `Ok(Some(content_size_in_bytes))` otherwise.
pub fn get_frame_content_size(
src: &[u8],
) -> Result<Option<u64>, ContentSizeError> {
parse_content_size(unsafe {
zstd_sys::ZSTD_getFrameContentSize(ptr_void(src), src.len())
})
}
/// Wraps the `ZSTD_findDecompressedSize()` function.
///
/// `src` should be exactly a sequence of ZSTD frames.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn find_decompressed_size(
src: &[u8],
) -> Result<Option<u64>, ContentSizeError> {
parse_content_size(unsafe {
zstd_sys::ZSTD_findDecompressedSize(ptr_void(src), src.len())
})
}
/// Wraps the `ZSTD_isFrame()` function.
#[cfg(feature = "experimental")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "experimental")))]
pub fn is_frame(buffer: &[u8]) -> bool {
unsafe { zstd_sys::ZSTD_isFrame(ptr_void(buffer), buffer.len()) > 0 }
}
/// Wraps the `ZSTD_getDictID_fromDict()` function.
///
/// Returns `None` if the dictionary is not a valid zstd dictionary.
pub fn get_dict_id_from_dict(dict: &[u8]) -> Option<NonZeroU32> {
NonZeroU32::new(unsafe {
zstd_sys::ZSTD_getDictID_fromDict(ptr_void(dict), dict.len()) as u32
})
}
/// Wraps the `ZSTD_getDictID_fromFrame()` function.
///
/// Returns `None` if the dictionary ID could not be decoded. This may happen if:
/// * The frame was not encoded with a dictionary.
/// * The frame intentionally did not include dictionary ID.
/// * The dictionary was non-conformant.
/// * `src` is too small and does not include the frame header.
/// * `src` is not a valid zstd frame prefix.
pub fn get_dict_id_from_frame(src: &[u8]) -> Option<NonZeroU32> {
NonZeroU32::new(unsafe {
zstd_sys::ZSTD_getDictID_fromFrame(ptr_void(src), src.len()) as u32
})
}
/// What kind of context reset should be applied.
pub enum ResetDirective {
/// Only the session will be reset.
///
/// All parameters will be preserved (including the dictionary).
/// But any frame being processed will be dropped.
///
/// It can be useful to start re-using a context after an error or when an
/// ongoing compression is no longer needed.
SessionOnly,
/// Only reset parameters (including dictionary or referenced prefix).
///
/// All parameters will be reset to default values.
///
/// This can only be done between sessions - no compression or decompression must be ongoing.
Parameters,
/// Reset both the session and parameters.
///
/// The result is similar to a newly created context.
SessionAndParameters,
}
impl ResetDirective {
gitextract_z1p3b8qn/
├── .gitattributes
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── linux.yml
│ ├── macos.yml
│ ├── wasm.yml
│ └── windows.yml
├── .gitignore
├── .gitmodules
├── Cargo.toml
├── LICENSE
├── Readme.md
├── assets/
│ ├── example.txt
│ ├── example.txt.v5.zst
│ ├── example.txt.v6.zst
│ ├── example.txt.v7.zst
│ ├── example.txt.v8.zst
│ └── example.txt.zst
├── examples/
│ ├── basic.rs
│ ├── benchmark.rs
│ ├── stream.rs
│ ├── train.rs
│ ├── zstd.rs
│ └── zstdcat.rs
├── rustfmt.toml
├── src/
│ ├── bulk/
│ │ ├── compressor.rs
│ │ ├── decompressor.rs
│ │ ├── mod.rs
│ │ └── tests.rs
│ ├── dict.rs
│ ├── lib.rs
│ └── stream/
│ ├── functions.rs
│ ├── mod.rs
│ ├── raw.rs
│ ├── read/
│ │ ├── mod.rs
│ │ └── tests.rs
│ ├── tests.rs
│ ├── write/
│ │ ├── mod.rs
│ │ └── tests.rs
│ └── zio/
│ ├── mod.rs
│ ├── reader.rs
│ └── writer.rs
├── tests/
│ └── issue_182.rs
└── zstd-safe/
├── Cargo.toml
├── LICENSE
├── Readme.md
├── build.rs
├── fuzz/
│ ├── .gitignore
│ ├── Cargo.toml
│ └── fuzz_targets/
│ └── zstd_fuzzer.rs
├── src/
│ ├── constants.rs
│ ├── constants_experimental.rs
│ ├── constants_seekable.rs
│ ├── lib.rs
│ ├── seekable.rs
│ └── tests.rs
├── update_consts.sh
└── zstd-sys/
├── Cargo.toml
├── LICENSE
├── LICENSE.BSD-3-Clause
├── Readme.md
├── build.rs
├── examples/
│ └── it_work.rs
├── src/
│ ├── bindings_zdict.rs
│ ├── bindings_zdict_experimental.rs
│ ├── bindings_zdict_std_experimental.rs
│ ├── bindings_zstd.rs
│ ├── bindings_zstd_experimental.rs
│ ├── bindings_zstd_seekable.rs
│ ├── bindings_zstd_std_experimental.rs
│ ├── lib.rs
│ └── wasm_shim.rs
├── test_it.sh
├── update_bindings.sh
├── update_zstd.sh
├── wasm-shim/
│ ├── assert.h
│ ├── stdio.h
│ ├── stdlib.h
│ ├── string.h
│ └── time.h
├── zdict.h
├── zstd.h
└── zstd_seekable.h
SYMBOL INDEX (1260 symbols across 41 files)
FILE: examples/basic.rs
function main (line 1) | fn main() {
FILE: examples/benchmark.rs
type Args (line 8) | struct Args {
function main (line 28) | fn main() {
FILE: examples/stream.rs
function main (line 5) | fn main() {
function compress (line 33) | fn compress(level: i32) {
function decompress (line 37) | fn decompress() {
FILE: examples/train.rs
type Args (line 13) | struct Args {
function main (line 22) | fn main() {
FILE: examples/zstd.rs
constant SUFFIX (line 7) | const SUFFIX: &'static str = ".zst";
function main (line 9) | fn main() {
function compress (line 25) | fn compress(source: &str) -> io::Result<()> {
function decompress (line 38) | fn decompress(source: &str) -> io::Result<()> {
FILE: examples/zstdcat.rs
type Args (line 7) | struct Args {
function main (line 12) | fn main() {
function decompress_file (line 28) | fn decompress_file(file: &str) -> io::Result<()> {
function decompress_from (line 36) | fn decompress_from<R: io::Read>(r: R) -> io::Result<()> {
FILE: src/bulk/compressor.rs
type Compressor (line 16) | pub struct Compressor<'a> {
function new (line 22) | pub fn new(level: i32) -> io::Result<Self> {
function with_dictionary (line 30) | pub fn with_dictionary(level: i32, dictionary: &[u8]) -> io::Result<Self> {
function with_prepared_dictionary (line 46) | pub fn with_prepared_dictionary<'b>(
function set_compression_level (line 65) | pub fn set_compression_level(&mut self, level: i32) -> io::Result<()> {
function set_dictionary (line 75) | pub fn set_dictionary(
function set_prepared_dictionary (line 97) | pub fn set_prepared_dictionary<'b>(
function compress_to_buffer (line 117) | pub fn compress_to_buffer<C: zstd_safe::WriteBuf + ?Sized>(
function compress (line 130) | pub fn compress(&mut self, data: &[u8]) -> io::Result<Vec<u8>> {
function context_mut (line 142) | pub fn context_mut(&mut self) -> &mut zstd_safe::CCtx<'a> {
function set_parameter (line 147) | pub fn set_parameter(
function set_pledged_src_size (line 165) | pub fn set_pledged_src_size(
function _assert_traits (line 178) | fn _assert_traits() {
FILE: src/bulk/decompressor.rs
type Decompressor (line 12) | pub struct Decompressor<'a> {
function new (line 18) | pub fn new() -> io::Result<Self> {
function with_dictionary (line 23) | pub fn with_dictionary(dictionary: &[u8]) -> io::Result<Self> {
function with_prepared_dictionary (line 37) | pub fn with_prepared_dictionary<'b>(
function set_dictionary (line 56) | pub fn set_dictionary(&mut self, dictionary: &[u8]) -> io::Result<()> {
function set_prepared_dictionary (line 68) | pub fn set_prepared_dictionary<'b>(
function decompress_to_buffer (line 86) | pub fn decompress_to_buffer<C: zstd_safe::WriteBuf + ?Sized>(
function decompress (line 100) | pub fn decompress(
function set_parameter (line 113) | pub fn set_parameter(
function upper_bound (line 134) | pub fn upper_bound(_data: &[u8]) -> Option<usize> {
function _assert_traits (line 147) | fn _assert_traits() {
FILE: src/bulk/mod.rs
function compress_to_buffer (line 24) | pub fn compress_to_buffer(
function compress (line 35) | pub fn compress(data: &[u8], level: i32) -> io::Result<Vec<u8>> {
function decompress_to_buffer (line 43) | pub fn decompress_to_buffer(
function decompress (line 54) | pub fn decompress(data: &[u8], capacity: usize) -> io::Result<Vec<u8>> {
FILE: src/bulk/tests.rs
constant TEXT (line 3) | const TEXT: &str = include_str!("../../assets/example.txt");
function test_direct (line 6) | fn test_direct() {
function test_stream_compat (line 17) | fn test_stream_compat() {
function has_content_size (line 34) | fn has_content_size() {
FILE: src/dict.rs
type EncoderDictionary (line 26) | pub struct EncoderDictionary<'a> {
function copy (line 34) | pub fn copy(dictionary: &[u8], level: i32) -> Self {
function new (line 49) | pub fn new(dictionary: &'a [u8], level: i32) -> Self {
function as_cdict (line 56) | pub fn as_cdict(&self) -> &CDict<'a> {
type DecoderDictionary (line 62) | pub struct DecoderDictionary<'a> {
function copy (line 70) | pub fn copy(dictionary: &[u8]) -> Self {
function new (line 83) | pub fn new(dict: &'a [u8]) -> Self {
function as_ddict (line 90) | pub fn as_ddict(&self) -> &DDict<'a> {
function from_continuous (line 109) | pub fn from_continuous(
function from_samples (line 146) | pub fn from_samples<S: AsRef<[u8]>>(
function from_sample_iterator (line 202) | pub fn from_sample_iterator<I, R>(
function from_files (line 231) | pub fn from_files<I, P>(filenames: I, max_size: usize) -> io::Result<Vec...
function test_dict_training (line 254) | fn test_dict_training() {
FILE: src/lib.rs
function compression_level_range (line 39) | pub fn compression_level_range(
function map_error_code (line 48) | fn map_error_code(code: usize) -> io::Error {
function test_cycle (line 56) | fn test_cycle<F, G>(data: &[u8], f: F, g: G)
function test_cycle_unwrap (line 67) | fn test_cycle_unwrap<F, G>(data: &[u8], f: F, g: G)
function default_compression_level_in_range (line 76) | fn default_compression_level_in_range() {
FILE: src/stream/functions.rs
function decode_all (line 8) | pub fn decode_all<R: io::Read>(source: R) -> io::Result<Vec<u8>> {
function copy_decode (line 17) | pub fn copy_decode<R, W>(source: R, mut destination: W) -> io::Result<()>
function encode_all (line 32) | pub fn encode_all<R: io::Read>(source: R, level: i32) -> io::Result<Vec<...
function copy_encode (line 43) | pub fn copy_encode<R, W>(
FILE: src/stream/raw.rs
type Operation (line 17) | pub trait Operation {
method run (line 24) | fn run<C: WriteBuf + ?Sized>(
method run_on_buffers (line 34) | fn run_on_buffers(
method flush (line 55) | fn flush<C: WriteBuf + ?Sized>(
method reinit (line 66) | fn reinit(&mut self) -> io::Result<()> {
method finish (line 76) | fn finish<C: WriteBuf + ?Sized>(
method run (line 91) | fn run<C: WriteBuf + ?Sized>(
method run (line 205) | fn run<C: WriteBuf + ?Sized>(
method flush (line 217) | fn flush<C: WriteBuf + ?Sized>(
method reinit (line 234) | fn reinit(&mut self) -> io::Result<()> {
method finish (line 247) | fn finish<C: WriteBuf + ?Sized>(
method run (line 373) | fn run<C: WriteBuf + ?Sized>(
method flush (line 385) | fn flush<C: WriteBuf + ?Sized>(
method finish (line 396) | fn finish<C: WriteBuf + ?Sized>(
method reinit (line 408) | fn reinit(&mut self) -> io::Result<()> {
type NoOp (line 88) | pub struct NoOp;
type Status (line 118) | pub struct Status {
type Decoder (line 134) | pub struct Decoder<'a> {
function new (line 140) | pub fn new() -> io::Result<Self> {
function with_dictionary (line 145) | pub fn with_dictionary(dictionary: &[u8]) -> io::Result<Self> {
function with_context (line 159) | pub fn with_context(context: &'a mut zstd_safe::DCtx<'static>) -> Self {
function with_prepared_dictionary (line 166) | pub fn with_prepared_dictionary<'b>(
function with_ref_prefix (line 182) | pub fn with_ref_prefix<'b>(ref_prefix: &'b [u8]) -> io::Result<Self>
function set_parameter (line 194) | pub fn set_parameter(&mut self, parameter: DParameter) -> io::Result<()> {
type Encoder (line 264) | pub struct Encoder<'a> {
function new (line 270) | pub fn new(level: i32) -> io::Result<Self> {
function with_dictionary (line 275) | pub fn with_dictionary(level: i32, dictionary: &[u8]) -> io::Result<Self> {
function with_context (line 294) | pub fn with_context(context: &'a mut zstd_safe::CCtx<'static>) -> Self {
function with_prepared_dictionary (line 301) | pub fn with_prepared_dictionary<'b>(
function with_ref_prefix (line 317) | pub fn with_ref_prefix<'b>(
function set_parameter (line 338) | pub fn set_parameter(&mut self, parameter: CParameter) -> io::Result<()> {
function set_pledged_src_size (line 355) | pub fn set_pledged_src_size(
type MaybeOwnedCCtx (line 422) | enum MaybeOwnedCCtx<'a> {
type MaybeOwnedDCtx (line 427) | enum MaybeOwnedDCtx<'a> {
function test_cycle (line 438) | fn test_cycle() {
FILE: src/stream/read/mod.rs
type Decoder (line 15) | pub struct Decoder<'a, R> {
type Encoder (line 20) | pub struct Encoder<'a, R> {
function new (line 26) | pub fn new(reader: R) -> io::Result<Self> {
function with_buffer (line 35) | pub fn with_buffer(reader: R) -> io::Result<Self> {
function with_dictionary (line 41) | pub fn with_dictionary(reader: R, dictionary: &[u8]) -> io::Result<Self> {
function with_context (line 50) | pub fn with_context(
function single_frame (line 66) | pub fn single_frame(mut self) -> Self {
function with_prepared_dictionary (line 74) | pub fn with_prepared_dictionary<'b>(
function with_ref_prefix (line 90) | pub fn with_ref_prefix<'b>(
function recommended_output_size (line 104) | pub fn recommended_output_size() -> usize {
function get_ref (line 109) | pub fn get_ref(&self) -> &R {
function get_mut (line 117) | pub fn get_mut(&mut self) -> &mut R {
function finish (line 125) | pub fn finish(self) -> R {
method read (line 133) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
function new (line 140) | pub fn new(reader: R, level: i32) -> io::Result<Self> {
function with_buffer (line 149) | pub fn with_buffer(reader: R, level: i32) -> io::Result<Self> {
function with_dictionary (line 156) | pub fn with_dictionary(
function with_context (line 170) | pub fn with_context(
function with_prepared_dictionary (line 185) | pub fn with_prepared_dictionary<'b>(
function recommended_output_size (line 199) | pub fn recommended_output_size() -> usize {
function get_ref (line 204) | pub fn get_ref(&self) -> &R {
function get_mut (line 212) | pub fn get_mut(&mut self) -> &mut R {
function flush (line 225) | pub fn flush(&mut self, out: &mut [u8]) -> io::Result<usize> {
function finish (line 233) | pub fn finish(self) -> R {
method read (line 241) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
function _assert_traits (line 246) | fn _assert_traits() {
FILE: src/stream/read/tests.rs
function test_error_handling (line 5) | fn test_error_handling() {
function test_cycle (line 15) | fn test_cycle() {
FILE: src/stream/tests.rs
function test_end_of_frame (line 10) | fn test_end_of_frame() {
function test_concatenated_frames (line 28) | fn test_concatenated_frames() {
function test_flush (line 42) | fn test_flush() {
function test_try_finish (line 58) | fn test_try_finish() {
function test_write_after_try_finish (line 79) | fn test_write_after_try_finish() {
function setup_try_finish (line 85) | fn setup_try_finish() -> Encoder<'static, PartialWrite<Vec<u8>>> {
function test_failing_write (line 108) | fn test_failing_write() {
function test_invalid_frame (line 145) | fn test_invalid_frame() {
function test_incomplete_frame (line 159) | fn test_incomplete_frame() {
function test_cli_compatibility (line 178) | fn test_cli_compatibility() {
function test_legacy (line 194) | fn test_legacy() {
function test_full_cycle (line 219) | fn test_full_cycle(input: &[u8], level: i32) {
function test_empty (line 228) | fn test_empty() {
function test_ll_source (line 236) | fn test_ll_source() {
function reader_to_writer (line 248) | fn reader_to_writer() {
function test_finish_empty_encoder (line 272) | fn test_finish_empty_encoder() {
FILE: src/stream/write/mod.rs
type Encoder (line 27) | pub struct Encoder<'a, W: Write> {
type Decoder (line 38) | pub struct Decoder<'a, W: Write> {
type AutoFinishEncoder (line 49) | pub struct AutoFinishEncoder<
type AutoFlushDecoder (line 66) | pub struct AutoFlushDecoder<
function new (line 78) | fn new(decoder: Decoder<'a, W>, on_flush: F) -> Self {
function get_ref (line 86) | pub fn get_ref(&self) -> &W {
function get_mut (line 96) | pub fn get_mut(&mut self) -> &mut W {
method drop (line 106) | fn drop(&mut self) {
method write (line 116) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
method flush (line 120) | fn flush(&mut self) -> io::Result<()> {
function new (line 126) | fn new(encoder: Encoder<'a, W>, on_finish: F) -> Self {
function get_ref (line 134) | pub fn get_ref(&self) -> &W {
function get_mut (line 144) | pub fn get_mut(&mut self) -> &mut W {
method drop (line 150) | fn drop(&mut self) {
method write (line 159) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
method flush (line 163) | fn flush(&mut self) -> io::Result<()> {
function new (line 174) | pub fn new(writer: W, level: i32) -> io::Result<Self> {
function with_dictionary (line 184) | pub fn with_dictionary(
function with_writer (line 196) | pub fn with_writer(writer: zio::Writer<W, raw::Encoder<'a>>) -> Self {
function with_encoder (line 201) | pub fn with_encoder(writer: W, encoder: raw::Encoder<'a>) -> Self {
function with_context (line 207) | pub fn with_context(
function with_prepared_dictionary (line 219) | pub fn with_prepared_dictionary<'b>(
function with_ref_prefix (line 231) | pub fn with_ref_prefix<'b>(
function auto_finish (line 244) | pub fn auto_finish(self) -> AutoFinishEncoder<'a, W> {
function on_finish (line 255) | pub fn on_finish<F: FnMut(io::Result<W>)>(
function get_ref (line 263) | pub fn get_ref(&self) -> &W {
function get_mut (line 271) | pub fn get_mut(&mut self) -> &mut W {
function finish (line 287) | pub fn finish(self) -> io::Result<W> {
function try_finish (line 301) | pub fn try_finish(mut self) -> Result<W, (Self, io::Error)> {
function do_finish (line 313) | pub fn do_finish(&mut self) -> io::Result<()> {
function recommended_input_size (line 318) | pub fn recommended_input_size() -> usize {
method write (line 326) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
method flush (line 330) | fn flush(&mut self) -> io::Result<()> {
function new (line 337) | pub fn new(writer: W) -> io::Result<Self> {
function with_dictionary (line 345) | pub fn with_dictionary(writer: W, dictionary: &[u8]) -> io::Result<Self> {
function with_writer (line 363) | pub fn with_writer(writer: zio::Writer<W, raw::Decoder<'a>>) -> Self {
function with_decoder (line 368) | pub fn with_decoder(writer: W, decoder: raw::Decoder<'a>) -> Self {
function with_context (line 374) | pub fn with_context(
function with_prepared_dictionary (line 386) | pub fn with_prepared_dictionary<'b>(
function get_ref (line 398) | pub fn get_ref(&self) -> &W {
function get_mut (line 406) | pub fn get_mut(&mut self) -> &mut W {
function into_inner (line 411) | pub fn into_inner(self) -> W {
function recommended_input_size (line 416) | pub fn recommended_input_size() -> usize {
function auto_flush (line 421) | pub fn auto_flush(self) -> AutoFlushDecoder<'a, W> {
function on_flush (line 432) | pub fn on_flush<F: FnMut(io::Result<()>)>(
method write (line 443) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
method flush (line 447) | fn flush(&mut self) -> io::Result<()> {
function _assert_traits (line 452) | fn _assert_traits() {
FILE: src/stream/write/tests.rs
function test_cycle (line 10) | fn test_cycle() {
function test_partial_write_flush (line 33) | fn test_partial_write_flush() {
function test_partial_write_finish (line 48) | fn test_partial_write_finish() {
function setup_partial_write (line 57) | fn setup_partial_write(input_data: &[u8]) -> Encoder<PartialWrite<Vec<u8...
FILE: src/stream/zio/reader.rs
type Reader (line 12) | pub struct Reader<R, D> {
type State (line 22) | enum State {
function new (line 35) | pub fn new(reader: R, operation: D) -> Self {
function set_single_frame (line 46) | pub fn set_single_frame(&mut self) {
function operation_mut (line 51) | pub fn operation_mut(&mut self) -> &mut D {
function reader_mut (line 56) | pub fn reader_mut(&mut self) -> &mut R {
function reader (line 61) | pub fn reader(&self) -> &R {
function into_inner (line 66) | pub fn into_inner(self) -> R {
function flush (line 73) | pub fn flush(&mut self, output: &mut [u8]) -> io::Result<usize>
function fill_buf (line 81) | fn fill_buf<R>(reader: &mut R) -> io::Result<&[u8]>
method read (line 110) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
function test_noop (line 210) | fn test_noop() {
function test_compress (line 225) | fn test_compress() {
FILE: src/stream/zio/writer.rs
type Writer (line 13) | pub struct Writer<W, D> {
function new (line 49) | pub fn new(writer: W, operation: D) -> Self {
function new_with_capacity (line 57) | pub fn new_with_capacity(
function with_output_buffer (line 74) | pub fn with_output_buffer(
function finish (line 101) | pub fn finish(&mut self) -> io::Result<()> {
function with_buffer (line 141) | fn with_buffer<F, T>(&mut self, f: F) -> T
function write_from_offset (line 154) | fn write_from_offset(&mut self) -> io::Result<()> {
function into_inner (line 177) | pub fn into_inner(self) -> (W, D) {
function writer (line 182) | pub fn writer(&self) -> &W {
function writer_mut (line 187) | pub fn writer_mut(&mut self) -> &mut W {
function operation (line 192) | pub fn operation(&self) -> &D {
function operation_mut (line 197) | pub fn operation_mut(&mut self) -> &mut D {
function offset (line 203) | pub fn offset(&self) -> usize {
function buffer (line 209) | pub fn buffer(&self) -> &[u8] {
method write (line 219) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
method flush (line 266) | fn flush(&mut self) -> io::Result<()> {
function test_noop (line 294) | fn test_noop() {
function test_compress (line 310) | fn test_compress() {
function test_compress_with_capacity (line 329) | fn test_compress_with_capacity() {
function test_decompress (line 351) | fn test_decompress() {
function test_decompress_with_capacity (line 369) | fn test_decompress_with_capacity() {
FILE: tests/issue_182.rs
constant TEXT (line 1) | const TEXT: &[u8] = include_bytes!("../assets/example.txt");
function test_issue_182 (line 5) | fn test_issue_182() {
FILE: zstd-safe/build.rs
function main (line 1) | fn main() {
FILE: zstd-safe/src/constants.rs
constant BLOCKSIZELOG_MAX (line 2) | pub const BLOCKSIZELOG_MAX: u32 = zstd_sys::ZSTD_BLOCKSIZELOG_MAX;
constant BLOCKSIZE_MAX (line 3) | pub const BLOCKSIZE_MAX: u32 = zstd_sys::ZSTD_BLOCKSIZE_MAX;
constant CLEVEL_DEFAULT (line 4) | pub const CLEVEL_DEFAULT: CompressionLevel = zstd_sys::ZSTD_CLEVEL_DEFAU...
constant CONTENTSIZE_ERROR (line 5) | pub const CONTENTSIZE_ERROR: u64 = zstd_sys::ZSTD_CONTENTSIZE_ERROR as u64;
constant CONTENTSIZE_UNKNOWN (line 6) | pub const CONTENTSIZE_UNKNOWN: u64 = zstd_sys::ZSTD_CONTENTSIZE_UNKNOWN ...
constant MAGIC_DICTIONARY (line 7) | pub const MAGIC_DICTIONARY: u32 = zstd_sys::ZSTD_MAGIC_DICTIONARY;
constant MAGICNUMBER (line 8) | pub const MAGICNUMBER: u32 = zstd_sys::ZSTD_MAGICNUMBER;
constant MAGIC_SKIPPABLE_MASK (line 9) | pub const MAGIC_SKIPPABLE_MASK: u32 = zstd_sys::ZSTD_MAGIC_SKIPPABLE_MASK;
constant MAGIC_SKIPPABLE_START (line 10) | pub const MAGIC_SKIPPABLE_START: u32 = zstd_sys::ZSTD_MAGIC_SKIPPABLE_ST...
constant VERSION_MAJOR (line 11) | pub const VERSION_MAJOR: u32 = zstd_sys::ZSTD_VERSION_MAJOR;
constant VERSION_MINOR (line 12) | pub const VERSION_MINOR: u32 = zstd_sys::ZSTD_VERSION_MINOR;
constant VERSION_NUMBER (line 13) | pub const VERSION_NUMBER: u32 = zstd_sys::ZSTD_VERSION_NUMBER;
constant VERSION_RELEASE (line 14) | pub const VERSION_RELEASE: u32 = zstd_sys::ZSTD_VERSION_RELEASE;
FILE: zstd-safe/src/constants_experimental.rs
constant BLOCKSIZE_MAX_MIN (line 2) | pub const BLOCKSIZE_MAX_MIN: u32 = zstd_sys::ZSTD_BLOCKSIZE_MAX_MIN;
constant BLOCKSPLITTER_LEVEL_MAX (line 3) | pub const BLOCKSPLITTER_LEVEL_MAX: u32 = zstd_sys::ZSTD_BLOCKSPLITTER_LE...
constant CHAINLOG_MAX_32 (line 4) | pub const CHAINLOG_MAX_32: u32 = zstd_sys::ZSTD_CHAINLOG_MAX_32;
constant CHAINLOG_MAX_64 (line 5) | pub const CHAINLOG_MAX_64: u32 = zstd_sys::ZSTD_CHAINLOG_MAX_64;
constant CHAINLOG_MIN (line 6) | pub const CHAINLOG_MIN: u32 = zstd_sys::ZSTD_CHAINLOG_MIN;
constant FRAMEHEADERSIZE_MAX (line 7) | pub const FRAMEHEADERSIZE_MAX: u32 = zstd_sys::ZSTD_FRAMEHEADERSIZE_MAX;
constant HASHLOG_MIN (line 8) | pub const HASHLOG_MIN: u32 = zstd_sys::ZSTD_HASHLOG_MIN;
constant LDM_BUCKETSIZELOG_MAX (line 9) | pub const LDM_BUCKETSIZELOG_MAX: u32 = zstd_sys::ZSTD_LDM_BUCKETSIZELOG_...
constant LDM_BUCKETSIZELOG_MIN (line 10) | pub const LDM_BUCKETSIZELOG_MIN: u32 = zstd_sys::ZSTD_LDM_BUCKETSIZELOG_...
constant LDM_HASHLOG_MIN (line 11) | pub const LDM_HASHLOG_MIN: u32 = zstd_sys::ZSTD_LDM_HASHLOG_MIN;
constant LDM_HASHRATELOG_MIN (line 12) | pub const LDM_HASHRATELOG_MIN: u32 = zstd_sys::ZSTD_LDM_HASHRATELOG_MIN;
constant LDM_MINMATCH_MAX (line 13) | pub const LDM_MINMATCH_MAX: u32 = zstd_sys::ZSTD_LDM_MINMATCH_MAX;
constant LDM_MINMATCH_MIN (line 14) | pub const LDM_MINMATCH_MIN: u32 = zstd_sys::ZSTD_LDM_MINMATCH_MIN;
constant MINMATCH_MAX (line 15) | pub const MINMATCH_MAX: u32 = zstd_sys::ZSTD_MINMATCH_MAX;
constant MINMATCH_MIN (line 16) | pub const MINMATCH_MIN: u32 = zstd_sys::ZSTD_MINMATCH_MIN;
constant OVERLAPLOG_MAX (line 17) | pub const OVERLAPLOG_MAX: u32 = zstd_sys::ZSTD_OVERLAPLOG_MAX;
constant OVERLAPLOG_MIN (line 18) | pub const OVERLAPLOG_MIN: u32 = zstd_sys::ZSTD_OVERLAPLOG_MIN;
constant SEARCHLOG_MIN (line 19) | pub const SEARCHLOG_MIN: u32 = zstd_sys::ZSTD_SEARCHLOG_MIN;
constant SKIPPABLEHEADERSIZE (line 20) | pub const SKIPPABLEHEADERSIZE: u32 = zstd_sys::ZSTD_SKIPPABLEHEADERSIZE;
constant SRCSIZEHINT_MIN (line 21) | pub const SRCSIZEHINT_MIN: u32 = zstd_sys::ZSTD_SRCSIZEHINT_MIN;
constant TARGETCBLOCKSIZE_MAX (line 22) | pub const TARGETCBLOCKSIZE_MAX: u32 = zstd_sys::ZSTD_TARGETCBLOCKSIZE_MAX;
constant TARGETCBLOCKSIZE_MIN (line 23) | pub const TARGETCBLOCKSIZE_MIN: u32 = zstd_sys::ZSTD_TARGETCBLOCKSIZE_MIN;
constant TARGETLENGTH_MAX (line 24) | pub const TARGETLENGTH_MAX: u32 = zstd_sys::ZSTD_TARGETLENGTH_MAX;
constant TARGETLENGTH_MIN (line 25) | pub const TARGETLENGTH_MIN: u32 = zstd_sys::ZSTD_TARGETLENGTH_MIN;
constant WINDOWLOG_LIMIT_DEFAULT (line 26) | pub const WINDOWLOG_LIMIT_DEFAULT: u32 = zstd_sys::ZSTD_WINDOWLOG_LIMIT_...
constant WINDOWLOG_MAX_32 (line 27) | pub const WINDOWLOG_MAX_32: u32 = zstd_sys::ZSTD_WINDOWLOG_MAX_32;
constant WINDOWLOG_MAX_64 (line 28) | pub const WINDOWLOG_MAX_64: u32 = zstd_sys::ZSTD_WINDOWLOG_MAX_64;
constant WINDOWLOG_MIN (line 29) | pub const WINDOWLOG_MIN: u32 = zstd_sys::ZSTD_WINDOWLOG_MIN;
FILE: zstd-safe/src/constants_seekable.rs
constant SEEKABLE_FRAMEINDEX_TOOLARGE (line 2) | pub const SEEKABLE_FRAMEINDEX_TOOLARGE: u64 = zstd_sys::ZSTD_SEEKABLE_FR...
constant SEEKABLE_MAGICNUMBER (line 3) | pub const SEEKABLE_MAGICNUMBER: u32 = zstd_sys::ZSTD_SEEKABLE_MAGICNUMBER;
constant SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE (line 4) | pub const SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE: u32 = zstd_sys::ZSTD_SEE...
constant SEEKABLE_MAXFRAMES (line 5) | pub const SEEKABLE_MAXFRAMES: u32 = zstd_sys::ZSTD_SEEKABLE_MAXFRAMES;
constant seekTableFooterSize (line 6) | pub const seekTableFooterSize: u32 = zstd_sys::ZSTD_seekTableFooterSize;
FILE: zstd-safe/src/lib.rs
type CompressionLevel (line 63) | pub type CompressionLevel = i32;
type ErrorCode (line 66) | pub type ErrorCode = usize;
type SafeResult (line 71) | pub type SafeResult = Result<usize, ErrorCode>;
type ContentSizeError (line 77) | pub struct ContentSizeError;
method fmt (line 80) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
function is_error (line 86) | fn is_error(code: usize) -> bool {
function parse_code (line 95) | fn parse_code(code: usize) -> SafeResult {
function parse_content_size (line 106) | fn parse_content_size(
function ptr_void (line 116) | fn ptr_void(src: &[u8]) -> *const c_void {
function ptr_mut_void (line 120) | fn ptr_mut_void(dst: &mut (impl WriteBuf + ?Sized)) -> *mut c_void {
function version_number (line 128) | pub fn version_number() -> u32 {
function version_string (line 136) | pub fn version_string() -> &'static str {
function min_c_level (line 144) | pub fn min_c_level() -> CompressionLevel {
function max_c_level (line 150) | pub fn max_c_level() -> CompressionLevel {
function compress (line 162) | pub fn compress<C: WriteBuf + ?Sized>(
function decompress (line 189) | pub fn decompress<C: WriteBuf + ?Sized>(
function get_decompressed_size (line 210) | pub fn get_decompressed_size(src: &[u8]) -> Option<NonZeroU64> {
function compress_bound (line 218) | pub fn compress_bound(src_size: usize) -> usize {
type CCtx (line 227) | pub struct CCtx<'a>(NonNull<zstd_sys::ZSTD_CCtx>, PhantomData<&'a ()>);
method default (line 230) | fn default() -> Self {
function try_create (line 239) | pub fn try_create() -> Option<Self> {
function create (line 252) | pub fn create() -> Self {
function compress (line 258) | pub fn compress<C: WriteBuf + ?Sized>(
function compress2 (line 280) | pub fn compress2<C: WriteBuf + ?Sized>(
function compress_using_dict (line 300) | pub fn compress_using_dict<C: WriteBuf + ?Sized>(
function compress_using_cdict (line 325) | pub fn compress_using_cdict<C: WriteBuf + ?Sized>(
function init (line 351) | pub fn init(&mut self, compression_level: CompressionLevel) -> SafeResult {
function init_src_size (line 363) | pub fn init_src_size(
function init_using_dict (line 383) | pub fn init_using_dict(
function init_using_cdict (line 404) | pub fn init_using_cdict<'b>(&mut self, cdict: &CDict<'b>) -> SafeResult
function load_dictionary (line 427) | pub fn load_dictionary(&mut self, dict: &[u8]) -> SafeResult {
function ref_cdict (line 441) | pub fn ref_cdict<'b>(&mut self, cdict: &CDict<'b>) -> SafeResult
function disable_dictionary (line 454) | pub fn disable_dictionary(&mut self) -> SafeResult {
function ref_prefix (line 470) | pub fn ref_prefix<'b>(&mut self, prefix: &'b [u8]) -> SafeResult
function compress_stream (line 495) | pub fn compress_stream<C: WriteBuf + ?Sized>(
function compress_stream2 (line 528) | pub fn compress_stream2<C: WriteBuf + ?Sized>(
function flush_stream (line 552) | pub fn flush_stream<C: WriteBuf + ?Sized>(
function end_stream (line 569) | pub fn end_stream<C: WriteBuf + ?Sized>(
function sizeof (line 584) | pub fn sizeof(&self) -> usize {
function reset (line 594) | pub fn reset(&mut self, reset: ResetDirective) -> SafeResult {
function set_parameter (line 604) | pub fn set_parameter(&mut self, param: CParameter) -> SafeResult {
function set_pledged_src_size (line 734) | pub fn set_pledged_src_size(
function try_clone (line 753) | pub fn try_clone(
function get_block_size (line 776) | pub fn get_block_size(&self) -> usize {
function compress_block (line 784) | pub fn compress_block<C: WriteBuf + ?Sized>(
function in_size (line 806) | pub fn in_size() -> usize {
function out_size (line 814) | pub fn out_size() -> usize {
function ref_thread_pool (line 827) | pub fn ref_thread_pool<'b>(&mut self, pool: &'b ThreadPool) -> SafeResult
function disable_thread_pool (line 842) | pub fn disable_thread_pool(&mut self) -> SafeResult {
function get_frame_progression (line 853) | pub fn get_frame_progression(&self) -> FrameProgression {
method drop (line 860) | fn drop(&mut self) {
function c_char_to_str (line 872) | unsafe fn c_char_to_str(text: *const c_char) -> &'static str {
function get_error_name (line 879) | pub fn get_error_name(code: usize) -> &'static str {
type DCtx (line 894) | pub struct DCtx<'a>(NonNull<zstd_sys::ZSTD_DCtx>, PhantomData<&'a ()>);
method default (line 897) | fn default() -> Self {
function try_create (line 906) | pub fn try_create() -> Option<Self> {
function create (line 918) | pub fn create() -> Self {
function decompress (line 929) | pub fn decompress<C: WriteBuf + ?Sized>(
function decompress_using_dict (line 955) | pub fn decompress_using_dict<C: WriteBuf + ?Sized>(
function decompress_using_ddict (line 981) | pub fn decompress_using_ddict<C: WriteBuf + ?Sized>(
function init (line 1008) | pub fn init(&mut self) -> SafeResult {
function init_using_dict (line 1017) | pub fn init_using_dict(&mut self, dict: &[u8]) -> SafeResult {
function init_using_ddict (line 1032) | pub fn init_using_ddict<'b>(&mut self, ddict: &DDict<'b>) -> SafeResult
function reset (line 1050) | pub fn reset(&mut self, reset: ResetDirective) -> SafeResult {
function load_dictionary (line 1067) | pub fn load_dictionary(&mut self, dict: &[u8]) -> SafeResult {
function disable_dictionary (line 1080) | pub fn disable_dictionary(&mut self) -> SafeResult {
function ref_ddict (line 1097) | pub fn ref_ddict<'b>(&mut self, ddict: &DDict<'b>) -> SafeResult
function ref_prefix (line 1113) | pub fn ref_prefix<'b>(&mut self, prefix: &'b [u8]) -> SafeResult
function set_parameter (line 1127) | pub fn set_parameter(&mut self, param: DParameter) -> SafeResult {
function decompress_stream (line 1174) | pub fn decompress_stream<C: WriteBuf + ?Sized>(
function in_size (line 1194) | pub fn in_size() -> usize {
function out_size (line 1201) | pub fn out_size() -> usize {
function sizeof (line 1206) | pub fn sizeof(&self) -> usize {
function decompress_block (line 1213) | pub fn decompress_block<C: WriteBuf + ?Sized>(
function insert_block (line 1234) | pub fn insert_block(&mut self, block: &[u8]) -> usize {
function try_clone (line 1250) | pub fn try_clone(&self) -> Result<Self, ErrorCode> {
method drop (line 1261) | fn drop(&mut self) {
type CDict (line 1273) | pub struct CDict<'a>(NonNull<zstd_sys::ZSTD_CDict>, PhantomData<&'a ()>);
function create (line 1285) | pub fn create(
function try_create (line 1298) | pub fn try_create(
function create_by_reference (line 1318) | pub fn create_by_reference(
function sizeof (line 1338) | pub fn sizeof(&self) -> usize {
function get_dict_id (line 1345) | pub fn get_dict_id(&self) -> Option<NonZeroU32> {
function create_cdict (line 1353) | pub fn create_cdict(
method drop (line 1361) | fn drop(&mut self) {
function compress_using_cdict (line 1372) | pub fn compress_using_cdict(
type DDict (line 1382) | pub struct DDict<'a>(NonNull<zstd_sys::ZSTD_DDict>, PhantomData<&'a ()>);
function create (line 1385) | pub fn create(dict_buffer: &[u8]) -> Self {
function try_create (line 1390) | pub fn try_create(dict_buffer: &[u8]) -> Option<Self> {
function sizeof (line 1404) | pub fn sizeof(&self) -> usize {
function create_by_reference (line 1413) | pub fn create_by_reference(dict_buffer: &'a [u8]) -> Self {
function get_dict_id (line 1429) | pub fn get_dict_id(&self) -> Option<NonZeroU32> {
function create_ddict (line 1439) | pub fn create_ddict(dict_buffer: &[u8]) -> DDict<'static> {
method drop (line 1444) | fn drop(&mut self) {
type ThreadPool (line 1460) | pub struct ThreadPool(NonNull<zstd_sys::ZSTD_threadPool>);
method new (line 1473) | pub fn new(num_threads: usize) -> Self {
method try_new (line 1479) | pub fn try_new(num_threads: usize) -> Option<Self> {
method drop (line 1492) | fn drop(&mut self) {
function decompress_using_ddict (line 1513) | pub fn decompress_using_ddict(
type CStream (line 1525) | pub type CStream<'a> = CCtx<'a>;
function create_cstream (line 1530) | pub fn create_cstream<'a>() -> CStream<'a> {
function init_cstream (line 1535) | pub fn init_cstream(
type InBuffer (line 1548) | pub struct InBuffer<'a> {
type WriteBuf (line 1572) | pub unsafe trait WriteBuf {
method as_slice (line 1574) | fn as_slice(&self) -> &[u8];
method capacity (line 1577) | fn capacity(&self) -> usize;
method as_mut_ptr (line 1580) | fn as_mut_ptr(&mut self) -> *mut u8;
method filled_until (line 1586) | unsafe fn filled_until(&mut self, n: usize);
method write_from (line 1598) | unsafe fn write_from<F>(&mut self, f: F) -> SafeResult
method as_slice (line 1616) | fn as_slice(&self) -> &[u8] {
method capacity (line 1620) | fn capacity(&self) -> usize {
method as_mut_ptr (line 1626) | fn as_mut_ptr(&mut self) -> *mut u8 {
method filled_until (line 1633) | unsafe fn filled_until(&mut self, n: usize) {
method as_slice (line 1673) | fn as_slice(&self) -> &[u8] {
method capacity (line 1677) | fn capacity(&self) -> usize {
method as_mut_ptr (line 1681) | fn as_mut_ptr(&mut self) -> *mut u8 {
method filled_until (line 1685) | unsafe fn filled_until(&mut self, n: usize) {
method as_slice (line 1693) | fn as_slice(&self) -> &[u8] {
method capacity (line 1696) | fn capacity(&self) -> usize {
method as_mut_ptr (line 1699) | fn as_mut_ptr(&mut self) -> *mut u8 {
method filled_until (line 1702) | unsafe fn filled_until(&mut self, n: usize) {
method as_slice (line 1710) | fn as_slice(&self) -> &[u8] {
method capacity (line 1713) | fn capacity(&self) -> usize {
method as_mut_ptr (line 1717) | fn as_mut_ptr(&mut self) -> *mut u8 {
method filled_until (line 1721) | unsafe fn filled_until(&mut self, _n: usize) {
method as_slice (line 1727) | fn as_slice(&self) -> &[u8] {
method capacity (line 1730) | fn capacity(&self) -> usize {
method as_mut_ptr (line 1734) | fn as_mut_ptr(&mut self) -> *mut u8 {
method filled_until (line 1738) | unsafe fn filled_until(&mut self, _n: usize) {
type OutBuffer (line 1773) | pub struct OutBuffer<'a, C: WriteBuf + ?Sized> {
function ptr_mut (line 1779) | fn ptr_mut<B>(ptr_void: &mut B) -> *mut B {
type OutBufferWrapper (line 1786) | struct OutBufferWrapper<'a, 'b, C: WriteBuf + ?Sized> {
type Target (line 1792) | type Target = zstd_sys::ZSTD_outBuffer;
method deref (line 1794) | fn deref(&self) -> &Self::Target {
method deref_mut (line 1802) | fn deref_mut(&mut self) -> &mut Self::Target {
function around (line 1811) | pub fn around(dst: &'a mut C) -> Self {
function around_pos (line 1820) | pub fn around_pos(dst: &'a mut C, pos: usize) -> Self {
function pos (line 1831) | pub fn pos(&self) -> usize {
function capacity (line 1837) | pub fn capacity(&self) -> usize {
function set_pos (line 1850) | pub unsafe fn set_pos(&mut self, pos: usize) {
function wrap (line 1860) | fn wrap<'b>(&'b mut self) -> OutBufferWrapper<'b, 'a, C> {
function as_slice (line 1872) | pub fn as_slice<'b>(&'b self) -> &'a [u8]
function as_mut_ptr (line 1881) | pub fn as_mut_ptr(&mut self) -> *mut u8 {
method drop (line 1887) | fn drop(&mut self) {
type InBufferWrapper (line 1893) | struct InBufferWrapper<'a, 'b> {
type Target (line 1899) | type Target = zstd_sys::ZSTD_inBuffer;
method deref (line 1901) | fn deref(&self) -> &Self::Target {
method deref_mut (line 1907) | fn deref_mut(&mut self) -> &mut Self::Target {
function around (line 1916) | pub fn around(src: &'a [u8]) -> Self {
function pos (line 1921) | pub fn pos(&self) -> usize {
function set_pos (line 1930) | pub fn set_pos(&mut self, pos: usize) {
function wrap (line 1937) | fn wrap<'b>(&'b mut self) -> InBufferWrapper<'b, 'a> {
method drop (line 1950) | fn drop(&mut self) {
type DStream (line 1958) | pub type DStream<'a> = DCtx<'a>;
function find_frame_compressed_size (line 1969) | pub fn find_frame_compressed_size(src: &[u8]) -> SafeResult {
function get_frame_content_size (line 1985) | pub fn get_frame_content_size(
function find_decompressed_size (line 1998) | pub fn find_decompressed_size(
function is_frame (line 2009) | pub fn is_frame(buffer: &[u8]) -> bool {
function get_dict_id_from_dict (line 2016) | pub fn get_dict_id_from_dict(dict: &[u8]) -> Option<NonZeroU32> {
function get_dict_id_from_frame (line 2030) | pub fn get_dict_id_from_frame(src: &[u8]) -> Option<NonZeroU32> {
type ResetDirective (line 2037) | pub enum ResetDirective {
method as_sys (line 2061) | fn as_sys(self) -> zstd_sys::ZSTD_ResetDirective {
type FrameFormat (line 2074) | pub enum FrameFormat {
type DictAttachPref (line 2086) | pub enum DictAttachPref {
type ParamSwitch (line 2098) | pub enum ParamSwitch {
type CParameter (line 2107) | pub enum CParameter {
type DParameter (line 2262) | pub enum DParameter {
function train_from_buffer (line 2286) | pub fn train_from_buffer<C: WriteBuf + ?Sized>(
function get_dict_id (line 2309) | pub fn get_dict_id(dict_buffer: &[u8]) -> Option<NonZeroU32> {
function get_block_size (line 2318) | pub fn get_block_size(cctx: &CCtx) -> usize {
function decompress_bound (line 2325) | pub fn decompress_bound(data: &[u8]) -> Result<u64, ErrorCode> {
function sequence_bound (line 2339) | pub fn sequence_bound(src_size: usize) -> usize {
function decompression_margin (line 2351) | pub fn decompression_margin(
FILE: zstd-safe/src/seekable.rs
type FrameIndexTooLargeError (line 17) | pub struct FrameIndexTooLargeError;
method fmt (line 20) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
type SeekableCStream (line 29) | pub struct SeekableCStream(NonNull<zstd_sys::ZSTD_seekable_CStream>);
method try_create (line 44) | pub fn try_create() -> Option<Self> {
method create (line 56) | pub fn create() -> Self {
method init (line 75) | pub fn init(
method compress_stream (line 102) | pub fn compress_stream<C: WriteBuf + ?Sized>(
method end_frame (line 123) | pub fn end_frame<C: WriteBuf + ?Sized>(
method end_stream (line 146) | pub fn end_stream<C: WriteBuf + ?Sized>(
method default (line 35) | fn default() -> Self {
method drop (line 163) | fn drop(&mut self) {
type FrameLog (line 176) | pub struct FrameLog(NonNull<zstd_sys::ZSTD_frameLog>);
method try_create (line 185) | pub fn try_create(checksum_flag: bool) -> Option<Self> {
method create (line 199) | pub fn create(checksum_flag: bool) -> Self {
method log_frame (line 210) | pub fn log_frame(
method write_seek_table (line 232) | pub fn write_seek_table<C: WriteBuf + ?Sized>(
method drop (line 249) | fn drop(&mut self) {
type Seekable (line 260) | pub struct Seekable<'a>(NonNull<zstd_sys::ZSTD_seekable>, PhantomData<&'...
method default (line 266) | fn default() -> Self {
function try_create (line 275) | pub fn try_create() -> Option<Self> {
function create (line 288) | pub fn create() -> Self {
function init_buff (line 298) | pub fn init_buff(&mut self, src: &'a [u8]) -> SafeResult {
function decompress (line 319) | pub fn decompress<C: WriteBuf + ?Sized>(
function decompress_frame (line 339) | pub fn decompress_frame<C: WriteBuf + ?Sized>(
function num_frames (line 359) | pub fn num_frames(&self) -> u32 {
function frame_compressed_offset (line 366) | pub fn frame_compressed_offset(
function frame_decompressed_offset (line 387) | pub fn frame_decompressed_offset(
function frame_compressed_size (line 408) | pub fn frame_compressed_size(&self, frame_index: u32) -> SafeResult {
function frame_decompressed_size (line 422) | pub fn frame_decompressed_size(&self, frame_index: u32) -> SafeResult {
function offset_to_frame_index (line 434) | pub fn offset_to_frame_index(&self, offset: u64) -> u32 {
method drop (line 442) | fn drop(&mut self) {
type AdvancedSeekable (line 451) | pub struct AdvancedSeekable<'a, F> {
type Target (line 465) | type Target = Seekable<'a>;
function deref (line 467) | fn deref(&self) -> &Self::Target {
function deref_mut (line 474) | fn deref_mut(&mut self) -> &mut Self::Target {
method drop (line 481) | fn drop(&mut self) {
function init_advanced (line 496) | pub fn init_advanced<F>(
function advanced_seek (line 531) | unsafe extern "C" fn advanced_seek<S: std::io::Seek>(
function advanced_read (line 570) | unsafe extern "C" fn advanced_read<R: std::io::Read>(
type SeekTableCreateError (line 588) | pub struct SeekTableCreateError;
method fmt (line 591) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
type SeekTable (line 596) | pub struct SeekTable(NonNull<zstd_sys::ZSTD_seekTable>);
method try_from_seekable (line 606) | pub fn try_from_seekable<'a>(
method num_frames (line 619) | pub fn num_frames(&self) -> u32 {
method frame_compressed_offset (line 627) | pub fn frame_compressed_offset(
method frame_decompressed_offset (line 649) | pub fn frame_decompressed_offset(
method frame_compressed_size (line 671) | pub fn frame_compressed_size(&self, frame_index: u32) -> SafeResult {
method frame_decompressed_size (line 686) | pub fn frame_decompressed_size(&self, frame_index: u32) -> SafeResult {
method offset_to_frame_index (line 699) | pub fn offset_to_frame_index(&self, offset: u64) -> u32 {
method drop (line 711) | fn drop(&mut self) {
FILE: zstd-safe/src/tests.rs
constant INPUT (line 6) | const INPUT: &[u8] = b"Rust is a multi-paradigm system programming langu...
constant LONG_CONTENT (line 7) | const LONG_CONTENT: &str = include_str!("lib.rs");
function test_writebuf (line 11) | fn test_writebuf() {
function test_simple_cycle (line 51) | fn test_simple_cycle() {
function test_cctx_cycle (line 64) | fn test_cctx_cycle() {
function test_dictionary (line 79) | fn test_dictionary() {
function test_checksum (line 128) | fn test_checksum() {
function test_upper_bound (line 163) | fn test_upper_bound() {
function test_seekable_cycle (line 179) | fn test_seekable_cycle() {
function test_seekable_seek_table (line 207) | fn test_seekable_seek_table() {
function test_seekable_advanced_cycle (line 255) | fn test_seekable_advanced_cycle() {
function new_seekable_archive (line 271) | fn new_seekable_archive(input: &[u8]) -> Vec<u8> {
function decompress_seekable (line 311) | fn decompress_seekable(seekable: &mut crate::seekable::Seekable<'_>) {
FILE: zstd-safe/zstd-sys/build.rs
function generate_bindings (line 6) | fn generate_bindings(defs: Vec<&str>, headerpaths: Vec<PathBuf>) {
function generate_bindings (line 53) | fn generate_bindings(_: Vec<&str>, _: Vec<PathBuf>) {}
function pkg_config (line 55) | fn pkg_config() -> (Vec<&'static str>, Vec<PathBuf>) {
function set_legacy (line 65) | fn set_legacy(_config: &mut cc::Build) {}
function set_legacy (line 68) | fn set_legacy(config: &mut cc::Build) {
function set_pthread (line 74) | fn set_pthread(config: &mut cc::Build) {
function set_pthread (line 79) | fn set_pthread(_config: &mut cc::Build) {}
function enable_threading (line 82) | fn enable_threading(config: &mut cc::Build) {
function enable_threading (line 87) | fn enable_threading(_config: &mut cc::Build) {}
function flag_if_supported_with_fallbacks (line 92) | fn flag_if_supported_with_fallbacks(config: &mut cc::Build, flags: &[&st...
function compile_zstd (line 102) | fn compile_zstd() {
function cargo_print (line 260) | fn cargo_print(content: &dyn fmt::Display) {
function main (line 266) | fn main() {
FILE: zstd-safe/zstd-sys/examples/it_work.rs
function zstd_version (line 4) | pub extern "C" fn zstd_version() -> u32 {
function test_compress (line 17) | pub extern "C" fn test_compress() -> bool {
function main (line 55) | fn main() {}
FILE: zstd-safe/zstd-sys/src/bindings_zdict.rs
function ZDICT_trainFromBuffer (line 40) | pub fn ZDICT_trainFromBuffer(
type ZDICT_params_t (line 50) | pub struct ZDICT_params_t {
function ZDICT_finalizeDictionary (line 60) | pub fn ZDICT_finalizeDictionary(
function ZDICT_getDictID (line 72) | pub fn ZDICT_getDictID(
function ZDICT_getDictHeaderSize (line 78) | pub fn ZDICT_getDictHeaderSize(
function ZDICT_isError (line 84) | pub fn ZDICT_isError(errorCode: usize) -> ::core::ffi::c_uint;
function ZDICT_getErrorName (line 87) | pub fn ZDICT_getErrorName(errorCode: usize) -> *const ::core::ffi::c_char;
FILE: zstd-safe/zstd-sys/src/bindings_zdict_experimental.rs
constant ZDICT_DICTSIZE_MIN (line 38) | pub const ZDICT_DICTSIZE_MIN: u32 = 256;
constant ZDICT_CONTENTSIZE_MIN (line 39) | pub const ZDICT_CONTENTSIZE_MIN: u32 = 128;
function ZDICT_trainFromBuffer (line 42) | pub fn ZDICT_trainFromBuffer(
type ZDICT_params_t (line 52) | pub struct ZDICT_params_t {
function ZDICT_finalizeDictionary (line 62) | pub fn ZDICT_finalizeDictionary(
function ZDICT_getDictID (line 74) | pub fn ZDICT_getDictID(
function ZDICT_getDictHeaderSize (line 80) | pub fn ZDICT_getDictHeaderSize(
function ZDICT_isError (line 86) | pub fn ZDICT_isError(errorCode: usize) -> ::core::ffi::c_uint;
function ZDICT_getErrorName (line 89) | pub fn ZDICT_getErrorName(errorCode: usize) -> *const ::core::ffi::c_char;
type ZDICT_cover_params_t (line 94) | pub struct ZDICT_cover_params_t {
type ZDICT_fastCover_params_t (line 106) | pub struct ZDICT_fastCover_params_t {
function ZDICT_trainFromBuffer_cover (line 120) | pub fn ZDICT_trainFromBuffer_cover(
function ZDICT_optimizeTrainFromBuffer_cover (line 131) | pub fn ZDICT_optimizeTrainFromBuffer_cover(
function ZDICT_trainFromBuffer_fastCover (line 142) | pub fn ZDICT_trainFromBuffer_fastCover(
function ZDICT_optimizeTrainFromBuffer_fastCover (line 153) | pub fn ZDICT_optimizeTrainFromBuffer_fastCover(
type ZDICT_legacy_params_t (line 164) | pub struct ZDICT_legacy_params_t {
function ZDICT_trainFromBuffer_legacy (line 170) | pub fn ZDICT_trainFromBuffer_legacy(
function ZDICT_addEntropyTablesFromBuffer (line 180) | pub fn ZDICT_addEntropyTablesFromBuffer(
FILE: zstd-safe/zstd-sys/src/bindings_zdict_std_experimental.rs
constant ZDICT_DICTSIZE_MIN (line 38) | pub const ZDICT_DICTSIZE_MIN: u32 = 256;
constant ZDICT_CONTENTSIZE_MIN (line 39) | pub const ZDICT_CONTENTSIZE_MIN: u32 = 128;
function ZDICT_trainFromBuffer (line 42) | pub fn ZDICT_trainFromBuffer(
type ZDICT_params_t (line 52) | pub struct ZDICT_params_t {
function ZDICT_finalizeDictionary (line 62) | pub fn ZDICT_finalizeDictionary(
function ZDICT_getDictID (line 74) | pub fn ZDICT_getDictID(
function ZDICT_getDictHeaderSize (line 80) | pub fn ZDICT_getDictHeaderSize(
function ZDICT_isError (line 86) | pub fn ZDICT_isError(errorCode: usize) -> ::core::ffi::c_uint;
function ZDICT_getErrorName (line 89) | pub fn ZDICT_getErrorName(errorCode: usize) -> *const ::core::ffi::c_char;
type ZDICT_cover_params_t (line 94) | pub struct ZDICT_cover_params_t {
type ZDICT_fastCover_params_t (line 106) | pub struct ZDICT_fastCover_params_t {
function ZDICT_trainFromBuffer_cover (line 120) | pub fn ZDICT_trainFromBuffer_cover(
function ZDICT_optimizeTrainFromBuffer_cover (line 131) | pub fn ZDICT_optimizeTrainFromBuffer_cover(
function ZDICT_trainFromBuffer_fastCover (line 142) | pub fn ZDICT_trainFromBuffer_fastCover(
function ZDICT_optimizeTrainFromBuffer_fastCover (line 153) | pub fn ZDICT_optimizeTrainFromBuffer_fastCover(
type ZDICT_legacy_params_t (line 164) | pub struct ZDICT_legacy_params_t {
function ZDICT_trainFromBuffer_legacy (line 170) | pub fn ZDICT_trainFromBuffer_legacy(
function ZDICT_addEntropyTablesFromBuffer (line 180) | pub fn ZDICT_addEntropyTablesFromBuffer(
FILE: zstd-safe/zstd-sys/src/bindings_zstd.rs
constant ZSTD_VERSION_MAJOR (line 38) | pub const ZSTD_VERSION_MAJOR: u32 = 1;
constant ZSTD_VERSION_MINOR (line 39) | pub const ZSTD_VERSION_MINOR: u32 = 5;
constant ZSTD_VERSION_RELEASE (line 40) | pub const ZSTD_VERSION_RELEASE: u32 = 7;
constant ZSTD_VERSION_NUMBER (line 41) | pub const ZSTD_VERSION_NUMBER: u32 = 10507;
constant ZSTD_CLEVEL_DEFAULT (line 42) | pub const ZSTD_CLEVEL_DEFAULT: u32 = 3;
constant ZSTD_MAGICNUMBER (line 43) | pub const ZSTD_MAGICNUMBER: u32 = 4247762216;
constant ZSTD_MAGIC_DICTIONARY (line 44) | pub const ZSTD_MAGIC_DICTIONARY: u32 = 3962610743;
constant ZSTD_MAGIC_SKIPPABLE_START (line 45) | pub const ZSTD_MAGIC_SKIPPABLE_START: u32 = 407710288;
constant ZSTD_MAGIC_SKIPPABLE_MASK (line 46) | pub const ZSTD_MAGIC_SKIPPABLE_MASK: u32 = 4294967280;
constant ZSTD_BLOCKSIZELOG_MAX (line 47) | pub const ZSTD_BLOCKSIZELOG_MAX: u32 = 17;
constant ZSTD_BLOCKSIZE_MAX (line 48) | pub const ZSTD_BLOCKSIZE_MAX: u32 = 131072;
constant ZSTD_CONTENTSIZE_UNKNOWN (line 49) | pub const ZSTD_CONTENTSIZE_UNKNOWN: i32 = -1;
constant ZSTD_CONTENTSIZE_ERROR (line 50) | pub const ZSTD_CONTENTSIZE_ERROR: i32 = -2;
type ZSTD_ErrorCode (line 53) | pub enum ZSTD_ErrorCode {
function ZSTD_getErrorString (line 92) | pub fn ZSTD_getErrorString(
function ZSTD_versionNumber (line 98) | pub fn ZSTD_versionNumber() -> ::core::ffi::c_uint;
function ZSTD_versionString (line 102) | pub fn ZSTD_versionString() -> *const ::core::ffi::c_char;
function ZSTD_compress (line 106) | pub fn ZSTD_compress(
function ZSTD_decompress (line 116) | pub fn ZSTD_decompress(
function ZSTD_getFrameContentSize (line 124) | pub fn ZSTD_getFrameContentSize(
function ZSTD_getDecompressedSize (line 131) | pub fn ZSTD_getDecompressedSize(
function ZSTD_findFrameCompressedSize (line 138) | pub fn ZSTD_findFrameCompressedSize(
function ZSTD_compressBound (line 144) | pub fn ZSTD_compressBound(srcSize: usize) -> usize;
function ZSTD_isError (line 147) | pub fn ZSTD_isError(result: usize) -> ::core::ffi::c_uint;
function ZSTD_getErrorCode (line 150) | pub fn ZSTD_getErrorCode(functionResult: usize) -> ZSTD_ErrorCode;
function ZSTD_getErrorName (line 153) | pub fn ZSTD_getErrorName(result: usize) -> *const ::core::ffi::c_char;
function ZSTD_minCLevel (line 156) | pub fn ZSTD_minCLevel() -> ::core::ffi::c_int;
function ZSTD_maxCLevel (line 159) | pub fn ZSTD_maxCLevel() -> ::core::ffi::c_int;
function ZSTD_defaultCLevel (line 162) | pub fn ZSTD_defaultCLevel() -> ::core::ffi::c_int;
type ZSTD_CCtx_s (line 166) | pub struct ZSTD_CCtx_s {
type ZSTD_CCtx (line 170) | pub type ZSTD_CCtx = ZSTD_CCtx_s;
function ZSTD_createCCtx (line 172) | pub fn ZSTD_createCCtx() -> *mut ZSTD_CCtx;
function ZSTD_freeCCtx (line 175) | pub fn ZSTD_freeCCtx(cctx: *mut ZSTD_CCtx) -> usize;
function ZSTD_compressCCtx (line 179) | pub fn ZSTD_compressCCtx(
type ZSTD_DCtx_s (line 190) | pub struct ZSTD_DCtx_s {
type ZSTD_DCtx (line 193) | pub type ZSTD_DCtx = ZSTD_DCtx_s;
function ZSTD_createDCtx (line 195) | pub fn ZSTD_createDCtx() -> *mut ZSTD_DCtx;
function ZSTD_freeDCtx (line 198) | pub fn ZSTD_freeDCtx(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressDCtx (line 202) | pub fn ZSTD_decompressDCtx(
type ZSTD_strategy (line 213) | pub enum ZSTD_strategy {
type ZSTD_cParameter (line 226) | pub enum ZSTD_cParameter {
type ZSTD_bounds (line 269) | pub struct ZSTD_bounds {
function ZSTD_cParam_getBounds (line 276) | pub fn ZSTD_cParam_getBounds(cParam: ZSTD_cParameter) -> ZSTD_bounds;
function ZSTD_CCtx_setParameter (line 280) | pub fn ZSTD_CCtx_setParameter(
function ZSTD_CCtx_setPledgedSrcSize (line 288) | pub fn ZSTD_CCtx_setPledgedSrcSize(
type ZSTD_ResetDirective (line 295) | pub enum ZSTD_ResetDirective {
function ZSTD_CCtx_reset (line 302) | pub fn ZSTD_CCtx_reset(
function ZSTD_compress2 (line 309) | pub fn ZSTD_compress2(
type ZSTD_dParameter (line 320) | pub enum ZSTD_dParameter {
function ZSTD_dParam_getBounds (line 331) | pub fn ZSTD_dParam_getBounds(dParam: ZSTD_dParameter) -> ZSTD_bounds;
function ZSTD_DCtx_setParameter (line 335) | pub fn ZSTD_DCtx_setParameter(
function ZSTD_DCtx_reset (line 343) | pub fn ZSTD_DCtx_reset(
type ZSTD_inBuffer_s (line 351) | pub struct ZSTD_inBuffer_s {
type ZSTD_inBuffer (line 360) | pub type ZSTD_inBuffer = ZSTD_inBuffer_s;
type ZSTD_outBuffer_s (line 363) | pub struct ZSTD_outBuffer_s {
type ZSTD_outBuffer (line 371) | pub type ZSTD_outBuffer = ZSTD_outBuffer_s;
type ZSTD_CStream (line 372) | pub type ZSTD_CStream = ZSTD_CCtx;
function ZSTD_createCStream (line 374) | pub fn ZSTD_createCStream() -> *mut ZSTD_CStream;
function ZSTD_freeCStream (line 377) | pub fn ZSTD_freeCStream(zcs: *mut ZSTD_CStream) -> usize;
type ZSTD_EndDirective (line 381) | pub enum ZSTD_EndDirective {
function ZSTD_compressStream2 (line 388) | pub fn ZSTD_compressStream2(
function ZSTD_CStreamInSize (line 396) | pub fn ZSTD_CStreamInSize() -> usize;
function ZSTD_CStreamOutSize (line 399) | pub fn ZSTD_CStreamOutSize() -> usize;
function ZSTD_initCStream (line 403) | pub fn ZSTD_initCStream(
function ZSTD_compressStream (line 410) | pub fn ZSTD_compressStream(
function ZSTD_flushStream (line 418) | pub fn ZSTD_flushStream(
function ZSTD_endStream (line 425) | pub fn ZSTD_endStream(
type ZSTD_DStream (line 430) | pub type ZSTD_DStream = ZSTD_DCtx;
function ZSTD_createDStream (line 432) | pub fn ZSTD_createDStream() -> *mut ZSTD_DStream;
function ZSTD_freeDStream (line 435) | pub fn ZSTD_freeDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_initDStream (line 439) | pub fn ZSTD_initDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_decompressStream (line 443) | pub fn ZSTD_decompressStream(
function ZSTD_DStreamInSize (line 450) | pub fn ZSTD_DStreamInSize() -> usize;
function ZSTD_DStreamOutSize (line 453) | pub fn ZSTD_DStreamOutSize() -> usize;
function ZSTD_compress_usingDict (line 457) | pub fn ZSTD_compress_usingDict(
function ZSTD_decompress_usingDict (line 470) | pub fn ZSTD_decompress_usingDict(
type ZSTD_CDict_s (line 482) | pub struct ZSTD_CDict_s {
type ZSTD_CDict (line 486) | pub type ZSTD_CDict = ZSTD_CDict_s;
function ZSTD_createCDict (line 489) | pub fn ZSTD_createCDict(
function ZSTD_freeCDict (line 497) | pub fn ZSTD_freeCDict(CDict: *mut ZSTD_CDict) -> usize;
function ZSTD_compress_usingCDict (line 501) | pub fn ZSTD_compress_usingCDict(
type ZSTD_DDict_s (line 512) | pub struct ZSTD_DDict_s {
type ZSTD_DDict (line 515) | pub type ZSTD_DDict = ZSTD_DDict_s;
function ZSTD_createDDict (line 518) | pub fn ZSTD_createDDict(
function ZSTD_freeDDict (line 525) | pub fn ZSTD_freeDDict(ddict: *mut ZSTD_DDict) -> usize;
function ZSTD_decompress_usingDDict (line 529) | pub fn ZSTD_decompress_usingDDict(
function ZSTD_getDictID_fromDict (line 540) | pub fn ZSTD_getDictID_fromDict(
function ZSTD_getDictID_fromCDict (line 547) | pub fn ZSTD_getDictID_fromCDict(
function ZSTD_getDictID_fromDDict (line 553) | pub fn ZSTD_getDictID_fromDDict(
function ZSTD_getDictID_fromFrame (line 559) | pub fn ZSTD_getDictID_fromFrame(
function ZSTD_CCtx_loadDictionary (line 566) | pub fn ZSTD_CCtx_loadDictionary(
function ZSTD_CCtx_refCDict (line 574) | pub fn ZSTD_CCtx_refCDict(
function ZSTD_CCtx_refPrefix (line 581) | pub fn ZSTD_CCtx_refPrefix(
function ZSTD_DCtx_loadDictionary (line 589) | pub fn ZSTD_DCtx_loadDictionary(
function ZSTD_DCtx_refDDict (line 597) | pub fn ZSTD_DCtx_refDDict(
function ZSTD_DCtx_refPrefix (line 604) | pub fn ZSTD_DCtx_refPrefix(
function ZSTD_sizeof_CCtx (line 612) | pub fn ZSTD_sizeof_CCtx(cctx: *const ZSTD_CCtx) -> usize;
function ZSTD_sizeof_DCtx (line 615) | pub fn ZSTD_sizeof_DCtx(dctx: *const ZSTD_DCtx) -> usize;
function ZSTD_sizeof_CStream (line 618) | pub fn ZSTD_sizeof_CStream(zcs: *const ZSTD_CStream) -> usize;
function ZSTD_sizeof_DStream (line 621) | pub fn ZSTD_sizeof_DStream(zds: *const ZSTD_DStream) -> usize;
function ZSTD_sizeof_CDict (line 624) | pub fn ZSTD_sizeof_CDict(cdict: *const ZSTD_CDict) -> usize;
function ZSTD_sizeof_DDict (line 627) | pub fn ZSTD_sizeof_DDict(ddict: *const ZSTD_DDict) -> usize;
FILE: zstd-safe/zstd-sys/src/bindings_zstd_experimental.rs
constant ZSTD_VERSION_MAJOR (line 38) | pub const ZSTD_VERSION_MAJOR: u32 = 1;
constant ZSTD_VERSION_MINOR (line 39) | pub const ZSTD_VERSION_MINOR: u32 = 5;
constant ZSTD_VERSION_RELEASE (line 40) | pub const ZSTD_VERSION_RELEASE: u32 = 7;
constant ZSTD_VERSION_NUMBER (line 41) | pub const ZSTD_VERSION_NUMBER: u32 = 10507;
constant ZSTD_CLEVEL_DEFAULT (line 42) | pub const ZSTD_CLEVEL_DEFAULT: u32 = 3;
constant ZSTD_MAGICNUMBER (line 43) | pub const ZSTD_MAGICNUMBER: u32 = 4247762216;
constant ZSTD_MAGIC_DICTIONARY (line 44) | pub const ZSTD_MAGIC_DICTIONARY: u32 = 3962610743;
constant ZSTD_MAGIC_SKIPPABLE_START (line 45) | pub const ZSTD_MAGIC_SKIPPABLE_START: u32 = 407710288;
constant ZSTD_MAGIC_SKIPPABLE_MASK (line 46) | pub const ZSTD_MAGIC_SKIPPABLE_MASK: u32 = 4294967280;
constant ZSTD_BLOCKSIZELOG_MAX (line 47) | pub const ZSTD_BLOCKSIZELOG_MAX: u32 = 17;
constant ZSTD_BLOCKSIZE_MAX (line 48) | pub const ZSTD_BLOCKSIZE_MAX: u32 = 131072;
constant ZSTD_CONTENTSIZE_UNKNOWN (line 49) | pub const ZSTD_CONTENTSIZE_UNKNOWN: i32 = -1;
constant ZSTD_CONTENTSIZE_ERROR (line 50) | pub const ZSTD_CONTENTSIZE_ERROR: i32 = -2;
constant ZSTD_FRAMEHEADERSIZE_MAX (line 51) | pub const ZSTD_FRAMEHEADERSIZE_MAX: u32 = 18;
constant ZSTD_SKIPPABLEHEADERSIZE (line 52) | pub const ZSTD_SKIPPABLEHEADERSIZE: u32 = 8;
constant ZSTD_WINDOWLOG_MAX_32 (line 53) | pub const ZSTD_WINDOWLOG_MAX_32: u32 = 30;
constant ZSTD_WINDOWLOG_MAX_64 (line 54) | pub const ZSTD_WINDOWLOG_MAX_64: u32 = 31;
constant ZSTD_WINDOWLOG_MIN (line 55) | pub const ZSTD_WINDOWLOG_MIN: u32 = 10;
constant ZSTD_HASHLOG_MIN (line 56) | pub const ZSTD_HASHLOG_MIN: u32 = 6;
constant ZSTD_CHAINLOG_MAX_32 (line 57) | pub const ZSTD_CHAINLOG_MAX_32: u32 = 29;
constant ZSTD_CHAINLOG_MAX_64 (line 58) | pub const ZSTD_CHAINLOG_MAX_64: u32 = 30;
constant ZSTD_CHAINLOG_MIN (line 59) | pub const ZSTD_CHAINLOG_MIN: u32 = 6;
constant ZSTD_SEARCHLOG_MIN (line 60) | pub const ZSTD_SEARCHLOG_MIN: u32 = 1;
constant ZSTD_MINMATCH_MAX (line 61) | pub const ZSTD_MINMATCH_MAX: u32 = 7;
constant ZSTD_MINMATCH_MIN (line 62) | pub const ZSTD_MINMATCH_MIN: u32 = 3;
constant ZSTD_TARGETLENGTH_MAX (line 63) | pub const ZSTD_TARGETLENGTH_MAX: u32 = 131072;
constant ZSTD_TARGETLENGTH_MIN (line 64) | pub const ZSTD_TARGETLENGTH_MIN: u32 = 0;
constant ZSTD_BLOCKSIZE_MAX_MIN (line 65) | pub const ZSTD_BLOCKSIZE_MAX_MIN: u32 = 1024;
constant ZSTD_OVERLAPLOG_MIN (line 66) | pub const ZSTD_OVERLAPLOG_MIN: u32 = 0;
constant ZSTD_OVERLAPLOG_MAX (line 67) | pub const ZSTD_OVERLAPLOG_MAX: u32 = 9;
constant ZSTD_WINDOWLOG_LIMIT_DEFAULT (line 68) | pub const ZSTD_WINDOWLOG_LIMIT_DEFAULT: u32 = 27;
constant ZSTD_LDM_HASHLOG_MIN (line 69) | pub const ZSTD_LDM_HASHLOG_MIN: u32 = 6;
constant ZSTD_LDM_MINMATCH_MIN (line 70) | pub const ZSTD_LDM_MINMATCH_MIN: u32 = 4;
constant ZSTD_LDM_MINMATCH_MAX (line 71) | pub const ZSTD_LDM_MINMATCH_MAX: u32 = 4096;
constant ZSTD_LDM_BUCKETSIZELOG_MIN (line 72) | pub const ZSTD_LDM_BUCKETSIZELOG_MIN: u32 = 1;
constant ZSTD_LDM_BUCKETSIZELOG_MAX (line 73) | pub const ZSTD_LDM_BUCKETSIZELOG_MAX: u32 = 8;
constant ZSTD_LDM_HASHRATELOG_MIN (line 74) | pub const ZSTD_LDM_HASHRATELOG_MIN: u32 = 0;
constant ZSTD_TARGETCBLOCKSIZE_MIN (line 75) | pub const ZSTD_TARGETCBLOCKSIZE_MIN: u32 = 1340;
constant ZSTD_TARGETCBLOCKSIZE_MAX (line 76) | pub const ZSTD_TARGETCBLOCKSIZE_MAX: u32 = 131072;
constant ZSTD_SRCSIZEHINT_MIN (line 77) | pub const ZSTD_SRCSIZEHINT_MIN: u32 = 0;
constant ZSTD_BLOCKSPLITTER_LEVEL_MAX (line 78) | pub const ZSTD_BLOCKSPLITTER_LEVEL_MAX: u32 = 6;
type ZSTD_ErrorCode (line 81) | pub enum ZSTD_ErrorCode {
function ZSTD_getErrorString (line 120) | pub fn ZSTD_getErrorString(
function ZSTD_versionNumber (line 126) | pub fn ZSTD_versionNumber() -> ::core::ffi::c_uint;
function ZSTD_versionString (line 130) | pub fn ZSTD_versionString() -> *const ::core::ffi::c_char;
function ZSTD_compress (line 134) | pub fn ZSTD_compress(
function ZSTD_decompress (line 144) | pub fn ZSTD_decompress(
function ZSTD_getFrameContentSize (line 152) | pub fn ZSTD_getFrameContentSize(
function ZSTD_getDecompressedSize (line 159) | pub fn ZSTD_getDecompressedSize(
function ZSTD_findFrameCompressedSize (line 166) | pub fn ZSTD_findFrameCompressedSize(
function ZSTD_compressBound (line 172) | pub fn ZSTD_compressBound(srcSize: usize) -> usize;
function ZSTD_isError (line 175) | pub fn ZSTD_isError(result: usize) -> ::core::ffi::c_uint;
function ZSTD_getErrorCode (line 178) | pub fn ZSTD_getErrorCode(functionResult: usize) -> ZSTD_ErrorCode;
function ZSTD_getErrorName (line 181) | pub fn ZSTD_getErrorName(result: usize) -> *const ::core::ffi::c_char;
function ZSTD_minCLevel (line 184) | pub fn ZSTD_minCLevel() -> ::core::ffi::c_int;
function ZSTD_maxCLevel (line 187) | pub fn ZSTD_maxCLevel() -> ::core::ffi::c_int;
function ZSTD_defaultCLevel (line 190) | pub fn ZSTD_defaultCLevel() -> ::core::ffi::c_int;
type ZSTD_CCtx_s (line 194) | pub struct ZSTD_CCtx_s {
type ZSTD_CCtx (line 198) | pub type ZSTD_CCtx = ZSTD_CCtx_s;
function ZSTD_createCCtx (line 200) | pub fn ZSTD_createCCtx() -> *mut ZSTD_CCtx;
function ZSTD_freeCCtx (line 203) | pub fn ZSTD_freeCCtx(cctx: *mut ZSTD_CCtx) -> usize;
function ZSTD_compressCCtx (line 207) | pub fn ZSTD_compressCCtx(
type ZSTD_DCtx_s (line 218) | pub struct ZSTD_DCtx_s {
type ZSTD_DCtx (line 221) | pub type ZSTD_DCtx = ZSTD_DCtx_s;
function ZSTD_createDCtx (line 223) | pub fn ZSTD_createDCtx() -> *mut ZSTD_DCtx;
function ZSTD_freeDCtx (line 226) | pub fn ZSTD_freeDCtx(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressDCtx (line 230) | pub fn ZSTD_decompressDCtx(
type ZSTD_strategy (line 241) | pub enum ZSTD_strategy {
type ZSTD_cParameter (line 254) | pub enum ZSTD_cParameter {
type ZSTD_bounds (line 297) | pub struct ZSTD_bounds {
function ZSTD_cParam_getBounds (line 304) | pub fn ZSTD_cParam_getBounds(cParam: ZSTD_cParameter) -> ZSTD_bounds;
function ZSTD_CCtx_setParameter (line 308) | pub fn ZSTD_CCtx_setParameter(
function ZSTD_CCtx_setPledgedSrcSize (line 316) | pub fn ZSTD_CCtx_setPledgedSrcSize(
type ZSTD_ResetDirective (line 323) | pub enum ZSTD_ResetDirective {
function ZSTD_CCtx_reset (line 330) | pub fn ZSTD_CCtx_reset(
function ZSTD_compress2 (line 337) | pub fn ZSTD_compress2(
type ZSTD_dParameter (line 348) | pub enum ZSTD_dParameter {
function ZSTD_dParam_getBounds (line 359) | pub fn ZSTD_dParam_getBounds(dParam: ZSTD_dParameter) -> ZSTD_bounds;
function ZSTD_DCtx_setParameter (line 363) | pub fn ZSTD_DCtx_setParameter(
function ZSTD_DCtx_reset (line 371) | pub fn ZSTD_DCtx_reset(
type ZSTD_inBuffer_s (line 379) | pub struct ZSTD_inBuffer_s {
type ZSTD_inBuffer (line 388) | pub type ZSTD_inBuffer = ZSTD_inBuffer_s;
type ZSTD_outBuffer_s (line 391) | pub struct ZSTD_outBuffer_s {
type ZSTD_outBuffer (line 399) | pub type ZSTD_outBuffer = ZSTD_outBuffer_s;
type ZSTD_CStream (line 400) | pub type ZSTD_CStream = ZSTD_CCtx;
function ZSTD_createCStream (line 402) | pub fn ZSTD_createCStream() -> *mut ZSTD_CStream;
function ZSTD_freeCStream (line 405) | pub fn ZSTD_freeCStream(zcs: *mut ZSTD_CStream) -> usize;
type ZSTD_EndDirective (line 409) | pub enum ZSTD_EndDirective {
function ZSTD_compressStream2 (line 416) | pub fn ZSTD_compressStream2(
function ZSTD_CStreamInSize (line 424) | pub fn ZSTD_CStreamInSize() -> usize;
function ZSTD_CStreamOutSize (line 427) | pub fn ZSTD_CStreamOutSize() -> usize;
function ZSTD_initCStream (line 431) | pub fn ZSTD_initCStream(
function ZSTD_compressStream (line 438) | pub fn ZSTD_compressStream(
function ZSTD_flushStream (line 446) | pub fn ZSTD_flushStream(
function ZSTD_endStream (line 453) | pub fn ZSTD_endStream(
type ZSTD_DStream (line 458) | pub type ZSTD_DStream = ZSTD_DCtx;
function ZSTD_createDStream (line 460) | pub fn ZSTD_createDStream() -> *mut ZSTD_DStream;
function ZSTD_freeDStream (line 463) | pub fn ZSTD_freeDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_initDStream (line 467) | pub fn ZSTD_initDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_decompressStream (line 471) | pub fn ZSTD_decompressStream(
function ZSTD_DStreamInSize (line 478) | pub fn ZSTD_DStreamInSize() -> usize;
function ZSTD_DStreamOutSize (line 481) | pub fn ZSTD_DStreamOutSize() -> usize;
function ZSTD_compress_usingDict (line 485) | pub fn ZSTD_compress_usingDict(
function ZSTD_decompress_usingDict (line 498) | pub fn ZSTD_decompress_usingDict(
type ZSTD_CDict_s (line 510) | pub struct ZSTD_CDict_s {
type ZSTD_CDict (line 514) | pub type ZSTD_CDict = ZSTD_CDict_s;
function ZSTD_createCDict (line 517) | pub fn ZSTD_createCDict(
function ZSTD_freeCDict (line 525) | pub fn ZSTD_freeCDict(CDict: *mut ZSTD_CDict) -> usize;
function ZSTD_compress_usingCDict (line 529) | pub fn ZSTD_compress_usingCDict(
type ZSTD_DDict_s (line 540) | pub struct ZSTD_DDict_s {
type ZSTD_DDict (line 543) | pub type ZSTD_DDict = ZSTD_DDict_s;
function ZSTD_createDDict (line 546) | pub fn ZSTD_createDDict(
function ZSTD_freeDDict (line 553) | pub fn ZSTD_freeDDict(ddict: *mut ZSTD_DDict) -> usize;
function ZSTD_decompress_usingDDict (line 557) | pub fn ZSTD_decompress_usingDDict(
function ZSTD_getDictID_fromDict (line 568) | pub fn ZSTD_getDictID_fromDict(
function ZSTD_getDictID_fromCDict (line 575) | pub fn ZSTD_getDictID_fromCDict(
function ZSTD_getDictID_fromDDict (line 581) | pub fn ZSTD_getDictID_fromDDict(
function ZSTD_getDictID_fromFrame (line 587) | pub fn ZSTD_getDictID_fromFrame(
function ZSTD_CCtx_loadDictionary (line 594) | pub fn ZSTD_CCtx_loadDictionary(
function ZSTD_CCtx_refCDict (line 602) | pub fn ZSTD_CCtx_refCDict(
function ZSTD_CCtx_refPrefix (line 609) | pub fn ZSTD_CCtx_refPrefix(
function ZSTD_DCtx_loadDictionary (line 617) | pub fn ZSTD_DCtx_loadDictionary(
function ZSTD_DCtx_refDDict (line 625) | pub fn ZSTD_DCtx_refDDict(
function ZSTD_DCtx_refPrefix (line 632) | pub fn ZSTD_DCtx_refPrefix(
function ZSTD_sizeof_CCtx (line 640) | pub fn ZSTD_sizeof_CCtx(cctx: *const ZSTD_CCtx) -> usize;
function ZSTD_sizeof_DCtx (line 643) | pub fn ZSTD_sizeof_DCtx(dctx: *const ZSTD_DCtx) -> usize;
function ZSTD_sizeof_CStream (line 646) | pub fn ZSTD_sizeof_CStream(zcs: *const ZSTD_CStream) -> usize;
function ZSTD_sizeof_DStream (line 649) | pub fn ZSTD_sizeof_DStream(zds: *const ZSTD_DStream) -> usize;
function ZSTD_sizeof_CDict (line 652) | pub fn ZSTD_sizeof_CDict(cdict: *const ZSTD_CDict) -> usize;
function ZSTD_sizeof_DDict (line 655) | pub fn ZSTD_sizeof_DDict(ddict: *const ZSTD_DDict) -> usize;
type ZSTD_CCtx_params_s (line 659) | pub struct ZSTD_CCtx_params_s {
type ZSTD_CCtx_params (line 662) | pub type ZSTD_CCtx_params = ZSTD_CCtx_params_s;
type ZSTD_Sequence (line 665) | pub struct ZSTD_Sequence {
type ZSTD_compressionParameters (line 673) | pub struct ZSTD_compressionParameters {
type ZSTD_frameParameters (line 691) | pub struct ZSTD_frameParameters {
type ZSTD_parameters (line 701) | pub struct ZSTD_parameters {
type ZSTD_dictContentType_e (line 707) | pub enum ZSTD_dictContentType_e {
type ZSTD_dictLoadMethod_e (line 714) | pub enum ZSTD_dictLoadMethod_e {
type ZSTD_format_e (line 722) | pub enum ZSTD_format_e {
type ZSTD_forceIgnoreChecksum_e (line 728) | pub enum ZSTD_forceIgnoreChecksum_e {
type ZSTD_refMultipleDDicts_e (line 734) | pub enum ZSTD_refMultipleDDicts_e {
type ZSTD_dictAttachPref_e (line 740) | pub enum ZSTD_dictAttachPref_e {
type ZSTD_literalCompressionMode_e (line 748) | pub enum ZSTD_literalCompressionMode_e {
type ZSTD_ParamSwitch_e (line 758) | pub enum ZSTD_ParamSwitch_e {
function ZSTD_findDecompressedSize (line 765) | pub fn ZSTD_findDecompressedSize(
function ZSTD_decompressBound (line 772) | pub fn ZSTD_decompressBound(
function ZSTD_frameHeaderSize (line 779) | pub fn ZSTD_frameHeaderSize(
type ZSTD_FrameType_e (line 786) | pub enum ZSTD_FrameType_e {
type ZSTD_FrameHeader (line 792) | pub struct ZSTD_FrameHeader {
function ZSTD_getFrameHeader (line 805) | pub fn ZSTD_getFrameHeader(
function ZSTD_getFrameHeader_advanced (line 813) | pub fn ZSTD_getFrameHeader_advanced(
function ZSTD_decompressionMargin (line 822) | pub fn ZSTD_decompressionMargin(
type ZSTD_SequenceFormat_e (line 829) | pub enum ZSTD_SequenceFormat_e {
function ZSTD_sequenceBound (line 835) | pub fn ZSTD_sequenceBound(srcSize: usize) -> usize;
function ZSTD_generateSequences (line 839) | pub fn ZSTD_generateSequences(
function ZSTD_mergeBlockDelimiters (line 849) | pub fn ZSTD_mergeBlockDelimiters(
function ZSTD_compressSequences (line 856) | pub fn ZSTD_compressSequences(
function ZSTD_compressSequencesAndLiterals (line 868) | pub fn ZSTD_compressSequencesAndLiterals(
function ZSTD_writeSkippableFrame (line 882) | pub fn ZSTD_writeSkippableFrame(
function ZSTD_readSkippableFrame (line 892) | pub fn ZSTD_readSkippableFrame(
function ZSTD_isSkippableFrame (line 902) | pub fn ZSTD_isSkippableFrame(
function ZSTD_estimateCCtxSize (line 909) | pub fn ZSTD_estimateCCtxSize(
function ZSTD_estimateCCtxSize_usingCParams (line 914) | pub fn ZSTD_estimateCCtxSize_usingCParams(
function ZSTD_estimateCCtxSize_usingCCtxParams (line 919) | pub fn ZSTD_estimateCCtxSize_usingCCtxParams(
function ZSTD_estimateDCtxSize (line 924) | pub fn ZSTD_estimateDCtxSize() -> usize;
function ZSTD_estimateCStreamSize (line 928) | pub fn ZSTD_estimateCStreamSize(
function ZSTD_estimateCStreamSize_usingCParams (line 933) | pub fn ZSTD_estimateCStreamSize_usingCParams(
function ZSTD_estimateCStreamSize_usingCCtxParams (line 938) | pub fn ZSTD_estimateCStreamSize_usingCCtxParams(
function ZSTD_estimateDStreamSize (line 943) | pub fn ZSTD_estimateDStreamSize(maxWindowSize: usize) -> usize;
function ZSTD_estimateDStreamSize_fromFrame (line 946) | pub fn ZSTD_estimateDStreamSize_fromFrame(
function ZSTD_estimateCDictSize (line 953) | pub fn ZSTD_estimateCDictSize(
function ZSTD_estimateCDictSize_advanced (line 959) | pub fn ZSTD_estimateCDictSize_advanced(
function ZSTD_estimateDDictSize (line 966) | pub fn ZSTD_estimateDDictSize(
function ZSTD_initStaticCCtx (line 973) | pub fn ZSTD_initStaticCCtx(
function ZSTD_initStaticCStream (line 979) | pub fn ZSTD_initStaticCStream(
function ZSTD_initStaticDCtx (line 985) | pub fn ZSTD_initStaticDCtx(
function ZSTD_initStaticDStream (line 991) | pub fn ZSTD_initStaticDStream(
function ZSTD_initStaticCDict (line 997) | pub fn ZSTD_initStaticCDict(
function ZSTD_initStaticDDict (line 1008) | pub fn ZSTD_initStaticDDict(
type ZSTD_allocFunction (line 1018) | pub type ZSTD_allocFunction = ::core::option::Option<
type ZSTD_freeFunction (line 1024) | pub type ZSTD_freeFunction = ::core::option::Option<
type ZSTD_customMem (line 1032) | pub struct ZSTD_customMem {
function ZSTD_createCCtx_advanced (line 1042) | pub fn ZSTD_createCCtx_advanced(
function ZSTD_createCStream_advanced (line 1047) | pub fn ZSTD_createCStream_advanced(
function ZSTD_createDCtx_advanced (line 1052) | pub fn ZSTD_createDCtx_advanced(
function ZSTD_createDStream_advanced (line 1057) | pub fn ZSTD_createDStream_advanced(
function ZSTD_createCDict_advanced (line 1062) | pub fn ZSTD_createCDict_advanced(
type POOL_ctx_s (line 1073) | pub struct POOL_ctx_s {
type ZSTD_threadPool (line 1077) | pub type ZSTD_threadPool = POOL_ctx_s;
function ZSTD_createThreadPool (line 1079) | pub fn ZSTD_createThreadPool(numThreads: usize) -> *mut ZSTD_threadPool;
function ZSTD_freeThreadPool (line 1082) | pub fn ZSTD_freeThreadPool(pool: *mut ZSTD_threadPool);
function ZSTD_CCtx_refThreadPool (line 1085) | pub fn ZSTD_CCtx_refThreadPool(
function ZSTD_createCDict_advanced2 (line 1091) | pub fn ZSTD_createCDict_advanced2(
function ZSTD_createDDict_advanced (line 1101) | pub fn ZSTD_createDDict_advanced(
function ZSTD_createCDict_byReference (line 1111) | pub fn ZSTD_createCDict_byReference(
function ZSTD_getCParams (line 1119) | pub fn ZSTD_getCParams(
function ZSTD_getParams (line 1127) | pub fn ZSTD_getParams(
function ZSTD_checkCParams (line 1135) | pub fn ZSTD_checkCParams(params: ZSTD_compressionParameters) -> usize;
function ZSTD_adjustCParams (line 1139) | pub fn ZSTD_adjustCParams(
function ZSTD_CCtx_setCParams (line 1147) | pub fn ZSTD_CCtx_setCParams(
function ZSTD_CCtx_setFParams (line 1154) | pub fn ZSTD_CCtx_setFParams(
function ZSTD_CCtx_setParams (line 1161) | pub fn ZSTD_CCtx_setParams(
function ZSTD_compress_advanced (line 1168) | pub fn ZSTD_compress_advanced(
function ZSTD_compress_usingCDict_advanced (line 1181) | pub fn ZSTD_compress_usingCDict_advanced(
function ZSTD_CCtx_loadDictionary_byReference (line 1193) | pub fn ZSTD_CCtx_loadDictionary_byReference(
function ZSTD_CCtx_loadDictionary_advanced (line 1201) | pub fn ZSTD_CCtx_loadDictionary_advanced(
function ZSTD_CCtx_refPrefix_advanced (line 1211) | pub fn ZSTD_CCtx_refPrefix_advanced(
function ZSTD_CCtx_getParameter (line 1220) | pub fn ZSTD_CCtx_getParameter(
function ZSTD_createCCtxParams (line 1228) | pub fn ZSTD_createCCtxParams() -> *mut ZSTD_CCtx_params;
function ZSTD_freeCCtxParams (line 1231) | pub fn ZSTD_freeCCtxParams(params: *mut ZSTD_CCtx_params) -> usize;
function ZSTD_CCtxParams_reset (line 1235) | pub fn ZSTD_CCtxParams_reset(params: *mut ZSTD_CCtx_params) -> usize;
function ZSTD_CCtxParams_init (line 1239) | pub fn ZSTD_CCtxParams_init(
function ZSTD_CCtxParams_init_advanced (line 1246) | pub fn ZSTD_CCtxParams_init_advanced(
function ZSTD_CCtxParams_setParameter (line 1253) | pub fn ZSTD_CCtxParams_setParameter(
function ZSTD_CCtxParams_getParameter (line 1261) | pub fn ZSTD_CCtxParams_getParameter(
function ZSTD_CCtx_setParametersUsingCCtxParams (line 1269) | pub fn ZSTD_CCtx_setParametersUsingCCtxParams(
function ZSTD_compressStream2_simpleArgs (line 1276) | pub fn ZSTD_compressStream2_simpleArgs(
function ZSTD_isFrame (line 1289) | pub fn ZSTD_isFrame(
function ZSTD_createDDict_byReference (line 1296) | pub fn ZSTD_createDDict_byReference(
function ZSTD_DCtx_loadDictionary_byReference (line 1303) | pub fn ZSTD_DCtx_loadDictionary_byReference(
function ZSTD_DCtx_loadDictionary_advanced (line 1311) | pub fn ZSTD_DCtx_loadDictionary_advanced(
function ZSTD_DCtx_refPrefix_advanced (line 1321) | pub fn ZSTD_DCtx_refPrefix_advanced(
function ZSTD_DCtx_setMaxWindowSize (line 1330) | pub fn ZSTD_DCtx_setMaxWindowSize(
function ZSTD_DCtx_getParameter (line 1337) | pub fn ZSTD_DCtx_getParameter(
function ZSTD_DCtx_setFormat (line 1345) | pub fn ZSTD_DCtx_setFormat(
function ZSTD_decompressStream_simpleArgs (line 1352) | pub fn ZSTD_decompressStream_simpleArgs(
function ZSTD_initCStream_srcSize (line 1364) | pub fn ZSTD_initCStream_srcSize(
function ZSTD_initCStream_usingDict (line 1372) | pub fn ZSTD_initCStream_usingDict(
function ZSTD_initCStream_advanced (line 1381) | pub fn ZSTD_initCStream_advanced(
function ZSTD_initCStream_usingCDict (line 1391) | pub fn ZSTD_initCStream_usingCDict(
function ZSTD_initCStream_usingCDict_advanced (line 1398) | pub fn ZSTD_initCStream_usingCDict_advanced(
function ZSTD_resetCStream (line 1407) | pub fn ZSTD_resetCStream(
type ZSTD_frameProgression (line 1414) | pub struct ZSTD_frameProgression {
function ZSTD_getFrameProgression (line 1423) | pub fn ZSTD_getFrameProgression(
function ZSTD_toFlushNow (line 1429) | pub fn ZSTD_toFlushNow(cctx: *mut ZSTD_CCtx) -> usize;
function ZSTD_initDStream_usingDict (line 1433) | pub fn ZSTD_initDStream_usingDict(
function ZSTD_initDStream_usingDDict (line 1441) | pub fn ZSTD_initDStream_usingDDict(
function ZSTD_resetDStream (line 1448) | pub fn ZSTD_resetDStream(zds: *mut ZSTD_DStream) -> usize;
type ZSTD_sequenceProducer_F (line 1450) | pub type ZSTD_sequenceProducer_F = ::core::option::Option<
function ZSTD_registerSequenceProducer (line 1465) | pub fn ZSTD_registerSequenceProducer(
function ZSTD_CCtxParams_registerSequenceProducer (line 1473) | pub fn ZSTD_CCtxParams_registerSequenceProducer(
function ZSTD_compressBegin (line 1481) | pub fn ZSTD_compressBegin(
function ZSTD_compressBegin_usingDict (line 1487) | pub fn ZSTD_compressBegin_usingDict(
function ZSTD_compressBegin_usingCDict (line 1495) | pub fn ZSTD_compressBegin_usingCDict(
function ZSTD_copyCCtx (line 1501) | pub fn ZSTD_copyCCtx(
function ZSTD_compressContinue (line 1508) | pub fn ZSTD_compressContinue(
function ZSTD_compressEnd (line 1517) | pub fn ZSTD_compressEnd(
function ZSTD_compressBegin_advanced (line 1526) | pub fn ZSTD_compressBegin_advanced(
function ZSTD_compressBegin_usingCDict_advanced (line 1535) | pub fn ZSTD_compressBegin_usingCDict_advanced(
function ZSTD_decodingBufferSize_min (line 1544) | pub fn ZSTD_decodingBufferSize_min(
function ZSTD_decompressBegin (line 1550) | pub fn ZSTD_decompressBegin(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressBegin_usingDict (line 1553) | pub fn ZSTD_decompressBegin_usingDict(
function ZSTD_decompressBegin_usingDDict (line 1560) | pub fn ZSTD_decompressBegin_usingDDict(
function ZSTD_nextSrcSizeToDecompress (line 1566) | pub fn ZSTD_nextSrcSizeToDecompress(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressContinue (line 1569) | pub fn ZSTD_decompressContinue(
function ZSTD_copyDCtx (line 1578) | pub fn ZSTD_copyDCtx(dctx: *mut ZSTD_DCtx, preparedDCtx: *const ZSTD_DCtx);
type ZSTD_nextInputType_e (line 1582) | pub enum ZSTD_nextInputType_e {
function ZSTD_nextInputType (line 1591) | pub fn ZSTD_nextInputType(dctx: *mut ZSTD_DCtx) -> ZSTD_nextInputType_e;
function ZSTD_getBlockSize (line 1595) | pub fn ZSTD_getBlockSize(cctx: *const ZSTD_CCtx) -> usize;
function ZSTD_compressBlock (line 1598) | pub fn ZSTD_compressBlock(
function ZSTD_decompressBlock (line 1607) | pub fn ZSTD_decompressBlock(
function ZSTD_insertBlock (line 1616) | pub fn ZSTD_insertBlock(
FILE: zstd-safe/zstd-sys/src/bindings_zstd_seekable.rs
constant ZSTD_seekTableFooterSize (line 38) | pub const ZSTD_seekTableFooterSize: u32 = 9;
constant ZSTD_SEEKABLE_MAGICNUMBER (line 39) | pub const ZSTD_SEEKABLE_MAGICNUMBER: u32 = 2408770225;
constant ZSTD_SEEKABLE_MAXFRAMES (line 40) | pub const ZSTD_SEEKABLE_MAXFRAMES: u32 = 134217728;
constant ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE (line 41) | pub const ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE: u32 = 1073741824;
constant ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (line 42) | pub const ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE: i32 = -2;
type ZSTD_seekable_CStream_s (line 45) | pub struct ZSTD_seekable_CStream_s {
type ZSTD_seekable_CStream (line 48) | pub type ZSTD_seekable_CStream = ZSTD_seekable_CStream_s;
type ZSTD_seekable_s (line 51) | pub struct ZSTD_seekable_s {
type ZSTD_seekable (line 54) | pub type ZSTD_seekable = ZSTD_seekable_s;
type ZSTD_seekTable_s (line 57) | pub struct ZSTD_seekTable_s {
type ZSTD_seekTable (line 60) | pub type ZSTD_seekTable = ZSTD_seekTable_s;
function ZSTD_seekable_createCStream (line 62) | pub fn ZSTD_seekable_createCStream() -> *mut ZSTD_seekable_CStream;
function ZSTD_seekable_freeCStream (line 65) | pub fn ZSTD_seekable_freeCStream(zcs: *mut ZSTD_seekable_CStream)
function ZSTD_seekable_initCStream (line 69) | pub fn ZSTD_seekable_initCStream(
function ZSTD_seekable_compressStream (line 77) | pub fn ZSTD_seekable_compressStream(
function ZSTD_seekable_endFrame (line 84) | pub fn ZSTD_seekable_endFrame(
function ZSTD_seekable_endStream (line 90) | pub fn ZSTD_seekable_endStream(
type ZSTD_frameLog_s (line 97) | pub struct ZSTD_frameLog_s {
type ZSTD_frameLog (line 100) | pub type ZSTD_frameLog = ZSTD_frameLog_s;
function ZSTD_seekable_createFrameLog (line 102) | pub fn ZSTD_seekable_createFrameLog(
function ZSTD_seekable_freeFrameLog (line 107) | pub fn ZSTD_seekable_freeFrameLog(fl: *mut ZSTD_frameLog) -> usize;
function ZSTD_seekable_logFrame (line 110) | pub fn ZSTD_seekable_logFrame(
function ZSTD_seekable_writeSeekTable (line 118) | pub fn ZSTD_seekable_writeSeekTable(
function ZSTD_seekable_create (line 124) | pub fn ZSTD_seekable_create() -> *mut ZSTD_seekable;
function ZSTD_seekable_free (line 127) | pub fn ZSTD_seekable_free(zs: *mut ZSTD_seekable) -> usize;
function ZSTD_seekable_initBuff (line 130) | pub fn ZSTD_seekable_initBuff(
function ZSTD_seekable_decompress (line 137) | pub fn ZSTD_seekable_decompress(
function ZSTD_seekable_decompressFrame (line 145) | pub fn ZSTD_seekable_decompressFrame(
function ZSTD_seekable_getNumFrames (line 153) | pub fn ZSTD_seekable_getNumFrames(
function ZSTD_seekable_getFrameCompressedOffset (line 158) | pub fn ZSTD_seekable_getFrameCompressedOffset(
function ZSTD_seekable_getFrameDecompressedOffset (line 164) | pub fn ZSTD_seekable_getFrameDecompressedOffset(
function ZSTD_seekable_getFrameCompressedSize (line 170) | pub fn ZSTD_seekable_getFrameCompressedSize(
function ZSTD_seekable_getFrameDecompressedSize (line 176) | pub fn ZSTD_seekable_getFrameDecompressedSize(
function ZSTD_seekable_offsetToFrameIndex (line 182) | pub fn ZSTD_seekable_offsetToFrameIndex(
function ZSTD_seekTable_create_fromSeekable (line 188) | pub fn ZSTD_seekTable_create_fromSeekable(
function ZSTD_seekTable_free (line 193) | pub fn ZSTD_seekTable_free(st: *mut ZSTD_seekTable) -> usize;
function ZSTD_seekTable_getNumFrames (line 196) | pub fn ZSTD_seekTable_getNumFrames(
function ZSTD_seekTable_getFrameCompressedOffset (line 201) | pub fn ZSTD_seekTable_getFrameCompressedOffset(
function ZSTD_seekTable_getFrameDecompressedOffset (line 207) | pub fn ZSTD_seekTable_getFrameDecompressedOffset(
function ZSTD_seekTable_getFrameCompressedSize (line 213) | pub fn ZSTD_seekTable_getFrameCompressedSize(
function ZSTD_seekTable_getFrameDecompressedSize (line 219) | pub fn ZSTD_seekTable_getFrameDecompressedSize(
function ZSTD_seekTable_offsetToFrameIndex (line 225) | pub fn ZSTD_seekTable_offsetToFrameIndex(
type ZSTD_seekable_read (line 230) | pub type ZSTD_seekable_read = ::core::option::Option<
type ZSTD_seekable_seek (line 237) | pub type ZSTD_seekable_seek = ::core::option::Option<
type ZSTD_seekable_customFile (line 246) | pub struct ZSTD_seekable_customFile {
function ZSTD_seekable_initAdvanced (line 252) | pub fn ZSTD_seekable_initAdvanced(
FILE: zstd-safe/zstd-sys/src/bindings_zstd_std_experimental.rs
constant ZSTD_VERSION_MAJOR (line 38) | pub const ZSTD_VERSION_MAJOR: u32 = 1;
constant ZSTD_VERSION_MINOR (line 39) | pub const ZSTD_VERSION_MINOR: u32 = 5;
constant ZSTD_VERSION_RELEASE (line 40) | pub const ZSTD_VERSION_RELEASE: u32 = 5;
constant ZSTD_VERSION_NUMBER (line 41) | pub const ZSTD_VERSION_NUMBER: u32 = 10505;
constant ZSTD_CLEVEL_DEFAULT (line 42) | pub const ZSTD_CLEVEL_DEFAULT: u32 = 3;
constant ZSTD_MAGICNUMBER (line 43) | pub const ZSTD_MAGICNUMBER: u32 = 4247762216;
constant ZSTD_MAGIC_DICTIONARY (line 44) | pub const ZSTD_MAGIC_DICTIONARY: u32 = 3962610743;
constant ZSTD_MAGIC_SKIPPABLE_START (line 45) | pub const ZSTD_MAGIC_SKIPPABLE_START: u32 = 407710288;
constant ZSTD_MAGIC_SKIPPABLE_MASK (line 46) | pub const ZSTD_MAGIC_SKIPPABLE_MASK: u32 = 4294967280;
constant ZSTD_BLOCKSIZELOG_MAX (line 47) | pub const ZSTD_BLOCKSIZELOG_MAX: u32 = 17;
constant ZSTD_BLOCKSIZE_MAX (line 48) | pub const ZSTD_BLOCKSIZE_MAX: u32 = 131072;
constant ZSTD_CONTENTSIZE_UNKNOWN (line 49) | pub const ZSTD_CONTENTSIZE_UNKNOWN: i32 = -1;
constant ZSTD_CONTENTSIZE_ERROR (line 50) | pub const ZSTD_CONTENTSIZE_ERROR: i32 = -2;
constant ZSTD_FRAMEHEADERSIZE_MAX (line 51) | pub const ZSTD_FRAMEHEADERSIZE_MAX: u32 = 18;
constant ZSTD_SKIPPABLEHEADERSIZE (line 52) | pub const ZSTD_SKIPPABLEHEADERSIZE: u32 = 8;
constant ZSTD_WINDOWLOG_MAX_32 (line 53) | pub const ZSTD_WINDOWLOG_MAX_32: u32 = 30;
constant ZSTD_WINDOWLOG_MAX_64 (line 54) | pub const ZSTD_WINDOWLOG_MAX_64: u32 = 31;
constant ZSTD_WINDOWLOG_MIN (line 55) | pub const ZSTD_WINDOWLOG_MIN: u32 = 10;
constant ZSTD_HASHLOG_MIN (line 56) | pub const ZSTD_HASHLOG_MIN: u32 = 6;
constant ZSTD_CHAINLOG_MAX_32 (line 57) | pub const ZSTD_CHAINLOG_MAX_32: u32 = 29;
constant ZSTD_CHAINLOG_MAX_64 (line 58) | pub const ZSTD_CHAINLOG_MAX_64: u32 = 30;
constant ZSTD_CHAINLOG_MIN (line 59) | pub const ZSTD_CHAINLOG_MIN: u32 = 6;
constant ZSTD_SEARCHLOG_MIN (line 60) | pub const ZSTD_SEARCHLOG_MIN: u32 = 1;
constant ZSTD_MINMATCH_MAX (line 61) | pub const ZSTD_MINMATCH_MAX: u32 = 7;
constant ZSTD_MINMATCH_MIN (line 62) | pub const ZSTD_MINMATCH_MIN: u32 = 3;
constant ZSTD_TARGETLENGTH_MAX (line 63) | pub const ZSTD_TARGETLENGTH_MAX: u32 = 131072;
constant ZSTD_TARGETLENGTH_MIN (line 64) | pub const ZSTD_TARGETLENGTH_MIN: u32 = 0;
constant ZSTD_BLOCKSIZE_MAX_MIN (line 65) | pub const ZSTD_BLOCKSIZE_MAX_MIN: u32 = 1024;
constant ZSTD_OVERLAPLOG_MIN (line 66) | pub const ZSTD_OVERLAPLOG_MIN: u32 = 0;
constant ZSTD_OVERLAPLOG_MAX (line 67) | pub const ZSTD_OVERLAPLOG_MAX: u32 = 9;
constant ZSTD_WINDOWLOG_LIMIT_DEFAULT (line 68) | pub const ZSTD_WINDOWLOG_LIMIT_DEFAULT: u32 = 27;
constant ZSTD_LDM_HASHLOG_MIN (line 69) | pub const ZSTD_LDM_HASHLOG_MIN: u32 = 6;
constant ZSTD_LDM_MINMATCH_MIN (line 70) | pub const ZSTD_LDM_MINMATCH_MIN: u32 = 4;
constant ZSTD_LDM_MINMATCH_MAX (line 71) | pub const ZSTD_LDM_MINMATCH_MAX: u32 = 4096;
constant ZSTD_LDM_BUCKETSIZELOG_MIN (line 72) | pub const ZSTD_LDM_BUCKETSIZELOG_MIN: u32 = 1;
constant ZSTD_LDM_BUCKETSIZELOG_MAX (line 73) | pub const ZSTD_LDM_BUCKETSIZELOG_MAX: u32 = 8;
constant ZSTD_LDM_HASHRATELOG_MIN (line 74) | pub const ZSTD_LDM_HASHRATELOG_MIN: u32 = 0;
constant ZSTD_TARGETCBLOCKSIZE_MIN (line 75) | pub const ZSTD_TARGETCBLOCKSIZE_MIN: u32 = 64;
constant ZSTD_TARGETCBLOCKSIZE_MAX (line 76) | pub const ZSTD_TARGETCBLOCKSIZE_MAX: u32 = 131072;
constant ZSTD_SRCSIZEHINT_MIN (line 77) | pub const ZSTD_SRCSIZEHINT_MIN: u32 = 0;
function ZSTD_versionNumber (line 80) | pub fn ZSTD_versionNumber() -> ::core::ffi::c_uint;
function ZSTD_versionString (line 84) | pub fn ZSTD_versionString() -> *const ::core::ffi::c_char;
function ZSTD_compress (line 88) | pub fn ZSTD_compress(
function ZSTD_decompress (line 98) | pub fn ZSTD_decompress(
function ZSTD_getFrameContentSize (line 106) | pub fn ZSTD_getFrameContentSize(
function ZSTD_getDecompressedSize (line 113) | pub fn ZSTD_getDecompressedSize(
function ZSTD_findFrameCompressedSize (line 120) | pub fn ZSTD_findFrameCompressedSize(
function ZSTD_compressBound (line 126) | pub fn ZSTD_compressBound(srcSize: usize) -> usize;
function ZSTD_isError (line 129) | pub fn ZSTD_isError(code: usize) -> ::core::ffi::c_uint;
function ZSTD_getErrorName (line 132) | pub fn ZSTD_getErrorName(code: usize) -> *const ::core::ffi::c_char;
function ZSTD_minCLevel (line 135) | pub fn ZSTD_minCLevel() -> ::core::ffi::c_int;
function ZSTD_maxCLevel (line 138) | pub fn ZSTD_maxCLevel() -> ::core::ffi::c_int;
function ZSTD_defaultCLevel (line 141) | pub fn ZSTD_defaultCLevel() -> ::core::ffi::c_int;
type ZSTD_CCtx_s (line 145) | pub struct ZSTD_CCtx_s {
type ZSTD_CCtx (line 149) | pub type ZSTD_CCtx = ZSTD_CCtx_s;
function ZSTD_createCCtx (line 151) | pub fn ZSTD_createCCtx() -> *mut ZSTD_CCtx;
function ZSTD_freeCCtx (line 154) | pub fn ZSTD_freeCCtx(cctx: *mut ZSTD_CCtx) -> usize;
function ZSTD_compressCCtx (line 158) | pub fn ZSTD_compressCCtx(
type ZSTD_DCtx_s (line 169) | pub struct ZSTD_DCtx_s {
type ZSTD_DCtx (line 172) | pub type ZSTD_DCtx = ZSTD_DCtx_s;
function ZSTD_createDCtx (line 174) | pub fn ZSTD_createDCtx() -> *mut ZSTD_DCtx;
function ZSTD_freeDCtx (line 177) | pub fn ZSTD_freeDCtx(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressDCtx (line 181) | pub fn ZSTD_decompressDCtx(
type ZSTD_strategy (line 192) | pub enum ZSTD_strategy {
type ZSTD_cParameter (line 205) | pub enum ZSTD_cParameter {
type ZSTD_bounds (line 247) | pub struct ZSTD_bounds {
function ZSTD_cParam_getBounds (line 254) | pub fn ZSTD_cParam_getBounds(cParam: ZSTD_cParameter) -> ZSTD_bounds;
function ZSTD_CCtx_setParameter (line 258) | pub fn ZSTD_CCtx_setParameter(
function ZSTD_CCtx_setPledgedSrcSize (line 266) | pub fn ZSTD_CCtx_setPledgedSrcSize(
type ZSTD_ResetDirective (line 273) | pub enum ZSTD_ResetDirective {
function ZSTD_CCtx_reset (line 280) | pub fn ZSTD_CCtx_reset(
function ZSTD_compress2 (line 287) | pub fn ZSTD_compress2(
type ZSTD_dParameter (line 298) | pub enum ZSTD_dParameter {
function ZSTD_dParam_getBounds (line 308) | pub fn ZSTD_dParam_getBounds(dParam: ZSTD_dParameter) -> ZSTD_bounds;
function ZSTD_DCtx_setParameter (line 312) | pub fn ZSTD_DCtx_setParameter(
function ZSTD_DCtx_reset (line 320) | pub fn ZSTD_DCtx_reset(
type ZSTD_inBuffer_s (line 328) | pub struct ZSTD_inBuffer_s {
type ZSTD_inBuffer (line 337) | pub type ZSTD_inBuffer = ZSTD_inBuffer_s;
type ZSTD_outBuffer_s (line 340) | pub struct ZSTD_outBuffer_s {
type ZSTD_outBuffer (line 348) | pub type ZSTD_outBuffer = ZSTD_outBuffer_s;
type ZSTD_CStream (line 349) | pub type ZSTD_CStream = ZSTD_CCtx;
function ZSTD_createCStream (line 351) | pub fn ZSTD_createCStream() -> *mut ZSTD_CStream;
function ZSTD_freeCStream (line 354) | pub fn ZSTD_freeCStream(zcs: *mut ZSTD_CStream) -> usize;
type ZSTD_EndDirective (line 358) | pub enum ZSTD_EndDirective {
function ZSTD_compressStream2 (line 365) | pub fn ZSTD_compressStream2(
function ZSTD_CStreamInSize (line 373) | pub fn ZSTD_CStreamInSize() -> usize;
function ZSTD_CStreamOutSize (line 376) | pub fn ZSTD_CStreamOutSize() -> usize;
function ZSTD_initCStream (line 380) | pub fn ZSTD_initCStream(
function ZSTD_compressStream (line 387) | pub fn ZSTD_compressStream(
function ZSTD_flushStream (line 395) | pub fn ZSTD_flushStream(
function ZSTD_endStream (line 402) | pub fn ZSTD_endStream(
type ZSTD_DStream (line 407) | pub type ZSTD_DStream = ZSTD_DCtx;
function ZSTD_createDStream (line 409) | pub fn ZSTD_createDStream() -> *mut ZSTD_DStream;
function ZSTD_freeDStream (line 412) | pub fn ZSTD_freeDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_initDStream (line 416) | pub fn ZSTD_initDStream(zds: *mut ZSTD_DStream) -> usize;
function ZSTD_decompressStream (line 420) | pub fn ZSTD_decompressStream(
function ZSTD_DStreamInSize (line 427) | pub fn ZSTD_DStreamInSize() -> usize;
function ZSTD_DStreamOutSize (line 430) | pub fn ZSTD_DStreamOutSize() -> usize;
function ZSTD_compress_usingDict (line 434) | pub fn ZSTD_compress_usingDict(
function ZSTD_decompress_usingDict (line 447) | pub fn ZSTD_decompress_usingDict(
type ZSTD_CDict_s (line 459) | pub struct ZSTD_CDict_s {
type ZSTD_CDict (line 463) | pub type ZSTD_CDict = ZSTD_CDict_s;
function ZSTD_createCDict (line 466) | pub fn ZSTD_createCDict(
function ZSTD_freeCDict (line 474) | pub fn ZSTD_freeCDict(CDict: *mut ZSTD_CDict) -> usize;
function ZSTD_compress_usingCDict (line 478) | pub fn ZSTD_compress_usingCDict(
type ZSTD_DDict_s (line 489) | pub struct ZSTD_DDict_s {
type ZSTD_DDict (line 492) | pub type ZSTD_DDict = ZSTD_DDict_s;
function ZSTD_createDDict (line 495) | pub fn ZSTD_createDDict(
function ZSTD_freeDDict (line 502) | pub fn ZSTD_freeDDict(ddict: *mut ZSTD_DDict) -> usize;
function ZSTD_decompress_usingDDict (line 506) | pub fn ZSTD_decompress_usingDDict(
function ZSTD_getDictID_fromDict (line 517) | pub fn ZSTD_getDictID_fromDict(
function ZSTD_getDictID_fromCDict (line 524) | pub fn ZSTD_getDictID_fromCDict(
function ZSTD_getDictID_fromDDict (line 530) | pub fn ZSTD_getDictID_fromDDict(
function ZSTD_getDictID_fromFrame (line 536) | pub fn ZSTD_getDictID_fromFrame(
function ZSTD_CCtx_loadDictionary (line 543) | pub fn ZSTD_CCtx_loadDictionary(
function ZSTD_CCtx_refCDict (line 551) | pub fn ZSTD_CCtx_refCDict(
function ZSTD_CCtx_refPrefix (line 558) | pub fn ZSTD_CCtx_refPrefix(
function ZSTD_DCtx_loadDictionary (line 566) | pub fn ZSTD_DCtx_loadDictionary(
function ZSTD_DCtx_refDDict (line 574) | pub fn ZSTD_DCtx_refDDict(
function ZSTD_DCtx_refPrefix (line 581) | pub fn ZSTD_DCtx_refPrefix(
function ZSTD_sizeof_CCtx (line 589) | pub fn ZSTD_sizeof_CCtx(cctx: *const ZSTD_CCtx) -> usize;
function ZSTD_sizeof_DCtx (line 592) | pub fn ZSTD_sizeof_DCtx(dctx: *const ZSTD_DCtx) -> usize;
function ZSTD_sizeof_CStream (line 595) | pub fn ZSTD_sizeof_CStream(zcs: *const ZSTD_CStream) -> usize;
function ZSTD_sizeof_DStream (line 598) | pub fn ZSTD_sizeof_DStream(zds: *const ZSTD_DStream) -> usize;
function ZSTD_sizeof_CDict (line 601) | pub fn ZSTD_sizeof_CDict(cdict: *const ZSTD_CDict) -> usize;
function ZSTD_sizeof_DDict (line 604) | pub fn ZSTD_sizeof_DDict(ddict: *const ZSTD_DDict) -> usize;
type ZSTD_CCtx_params_s (line 608) | pub struct ZSTD_CCtx_params_s {
type ZSTD_CCtx_params (line 611) | pub type ZSTD_CCtx_params = ZSTD_CCtx_params_s;
type ZSTD_Sequence (line 614) | pub struct ZSTD_Sequence {
type ZSTD_compressionParameters (line 622) | pub struct ZSTD_compressionParameters {
type ZSTD_frameParameters (line 640) | pub struct ZSTD_frameParameters {
type ZSTD_parameters (line 650) | pub struct ZSTD_parameters {
type ZSTD_dictContentType_e (line 656) | pub enum ZSTD_dictContentType_e {
type ZSTD_dictLoadMethod_e (line 663) | pub enum ZSTD_dictLoadMethod_e {
type ZSTD_format_e (line 671) | pub enum ZSTD_format_e {
type ZSTD_forceIgnoreChecksum_e (line 677) | pub enum ZSTD_forceIgnoreChecksum_e {
type ZSTD_refMultipleDDicts_e (line 683) | pub enum ZSTD_refMultipleDDicts_e {
type ZSTD_dictAttachPref_e (line 689) | pub enum ZSTD_dictAttachPref_e {
type ZSTD_literalCompressionMode_e (line 697) | pub enum ZSTD_literalCompressionMode_e {
type ZSTD_paramSwitch_e (line 707) | pub enum ZSTD_paramSwitch_e {
function ZSTD_findDecompressedSize (line 714) | pub fn ZSTD_findDecompressedSize(
function ZSTD_decompressBound (line 721) | pub fn ZSTD_decompressBound(
function ZSTD_frameHeaderSize (line 728) | pub fn ZSTD_frameHeaderSize(
type ZSTD_frameType_e (line 735) | pub enum ZSTD_frameType_e {
type ZSTD_frameHeader (line 741) | pub struct ZSTD_frameHeader {
function ZSTD_getFrameHeader (line 754) | pub fn ZSTD_getFrameHeader(
function ZSTD_getFrameHeader_advanced (line 762) | pub fn ZSTD_getFrameHeader_advanced(
function ZSTD_decompressionMargin (line 771) | pub fn ZSTD_decompressionMargin(
type ZSTD_sequenceFormat_e (line 778) | pub enum ZSTD_sequenceFormat_e {
function ZSTD_sequenceBound (line 784) | pub fn ZSTD_sequenceBound(srcSize: usize) -> usize;
function ZSTD_generateSequences (line 788) | pub fn ZSTD_generateSequences(
function ZSTD_mergeBlockDelimiters (line 798) | pub fn ZSTD_mergeBlockDelimiters(
function ZSTD_compressSequences (line 805) | pub fn ZSTD_compressSequences(
function ZSTD_writeSkippableFrame (line 817) | pub fn ZSTD_writeSkippableFrame(
function ZSTD_readSkippableFrame (line 827) | pub fn ZSTD_readSkippableFrame(
function ZSTD_isSkippableFrame (line 837) | pub fn ZSTD_isSkippableFrame(
function ZSTD_estimateCCtxSize (line 844) | pub fn ZSTD_estimateCCtxSize(
function ZSTD_estimateCCtxSize_usingCParams (line 849) | pub fn ZSTD_estimateCCtxSize_usingCParams(
function ZSTD_estimateCCtxSize_usingCCtxParams (line 854) | pub fn ZSTD_estimateCCtxSize_usingCCtxParams(
function ZSTD_estimateDCtxSize (line 859) | pub fn ZSTD_estimateDCtxSize() -> usize;
function ZSTD_estimateCStreamSize (line 863) | pub fn ZSTD_estimateCStreamSize(
function ZSTD_estimateCStreamSize_usingCParams (line 868) | pub fn ZSTD_estimateCStreamSize_usingCParams(
function ZSTD_estimateCStreamSize_usingCCtxParams (line 873) | pub fn ZSTD_estimateCStreamSize_usingCCtxParams(
function ZSTD_estimateDStreamSize (line 878) | pub fn ZSTD_estimateDStreamSize(windowSize: usize) -> usize;
function ZSTD_estimateDStreamSize_fromFrame (line 881) | pub fn ZSTD_estimateDStreamSize_fromFrame(
function ZSTD_estimateCDictSize (line 888) | pub fn ZSTD_estimateCDictSize(
function ZSTD_estimateCDictSize_advanced (line 894) | pub fn ZSTD_estimateCDictSize_advanced(
function ZSTD_estimateDDictSize (line 901) | pub fn ZSTD_estimateDDictSize(
function ZSTD_initStaticCCtx (line 908) | pub fn ZSTD_initStaticCCtx(
function ZSTD_initStaticCStream (line 914) | pub fn ZSTD_initStaticCStream(
function ZSTD_initStaticDCtx (line 920) | pub fn ZSTD_initStaticDCtx(
function ZSTD_initStaticDStream (line 926) | pub fn ZSTD_initStaticDStream(
function ZSTD_initStaticCDict (line 932) | pub fn ZSTD_initStaticCDict(
function ZSTD_initStaticDDict (line 943) | pub fn ZSTD_initStaticDDict(
type ZSTD_allocFunction (line 953) | pub type ZSTD_allocFunction = ::core::option::Option<
type ZSTD_freeFunction (line 959) | pub type ZSTD_freeFunction = ::core::option::Option<
type ZSTD_customMem (line 967) | pub struct ZSTD_customMem {
function ZSTD_createCCtx_advanced (line 977) | pub fn ZSTD_createCCtx_advanced(
function ZSTD_createCStream_advanced (line 982) | pub fn ZSTD_createCStream_advanced(
function ZSTD_createDCtx_advanced (line 987) | pub fn ZSTD_createDCtx_advanced(
function ZSTD_createDStream_advanced (line 992) | pub fn ZSTD_createDStream_advanced(
function ZSTD_createCDict_advanced (line 997) | pub fn ZSTD_createCDict_advanced(
type POOL_ctx_s (line 1008) | pub struct POOL_ctx_s {
type ZSTD_threadPool (line 1012) | pub type ZSTD_threadPool = POOL_ctx_s;
function ZSTD_createThreadPool (line 1014) | pub fn ZSTD_createThreadPool(numThreads: usize) -> *mut ZSTD_threadPool;
function ZSTD_freeThreadPool (line 1017) | pub fn ZSTD_freeThreadPool(pool: *mut ZSTD_threadPool);
function ZSTD_CCtx_refThreadPool (line 1020) | pub fn ZSTD_CCtx_refThreadPool(
function ZSTD_createCDict_advanced2 (line 1026) | pub fn ZSTD_createCDict_advanced2(
function ZSTD_createDDict_advanced (line 1036) | pub fn ZSTD_createDDict_advanced(
function ZSTD_createCDict_byReference (line 1046) | pub fn ZSTD_createCDict_byReference(
function ZSTD_getCParams (line 1054) | pub fn ZSTD_getCParams(
function ZSTD_getParams (line 1062) | pub fn ZSTD_getParams(
function ZSTD_checkCParams (line 1070) | pub fn ZSTD_checkCParams(params: ZSTD_compressionParameters) -> usize;
function ZSTD_adjustCParams (line 1074) | pub fn ZSTD_adjustCParams(
function ZSTD_CCtx_setCParams (line 1082) | pub fn ZSTD_CCtx_setCParams(
function ZSTD_CCtx_setFParams (line 1089) | pub fn ZSTD_CCtx_setFParams(
function ZSTD_CCtx_setParams (line 1096) | pub fn ZSTD_CCtx_setParams(
function ZSTD_compress_advanced (line 1103) | pub fn ZSTD_compress_advanced(
function ZSTD_compress_usingCDict_advanced (line 1116) | pub fn ZSTD_compress_usingCDict_advanced(
function ZSTD_CCtx_loadDictionary_byReference (line 1128) | pub fn ZSTD_CCtx_loadDictionary_byReference(
function ZSTD_CCtx_loadDictionary_advanced (line 1136) | pub fn ZSTD_CCtx_loadDictionary_advanced(
function ZSTD_CCtx_refPrefix_advanced (line 1146) | pub fn ZSTD_CCtx_refPrefix_advanced(
function ZSTD_CCtx_getParameter (line 1155) | pub fn ZSTD_CCtx_getParameter(
function ZSTD_createCCtxParams (line 1163) | pub fn ZSTD_createCCtxParams() -> *mut ZSTD_CCtx_params;
function ZSTD_freeCCtxParams (line 1166) | pub fn ZSTD_freeCCtxParams(params: *mut ZSTD_CCtx_params) -> usize;
function ZSTD_CCtxParams_reset (line 1170) | pub fn ZSTD_CCtxParams_reset(params: *mut ZSTD_CCtx_params) -> usize;
function ZSTD_CCtxParams_init (line 1174) | pub fn ZSTD_CCtxParams_init(
function ZSTD_CCtxParams_init_advanced (line 1181) | pub fn ZSTD_CCtxParams_init_advanced(
function ZSTD_CCtxParams_setParameter (line 1188) | pub fn ZSTD_CCtxParams_setParameter(
function ZSTD_CCtxParams_getParameter (line 1196) | pub fn ZSTD_CCtxParams_getParameter(
function ZSTD_CCtx_setParametersUsingCCtxParams (line 1204) | pub fn ZSTD_CCtx_setParametersUsingCCtxParams(
function ZSTD_compressStream2_simpleArgs (line 1211) | pub fn ZSTD_compressStream2_simpleArgs(
function ZSTD_isFrame (line 1224) | pub fn ZSTD_isFrame(
function ZSTD_createDDict_byReference (line 1231) | pub fn ZSTD_createDDict_byReference(
function ZSTD_DCtx_loadDictionary_byReference (line 1238) | pub fn ZSTD_DCtx_loadDictionary_byReference(
function ZSTD_DCtx_loadDictionary_advanced (line 1246) | pub fn ZSTD_DCtx_loadDictionary_advanced(
function ZSTD_DCtx_refPrefix_advanced (line 1256) | pub fn ZSTD_DCtx_refPrefix_advanced(
function ZSTD_DCtx_setMaxWindowSize (line 1265) | pub fn ZSTD_DCtx_setMaxWindowSize(
function ZSTD_DCtx_getParameter (line 1272) | pub fn ZSTD_DCtx_getParameter(
function ZSTD_DCtx_setFormat (line 1280) | pub fn ZSTD_DCtx_setFormat(
function ZSTD_decompressStream_simpleArgs (line 1287) | pub fn ZSTD_decompressStream_simpleArgs(
function ZSTD_initCStream_srcSize (line 1299) | pub fn ZSTD_initCStream_srcSize(
function ZSTD_initCStream_usingDict (line 1307) | pub fn ZSTD_initCStream_usingDict(
function ZSTD_initCStream_advanced (line 1316) | pub fn ZSTD_initCStream_advanced(
function ZSTD_initCStream_usingCDict (line 1326) | pub fn ZSTD_initCStream_usingCDict(
function ZSTD_initCStream_usingCDict_advanced (line 1333) | pub fn ZSTD_initCStream_usingCDict_advanced(
function ZSTD_resetCStream (line 1342) | pub fn ZSTD_resetCStream(
type ZSTD_frameProgression (line 1349) | pub struct ZSTD_frameProgression {
function ZSTD_getFrameProgression (line 1358) | pub fn ZSTD_getFrameProgression(
function ZSTD_toFlushNow (line 1364) | pub fn ZSTD_toFlushNow(cctx: *mut ZSTD_CCtx) -> usize;
function ZSTD_initDStream_usingDict (line 1368) | pub fn ZSTD_initDStream_usingDict(
function ZSTD_initDStream_usingDDict (line 1376) | pub fn ZSTD_initDStream_usingDDict(
function ZSTD_resetDStream (line 1383) | pub fn ZSTD_resetDStream(zds: *mut ZSTD_DStream) -> usize;
type ZSTD_sequenceProducer_F (line 1385) | pub type ZSTD_sequenceProducer_F = ::core::option::Option<
function ZSTD_registerSequenceProducer (line 1400) | pub fn ZSTD_registerSequenceProducer(
function ZSTD_compressBegin (line 1408) | pub fn ZSTD_compressBegin(
function ZSTD_compressBegin_usingDict (line 1414) | pub fn ZSTD_compressBegin_usingDict(
function ZSTD_compressBegin_usingCDict (line 1422) | pub fn ZSTD_compressBegin_usingCDict(
function ZSTD_copyCCtx (line 1428) | pub fn ZSTD_copyCCtx(
function ZSTD_compressContinue (line 1435) | pub fn ZSTD_compressContinue(
function ZSTD_compressEnd (line 1444) | pub fn ZSTD_compressEnd(
function ZSTD_compressBegin_advanced (line 1453) | pub fn ZSTD_compressBegin_advanced(
function ZSTD_compressBegin_usingCDict_advanced (line 1462) | pub fn ZSTD_compressBegin_usingCDict_advanced(
function ZSTD_decodingBufferSize_min (line 1471) | pub fn ZSTD_decodingBufferSize_min(
function ZSTD_decompressBegin (line 1477) | pub fn ZSTD_decompressBegin(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressBegin_usingDict (line 1480) | pub fn ZSTD_decompressBegin_usingDict(
function ZSTD_decompressBegin_usingDDict (line 1487) | pub fn ZSTD_decompressBegin_usingDDict(
function ZSTD_nextSrcSizeToDecompress (line 1493) | pub fn ZSTD_nextSrcSizeToDecompress(dctx: *mut ZSTD_DCtx) -> usize;
function ZSTD_decompressContinue (line 1496) | pub fn ZSTD_decompressContinue(
function ZSTD_copyDCtx (line 1505) | pub fn ZSTD_copyDCtx(dctx: *mut ZSTD_DCtx, preparedDCtx: *const ZSTD_DCtx);
type ZSTD_nextInputType_e (line 1509) | pub enum ZSTD_nextInputType_e {
function ZSTD_nextInputType (line 1518) | pub fn ZSTD_nextInputType(dctx: *mut ZSTD_DCtx) -> ZSTD_nextInputType_e;
function ZSTD_getBlockSize (line 1522) | pub fn ZSTD_getBlockSize(cctx: *const ZSTD_CCtx) -> usize;
function ZSTD_compressBlock (line 1525) | pub fn ZSTD_compressBlock(
function ZSTD_decompressBlock (line 1534) | pub fn ZSTD_decompressBlock(
function ZSTD_insertBlock (line 1543) | pub fn ZSTD_insertBlock(
FILE: zstd-safe/zstd-sys/src/wasm_shim.rs
constant USIZE_ALIGN (line 4) | const USIZE_ALIGN: usize = core::mem::align_of::<usize>();
constant USIZE_SIZE (line 5) | const USIZE_SIZE: usize = core::mem::size_of::<usize>();
function rust_zstd_wasm_shim_qsort (line 8) | pub extern "C" fn rust_zstd_wasm_shim_qsort(
function qsort (line 26) | unsafe fn qsort<const N: usize>(
function rust_zstd_wasm_shim_malloc (line 44) | pub extern "C" fn rust_zstd_wasm_shim_malloc(size: usize) -> *mut c_void {
function rust_zstd_wasm_shim_memcmp (line 49) | pub extern "C" fn rust_zstd_wasm_shim_memcmp(
function rust_zstd_wasm_shim_calloc (line 67) | pub extern "C" fn rust_zstd_wasm_shim_calloc(
function wasm_shim_alloc (line 76) | fn wasm_shim_alloc<const ZEROED: bool>(size: usize) -> *mut c_void {
function rust_zstd_wasm_shim_free (line 102) | pub unsafe extern "C" fn rust_zstd_wasm_shim_free(ptr: *mut c_void) {
function rust_zstd_wasm_shim_memcpy (line 117) | pub unsafe extern "C" fn rust_zstd_wasm_shim_memcpy(
function rust_zstd_wasm_shim_memmove (line 127) | pub unsafe extern "C" fn rust_zstd_wasm_shim_memmove(
function rust_zstd_wasm_shim_memset (line 137) | pub unsafe extern "C" fn rust_zstd_wasm_shim_memset(
FILE: zstd-safe/zstd-sys/wasm-shim/string.h
function memcmp (line 11) | inline int memcmp(const void *str1, const void *str2, size_t n) {
FILE: zstd-safe/zstd-sys/wasm-shim/time.h
type clock_t (line 6) | typedef unsigned long long clock_t;
function clock_t (line 9) | inline clock_t clock() {
Condensed preview — 82 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (595K chars).
[
{
"path": ".gitattributes",
"chars": 22,
"preview": "/assets/* -text -crlf\n"
},
{
"path": ".github/dependabot.yml",
"chars": 539,
"preview": "# Dependabot dependency version checks / updates\n\nversion: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n # Work"
},
{
"path": ".github/workflows/linux.yml",
"chars": 1102,
"preview": "name: Linux\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CARGO_TERM_COLOR: always\n"
},
{
"path": ".github/workflows/macos.yml",
"chars": 355,
"preview": "name: macOS\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CARGO_TERM_COLOR: always\n"
},
{
"path": ".github/workflows/wasm.yml",
"chars": 524,
"preview": "name: Wasm\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CARGO_TERM_COLOR: always\n\n"
},
{
"path": ".github/workflows/windows.yml",
"chars": 1483,
"preview": "name: Windows\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CARGO_TERM_COLOR: alway"
},
{
"path": ".gitignore",
"chars": 40,
"preview": "target\nCargo.lock\n/silesia\n/silesia.zip\n"
},
{
"path": ".gitmodules",
"chars": 110,
"preview": "[submodule \"zstd-safe/zstd-sys/zstd\"]\n\tpath = zstd-safe/zstd-sys/zstd\n\turl = https://github.com/facebook/zstd\n"
},
{
"path": "Cargo.toml",
"chars": 1494,
"preview": "[package]\nauthors = [\"Alexandre Bury <alexandre.bury@gmail.com>\"]\ndescription = \"Binding for the zstd compression librar"
},
{
"path": "LICENSE",
"chars": 1501,
"preview": "BSD 3-Clause License\n\nCopyright (c) 2026, Alexandre Bury\n\nRedistribution and use in source and binary forms, with or wit"
},
{
"path": "Readme.md",
"chars": 3191,
"preview": "# zstd\n\n[](https://crates.io/crates/zstd)\n[![BSD-3-Clause licensed"
},
{
"path": "assets/example.txt",
"chars": 940,
"preview": "’Twas brillig, and the slithy toves\nDid gyre and gimble in the wade;\nAll mimsy were the borogoves,\nAnd the mome raths ou"
},
{
"path": "examples/basic.rs",
"chars": 446,
"preview": "fn main() {\n let some_content = \"Something\";\n let compression_level = 3;\n\n // Compress some text\n let compre"
},
{
"path": "examples/benchmark.rs",
"chars": 2905,
"preview": "use clap::Parser;\nuse humansize::{format_size, DECIMAL};\nuse std::io::Read;\nuse std::path::PathBuf;\n\n#[derive(Parser, De"
},
{
"path": "examples/stream.rs",
"chars": 1082,
"preview": "use std::env;\nuse std::io::{self, Write};\nuse std::str::FromStr;\n\nfn main() {\n match env::args().nth(1) {\n Non"
},
{
"path": "examples/train.rs",
"chars": 812,
"preview": "use clap::Parser;\nuse std::io;\nuse std::path::PathBuf;\n\n#[derive(Parser, Debug)]\n#[command(author, version, about, long_"
},
{
"path": "examples/zstd.rs",
"chars": 1170,
"preview": "use zstd;\n\nuse std::env;\nuse std::fs;\nuse std::io;\n\nconst SUFFIX: &'static str = \".zst\";\n\nfn main() {\n for arg in env"
},
{
"path": "examples/zstdcat.rs",
"chars": 1081,
"preview": "use clap::Parser;\nuse std::fs;\nuse std::io;\n\n#[derive(Parser, Debug)]\n#[command(author, version, about, long_about=None)"
},
{
"path": "rustfmt.toml",
"chars": 63,
"preview": "max_width = 79\nreorder_imports = true\nuse_try_shorthand = true\n"
},
{
"path": "src/bulk/compressor.rs",
"chars": 5715,
"preview": "use crate::map_error_code;\n\nuse std::io;\nuse zstd_safe;\n\n/// Allows to compress independently multiple chunks of data.\n/"
},
{
"path": "src/bulk/decompressor.rs",
"chars": 4461,
"preview": "use crate::map_error_code;\n\n#[cfg(feature = \"experimental\")]\nuse std::convert::TryInto;\nuse std::io;\nuse zstd_safe;\n\n///"
},
{
"path": "src/bulk/mod.rs",
"chars": 1720,
"preview": "//! Compress and decompress data in bulk.\n//!\n//! These methods process all the input data at once.\n//! It is therefore "
},
{
"path": "src/bulk/tests.rs",
"chars": 1071,
"preview": "use super::{compress, decompress};\n\nconst TEXT: &str = include_str!(\"../../assets/example.txt\");\n\n#[test]\nfn test_direct"
},
{
"path": "src/dict.rs",
"chars": 9487,
"preview": "//! Train a dictionary from various sources.\n//!\n//! A dictionary can help improve the compression of small files.\n//! T"
},
{
"path": "src/lib.rs",
"chars": 2002,
"preview": "//! Rust binding to the [zstd library][zstd].\n//!\n//! This crate provides:\n//!\n//! * An [encoder](stream/write/struct.En"
},
{
"path": "src/stream/functions.rs",
"chars": 1524,
"preview": "use std::io;\n\nuse super::{Decoder, Encoder};\n\n/// Decompress from the given source as if using a `Decoder`.\n///\n/// The "
},
{
"path": "src/stream/mod.rs",
"chars": 7790,
"preview": "//! Compress and decompress Zstd streams.\n//!\n//! Zstd streams are the main way to compress and decompress data.\n//! The"
},
{
"path": "src/stream/raw.rs",
"chars": 14013,
"preview": "//! Raw in-memory stream compression/decompression.\n//!\n//! This module defines a `Decoder` and an `Encoder` to decode/e"
},
{
"path": "src/stream/read/mod.rs",
"chars": 7471,
"preview": "//! Implement pull-based [`Read`] trait for both compressing and decompressing.\nuse std::io::{self, BufRead, BufReader, "
},
{
"path": "src/stream/read/tests.rs",
"chars": 691,
"preview": "use crate::stream::read::{Decoder, Encoder};\nuse std::io::Read;\n\n#[test]\nfn test_error_handling() {\n let invalid_inpu"
},
{
"path": "src/stream/tests.rs",
"chars": 7407,
"preview": "use super::{copy_encode, decode_all, encode_all};\nuse super::{Decoder, Encoder};\n\nuse partial_io::{PartialOp, PartialWri"
},
{
"path": "src/stream/write/mod.rs",
"chars": 14452,
"preview": "//! Implement push-based [`Write`] trait for both compressing and decompressing.\nuse std::io::{self, Write};\n\nuse zstd_s"
},
{
"path": "src/stream/write/tests.rs",
"chars": 2171,
"preview": "use std::io::{Cursor, Write};\nuse std::iter;\n\nuse partial_io::{PartialOp, PartialWrite};\n\nuse crate::stream::decode_all;"
},
{
"path": "src/stream/zio/mod.rs",
"chars": 160,
"preview": "//! Wrappers around raw operations implementing `std::io::{Read, Write}`.\n\nmod reader;\nmod writer;\n\npub use self::reader"
},
{
"path": "src/stream/zio/reader.rs",
"chars": 7522,
"preview": "use std::io::{self, BufRead, Read};\n\nuse crate::stream::raw::{InBuffer, Operation, OutBuffer};\n\n// [ reader -> zstd ] ->"
},
{
"path": "src/stream/zio/writer.rs",
"chars": 11366,
"preview": "use std::io::{self, Write};\n\nuse crate::stream::raw::{InBuffer, Operation, OutBuffer};\n\n// input -> [ zstd -> buffer -> "
},
{
"path": "tests/issue_182.rs",
"chars": 409,
"preview": "const TEXT: &[u8] = include_bytes!(\"../assets/example.txt\");\n\n#[test]\n#[should_panic]\nfn test_issue_182() {\n use std:"
},
{
"path": "zstd-safe/Cargo.toml",
"chars": 1352,
"preview": "[package]\nauthors = [\"Alexandre Bury <alexandre.bury@gmail.com>\"]\nname = \"zstd-safe\"\nbuild = \"build.rs\"\nversion = \"7.2.4"
},
{
"path": "zstd-safe/LICENSE",
"chars": 1501,
"preview": "BSD 3-Clause License\n\nCopyright (c) 2026, Alexandre Bury\n\nRedistribution and use in source and binary forms, with or wit"
},
{
"path": "zstd-safe/Readme.md",
"chars": 438,
"preview": "# zstd-safe\n\nThis is a thin, no-std, safe abstraction built on top of the bindings from [zstd-sys].\n\nIt is close to a 1-"
},
{
"path": "zstd-safe/build.rs",
"chars": 345,
"preview": "fn main() {\n // Force the `std` feature in some cases\n let target_arch =\n std::env::var(\"CARGO_CFG_TARGET_A"
},
{
"path": "zstd-safe/fuzz/.gitignore",
"chars": 33,
"preview": "target\ncorpus\nartifacts\ncoverage\n"
},
{
"path": "zstd-safe/fuzz/Cargo.toml",
"chars": 469,
"preview": "[package]\nname = \"zstd-safe-fuzz\"\nversion = \"0.0.0\"\npublish = false\nedition = \"2018\"\n\n[package.metadata]\ncargo-fuzz = tr"
},
{
"path": "zstd-safe/fuzz/fuzz_targets/zstd_fuzzer.rs",
"chars": 3288,
"preview": "#![no_main]\n\nextern crate zstd_safe;\nuse libfuzzer_sys::fuzz_target;\n\nfuzz_target!(|data: &[u8]| {\n // Generate rando"
},
{
"path": "zstd-safe/src/constants.rs",
"chars": 960,
"preview": "// This file has been generated by ./update_consts.sh\npub const BLOCKSIZELOG_MAX: u32 = zstd_sys::ZSTD_BLOCKSIZELOG_MAX;"
},
{
"path": "zstd-safe/src/constants_experimental.rs",
"chars": 1952,
"preview": "// This file has been generated by ./update_consts.sh\npub const BLOCKSIZE_MAX_MIN: u32 = zstd_sys::ZSTD_BLOCKSIZE_MAX_MI"
},
{
"path": "zstd-safe/src/constants_seekable.rs",
"chars": 478,
"preview": "// This file has been generated by ./update_consts.sh\npub const SEEKABLE_FRAMEINDEX_TOOLARGE: u64 = zstd_sys::ZSTD_SEEKA"
},
{
"path": "zstd-safe/src/lib.rs",
"chars": 74799,
"preview": "#![no_std]\n//! Minimal safe wrapper around zstd-sys.\n//!\n//! This crates provides a minimal translation of the [zstd-sys"
},
{
"path": "zstd-safe/src/seekable.rs",
"chars": 22349,
"preview": "//! The seekable format splits the compressed data into a series of \"frames\",\n//! each compressed individually so that d"
},
{
"path": "zstd-safe/src/tests.rs",
"chars": 10554,
"preview": "extern crate std;\nuse crate as zstd_safe;\n\nuse self::std::vec::Vec;\n\nconst INPUT: &[u8] = b\"Rust is a multi-paradigm sys"
},
{
"path": "zstd-safe/update_consts.sh",
"chars": 1188,
"preview": "#!/bin/bash\ndeclare -A varTypes\nvarTypes[CLEVEL_DEFAULT]=CompressionLevel\nvarTypes[CONTENTSIZE_UNKNOWN]=u64\nvarTypes[CON"
},
{
"path": "zstd-safe/zstd-sys/Cargo.toml",
"chars": 2455,
"preview": "[package]\nauthors = [\"Alexandre Bury <alexandre.bury@gmail.com>\"]\nbuild = \"build.rs\"\ncategories = [\n \"api-bindings\",\n"
},
{
"path": "zstd-safe/zstd-sys/LICENSE",
"chars": 1501,
"preview": "BSD 3-Clause License\n\nCopyright (c) 2026, Alexandre Bury\n\nRedistribution and use in source and binary forms, with or wit"
},
{
"path": "zstd-safe/zstd-sys/LICENSE.BSD-3-Clause",
"chars": 1614,
"preview": "The auto-generated bindings are under the 3-clause BSD license:\n\nBSD License\n\nFor Zstandard software\n\nCopyright (c) Meta"
},
{
"path": "zstd-safe/zstd-sys/Readme.md",
"chars": 935,
"preview": "# zstd-sys\n\nThis is the low-level auto-generated binding to the [zstd] library.\nYou probably don't want to use this libr"
},
{
"path": "zstd-safe/zstd-sys/build.rs",
"chars": 10010,
"preview": "use std::ffi::OsStr;\nuse std::path::{Path, PathBuf};\nuse std::{env, fmt, fs};\n\n#[cfg(feature = \"bindgen\")]\nfn generate_b"
},
{
"path": "zstd-safe/zstd-sys/examples/it_work.rs",
"chars": 1283,
"preview": "use std::convert::TryInto;\n\n#[no_mangle]\npub extern \"C\" fn zstd_version() -> u32 {\n unsafe { zstd_sys::ZSTD_versionNu"
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zdict.rs",
"chars": 6963,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zdict_experimental.rs",
"chars": 15782,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zdict_std_experimental.rs",
"chars": 15781,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zstd.rs",
"chars": 42231,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zstd_experimental.rs",
"chars": 111734,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zstd_seekable.rs",
"chars": 7684,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/bindings_zstd_std_experimental.rs",
"chars": 104126,
"preview": "/*\nThis file is auto-generated from the public API of the zstd library.\nIt is released under the same BSD license.\n\nBSD "
},
{
"path": "zstd-safe/zstd-sys/src/lib.rs",
"chars": 1100,
"preview": "#![allow(non_upper_case_globals)]\n#![allow(non_camel_case_types)]\n#![allow(non_snake_case)]\n#![no_std]\n//! Low-level bin"
},
{
"path": "zstd-safe/zstd-sys/src/wasm_shim.rs",
"chars": 4248,
"preview": "use alloc::alloc::{alloc, alloc_zeroed, dealloc, Layout};\nuse core::ffi::{c_int, c_void};\n\nconst USIZE_ALIGN: usize = co"
},
{
"path": "zstd-safe/zstd-sys/test_it.sh",
"chars": 128,
"preview": "#!/bin/sh\nfor EXP in \"experimental\" \"\"; do\n for STD in \"std\" \"\"; do\n cargo test --features \"$EXP $STD\"\n don"
},
{
"path": "zstd-safe/zstd-sys/update_bindings.sh",
"chars": 1439,
"preview": "#!/bin/sh\n\nRUST_TARGET=1.64\nbindgen=\"bindgen --no-layout-tests --blocklist-type=max_align_t --rustified-enum=.* --use-co"
},
{
"path": "zstd-safe/zstd-sys/update_zstd.sh",
"chars": 1647,
"preview": "#!/bin/bash\nset -e\nset -o pipefail\n\ncd zstd\nCURRENT=$(git describe --tags)\ngit fetch -q\nTAG=$(git tag -l | grep '^v1' | "
},
{
"path": "zstd-safe/zstd-sys/wasm-shim/assert.h",
"chars": 79,
"preview": "#ifndef _ASSERT_H\n#define _ASSERT_H\n\n#define assert(expr)\n\n#endif // _ASSERT_H\n"
},
{
"path": "zstd-safe/zstd-sys/wasm-shim/stdio.h",
"chars": 127,
"preview": "#include <stddef.h>\n\n#ifndef\t_STDIO_H\n#define\t_STDIO_H\t1\n\n#define fprintf(expr, ...)\n#define fflush(expr)\n\n#endif // _ST"
},
{
"path": "zstd-safe/zstd-sys/wasm-shim/stdlib.h",
"chars": 647,
"preview": "#include <stddef.h>\n\n#ifndef _STDLIB_H\n#define _STDLIB_H 1\n\nvoid* rust_zstd_wasm_shim_malloc(size_t size);\nvoid* rust_zs"
},
{
"path": "zstd-safe/zstd-sys/wasm-shim/string.h",
"chars": 860,
"preview": "#include <stdlib.h>\n\n#ifndef\t_STRING_H\n#define\t_STRING_H\t1\n\nint rust_zstd_wasm_shim_memcmp(const void *str1, const void "
},
{
"path": "zstd-safe/zstd-sys/wasm-shim/time.h",
"chars": 229,
"preview": "#ifndef _TIME_H\n#define _TIME_H\n\n#define CLOCKS_PER_SEC 1000\n\ntypedef unsigned long long clock_t;\n\n// Clock is just use "
},
{
"path": "zstd-safe/zstd-sys/zdict.h",
"chars": 399,
"preview": "#ifdef PKG_CONFIG\n\n/* Just use installed headers */\n#include <zdict.h>\n// Don't use experimental features like zstdmt\n\n#"
},
{
"path": "zstd-safe/zstd-sys/zstd.h",
"chars": 585,
"preview": "#ifdef PKG_CONFIG\n\n/* Just use installed headers */\n#include <zstd.h>\n#ifdef ZSTD_RUST_BINDINGS_EXPERIMENTAL\n#include <z"
},
{
"path": "zstd-safe/zstd-sys/zstd_seekable.h",
"chars": 451,
"preview": "#ifdef PKG_CONFIG\n\n/* Just use installed headers */\n#include <zstd_seekable.h>\n// Don't use experimental features like z"
}
]
// ... and 5 more files (download for full content)
About this extraction
This page contains the full source code of the gyscos/zstd-rs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 82 files (558.6 KB), approximately 147.7k tokens, and a symbol index with 1260 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.