Ruby API reference

Purpose

Complete reference for the Cabriolet Ruby API. Use this section to integrate Cabriolet into your Ruby applications with detailed class and method documentation.

Concepts

Cabriolet’s Ruby API follows object-oriented design principles with a consistent interface across all formats. Each format provides Decompressor and Compressor classes, along with model classes representing the archive structure.

Quick API reference

CAB Format

require 'cabriolet'

# Decompress
decompressor = Cabriolet::CAB::Decompressor.new('archive.cab')
decompressor.extract('output/')

# Compress
compressor = Cabriolet::CAB::Compressor.new(compression: :mszip)
compressor.add_file('file.txt')
compressor.write('new.cab')

CHM Format

require 'cabriolet'

# Decompress
decompressor = Cabriolet::CHM::Decompressor.new('help.chm')
decompressor.extract('output/')

SZDD Format

require 'cabriolet'

# Decompress
decompressor = Cabriolet::SZDD::Decompressor.new('notepad.ex_')
decompressor.extract('notepad.exe')

# Compress
compressor = Cabriolet::SZDD::Compressor.new
compressor.compress('notepad.exe', 'notepad.ex_')

Module Hierarchy

Cabriolet
├── CAB
│   ├── Decompressor
│   ├── Compressor
│   ├── Parser
│   └── Extractor
├── CHM
│   ├── Decompressor
│   ├── Compressor
│   └── Parser
├── SZDD
│   ├── Decompressor
│   ├── Compressor
│   └── Parser
├── KWAJ
│   ├── Decompressor
│   ├── Compressor
│   └── Parser
├── HLP
│   ├── Decompressor
│   ├── Compressor
│   └── Parser
├── LIT
│   ├── Decompressor
│   └── Compressor
├── OAB
│   ├── Decompressor
│   └── Compressor
├── Models
│   ├── Cabinet
│   ├── Folder
│   ├── File
│   ├── ChmHeader
│   ├── SzddHeader
│   ├── KwajHeader
│   ├── HlpHeader
│   └── LitHeader
├── System
│   ├── IOSystem
│   ├── FileHandle
│   └── MemoryHandle
├── Decompressors
│   ├── None
│   ├── LZSS
│   ├── MSZIP
│   ├── LZX
│   └── Quantum
└── Errors
    ├── Error
    ├── FormatError
    ├── CorruptionError
    ├── UnsupportedError
    └── IOError

Common patterns

Opening archives

All decompressors follow the same pattern:

# From file path
decompressor = Cabriolet::CAB::Decompressor.new('archive.cab')

# From file handle
File.open('archive.cab', 'rb') do |f|
  decompressor = Cabriolet::CAB::Decompressor.new(f)
end

# From IO object
io = StringIO.new(cab_data)
decompressor = Cabriolet::CAB::Decompressor.new(io)

Extracting files

# Extract all to directory
decompressor.extract('output/')

# Extract single file
decompressor.extract_file('readme.txt', 'output/readme.txt')

# Extract to memory
data = decompressor.extract_to_memory('file.dat')

# Iterate files
decompressor.each_file do |file|
  puts "#{file.name}: #{file.size} bytes"
end

Creating archives

# Create new archive
compressor = Cabriolet::CAB::Compressor.new

# Add files
compressor.add_file('readme.txt')
compressor.add_file('data.bin')

# Write to disk
compressor.write('archive.cab')

# Write to IO
output = StringIO.new
compressor.write(output)
cab_data = output.string

Error handling

require 'cabriolet'

begin
  decompressor = Cabriolet::CAB::Decompressor.new('archive.cab')
  decompressor.extract('output/')
rescue Cabriolet::FormatError => e
  puts "Invalid format: #{e.message}"
rescue Cabriolet::CorruptionError => e
  puts "Corrupted archive: #{e.message}"
rescue Cabriolet::IOError => e
  puts "I/O error: #{e.message}"
rescue Cabriolet::Error => e
  puts "Error: #{e.message}"
end

Thread Safety

Cabriolet classes are thread-safe for read operations:

  • Decompressors: Safe to use from multiple threads

  • Compressors: Not thread-safe, use one per thread

  • Models: Immutable after creation, safe to share

Performance considerations

Memory usage

# Low memory: Stream files one at a time
decompressor.each_file do |file|
  file.extract_to("output/#{file.name}")
end

# Higher memory: Load entire archive
cabinet = decompressor.cabinet
cabinet.files.each do |file|
  # Process files
end

I/O efficiency

# Efficient: Batch operations
compressor = Cabriolet::CAB::Compressor.new
Dir.glob('files/**/*').each do |path|
  compressor.add_file(path) if File.file?(path)
end
compressor.write('archive.cab')

# Inefficient: Multiple writes
Dir.glob('files/**/*').each do |path|
  compressor = Cabriolet::CAB::Compressor.new
  compressor.add_file(path)
  compressor.write("#{File.basename(path)}.cab")
end

API Conventions

Naming

  • Classes: CamelCase (e.g., Decompressor)

  • Methods: snake_case (e.g., extract_file)

  • Constants: SCREAMING_SNAKE_CASE (e.g., COMPRESSION_NONE)

Parameters

  • Required first: method(required, optional = default)

  • Options hash last: method(param, options = {})

  • Blocks accepted: Many methods accept blocks for iteration

Return values

  • Self for chaining: Modification methods return self

  • Enumerators: Iteration methods return enumerators if no block

  • Nil for side effects: Write operations return nil

Next steps


Table of contents