Module: Omnizip::Formats::Gzip
- Defined in:
- lib/omnizip/formats/gzip.rb
Overview
GZIP compression format
GZIP is a file compression format that wraps Deflate compression with a 10-byte header and 8-byte footer containing CRC32 and uncompressed size.
Format structure:
- Header (10 bytes minimum):
- Magic bytes: 0x1F 0x8B
- Compression method: 0x08 (Deflate)
- Flags
- Modification time (4 bytes)
- Extra flags
- OS type
- Compressed data (Deflate)
- Footer (8 bytes):
- CRC32 (4 bytes)
- Uncompressed size (4 bytes, modulo 2^32)
Constant Summary collapse
- GZIP_MAGIC =
GZIP magic bytes
[0x1F, 0x8B].pack("C*")
- CM_DEFLATE =
Compression method (Deflate)
8- FTEXT =
Flag bits
0x01- FHCRC =
File is text
0x02- FEXTRA =
Header CRC present
0x04- FNAME =
Extra fields present
0x08- FCOMMENT =
Original filename present
0x10- OS_FAT =
OS types
0- OS_UNIX =
FAT filesystem
3- OS_UNKNOWN =
Unix
255
Class Method Summary collapse
-
.compress(input_path, output_path, options = {}) ⇒ Object
Compress a file with GZIP.
-
.compress_stream(input_io, output_io, options = {}) ⇒ Object
Compress data stream with GZIP.
-
.decompress(input_path, output_path) ⇒ Object
Decompress a GZIP file.
-
.decompress_stream(input_io, output_io) ⇒ Hash
Decompress GZIP stream.
-
.register! ⇒ Object
Register GZIP format when loaded.
Class Method Details
.compress(input_path, output_path, options = {}) ⇒ Object
Compress a file with GZIP
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/omnizip/formats/gzip.rb', line 54 def compress(input_path, output_path, = {}) input_data = File.binread(input_path) File.open(output_path, "wb") do |output| original_name = [:original_name] || File.basename(input_path) compress_stream( StringIO.new(input_data), output, .merge(original_name: original_name), ) end end |
.compress_stream(input_io, output_io, options = {}) ⇒ Object
Compress data stream with GZIP
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/omnizip/formats/gzip.rb', line 85 def compress_stream(input_io, output_io, = {}) input_data = input_io.read level = [:level] || Zlib::DEFAULT_COMPRESSION mtime = [:mtime] || Time.now original_name = [:original_name] # Write GZIP header write_header(output_io, mtime, original_name) # Compress data with Deflate deflate = Zlib::Deflate.new( level, Zlib::MAX_WBITS + 16, # Use GZIP wrapper ) compressed = deflate.deflate(input_data, Zlib::FINISH) deflate.close # Extract just the compressed data (remove zlib's GZIP wrapper) # We'll write our own footer output_io.write(compressed[0...-8]) if compressed.bytesize > 8 # Write GZIP footer (output_io, input_data) end |
.decompress(input_path, output_path) ⇒ Object
Decompress a GZIP file
72 73 74 75 76 77 78 |
# File 'lib/omnizip/formats/gzip.rb', line 72 def decompress(input_path, output_path) File.open(input_path, "rb") do |input| File.open(output_path, "wb") do |output| decompress_stream(input, output) end end end |
.decompress_stream(input_io, output_io) ⇒ Hash
Decompress GZIP stream
115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/omnizip/formats/gzip.rb', line 115 def decompress_stream(input_io, output_io) # Read and parse header = read_header(input_io) # Decompress with Deflate inflate = Zlib::Inflate.new(Zlib::MAX_WBITS + 16) decompressed = inflate.inflate(input_io.read) inflate.close # Write decompressed data output_io.write(decompressed) end |
.register! ⇒ Object
Register GZIP format when loaded
131 132 133 134 |
# File 'lib/omnizip/formats/gzip.rb', line 131 def register! FormatRegistry.register(".gz", Omnizip::Formats::Gzip) FormatRegistry.register(".gzip", Omnizip::Formats::Gzip) end |