Class: Omnizip::Formats::SevenZip::StreamCompressor
- Inherits:
-
Object
- Object
- Omnizip::Formats::SevenZip::StreamCompressor
- Defined in:
- lib/omnizip/formats/seven_zip/stream_compressor.rb
Overview
Compresses data streams using coder chains Opposite of StreamDecompressor - applies compression algorithms
Instance Attribute Summary collapse
-
#algorithm ⇒ Object
readonly
Returns the value of attribute algorithm.
-
#filters ⇒ Object
readonly
Returns the value of attribute filters.
-
#level ⇒ Object
readonly
Returns the value of attribute level.
Instance Method Summary collapse
-
#compress(data) ⇒ String
Compress data.
-
#compress_files(file_entries) ⇒ Hash
Compress multiple files into single stream (solid compression).
-
#filter_ids ⇒ Array<Integer>
Get filter IDs for filter chain.
-
#initialize(algorithm: :lzma2, level: 5, filters: []) ⇒ StreamCompressor
constructor
Initialize compressor.
-
#method_id ⇒ Integer
Get method ID for this compression algorithm.
-
#properties ⇒ String?
Get properties for compression algorithm.
Constructor Details
#initialize(algorithm: :lzma2, level: 5, filters: []) ⇒ StreamCompressor
Initialize compressor
18 19 20 21 22 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 18 def initialize(algorithm: :lzma2, level: 5, filters: []) @algorithm = algorithm @level = level @filters = Array(filters) end |
Instance Attribute Details
#algorithm ⇒ Object (readonly)
Returns the value of attribute algorithm.
11 12 13 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 11 def algorithm @algorithm end |
#filters ⇒ Object (readonly)
Returns the value of attribute filters.
11 12 13 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 11 def filters @filters end |
#level ⇒ Object (readonly)
Returns the value of attribute level.
11 12 13 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 11 def level @level end |
Instance Method Details
#compress(data) ⇒ String
Compress data
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 28 def compress(data) result = data # Apply filters first @filters.each do |filter_sym| filter_class = FilterRegistry.get(filter_sym) next unless filter_class filter = filter_class.new input_io = StringIO.new(result) output_io = StringIO.new output_io.set_encoding("BINARY") filter.encode(input_io, output_io) result = output_io.string end # Apply compression algorithm if @algorithm && @algorithm != :copy algo_class = Omnizip::AlgorithmRegistry.get(@algorithm) raise "Algorithm not found: #{@algorithm}" unless algo_class encoder = algo_class.new input_io = StringIO.new(result) output_io = StringIO.new output_io.set_encoding("BINARY") # For 7-Zip format, use raw_mode (no property byte in compressed data) # The properties are encoded in the 7-Zip header instead encoder.compress(input_io, output_io, { raw_mode: true, standalone: false }) result = output_io.string end result end |
#compress_files(file_entries) ⇒ Hash
Compress multiple files into single stream (solid compression)
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 68 def compress_files(file_entries) # Concatenate all file data combined_data = String.new(encoding: "BINARY") unpack_sizes = [] crcs = [] file_entries.each do |entry| next unless entry.has_stream? && entry.source_path data = File.binread(entry.source_path) combined_data << data unpack_sizes << data.bytesize # Calculate CRC crc = Omnizip::Checksums::Crc32.new crc.update(data) crcs << crc.value end # Compress combined data packed_data = compress(combined_data) { packed_data: packed_data, packed_size: packed_data.bytesize, unpack_size: combined_data.bytesize, unpack_sizes: unpack_sizes, crcs: crcs, } end |
#filter_ids ⇒ Array<Integer>
Get filter IDs for filter chain
116 117 118 119 120 121 122 123 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 116 def filter_ids @filters.filter_map do |filter_sym| case filter_sym when :bcj_x86 then Constants::FilterId::BCJ_X86 when :delta then Constants::FilterId::DELTA end end end |
#method_id ⇒ Integer
Get method ID for this compression algorithm
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 102 def method_id case @algorithm when :copy then Constants::MethodId::COPY when :lzma then Constants::MethodId::LZMA when :lzma2 then Constants::MethodId::LZMA2 when :ppmd, :ppmd7 then Constants::MethodId::PPMD when :bzip2 then Constants::MethodId::BZIP2 else Constants::MethodId::LZMA2 end end |
#properties ⇒ String?
Get properties for compression algorithm
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/omnizip/formats/seven_zip/stream_compressor.rb', line 128 def properties return nil if @algorithm == :copy || @algorithm.nil? case @algorithm when :lzma2 # LZMA2 properties: dictionary size encoded dict_size = 1 << (15 + @level) prop = 0 prop += 1 while dict_size > (2 << prop) [prop].pack("C") when :lzma # LZMA properties: lc, lp, pb, dict_size lc = 3 lp = 0 pb = 2 dict_size = 1 << (15 + @level) [lc + (lp * 9) + (pb * 9 * 5)].pack("C") + [dict_size].pack("V") end end |