### 7z SFX Configuration Block Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/15-sfx-archives.md An example of the optional configuration block used in 7z SFX archives, specifying installer settings like title, prompts, and execution behavior. ```ini ;!@Install@!UTF-8! Title="Application Installer" BeginPrompt="Install Application?" RunProgram="setup.exe" Directory="%%T" Progress="yes" ;!@InstallEnd@! ``` -------------------------------- ### List Available Examples Source: https://github.com/andreyakinshin/zesven/blob/main/rs/AGENTS.md List all available example executables in the `examples/` directory of the Rust project. ```bash # List available examples ls examples/ ``` -------------------------------- ### Run a Specific Example Source: https://github.com/andreyakinshin/zesven/blob/main/rs/AGENTS.md Execute a specific example from the `examples/` directory using `cargo run`. This requires specifying the example name and any necessary arguments. ```bash # Run an example cargo run --example extract_selective -- archive.7z ./output cargo run --example create_archive -- output.7z file1.txt file2.txt ``` -------------------------------- ### Quick Example: Async Archive Operations Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/async/index.md A basic example demonstrating how to open an archive, list its entries, and extract its contents asynchronously. ```rust use zesven::{AsyncArchive, AsyncExtractOptions, Result}; #[tokio::main] async fn main() -> Result<()> { let mut archive = AsyncArchive::open_path("archive.7z").await?; for entry in archive.entries() { println!("{}: {} bytes", entry.path.as_str(), entry.size); } archive.extract("./output", (), &AsyncExtractOptions::default()).await?; Ok(()) } ``` -------------------------------- ### Example Solid Archive Structure Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/13-solid-archives.md This example shows the internal metadata structure of a 7-Zip solid archive containing three files. ```text PackInfo: PackPos = 0 NumPackStreams = 1 PackSize[0] = 500 UnpackInfo: NumFolders = 1 Folder[0]: Coders: [LZMA2] UnpackSize = 1000 SubStreamsInfo: NumUnpackStream[0] = 3 SubStreamSize = [300, 400] # Third = 1000 - 300 - 400 = 300 Digests = [CRC_A, CRC_B, CRC_C] FilesInfo: NumFiles = 3 Names = ["a.txt", "b.txt", "c.txt"] ``` -------------------------------- ### Example BindPair Usage Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/07-unpack-info.md Provides an example of how BindPairs connect streams in a folder with two simple coders. ```plaintext Example: Folder with 2 simple coders (each having 1 input, 1 output): - Coder 0: input index 0, output index 0 - Coder 1: input index 1, output index 1 - BindPair `(InIndex=1, OutIndex=0)` connects coder 1's input to coder 0's output ``` -------------------------------- ### Complete SubStreamsInfo Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/08-substreams-info.md An example demonstrating the complete byte structure of SubStreamsInfo for an archive with two folders, one non-solid and one solid. ```plaintext 08 # SubStreamsInfo 0D # NumUnpackStream 01 # Folder 0: 1 file 03 # Folder 1: 3 files # (no End marker for NumUnpackStream) 09 # Sizes (for folder 1 only, folder 0 is implicit) 80 00 01 # File 0 size: 256 80 00 02 # File 1 size: 512 # File 2 size: calculated from folder size 00 # End Sizes 0A # Digests 01 # AllAreDefined = true # (folder 0's file uses folder CRC) 11 22 33 44 # Folder 1, File 0 CRC 55 66 77 88 # Folder 1, File 1 CRC 99 AA BB CC # Folder 1, File 2 CRC 00 # End SubStreamsInfo ``` -------------------------------- ### Complete PackInfo Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/06-pack-info.md An example byte sequence for a PackInfo section with 3 pack streams, including sizes and CRCs for all streams. ```hex 06 # PackInfo property ID 00 # PackPos = 0 03 # NumPackStreams = 3 09 # Sizes property ID 80 00 01 # PackSize[0] = 256 (NUMBER encoding) 80 00 02 # PackSize[1] = 512 80 00 04 # PackSize[2] = 1024 00 # End of Sizes 0A # Digests property ID 01 # AllAreDefined = true 78 56 34 12 # CRC[0] = 0x12345678 AB CD EF 01 # CRC[1] = 0x01EFCDAB 11 22 33 44 # CRC[2] = 0x44332211 00 # End of PackInfo ``` -------------------------------- ### Complete 7z Archive Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/09-files-info.md A byte-level example demonstrating the structure of a 7z archive containing three entries: a text file, a directory, and a source file. ```plaintext 05 # FilesInfo 03 # NumFiles = 3 0E # EmptyStream 01 # Size = 1 40 # BitField: 01000000 (entry 1 is empty) 0F # EmptyFile 01 # Size = 1 00 # BitField: 00000000 (not empty file, so directory) 11 # Name 36 # Size = 54 bytes 00 # External = inline # "readme.txt\0" 72 00 65 00 61 00 64 00 6D 00 65 00 2E 00 74 00 78 00 74 00 00 00 # "src/\0" 73 00 72 00 63 00 2F 00 00 00 # "src/main.rs\0" 73 00 72 00 63 00 2F 00 6D 00 61 00 69 00 6E 00 2E 00 72 00 73 00 00 00 14 # MTime 03 # Size 01 # AllAreDefined = true 00 # External = inline # 3 FILETIME values (8 bytes each) 00 80 3E D5 DE B1 9D 01 # readme.txt mtime 00 80 3E D5 DE B1 9D 01 # src/ mtime 00 80 3E D5 DE B1 9D 01 # src/main.rs mtime 15 # Attributes 0E # Size 01 # AllAreDefined = true 00 # External = inline 20 00 00 00 # readme.txt: ARCHIVE 10 00 00 00 # src/: DIRECTORY 20 00 00 00 # src/main.rs: ARCHIVE 00 # End FilesInfo ``` -------------------------------- ### Example Error Message: Unsupported Compression Method Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/18-error-conditions.md Shows an example error message for an unsupported compression method, detailing the method ID and the affected entry. ```text Error: Unsupported compression method Method ID: 0x04F71199 Entry: "data.bin" ``` -------------------------------- ### PPMd Properties Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/10-compression-methods.md Shows an example of PPMd properties, specifying the model order and memory size for compression. This configuration impacts the effectiveness and resource usage of the PPMd algorithm. ```Assembly 06 00 00 00 10 # Order=6, Memory=256 MiB (0x10000000) ``` -------------------------------- ### CLI Tool Installation Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/cookbook.md Command to install the zesven CLI tool with the 'cli' feature enabled. ```bash cargo install zesven --features cli ``` -------------------------------- ### Install cargo-fuzz Source: https://github.com/andreyakinshin/zesven/blob/main/rs/fuzz/README.md Install the cargo-fuzz tool, which is required for running fuzz targets. ```bash cargo install cargo-fuzz ``` -------------------------------- ### Empty PackInfo Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/06-pack-info.md An example byte sequence for a PackInfo section in an archive that contains no compressed data. It shows PackPos and NumPackStreams set to 0. ```hex 06 # PackInfo 00 # PackPos = 0 00 # NumPackStreams = 0 00 # End (no Sizes or Digests) ``` -------------------------------- ### Simple Folder Example (LZMA2) Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/07-unpack-info.md Illustrates the data flow and structure for a simple folder using the LZMA2 coder. ```plaintext Pack Stream 0 ──▶ [LZMA2] ──▶ Uncompressed Output Folder: NumCoders = 1 Coder[0]: Flags = 0x21 (IDSize=1, HasProperties) MethodID = 21 (LZMA2) Properties = [dictionary_byte] BindPairs: (none, single output) PackStreamIndices: 0 (implicit) UnpackSize[0] = output_size ``` -------------------------------- ### Complete UnpackInfo Example (BCJ + LZMA2) Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/07-unpack-info.md A detailed byte-level representation of the UnpackInfo block for an archive containing a single file compressed with BCJ and LZMA2. This example breaks down the folder structure, coder definitions, bind pairs, and unpack sizes. ```text 07 # UnpackInfo 0B # Folders section 01 # NumFolders = 1 00 # External = inline # Folder 0: 02 # NumCoders = 2 # Coder 0: LZMA2 21 # Flags: IDSize=1, HasProperties 21 # MethodID: LZMA2 15 # PropertiesSize = 1 18 # Dictionary property (16 MiB) # Coder 1: BCJ (x86) 04 # Flags: IDSize=4, no props 03 03 01 03 # MethodID: BCJ # BindPairs: (TotalOutStreams - 1 = 1) 01 # InIndex = 1 (Coder 1's input) 00 # OutIndex = 0 (Coder 0's output) # PackStreamIndices: (implicit, only 1) 0C # CodersUnpackSize 80 00 80 # UnpackSize[0] = 32768 (LZMA2 output) 80 00 80 # UnpackSize[1] = 32768 (BCJ output, same) 0A # UnpackDigests 01 # AllAreDefined 12 34 56 78 # CRC of folder 0 00 # End UnpackInfo ``` -------------------------------- ### CLI Tool Configuration Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reference/feature-flags.md Example TOML configuration for building a command-line interface tool, enabling 'cli', 'zstd', and 'lz4' features. ```toml [dependencies] zesven = { version = "1.0", features = ["cli", "zstd", "lz4"] } ``` -------------------------------- ### Sizes Section Encoding Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/08-substreams-info.md Demonstrates the byte encoding for the Sizes section, showing stored sizes for files in a folder. ```plaintext 09 # Sizes property ID 64 # 100 80 48 # 200 (NUMBER encoding) 80 16 # 150 # (no value for last file) 00 # End ``` -------------------------------- ### NumUnpackStream Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/08-substreams-info.md Illustrates the byte encoding for NumUnpackStream with three folders containing 1, 4, and 2 files respectively. ```plaintext 0D # NumUnpackStream property ID 01 # Folder 0: 1 file 04 # Folder 1: 4 files (solid block) 02 # Folder 2: 2 files (solid block) # (no End marker here; continues with Sizes or End of SubStreamsInfo) ``` -------------------------------- ### LZMA Properties Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/10-compression-methods.md Demonstrates LZMA properties for setting dictionary size and encoder parameters. These values configure the compression algorithm's behavior. ```Assembly 5D 00 00 10 00 # lc=3, lp=0, pb=2, dict=16 MiB (0x01000000) 5D 00 00 00 02 # lc=3, lp=0, pb=2, dict=32 MiB (0x02000000) ``` -------------------------------- ### Example FILETIME Value Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/16-timestamps-attributes.md Demonstrates the byte representation of a specific FILETIME value corresponding to a Unix timestamp. ```text # 2024-01-15 12:00:00 UTC # Unix: 1705320000 # FILETIME: 1705320000 * 10000000 + 116444736000000000 # = 133497936000000000 # = 0x01DA47AA5D872000 Bytes: 00 20 87 5D AA 47 DA 01 ``` -------------------------------- ### Install zesven Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/index.md Add the zesven crate to your Rust project using Cargo. ```sh cargo add zesven ``` -------------------------------- ### Maximum Compatibility Configuration Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reference/feature-flags.md Example TOML configuration for maximum compatibility, enabling 'lz4', 'zstd', and 'brotli' compression features. ```toml [dependencies] zesven = { version = "1.0", features = ["lz4", "zstd", "brotli"] } ``` -------------------------------- ### Example Offset Calculation in 7z Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/02-archive-structure.md Illustrates the calculation of NextHeaderOffset based on pack data size and header size. Assumes a specific header size and pack data size. ```text Signature Header: bytes 0-31 (32 bytes) Pack Data: bytes 32-1031 (1000 bytes) Next Header: bytes 1032-1231 (200 bytes) NextHeaderOffset = 1000 (offset from byte 32 to byte 1032) NextHeaderSize = 200 ``` -------------------------------- ### Coder Order in Folder Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/11-filters.md Illustrates the coder order for compression and how it's represented in folder definitions, with BCJ and LZMA2 as an example. ```text Compression: Input → BCJ → LZMA2 → Output Folder coders: [LZMA2, BCJ] Bind pairs: BCJ input binds to LZMA2 output ``` -------------------------------- ### Enabling Optional Compression Methods Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/compression-options.md Examples of configuring Zstandard, LZ4, and Brotli compression methods. These require enabling corresponding feature flags in the `Cargo.toml` file. ```toml [dependencies] zesven = { version = "1.0", features = ["zstd", "lz4", "brotli"] } ``` ```rust use zesven::{WriteOptions, codec::CodecMethod, Result}; fn example() -> Result<()> { // Zstandard - fast with good ratio (level range differs from LZMA) let options = WriteOptions::new() .method(CodecMethod::Zstd) .level_clamped(9); // LZ4 - extremely fast let options = WriteOptions::new() .method(CodecMethod::Lz4); // Brotli - excellent ratio for web content let options = WriteOptions::new() .method(CodecMethod::Brotli) .level_clamped(9); Ok(()) } ``` -------------------------------- ### Multi-Volume Archive Structure Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/14-multi-volume.md Illustrates the layout of a 7z archive split into multiple volumes, showing the signature header and pack data offsets for each volume. ```text archive.7z.001: Offset 0x00: Signature Header Offset 0x20: Pack data bytes 0-10485727 archive.7z.002: Offset 0x00: Pack data bytes 10485728-20971455 archive.7z.003: Offset 0x00: Pack data bytes 20971456-25000000 Offset after pack: Next Header (remaining space) ``` -------------------------------- ### Name Property Encoding Examples Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/09-files-info.md Illustrates the UTF-16-LE encoding for file and directory names, including path separators and null terminators. ```plaintext "file.txt" → 66 00 69 00 6C 00 65 00 2E 00 74 00 78 00 74 00 00 00 "dir/" → 64 00 69 00 72 00 2F 00 00 00 "dir/subfile.txt" → 64 00 69 00 72 00 2F 00 73 00 ... 00 00 ``` -------------------------------- ### LZMA Method Properties Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/appendix/b-method-ids.md Shows the default properties for the LZMA compression method, including literal context, literal position, position bits, and dictionary size. ```text 5D 00 00 10 00 (lc=3, lp=0, pb=2, dict=16 MiB) ``` -------------------------------- ### 7z Header with Empty Files Only Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/05-header-structure.md An example of a 7z header for an archive containing two empty files with names. It demonstrates the FilesInfo structure with NumFiles, EmptyStream, and Name properties. ```hex 01 # Header 05 # FilesInfo 02 # NumFiles = 2 0E # EmptyStream 01 # Size = 1 C0 # BitField: both files are empty streams (bits 7,6 = 1,1) 11 # Name 0E # Size = 14 00 # External = inline 61 00 00 00 # "a" + null 62 00 00 00 # "b" + null 00 # End of FilesInfo 00 # End of Header ``` -------------------------------- ### Basic Archive Extraction Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reading/index.md A quick example showing how to open an archive, print its basic information, and extract all its contents to a specified directory using default options. The `ExtractOptions::default()` provides standard extraction behavior. ```rust use zesven::{Archive, ExtractOptions, Result}; fn main() -> Result<()> { let mut archive = Archive::open_path("archive.7z")?; // Print archive info println!("Archive: {} entries, {} total bytes", archive.len(), archive.entries().map(|e| e.size).sum::()); // Extract with default options let result = archive.extract("./output", (), &ExtractOptions::default())?; println!("Extracted {} files ({} bytes)", result.entries_extracted, result.bytes_extracted); Ok(()) } ``` -------------------------------- ### Variable-Length Integer Encoding Examples Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/04-data-encoding.md Illustrates how integer values are encoded into variable-length byte sequences. Larger values require more bytes. ```text 0 00 1 01 127 7F 128 80 80 255 80 FF 256 81 00 16383 BF FF 16384 C0 00 40 65535 C0 FF FF 2^32 - 1 F0 FF FF FF FF 2^64 - 1 FF FF FF FF FF FF FF FF FF ``` -------------------------------- ### Archive Properties Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/12-encryption.md Illustrates the byte structure of archive properties including salt size, IV size, iteration count, salt, and IV. ```plaintext Properties (18 bytes): 88 # SaltSize=8, IVSize=8 13 # NumCyclesPower = 19 (0x13) 01 02 03 04 05 06 07 08 # Salt 11 12 13 14 15 16 17 18 # IV (padded to 16 with zeros) ``` -------------------------------- ### PKCS#7 Padding Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/12-encryption.md Illustrates the PKCS#7 padding scheme where data is padded to a 16-byte boundary with bytes indicating the padding length. ```hex 03 03 03 ``` -------------------------------- ### Pack Data Start Calculation Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/06-pack-info.md Calculates the absolute file position where compressed pack data begins within a 7z archive. ```plaintext pack_data_start = 32 + PackPos ``` -------------------------------- ### Create Self-Extracting Archive (SFX) Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/advanced/index.md Build self-extracting executable archives. Requires a stub file (e.g., 7zS.sfx) and configuration for the installer title and progress display. ```rust use zesven::sfx::{SfxBuilder, SfxConfig, SfxStub, SfxFormat}; use zesven::Result; use std::fs::File; fn main() -> Result<()> { let stub = SfxStub::from_file("7zS.sfx")?; let config = SfxConfig::new() .title("My Installer") .progress(true); let archive_data = std::fs::read("archive.7z")?; let mut output = File::create("installer.exe")?; SfxBuilder::new() .stub(stub) .config(config) .build(&mut output, &archive_data)?; Ok(()) } ``` -------------------------------- ### BooleanList Encoding Example (Mixed Values) Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/04-data-encoding.md Represents a BooleanList with mixed true and false values. It starts with a zero 'AllAreDefined' byte, followed by the BitField. ```text 00 # AllAreDefined = 0 B8 # BitField: 10111000 (items 0-4 in bits 7-3, padding in 2-0) ``` -------------------------------- ### CI Configuration for Cross-Platform Testing Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reference/platform-support.md Example GitHub Actions CI configuration to test your project on Linux, macOS, and Windows. Ensures compatibility across different operating systems. ```yaml # .github/workflows/ci.yml jobs: test: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - run: cargo test ``` -------------------------------- ### Basic Archive Creation Workflow Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/index.md Illustrates the fundamental steps for creating a 7z archive: creating a writer, configuring options, adding files, and finalizing the archive. ```rust use zesven::{Writer, WriteOptions, ArchivePath, Result}; fn main() -> Result<()> { let options = WriteOptions::new() .level(7)? // Compression level 0-9 .solid(); // Enable solid compression let mut writer = Writer::create_path("backup.7z")? .options(options); // Add files from disk writer.add_path("document.pdf", ArchivePath::new("docs/document.pdf")?)?; writer.add_path("image.png", ArchivePath::new("images/photo.png")?)?; // Add data from memory writer.add_bytes(ArchivePath::new("readme.txt")?, b"Project readme")?; // Finalize let result = writer.finish()?; println!("Compressed {} bytes to {} bytes ({:.1}% savings)", result.total_size, result.compressed_size, result.space_savings() * 100.0); Ok(()) } ``` -------------------------------- ### Create Archive and Add File Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/creating-archives.md Demonstrates the basic process of creating a new archive file and adding a single file from disk to it. ```rust use zesven::{Writer, ArchivePath, Result}; fn main() -> Result<()> { let mut writer = Writer::create_path("archive.7z")?; // Add a file from disk writer.add_path("source.txt", ArchivePath::new("source.txt")?)?; // Finalize the archive writer.finish()?; Ok(()) } ``` -------------------------------- ### Configure Compression with LZMA2 Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/cookbook.md Demonstrates how to configure writer options to use LZMA2 compression with maximum level and create a solid archive. ```rust use zesven::{Writer, ArchivePath, Result}; use zesven::write::WriteOptions; use zesven::codec::CodecMethod; fn main() -> Result<()> { let options = WriteOptions::new() .method(CodecMethod::Lzma2) .level(9)? // 0-9, where 9 is maximum compression .solid(); let mut writer = Writer::create_path("compressed.7z")? .options(options); writer.add_path("large_file.bin", ArchivePath::new("large_file.bin")?)?; writer.finish()?; Ok(()) } ``` -------------------------------- ### Partial Digests Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/06-pack-info.md An example byte sequence for a Digests section where not all streams have CRCs defined. It shows the use of a bitfield to indicate which streams have associated CRCs. ```hex 0A # Digests property ID 00 # AllAreDefined = false A0 # BitField = 0xA0: bit 7 (item 0) = 1, bit 5 (item 2) = 1 78 56 34 12 # CRC for stream 0 11 22 33 44 # CRC for stream 2 # (no CRC for stream 1) ``` -------------------------------- ### Compression Level Examples Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/compression-options.md Demonstrates setting different compression levels for various use cases: level 1 for fast compression on large files, level 9 for maximum compression on final archives, and level 5 for a balanced approach. ```rust use zesven::{WriteOptions, Result}; fn main() -> Result<()> { // Fast compression for large files let fast = WriteOptions::new().level(1)?; // Maximum compression for final archives let maximum = WriteOptions::new().level(9)?; // Balanced (default) let balanced = WriteOptions::new().level(5)?; Ok(()) } ``` -------------------------------- ### Verify 7z Start Header CRC Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/appendix/c-crc-algorithm.md Checks the integrity of the 7z start header by calculating its CRC and comparing it with the stored value. Assumes a helper function `read_u32_le` exists. ```c bool verify_start_header(const uint8_t* header) { // Header is 32 bytes uint32_t stored_crc = read_u32_le(&header[8]); uint32_t calculated_crc = crc32(&header[12], 20); return stored_crc == calculated_crc; } ``` -------------------------------- ### Create Solid Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/cookbook.md Shows how to create a solid archive where files are compressed together for potentially better compression ratios. This is useful when archiving similar files. ```rust use zesven::{Writer, ArchivePath, Result}; use zesven::write::WriteOptions; fn main() -> Result<()> { let options = WriteOptions::new() .solid(); // Compress files together for better ratio let mut writer = Writer::create_path("solid.7z")? .options(options); // Similar files compress better together in solid mode writer.add_path("file1.txt", ArchivePath::new("file1.txt")?)?; writer.add_path("file2.txt", ArchivePath::new("file2.txt")?)?; writer.add_path("file3.txt", ArchivePath::new("file3.txt")?)?; writer.finish()?; Ok(()) } ``` -------------------------------- ### Common Filter Chains Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/11-filters.md Examples of common filter chaining patterns for executables and multi-channel audio. ```text Data → [BCJ x86] → [LZMA2] → Compressed ``` ```text Data → [Delta, distance=2] → [LZMA2] → Compressed ``` -------------------------------- ### 7z Multi-Volume Naming Convention Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/14-multi-volume.md Volumes use zero-padded numeric extensions, typically starting from .001. ```text archive.7z.001 # First volume archive.7z.002 # Second volume archive.7z.003 # Third volume ... archive.7z.NNN # Nth volume ``` -------------------------------- ### Creating a Solid Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/13-solid-archives.md Outlines the steps for creating a solid archive, including sorting files for better compression, grouping them into blocks, concatenating, and compressing them as a single unit. This is crucial for optimizing storage. ```javascript function create_solid_archive(files, options): if options.solid: # Sort files by type/extension for better compression files = sort_by_extension(files) # Group into solid blocks blocks = group_files(files, options.solid_block_size) for block in blocks: # Concatenate all files in block combined = concatenate(block) # Compress as single unit compressed = compress(combined, options.method) # Record substream sizes sizes = [file.size for file in block[:-1]] ``` -------------------------------- ### JavaScript Usage for Wasm Archive Extraction Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/cookbook.md Example of using the WasmArchive in JavaScript to extract files from an archive. ```javascript import init, { WasmArchive } from "zesven"; async function extractArchive(arrayBuffer) { await init(); const archive = new WasmArchive(new Uint8Array(arrayBuffer)); // List entries const entries = archive.getEntries(); for (const entry of entries) { console.log(`${entry.path}: ${entry.size} bytes`); } // Extract specific file const data = archive.extractFile("config.json"); const config = JSON.parse(new TextDecoder().decode(data)); archive.free(); return config; } ``` -------------------------------- ### Basic Operations: Creating Archives Asynchronously Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/async/index.md Shows how to create a new archive file and add data to it asynchronously. ```rust use zesven::{AsyncWriter, ArchivePath, Result}; #[tokio::main] async fn main() -> Result<()> { let mut writer = AsyncWriter::create_path("new.7z").await?; writer.add_bytes(ArchivePath::new("hello.txt")?, b"Hello").await?; writer.finish().await?; Ok(()) } ``` -------------------------------- ### Initialize Incremental CRC-32 Calculation Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/appendix/c-crc-algorithm.md Returns the initial CRC-32 value, which is 0xFFFFFFFF, to start an incremental calculation. ```c uint32_t crc32_init() { return 0xFFFFFFFF; } ``` -------------------------------- ### Async File I/O with Tokio Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/async/tokio-integration.md Demonstrates using Tokio's asynchronous file I/O (`tokio::fs::File`) with zesven's `AsyncArchive`. ```rust use zesven::{AsyncArchive, AsyncExtractOptions, Result}; use tokio::fs::File; use tokio::io::BufReader; #[tokio::main] async fn main() -> Result<()> { // Open from Tokio file let file = File::open("archive.7z").await?; let reader = BufReader::new(file); let archive = AsyncArchive::open(reader).await?; println!("Found {} entries", archive.len()); Ok(()) } ``` -------------------------------- ### First Volume Structure Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/14-multi-volume.md The first volume contains the signature header followed by the start of the pack data. ```text ┌─────────────────────────┐ │ Signature Header │ 32 bytes ├─────────────────────────┤ │ Pack Data (start) │ Up to volume boundary └─────────────────────────┘ ``` -------------------------------- ### Basic Archive Creation Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/cookbook.md Creates a new 7z archive and adds files from disk or directly as byte slices. ```rust use zesven::{Writer, ArchivePath, Result}; fn main() -> Result<()> { let mut writer = Writer::create_path("new.7z")?; // Add file from disk writer.add_path("document.pdf", ArchivePath::new("document.pdf")?)?; // Add bytes directly writer.add_bytes(ArchivePath::new("hello.txt")?, b"Hello, World!")?; let result = writer.finish()?; println!("Compressed {} bytes to {} bytes", result.total_size, result.compressed_size); Ok(()) } ``` -------------------------------- ### Iteration Counter Encoding Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/12-encryption.md Shows the little-endian byte representation of an iteration counter, specifically for the value 256. ```hex 00 01 00 00 00 00 00 00 ``` -------------------------------- ### StartPos Structure Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/appendix/a-property-ids.md Defines the structure for start positions within streams. This property is deprecated and rarely used; implementations should ignore it. ```7z StartPos ::= 0x18 Size Data ``` -------------------------------- ### Pack Stream Layout Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/06-pack-info.md Illustrates the contiguous layout of pack streams in the archive, starting from offset 32 + PackPos. ```plaintext Offset 32 + PackPos: ┌─────────────────────┐ │ Pack Stream 0 │ PackSize[0] bytes ├─────────────────────┤ │ Pack Stream 1 │ PackSize[1] bytes ├─────────────────────┤ │ ... │ ├─────────────────────┤ │ Pack Stream N-1 │ PackSize[N-1] bytes └─────────────────────┘ ``` -------------------------------- ### Volume Size Options with VolumeConfig Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/advanced/multi-volume.md Configure volume sizes for multi-volume archives using `VolumeConfig`. Convenience methods are provided for common sizes like CD and DVD, as well as custom and default sizes. ```rust use zesven::VolumeConfig; // CD-sized volumes (convenience method) let cd = VolumeConfig::cd("archive.7z"); // DVD-sized volumes (convenience method) let dvd = VolumeConfig::dvd("archive.7z"); // Custom size let custom = VolumeConfig::new("archive.7z", 100 * 1024 * 1024); // Default 100 MB volumes let default = VolumeConfig::with_default_size("archive.7z"); ``` -------------------------------- ### Create a 7z Archive Source: https://github.com/andreyakinshin/zesven/blob/main/rs/README.md This snippet demonstrates how to create a new .7z archive and add files to it. The writer must be finished after adding all paths. ```rust use zesven::{Writer, ArchivePath}; fn main() -> zesven::Result<()> { let mut writer = Writer::create_path("new.7z")?; writer.add_path("file.txt", ArchivePath::new("file.txt")?)?; writer.finish()?; Ok(()) } ``` -------------------------------- ### BitField Encoding Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/04-data-encoding.md Shows the byte encoding for a sequence of boolean values, including padding with zeros in the last byte. ```text Encoding: B2 80 ``` -------------------------------- ### Minimal Build with Specific Features Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reference/feature-flags.md This configuration disables default features and explicitly enables only the 'lzma2' feature for a smaller binary size. ```toml [dependencies] zesven = { version = "1.0", default-features = false, features = ["lzma2"] } ``` -------------------------------- ### Password to UTF-16-LE Encoding Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/12-encryption.md Demonstrates how a plain text password is converted to UTF-16-LE byte representation for key derivation. ```hex 74 00 65 00 73 00 74 00 ``` -------------------------------- ### Extract Specific Paths from Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reading/selective-extraction.md Filter entries by providing a `HashSet` of desired paths. This example extracts only 'readme.txt', 'config.json', and 'src/main.rs'. ```rust use zesven::{Archive, ExtractOptions, Entry, Result}; use std::collections::HashSet; fn main() -> Result<()> { let mut archive = Archive::open_path("archive.7z")?; let wanted: HashSet<&str> = [ "readme.txt", "config.json", "src/main.rs", ].into_iter().collect(); archive.extract("./output", |entry: &Entry| { wanted.contains(entry.path.as_str()) }, &ExtractOptions::default())?; Ok(()) } ``` -------------------------------- ### ArchiveEditor: Basic Operations Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/advanced/editing.md Demonstrates opening an archive, queuing delete and rename operations, and applying them to a new file using `ArchiveEditor`. ```rust use zesven::{Archive, ArchivePath, Result}; use zesven::edit::ArchiveEditor; use std::fs::File; fn main() -> Result<()> { // Open the archive first let archive = Archive::open_path("archive.7z")?; let mut editor = ArchiveEditor::new(archive); // Queue operations using direct methods editor.delete("unwanted.txt")?; editor.rename("old.txt", "new.txt")?; // Apply all operations to a new file let output = File::create("modified.7z")?; editor.apply(output)?; Ok(()) } ``` -------------------------------- ### Extract Only .txt Files Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reading/selective-extraction.md Use a closure to filter entries based on their path. This example extracts only files ending with the .txt extension. ```rust use zesven::{Archive, ExtractOptions, Result}; fn main() -> Result<()> { let mut archive = Archive::open_path("archive.7z")?; // Extract only .txt files archive.extract("./output", |entry: &_| { entry.path.as_str().ends_with(".txt") }, &ExtractOptions::default())?; Ok(()) } ``` -------------------------------- ### Common zesven Operations Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reference/index.md Demonstrates opening an archive, extracting its contents, and creating a new archive with data. Ensure necessary imports are included. ```rust use zesven::{Archive, Writer, ArchivePath, ExtractOptions, WriteOptions, Result}; // Open archive let archive = Archive::open_path("archive.7z")?; // Extract let mut archive = Archive::open_path("archive.7z")?; archive.extract("./output", (), &ExtractOptions::default())?; // Create archive let mut writer = Writer::create_path("new.7z")?; writer.add_bytes(ArchivePath::new("file.txt")?, b"data")?; writer.finish()?; ``` -------------------------------- ### Recommended Archive Settings for Compatibility Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/appendix/d-compatibility.md Use these settings for maximum compatibility with most 7-Zip implementations. Avoid advanced compression methods and large solid blocks. ```text Compression: LZMA2 Dictionary: 16 MiB or less Solid: Off (or small blocks) Header compression: LZMA2 Header encryption: Off Filters: BCJ for executables only ``` -------------------------------- ### Coder Chain Example Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/01-glossary.md Illustrates a typical sequence of coders applied to data for compression. Data flows sequentially through each coder in the chain. ```text Input → [Coder 1] → [Coder 2] → ... → [Coder N] → Output ``` -------------------------------- ### Create SFX Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/advanced/sfx.md Builds a self-extracting executable by combining a stub, configuration, and archive data. Ensure the stub executable (e.g., 7zS.sfx) and archive file (e.g., archive.7z) exist. ```rust use zesven::sfx::{SfxBuilder, SfxConfig, SfxStub}; use zesven::Result; use std::fs::File; fn main() -> Result<()> { // Load a stub executable (e.g., 7zS.sfx from 7-Zip) let stub = SfxStub::from_file("7zS.sfx")?; let config = SfxConfig::new() .title("My Application Installer") .extract_path("./MyApp"); // Read the archive data let archive_data = std::fs::read("archive.7z")?; // Build the SFX let mut output = File::create("installer.exe")?; SfxBuilder::new() .stub(stub) .config(config) .build(&mut output, &archive_data)?; Ok(()) } ``` -------------------------------- ### 7z Signature Bytes Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/03-signature-header.md Specifies the magic bytes that identify a file as a 7z archive. Implementations must reject files not starting with this sequence. ```markdown | Byte | Hex | ASCII | Description | | ---- | ---- | ----- | -------------- | | 0 | 0x37 | '7' | ASCII digit 7 | | 1 | 0x7A | 'z' | ASCII letter z | | 2 | 0xBC | - | Magic byte | | 3 | 0xAF | - | Magic byte | | 4 | 0x27 | - | Magic byte | | 5 | 0x1C | - | Magic byte | ``` -------------------------------- ### Add Directories to Archive Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/creating-archives.md Shows how to create directory entries within an archive, including empty directories and directories containing files. ```rust use zesven::{Writer, ArchivePath, Result}; use zesven::write::EntryMeta; fn main() -> Result<()> { let mut writer = Writer::create_path("archive.7z")?; // Add an empty directory writer.add_directory( ArchivePath::new("empty_folder")?, EntryMeta::directory(), )?; // Add files within it writer.add_bytes( ArchivePath::new("empty_folder/readme.txt")?, b"Folder contents", )?; writer.finish()?; Ok(()) } ``` -------------------------------- ### Get Append Result Information Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/writing/appending.md After finishing the append operation, retrieve and print information about the added files and the archive's state. ```rust use zesven::{ArchiveAppender, ArchivePath, Result}; fn main() -> Result<()> { let mut appender = ArchiveAppender::open("archive.7z")?; appender.add_bytes(ArchivePath::new("data.txt")?, b"Data")?; let result = appender.finish()?; println!("Files added: {}", result.entries_added); println!("Total entries: {}", result.total_entries); println!("Total bytes: {}", result.total_bytes); Ok(()) } ``` -------------------------------- ### Extract Files Larger Than 1KB Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reading/selective-extraction.md Filter entries based on their size using a closure. This example extracts files that are larger than 1024 bytes. ```rust use zesven::{Archive, ExtractOptions, Entry, Result}; fn main() -> Result<()> { let mut archive = Archive::open_path("archive.7z")?; // Extract files larger than 1KB archive.extract("./output", |entry: &Entry| { entry.size > 1024 }, &ExtractOptions::default())?; Ok(()) } ``` -------------------------------- ### Open Archive from Different Sources Source: https://github.com/andreyakinshin/zesven/blob/main/docs/rs/reading/index.md Demonstrates opening a 7z archive from a file path, an already opened file, or a memory buffer. Ensure the reader type implements `Read + Seek`. ```rust use zesven::{Archive, Result}; use std::fs::File; use std::io::Cursor; fn main() -> Result<()> { // From a file path (most common) let archive = Archive::open_path("archive.7z")?; // From an open file let file = File::open("archive.7z")?; let archive = Archive::open(file)?; // From memory let data = std::fs::read("archive.7z")?; let archive = Archive::open(Cursor::new(data))?; Ok(()) } ``` -------------------------------- ### BooleanList Encoding Example (All True) Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/04-data-encoding.md Represents a BooleanList where all values are true. This uses the 'all true' shortcut, indicated by a non-zero 'AllAreDefined' byte. ```text 01 # AllAreDefined = 1, no BitField needed ``` -------------------------------- ### Example Error Message: Path Traversal Source: https://github.com/andreyakinshin/zesven/blob/main/docs/7z/18-error-conditions.md Demonstrates an error message indicating a path traversal attempt, specifying the problematic path and entry index. ```text Error: Path traversal detected Path: "../../../etc/passwd" Entry: 3 ```