//! LZ4 Frame Format //! //! As defined in //! //! # 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 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 for Error { fn from(e: io::Error) -> Self { match e.get_ref().map(|e| e.downcast_ref::()) { Some(_) => *e.into_inner().unwrap().downcast::().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 {}