Constants API ​
The Constants API provides algorithm-specific constants, limits, and configuration values used throughout Archive.zig.
Core Constants ​
General Constants ​
zig
pub const Constants = struct {
pub const DEFAULT_BUFFER_SIZE: usize = 64 * 1024;
pub const MIN_BUFFER_SIZE: usize = 1024;
pub const MAX_BUFFER_SIZE: usize = 16 * 1024 * 1024;
pub const DEFAULT_MEMORY_LEVEL: u8 = 6;
pub const MIN_MEMORY_LEVEL: u8 = 1;
pub const MAX_MEMORY_LEVEL: u8 = 9;
pub const DEFAULT_WINDOW_SIZE: u32 = 32768;
pub const MIN_WINDOW_SIZE: u32 = 256;
pub const MAX_WINDOW_SIZE: u32 = 32768;
};Compression Level Constants ​
zig
pub const LevelConstants = struct {
pub const FASTEST_LEVEL: u8 = 1;
pub const FAST_LEVEL: u8 = 3;
pub const DEFAULT_LEVEL: u8 = 6;
pub const BEST_LEVEL: u8 = 9;
pub const MIN_LEVEL: u8 = 0;
pub const MAX_LEVEL: u8 = 9;
};Algorithm-Specific Constants ​
ZSTD Constants ​
zig
pub const ZstdConstants = struct {
pub const MIN_LEVEL: c_int = 1;
pub const MAX_LEVEL: c_int = 22;
pub const DEFAULT_LEVEL: c_int = 3;
pub const ULTRA_MIN_LEVEL: c_int = 20;
pub const ULTRA_MAX_LEVEL: c_int = 22;
// Window log constants
pub const MIN_WINDOW_LOG: c_int = 10;
pub const MAX_WINDOW_LOG: c_int = 31;
pub const DEFAULT_WINDOW_LOG: c_int = 22;
// Hash log constants
pub const MIN_HASH_LOG: c_int = 6;
pub const MAX_HASH_LOG: c_int = 26;
pub const DEFAULT_HASH_LOG: c_int = 20;
// Chain log constants
pub const MIN_CHAIN_LOG: c_int = 6;
pub const MAX_CHAIN_LOG: c_int = 28;
pub const DEFAULT_CHAIN_LOG: c_int = 16;
// Search log constants
pub const MIN_SEARCH_LOG: c_int = 1;
pub const MAX_SEARCH_LOG: c_int = 26;
pub const DEFAULT_SEARCH_LOG: c_int = 8;
// Target length constants
pub const MIN_TARGET_LENGTH: c_int = 4;
pub const MAX_TARGET_LENGTH: c_int = 999;
pub const DEFAULT_TARGET_LENGTH: c_int = 64;
// LDM (Long Distance Matching) constants
pub const LDM_MIN_MEMORY: c_int = 10;
pub const LDM_MAX_MEMORY: c_int = 23;
pub const LDM_DEFAULT_MEMORY: c_int = 20;
pub const LDM_MIN_HASH_RATE_LOG: c_int = 0;
pub const LDM_MAX_HASH_RATE_LOG: c_int = 16;
pub const LDM_DEFAULT_HASH_RATE_LOG: c_int = 8;
// Magic number
pub const MAGIC_NUMBER: u32 = 0xFD2FB528;
pub const MAGIC_BYTES: [4]u8 = [_]u8{ 0x28, 0xB5, 0x2F, 0xFD };
// Frame constants
pub const FRAME_HEADER_SIZE_MIN: usize = 6;
pub const FRAME_HEADER_SIZE_MAX: usize = 18;
pub const BLOCK_HEADER_SIZE: usize = 3;
pub const BLOCK_SIZE_MAX: usize = 128 * 1024;
// Dictionary constants
pub const DICT_SIZE_MIN: usize = 256;
pub const DICT_SIZE_MAX: usize = 2 * 1024 * 1024;
};LZ4 Constants ​
zig
pub const Lz4Constants = struct {
pub const MIN_LEVEL: c_int = 1;
pub const MAX_LEVEL: c_int = 12;
pub const DEFAULT_LEVEL: c_int = 1;
pub const ACCELERATION_DEFAULT: c_int = 1;
pub const ACCELERATION_MAX: c_int = 65537;
// Magic number
pub const MAGIC_NUMBER: u32 = 0x184D2204;
pub const MAGIC_BYTES: [4]u8 = [_]u8{ 0x04, 0x22, 0x4D, 0x18 };
// Frame constants
pub const FRAME_HEADER_SIZE: usize = 7;
pub const FRAME_HEADER_SIZE_MAX: usize = 19;
pub const BLOCK_HEADER_SIZE: usize = 4;
// Block size constants
pub const BLOCK_SIZE_64KB: u32 = 64 * 1024;
pub const BLOCK_SIZE_256KB: u32 = 256 * 1024;
pub const BLOCK_SIZE_1MB: u32 = 1024 * 1024;
pub const BLOCK_SIZE_4MB: u32 = 4 * 1024 * 1024;
pub const BLOCK_SIZE_DEFAULT: u32 = BLOCK_SIZE_64KB;
// Dictionary constants
pub const DICT_SIZE_MIN: usize = 4;
pub const DICT_SIZE_MAX: usize = 64 * 1024;
};Gzip Constants ​
zig
pub const GzipConstants = struct {
pub const MAGIC_BYTES: [2]u8 = [_]u8{ 0x1F, 0x8B };
pub const HEADER_SIZE_MIN: usize = 10;
pub const HEADER_SIZE_MAX: usize = 255;
pub const FOOTER_SIZE: usize = 8;
// Compression methods
pub const METHOD_DEFLATE: u8 = 8;
// Flags
pub const FLAG_TEXT: u8 = 0x01;
pub const FLAG_CRC: u8 = 0x02;
pub const FLAG_EXTRA: u8 = 0x04;
pub const FLAG_NAME: u8 = 0x08;
pub const FLAG_COMMENT: u8 = 0x10;
// Operating system constants
pub const OS_FAT: u8 = 0;
pub const OS_AMIGA: u8 = 1;
pub const OS_VMS: u8 = 2;
pub const OS_UNIX: u8 = 3;
pub const OS_VM_CMS: u8 = 4;
pub const OS_ATARI_TOS: u8 = 5;
pub const OS_HPFS: u8 = 6;
pub const OS_MACINTOSH: u8 = 7;
pub const OS_Z_SYSTEM: u8 = 8;
pub const OS_CP_M: u8 = 9;
pub const OS_TOPS_20: u8 = 10;
pub const OS_NTFS: u8 = 11;
pub const OS_QDOS: u8 = 12;
pub const OS_ACORN_RISCOS: u8 = 13;
pub const OS_UNKNOWN: u8 = 255;
};Zlib Constants ​
zig
pub const ZlibConstants = struct {
pub const HEADER_SIZE: usize = 2;
pub const FOOTER_SIZE: usize = 4;
// Compression methods
pub const METHOD_DEFLATE: u8 = 8;
// Compression info (window size)
pub const CINFO_32K: u8 = 7; // 2^(7+8) = 32KB window
// Flags
pub const FCHECK_MASK: u8 = 0x1F;
pub const FDICT_FLAG: u8 = 0x20;
pub const FLEVEL_MASK: u8 = 0xC0;
pub const FLEVEL_FASTEST: u8 = 0x00;
pub const FLEVEL_FAST: u8 = 0x40;
pub const FLEVEL_DEFAULT: u8 = 0x80;
pub const FLEVEL_SLOWEST: u8 = 0xC0;
// Dictionary constants
pub const DICT_ID_SIZE: usize = 4;
};Deflate Constants ​
zig
pub const DeflateConstants = struct {
// Window size constants
pub const MIN_WINDOW_BITS: u8 = 8;
pub const MAX_WINDOW_BITS: u8 = 15;
pub const DEFAULT_WINDOW_BITS: u8 = 15;
// Memory level constants
pub const MIN_MEM_LEVEL: u8 = 1;
pub const MAX_MEM_LEVEL: u8 = 9;
pub const DEFAULT_MEM_LEVEL: u8 = 8;
// Strategy constants
pub const STRATEGY_DEFAULT: u8 = 0;
pub const STRATEGY_FILTERED: u8 = 1;
pub const STRATEGY_HUFFMAN_ONLY: u8 = 2;
pub const STRATEGY_RLE: u8 = 3;
pub const STRATEGY_FIXED: u8 = 4;
// Block type constants
pub const BLOCK_TYPE_STORED: u8 = 0;
pub const BLOCK_TYPE_FIXED: u8 = 1;
pub const BLOCK_TYPE_DYNAMIC: u8 = 2;
// Length codes
pub const LENGTH_CODES: usize = 29;
pub const LITERALS: usize = 256;
pub const L_CODES: usize = LITERALS + 1 + LENGTH_CODES;
pub const D_CODES: usize = 30;
pub const BL_CODES: usize = 19;
pub const HEAP_SIZE: usize = 2 * L_CODES + 1;
pub const MAX_BITS: usize = 15;
};LZMA Constants ​
zig
pub const LzmaConstants = struct {
pub const MAGIC_BYTES: [3]u8 = [_]u8{ 0x5D, 0x00, 0x00 };
pub const HEADER_SIZE: usize = 13;
// Dictionary size constants
pub const DICT_SIZE_MIN: u32 = 4096;
pub const DICT_SIZE_MAX: u32 = 1 << 27; // 128MB
pub const DICT_SIZE_DEFAULT: u32 = 1 << 24; // 16MB
// Properties constants
pub const LC_DEFAULT: u8 = 3; // Literal context bits
pub const LP_DEFAULT: u8 = 0; // Literal position bits
pub const PB_DEFAULT: u8 = 2; // Position bits
pub const LC_MAX: u8 = 8;
pub const LP_MAX: u8 = 4;
pub const PB_MAX: u8 = 4;
// Match finder constants
pub const MF_BT2: u8 = 0;
pub const MF_BT3: u8 = 1;
pub const MF_BT4: u8 = 2;
pub const MF_HC4: u8 = 3;
pub const MF_DEFAULT: u8 = MF_BT4;
// Number of fast bytes
pub const NUM_FAST_BYTES_MIN: u32 = 5;
pub const NUM_FAST_BYTES_MAX: u32 = 273;
pub const NUM_FAST_BYTES_DEFAULT: u32 = 32;
};XZ Constants ​
zig
pub const XzConstants = struct {
pub const MAGIC_BYTES: [6]u8 = [_]u8{ 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00 };
pub const HEADER_SIZE: usize = 12;
pub const FOOTER_SIZE: usize = 12;
// Stream flags
pub const STREAM_HEADER_SIZE: usize = 12;
pub const STREAM_FOOTER_SIZE: usize = 12;
pub const BLOCK_HEADER_SIZE_MIN: usize = 8;
pub const BLOCK_HEADER_SIZE_MAX: usize = 1024;
// Check types
pub const CHECK_NONE: u8 = 0;
pub const CHECK_CRC32: u8 = 1;
pub const CHECK_CRC64: u8 = 4;
pub const CHECK_SHA256: u8 = 10;
// Filter IDs
pub const FILTER_LZMA2: u64 = 0x21;
pub const FILTER_X86: u64 = 0x04;
pub const FILTER_POWERPC: u64 = 0x05;
pub const FILTER_IA64: u64 = 0x06;
pub const FILTER_ARM: u64 = 0x07;
pub const FILTER_ARMTHUMB: u64 = 0x08;
pub const FILTER_SPARC: u64 = 0x09;
// Dictionary size constants
pub const DICT_SIZE_MIN: u32 = 4096;
pub const DICT_SIZE_MAX: u32 = 1 << 30; // 1GB
pub const DICT_SIZE_DEFAULT: u32 = 1 << 23; // 8MB
};ZIP Constants ​
zig
pub const ZipConstants = struct {
// Signatures
pub const LOCAL_FILE_HEADER_SIGNATURE: u32 = 0x04034b50;
pub const CENTRAL_DIRECTORY_HEADER_SIGNATURE: u32 = 0x02014b50;
pub const END_OF_CENTRAL_DIRECTORY_SIGNATURE: u32 = 0x06054b50;
pub const DATA_DESCRIPTOR_SIGNATURE: u32 = 0x08074b50;
// Header sizes
pub const LOCAL_FILE_HEADER_SIZE: usize = 30;
pub const CENTRAL_DIRECTORY_HEADER_SIZE: usize = 46;
pub const END_OF_CENTRAL_DIRECTORY_SIZE: usize = 22;
pub const DATA_DESCRIPTOR_SIZE: usize = 16;
// Compression methods
pub const METHOD_STORED: u16 = 0;
pub const METHOD_SHRUNK: u16 = 1;
pub const METHOD_REDUCED_1: u16 = 2;
pub const METHOD_REDUCED_2: u16 = 3;
pub const METHOD_REDUCED_3: u16 = 4;
pub const METHOD_REDUCED_4: u16 = 5;
pub const METHOD_IMPLODED: u16 = 6;
pub const METHOD_DEFLATED: u16 = 8;
pub const METHOD_DEFLATE64: u16 = 9;
pub const METHOD_BZIP2: u16 = 12;
pub const METHOD_LZMA: u16 = 14;
pub const METHOD_PPMD: u16 = 98;
// General purpose bit flags
pub const FLAG_ENCRYPTED: u16 = 0x0001;
pub const FLAG_DATA_DESCRIPTOR: u16 = 0x0008;
pub const FLAG_UTF8: u16 = 0x0800;
// Version constants
pub const VERSION_MADE_BY: u16 = 0x031E; // Version 3.1, Unix
pub const VERSION_NEEDED: u16 = 0x0014; // Version 2.0
// Limits
pub const MAX_COMMENT_SIZE: usize = 65535;
pub const MAX_FILENAME_SIZE: usize = 65535;
pub const MAX_EXTRA_SIZE: usize = 65535;
};TAR Constants ​
zig
pub const TarConstants = struct {
pub const BLOCK_SIZE: usize = 512;
pub const NAME_SIZE: usize = 100;
pub const MODE_SIZE: usize = 8;
pub const UID_SIZE: usize = 8;
pub const GID_SIZE: usize = 8;
pub const SIZE_SIZE: usize = 12;
pub const MTIME_SIZE: usize = 12;
pub const CHECKSUM_SIZE: usize = 8;
pub const LINKNAME_SIZE: usize = 100;
pub const MAGIC_SIZE: usize = 6;
pub const VERSION_SIZE: usize = 2;
pub const UNAME_SIZE: usize = 32;
pub const GNAME_SIZE: usize = 32;
pub const DEVMAJOR_SIZE: usize = 8;
pub const DEVMINOR_SIZE: usize = 8;
pub const PREFIX_SIZE: usize = 155;
// Magic values
pub const MAGIC_USTAR: [6]u8 = [_]u8{ 'u', 's', 't', 'a', 'r', 0 };
pub const VERSION_USTAR: [2]u8 = [_]u8{ '0', '0' };
// File types
pub const TYPE_REGULAR: u8 = '0';
pub const TYPE_REGULAR_ALT: u8 = 0;
pub const TYPE_LINK: u8 = '1';
pub const TYPE_SYMLINK: u8 = '2';
pub const TYPE_CHAR: u8 = '3';
pub const TYPE_BLOCK: u8 = '4';
pub const TYPE_DIRECTORY: u8 = '5';
pub const TYPE_FIFO: u8 = '6';
pub const TYPE_CONTIGUOUS: u8 = '7';
pub const TYPE_GNU_LONGNAME: u8 = 'L';
pub const TYPE_GNU_LONGLINK: u8 = 'K';
};Magic Byte Detection ​
Magic Byte Constants ​
zig
pub const MagicBytes = struct {
pub const GZIP: [2]u8 = GzipConstants.MAGIC_BYTES;
pub const ZSTD: [4]u8 = ZstdConstants.MAGIC_BYTES;
pub const LZ4: [4]u8 = Lz4Constants.MAGIC_BYTES;
pub const LZMA: [3]u8 = LzmaConstants.MAGIC_BYTES;
pub const XZ: [6]u8 = XzConstants.MAGIC_BYTES;
pub const ZIP: [4]u8 = [_]u8{ 0x50, 0x4B, 0x03, 0x04 };
// Zlib magic bytes (variable second byte)
pub const ZLIB_78_01: [2]u8 = [_]u8{ 0x78, 0x01 };
pub const ZLIB_78_5E: [2]u8 = [_]u8{ 0x78, 0x5E };
pub const ZLIB_78_9C: [2]u8 = [_]u8{ 0x78, 0x9C };
pub const ZLIB_78_DA: [2]u8 = [_]u8{ 0x78, 0xDA };
};Error Constants ​
Error Code Constants ​
zig
pub const ErrorConstants = struct {
pub const SUCCESS: i32 = 0;
pub const ERROR_GENERIC: i32 = -1;
pub const ERROR_OUT_OF_MEMORY: i32 = -2;
pub const ERROR_INVALID_DATA: i32 = -3;
pub const ERROR_CORRUPTED_STREAM: i32 = -4;
pub const ERROR_CHECKSUM_MISMATCH: i32 = -5;
pub const ERROR_UNSUPPORTED_ALGORITHM: i32 = -6;
pub const ERROR_INVALID_MAGIC: i32 = -7;
pub const ERROR_BUFFER_TOO_SMALL: i32 = -8;
pub const ERROR_COMPRESSION_FAILED: i32 = -9;
pub const ERROR_DECOMPRESSION_FAILED: i32 = -10;
};Platform Constants ​
Platform-Specific Constants ​
zig
pub const PlatformConstants = struct {
pub const PAGE_SIZE_DEFAULT: usize = 4096;
pub const PAGE_SIZE_LARGE: usize = 2 * 1024 * 1024; // 2MB
pub const CACHE_LINE_SIZE: usize = 64;
// Windows-specific
pub const WINDOWS_MAX_PATH: usize = 260;
pub const WINDOWS_LONG_PATH_PREFIX: []const u8 = "\\\\?\\";
// Unix-specific
pub const UNIX_MAX_PATH: usize = 4096;
pub const UNIX_PATH_SEPARATOR: u8 = '/';
// Cross-platform
pub const MAX_FILENAME_LENGTH: usize = 255;
};Usage Examples ​
Using Constants in Configuration ​
zig
const std = @import("std");
const archive = @import("archive");
pub fn constantsExample() !void {
// Use ZSTD constants for configuration
const zstd_config = archive.CompressionConfig.init(.zstd)
.withZstdLevel(archive.Constants.ZstdConstants.DEFAULT_LEVEL)
.withBufferSize(archive.Constants.DEFAULT_BUFFER_SIZE);
// Use LZ4 constants
const lz4_config = archive.CompressionConfig.init(.lz4)
.withLz4Level(archive.Constants.Lz4Constants.DEFAULT_LEVEL)
.withBufferSize(archive.Constants.Lz4Constants.BLOCK_SIZE_64KB);
// Use general constants
const buffer_size = std.math.clamp(
128 * 1024,
archive.Constants.MIN_BUFFER_SIZE,
archive.Constants.MAX_BUFFER_SIZE
);
std.debug.print("ZSTD default level: {d}\n", .{archive.Constants.ZstdConstants.DEFAULT_LEVEL});
std.debug.print("LZ4 default level: {d}\n", .{archive.Constants.Lz4Constants.DEFAULT_LEVEL});
std.debug.print("Clamped buffer size: {d}\n", .{buffer_size});
}Magic Byte Detection ​
zig
pub fn magicByteExample(data: []const u8) !void {
if (data.len < 2) return;
// Check for gzip
if (std.mem.eql(u8, data[0..2], &archive.Constants.MagicBytes.GZIP)) {
std.debug.print("Detected: Gzip\n", .{});
return;
}
// Check for ZSTD
if (data.len >= 4 and std.mem.eql(u8, data[0..4], &archive.Constants.MagicBytes.ZSTD)) {
std.debug.print("Detected: ZSTD\n", .{});
return;
}
// Check for LZ4
if (data.len >= 4 and std.mem.eql(u8, data[0..4], &archive.Constants.MagicBytes.LZ4)) {
std.debug.print("Detected: LZ4\n", .{});
return;
}
// Check for zlib (multiple possible second bytes)
if (data[0] == 0x78) {
const second_byte = data[1];
if (second_byte == 0x01 or second_byte == 0x5E or second_byte == 0x9C or second_byte == 0xDA) {
std.debug.print("Detected: Zlib\n", .{});
return;
}
}
std.debug.print("Unknown format\n", .{});
}Validation Using Constants ​
zig
pub fn validateConfiguration(config: archive.CompressionConfig) !void {
// Validate buffer size
if (config.buffer_size < archive.Constants.MIN_BUFFER_SIZE or
config.buffer_size > archive.Constants.MAX_BUFFER_SIZE) {
return error.InvalidBufferSize;
}
// Validate memory level
if (config.memory_level < archive.Constants.MIN_MEMORY_LEVEL or
config.memory_level > archive.Constants.MAX_MEMORY_LEVEL) {
return error.InvalidMemoryLevel;
}
// Validate algorithm-specific settings
switch (config.algorithm) {
.zstd => {
if (config.zstd_level) |level| {
if (level < archive.Constants.ZstdConstants.MIN_LEVEL or
level > archive.Constants.ZstdConstants.MAX_LEVEL) {
return error.InvalidZstdLevel;
}
}
},
.lz4 => {
if (config.lz4_level) |level| {
if (level < archive.Constants.Lz4Constants.MIN_LEVEL or
level > archive.Constants.Lz4Constants.MAX_LEVEL) {
return error.InvalidLz4Level;
}
}
},
else => {},
}
std.debug.print("Configuration is valid\n", .{});
}Best Practices ​
Constants Guidelines ​
- Use constants for validation - Validate inputs against defined limits
- Reference algorithm constants - Use algorithm-specific constants for configuration
- Check magic bytes - Use magic byte constants for format detection
- Respect platform limits - Use platform constants for cross-platform compatibility
- Validate ranges - Use min/max constants to validate user inputs
- Use default values - Reference default constants for sensible defaults
- Document limits - Constants serve as documentation for API limits
Common Patterns ​
zig
// Clamp values to valid ranges
const level = std.math.clamp(
user_level,
archive.Constants.ZstdConstants.MIN_LEVEL,
archive.Constants.ZstdConstants.MAX_LEVEL
);
// Use defaults when values are not specified
const buffer_size = user_buffer_size orelse archive.Constants.DEFAULT_BUFFER_SIZE;
// Validate against constants
if (window_size < archive.Constants.MIN_WINDOW_SIZE) {
return error.WindowSizeTooSmall;
}
// Format detection using magic bytes
const magic = data[0..4];
if (std.mem.eql(u8, magic, &archive.Constants.MagicBytes.ZSTD)) {
return .zstd;
}