Class: Omnizip::Formats::Xz::Writer
- Inherits:
-
Object
- Object
- Omnizip::Formats::Xz::Writer
- Includes:
- Omnizip::Formats::XzConst
- Defined in:
- lib/omnizip/formats/xz/writer.rb
Overview
XZ format writer
Creates .xz files compatible with XZ Utils. Structure: Stream Header + Block(s) + Index + Stream Footer
Based on: xz/src/liblzma/common/stream_encoder.c
Constant Summary collapse
- HEADER_MAGIC =
XZ format magic bytes
[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00].freeze
- FOOTER_MAGIC =
[0x59, 0x5A].freeze
Constants included from Omnizip::Formats::XzConst
Omnizip::Formats::XzConst::BACKWARD_SIZE_MAX, Omnizip::Formats::XzConst::BACKWARD_SIZE_MIN, Omnizip::Formats::XzConst::BLOCK_HEADER_SIZE_MAX, Omnizip::Formats::XzConst::BLOCK_HEADER_SIZE_MIN, Omnizip::Formats::XzConst::CHECK_CRC32, Omnizip::Formats::XzConst::CHECK_CRC64, Omnizip::Formats::XzConst::CHECK_NONE, Omnizip::Formats::XzConst::CHECK_SHA256, Omnizip::Formats::XzConst::FILTERS_MAX, Omnizip::Formats::XzConst::FILTER_LZMA2, Omnizip::Formats::XzConst::INDEX_INDICATOR, Omnizip::Formats::XzConst::MAGIC, Omnizip::Formats::XzConst::STREAM_FLAGS_SIZE, Omnizip::Formats::XzConst::STREAM_FOOTER_SIZE, Omnizip::Formats::XzConst::STREAM_HEADER_SIZE, Omnizip::Formats::XzConst::VLI_BYTES_MAX, Omnizip::Formats::XzConst::VLI_UNKNOWN
Class Method Summary collapse
-
.create(filename, options = {}) {|writer| ... } ⇒ Object
Create XZ file with block given.
-
.encode_vli(value) ⇒ String
Encode VLI (variable-length integer).
Instance Method Summary collapse
-
#add_data(data) ⇒ Object
Add data block to stream.
-
#finalize ⇒ Object
Finalize XZ stream.
-
#initialize(output, options = {}) ⇒ Writer
constructor
Initialize XZ writer.
-
#write_block_from_encoder(block) ⇒ Object
Write block from BlockEncoder output.
-
#write_check_from_block(block) ⇒ Object
Write check value from block.
Constructor Details
#initialize(output, options = {}) ⇒ Writer
Initialize XZ writer
59 60 61 62 63 64 65 |
# File 'lib/omnizip/formats/xz/writer.rb', line 59 def initialize(output, = {}) @output = output @options = @blocks = [] write_stream_header end |
Class Method Details
.create(filename, options = {}) {|writer| ... } ⇒ Object
Create XZ file with block given
47 48 49 50 51 52 53 |
# File 'lib/omnizip/formats/xz/writer.rb', line 47 def self.create(filename, = {}) File.open(filename, "wb") do |f| writer = new(f, ) yield writer if block_given? writer.finalize end end |
.encode_vli(value) ⇒ String
Encode VLI (variable-length integer)
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/omnizip/formats/xz/writer.rb', line 130 def self.encode_vli(value) value bytes = [] loop do # Get low 7 bits byte = value & 0x7F value >>= 7 # Set continuation bit if there's more data byte |= 0x80 unless value.zero? bytes << byte break if value.zero? end bytes.pack("C*") end |
Instance Method Details
#add_data(data) ⇒ Object
Add data block to stream
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/omnizip/formats/xz/writer.rb', line 70 def add_data(data) # Use BlockEncoder for XZ Utils compatibility # This produces compressed blocks compatible with XZ Utils block_encoder = Omnizip::Formats::XzImpl::BlockEncoder.new( check_type: @options[:check_type] || CHECK_CRC64, dict_size: @options[:dict_size] || (64 * 1024 * 1024), # Use 64MB to match XZ Utils default include_block_sizes: true, # Include size fields for XZ Utils compatibility ) block = block_encoder.encode_block(data) # Store block info for index @blocks << { compressed: block[:data], actual_compressed_size: block[:compressed_size], uncompressed_data: data, uncompressed_size: block[:uncompressed_size], unpadded_size: block_encoder.unpadded_size, } # Write block using the encoded data from BlockEncoder write_block_from_encoder(block) end |
#finalize ⇒ Object
Finalize XZ stream
119 120 121 122 |
# File 'lib/omnizip/formats/xz/writer.rb', line 119 def finalize write_index end |
#write_block_from_encoder(block) ⇒ Object
Write block from BlockEncoder output
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/omnizip/formats/xz/writer.rb', line 97 def write_block_from_encoder(block) # Write block header (from BlockEncoder) @output.write(block[:header]) # Write compressed data @output.write(block[:data]) # Write padding (from BlockEncoder) @output.write(block[:padding]) # Write check (CRC64 of uncompressed data) write_check_from_block(block) end |
#write_check_from_block(block) ⇒ Object
Write check value from block
114 115 116 |
# File 'lib/omnizip/formats/xz/writer.rb', line 114 def write_check_from_block(block) @output.write(block[:check]) end |