summaryrefslogtreecommitdiff
path: root/src/frame/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/frame/mod.rs')
-rw-r--r--src/frame/mod.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/frame/mod.rs b/src/frame/mod.rs
new file mode 100644
index 0000000..8acfad2
--- /dev/null
+++ b/src/frame/mod.rs
@@ -0,0 +1,111 @@
+//! LZ4 Frame Format
+//!
+//! As defined in <https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md>
+//!
+//! # Example: compress data on `stdin` with frame format
+//! This program reads data from `stdin`, compresses it and emits it to `stdout`.
+//! This example can be found in `examples/compress.rs`:
+//! ```no_run
+//! use std::io;
+//! let stdin = io::stdin();
+//! let stdout = io::stdout();
+//! let mut rdr = stdin.lock();
+//! // Wrap the stdout writer in a LZ4 Frame writer.
+//! let mut wtr = lz4_flex::frame::FrameEncoder::new(stdout.lock());
+//! io::copy(&mut rdr, &mut wtr).expect("I/O operation failed");
+//! wtr.finish().unwrap();
+//! ```
+//!
+
+use std::{fmt, io};
+
+#[cfg_attr(feature = "safe-encode", forbid(unsafe_code))]
+pub(crate) mod compress;
+#[cfg_attr(feature = "safe-decode", forbid(unsafe_code))]
+pub(crate) mod decompress;
+pub(crate) mod header;
+
+pub use compress::{AutoFinishEncoder, FrameEncoder};
+pub use decompress::FrameDecoder;
+pub use header::{BlockMode, BlockSize, FrameInfo};
+
+#[derive(Debug)]
+#[non_exhaustive]
+/// Errors that can occur when de/compressing lz4.
+pub enum Error {
+ /// Compression error.
+ CompressionError(crate::block::CompressError),
+ /// Decompression error.
+ DecompressionError(crate::block::DecompressError),
+ /// An io::Error was encountered.
+ IoError(io::Error),
+ /// Unsupported block size.
+ UnsupportedBlocksize(u8),
+ /// Unsupported frame version.
+ UnsupportedVersion(u8),
+ /// Wrong magic number for the LZ4 frame format.
+ WrongMagicNumber,
+ /// Reserved bits set.
+ ReservedBitsSet,
+ /// Block header is malformed.
+ InvalidBlockInfo,
+ /// Read a block larger than specified in the Frame header.
+ BlockTooBig,
+ /// The Frame header checksum doesn't match.
+ HeaderChecksumError,
+ /// The block checksum doesn't match.
+ BlockChecksumError,
+ /// The content checksum doesn't match.
+ ContentChecksumError,
+ /// Read an skippable frame.
+ /// The caller may read the specified amount of bytes from the underlying io::Read.
+ SkippableFrame(u32),
+ /// External dictionaries are not supported.
+ DictionaryNotSupported,
+ /// Content length differs.
+ ContentLengthError {
+ /// Expected content length.
+ expected: u64,
+ /// Actual content lenght.
+ actual: u64,
+ },
+}
+
+impl From<Error> for io::Error {
+ fn from(e: Error) -> Self {
+ match e {
+ Error::IoError(e) => e,
+ Error::CompressionError(_)
+ | Error::DecompressionError(_)
+ | Error::SkippableFrame(_)
+ | Error::DictionaryNotSupported => io::Error::new(io::ErrorKind::Other, e),
+ Error::WrongMagicNumber
+ | Error::UnsupportedBlocksize(..)
+ | Error::UnsupportedVersion(..)
+ | Error::ReservedBitsSet
+ | Error::InvalidBlockInfo
+ | Error::BlockTooBig
+ | Error::HeaderChecksumError
+ | Error::ContentChecksumError
+ | Error::BlockChecksumError
+ | Error::ContentLengthError { .. } => io::Error::new(io::ErrorKind::InvalidData, e),
+ }
+ }
+}
+
+impl From<io::Error> for Error {
+ fn from(e: io::Error) -> Self {
+ match e.get_ref().map(|e| e.downcast_ref::<Error>()) {
+ Some(_) => *e.into_inner().unwrap().downcast::<Error>().unwrap(),
+ None => Error::IoError(e),
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
+ write!(f, "{self:?}")
+ }
+}
+
+impl std::error::Error for Error {}