1 //! LZ4 Frame Format 2 //! 3 //! As defined in <https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md> 4 //! 5 //! # Example: compress data on `stdin` with frame format 6 //! This program reads data from `stdin`, compresses it and emits it to `stdout`. 7 //! This example can be found in `examples/compress.rs`: 8 //! ```no_run 9 //! use std::io; 10 //! let stdin = io::stdin(); 11 //! let stdout = io::stdout(); 12 //! let mut rdr = stdin.lock(); 13 //! // Wrap the stdout writer in a LZ4 Frame writer. 14 //! let mut wtr = lz4_flex::frame::FrameEncoder::new(stdout.lock()); 15 //! io::copy(&mut rdr, &mut wtr).expect("I/O operation failed"); 16 //! wtr.finish().unwrap(); 17 //! ``` 18 //! 19 20 use std::{fmt, io}; 21 22 #[cfg_attr(feature = "safe-encode", forbid(unsafe_code))] 23 pub(crate) mod compress; 24 #[cfg_attr(feature = "safe-decode", forbid(unsafe_code))] 25 pub(crate) mod decompress; 26 pub(crate) mod header; 27 28 pub use compress::{AutoFinishEncoder, FrameEncoder}; 29 pub use decompress::FrameDecoder; 30 pub use header::{BlockMode, BlockSize, FrameInfo}; 31 32 #[derive(Debug)] 33 #[non_exhaustive] 34 /// Errors that can occur when de/compressing lz4. 35 pub enum Error { 36 /// Compression error. 37 CompressionError(crate::block::CompressError), 38 /// Decompression error. 39 DecompressionError(crate::block::DecompressError), 40 /// An io::Error was encountered. 41 IoError(io::Error), 42 /// Unsupported block size. 43 UnsupportedBlocksize(u8), 44 /// Unsupported frame version. 45 UnsupportedVersion(u8), 46 /// Wrong magic number for the LZ4 frame format. 47 WrongMagicNumber, 48 /// Reserved bits set. 49 ReservedBitsSet, 50 /// Block header is malformed. 51 InvalidBlockInfo, 52 /// Read a block larger than specified in the Frame header. 53 BlockTooBig, 54 /// The Frame header checksum doesn't match. 55 HeaderChecksumError, 56 /// The block checksum doesn't match. 57 BlockChecksumError, 58 /// The content checksum doesn't match. 59 ContentChecksumError, 60 /// Read an skippable frame. 61 /// The caller may read the specified amount of bytes from the underlying io::Read. 62 SkippableFrame(u32), 63 /// External dictionaries are not supported. 64 DictionaryNotSupported, 65 /// Content length differs. 66 ContentLengthError { 67 /// Expected content length. 68 expected: u64, 69 /// Actual content lenght. 70 actual: u64, 71 }, 72 } 73 74 impl From<Error> for io::Error { from(e: Error) -> Self75 fn from(e: Error) -> Self { 76 match e { 77 Error::IoError(e) => e, 78 Error::CompressionError(_) 79 | Error::DecompressionError(_) 80 | Error::SkippableFrame(_) 81 | Error::DictionaryNotSupported => io::Error::new(io::ErrorKind::Other, e), 82 Error::WrongMagicNumber 83 | Error::UnsupportedBlocksize(..) 84 | Error::UnsupportedVersion(..) 85 | Error::ReservedBitsSet 86 | Error::InvalidBlockInfo 87 | Error::BlockTooBig 88 | Error::HeaderChecksumError 89 | Error::ContentChecksumError 90 | Error::BlockChecksumError 91 | Error::ContentLengthError { .. } => io::Error::new(io::ErrorKind::InvalidData, e), 92 } 93 } 94 } 95 96 impl From<io::Error> for Error { from(e: io::Error) -> Self97 fn from(e: io::Error) -> Self { 98 match e.get_ref().map(|e| e.downcast_ref::<Error>()) { 99 Some(_) => *e.into_inner().unwrap().downcast::<Error>().unwrap(), 100 None => Error::IoError(e), 101 } 102 } 103 } 104 105 impl fmt::Display for Error { fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result106 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { 107 write!(f, "{self:?}") 108 } 109 } 110 111 impl std::error::Error for Error {} 112