Class: Omnizip::Formats::SevenZip::Writer

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/seven_zip/writer.rb

Overview

.7z archive writer - 7-Zip compatible implementation

Creates archives that are fully compatible with official 7-Zip (7zz command).

Archive structure:

  • Start Header (32 bytes)
  • LZMA2 compressed file data
  • UNCOMPRESSED Next Header metadata (properties: kHeader, kPackInfo, etc.)
  • Metadata footer (filename, attributes, timestamps)

Constant Summary collapse

COPY_MAIN_BYTE =

Constants for array literals used in loops (RuboCop Performance/CollectionLiteralInLoop)

[0x01].pack("C").freeze
COPY_METHOD_ID =
[0x00].pack("C").freeze
NULL_TERMINATOR =
[0x00, 0x00].pack("CC").freeze
FILE_ATTRIBUTE_ARCHIVE =
[0x20].pack("V").freeze

Constants included from Constants

Constants::MAJOR_VERSION, Constants::MAX_NUM_BONDS, Constants::MAX_NUM_CODERS, Constants::MAX_NUM_PACK_STREAMS, Constants::MINOR_VERSION, Constants::SIGNATURE, Constants::SIGNATURE_SIZE, Constants::START_HEADER_SIZE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output_path, options = {}) ⇒ Writer

Returns a new instance of Writer.



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 28

def initialize(output_path, options = {})
  @output_path = output_path
  @options = {
    algorithm: :lzma2,
    level: 5,
    dict_size: 8 * 1024 * 1024, # 8MB default dictionary
    solid: true, # Solid mode for LZMA2 compression
    filters: [],
    encrypt_headers: false,
  }.merge(options)
  @collector = FileCollector.new
  @entries = []
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries.



26
27
28
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 26

def entries
  @entries
end

#optionsObject (readonly)

Returns the value of attribute options.



26
27
28
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 26

def options
  @options
end

#output_pathObject (readonly)

Returns the value of attribute output_path.



26
27
28
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 26

def output_path
  @output_path
end

Instance Method Details

#add_data(archive_path, data, options = {}) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 55

def add_data(archive_path, data, options = {})
  data_str = data.is_a?(String) ? data : data.read

  entry = Models::FileEntry.new
  entry.name = archive_path
  entry.source_path = nil
  entry.size = data_str.bytesize
  entry.mtime = Time.now
  entry.has_stream = true
  entry.inline_data = data_str
  entry.compression_options = options
  @entries << entry
end

#add_directory(dir_path, recursive = true) ⇒ Object



47
48
49
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 47

def add_directory(dir_path, recursive = true)
  @collector.add_path(dir_path, recursive: recursive)
end

#add_file(file_path, archive_path = nil) ⇒ Object



42
43
44
45
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 42

def add_file(file_path, archive_path = nil)
  @collector.add_path(file_path, archive_path: archive_path,
                                 recursive: false)
end

#add_files(pattern) ⇒ Object



51
52
53
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 51

def add_files(pattern)
  @collector.add_glob(pattern)
end

#writeObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/omnizip/formats/seven_zip/writer.rb', line 69

def write
  # Collect any files from the collector (if add_file/add_directory was used)
  collected_entries = @collector.collect_files
  # Merge with entries added via add_data
  @entries.concat(collected_entries)

  # Check if split archive requested
  if @options[:volume_size]
    write_split_archive
  else
    File.open(@output_path, "wb") do |io|
      write_archive(io)
    end
  end
end