Class: Omnizip::Formats::Rar::Rar5::Solid::SolidManager

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/formats/rar/rar5/solid/solid_manager.rb

Overview

Solid compression manager

This manager coordinates solid compression by:

  1. Collecting files into a SolidStream
  2. Compressing the entire stream with persistent dictionary
  3. Tracking file boundaries for extraction

The result is better compression ratios at the cost of:

  • Cannot extract individual files without decompressing entire solid block
  • Corruption in one file may affect others in the same block

Examples:

Create solid archive

manager = SolidManager.new(level: 5)
manager.add_file('file1.txt', data1)
manager.add_file('file2.txt', data2)
compressed = manager.compress_all

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ SolidManager

Initialize solid manager

Parameters:

  • options (Hash) (defaults to: {})

    Options

Options Hash (options):

  • :level (Integer)

    Compression level (1-5, default: 3)



38
39
40
41
42
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 38

def initialize(options = {})
  @level = options[:level] || 3
  @stream = SolidStream.new
  @encoder = SolidEncoder.new(level: @level)
end

Instance Attribute Details

#encoderSolidEncoder (readonly)

Returns Compression encoder.

Returns:



29
30
31
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 29

def encoder
  @encoder
end

#levelInteger (readonly)

Returns Compression level.

Returns:

  • (Integer)

    Compression level



32
33
34
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 32

def level
  @level
end

#streamSolidStream (readonly)

Returns File stream.

Returns:



26
27
28
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 26

def stream
  @stream
end

Instance Method Details

#add_file(filename, data, metadata = {}) ⇒ void

This method returns an undefined value.

Add file to solid block

Parameters:

  • filename (String)

    File name

  • data (String)

    File data

  • metadata (Hash) (defaults to: {})

    File metadata



50
51
52
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 50

def add_file(filename, data,  = {})
  @stream.add_file(filename, data, )
end

#clearvoid

This method returns an undefined value.

Clear all data



121
122
123
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 121

def clear
  @stream.clear
end

#compress_allHash

Compress all files in solid mode

Returns compressed data and file metadata needed for headers.

Parameters:

  • result (Hash)

    a customizable set of options

Returns:

  • (Hash)

    Compressed result



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 63

def compress_all
  # Get concatenated data
  data = @stream.concatenated_data

  # Compress entire stream
  compressed = @encoder.compress_stream(data)

  {
    compressed_data: compressed,
    compressed_size: compressed.bytesize,
    uncompressed_size: data.bytesize,
    files: @stream.files.dup,
  }
end

#compression_ratio(compressed_size) ⇒ Float

Calculate compression ratio

Parameters:

  • compressed_size (Integer)

    Compressed data size

Returns:

  • (Float)

    Compression ratio (0.0-1.0)



129
130
131
132
133
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 129

def compression_ratio(compressed_size)
  return 0.0 if total_size.zero?

  compressed_size.to_f / total_size
end

#extract_file(compressed_data, file_index) ⇒ String?

Decompress solid stream and extract file

Parameters:

  • compressed_data (String)

    Compressed data

  • file_index (Integer)

    File index to extract

Returns:

  • (String, nil)

    File data or nil if not found



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 83

def extract_file(compressed_data, file_index)
  # Validate index
  return nil if file_index.negative? || file_index >= @stream.file_count

  # Decompress entire stream
  decompressed = @encoder.decompress_stream(compressed_data)

  # Extract specific file
  file = @stream.file_at(file_index)
  return nil unless file

  decompressed[file[:offset], file[:size]]
end

#file_countInteger

Get file count

Returns:

  • (Integer)

    Number of files



100
101
102
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 100

def file_count
  @stream.file_count
end

#has_files?Boolean

Check if manager has files

Returns:

  • (Boolean)

    true if files added



114
115
116
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 114

def has_files?
  !@stream.empty?
end

#total_sizeInteger

Get total uncompressed size

Returns:

  • (Integer)

    Total size in bytes



107
108
109
# File 'lib/omnizip/formats/rar/rar5/solid/solid_manager.rb', line 107

def total_size
  @stream.total_size
end