Slide 44
Slide 44 text
1 class Gzip < BinData::Record
2 # Known compression methods
3 DEFLATE = 8
4
5 endian :little
6
7 uint16 :ident, asserted_value: 0x8b1f
8 uint8 :compression_method, asserted_value: DEFLATE
9
10 bit3 :freserved, asserted_value: 0
11 bit1 :fcomment
12 bit1 :ffile_name
13 bit1 :fextra
14 bit1 :fcrc16
15 bit1 :ftext
16
17 uint32 :mtime
18 uint8 :extra_flags
19 uint8 :os
20
21 struct :extra, onlyif: -> { fextra.nonzero? } do
22 uint16 :len
23 string :data, read_length: :len
24 end
25 stringz :file_name, onlyif: -> { ffile_name.nonzero? }
26 stringz :comment, onlyif: -> { fcomment.nonzero? }
27 uint16 :crc16, onlyif: -> { fcrc16.nonzero? }
28
29 # ignore rest so that we don't load everything into memory
30 end
1 def original_filename(file_path)
2 File.open(file_path, "rb") do |f|
3 header = f.read(10)
4 magic, cm, flg, mtime, xfl, os = header.unpack("H4H2B8LH2C")
5
6 (magic == "1f8b") || raise("Invalid gzip header")
7 (cm == "08") || raise("Unknown compression method")
8
9 _, _, _, fcomment, fname, fextra, fhcrc, ftext = flg.split("")
10
11 if fextra == "1"
12 xlen = f.read(2).unpack1("S")
13 f.seek(xlen, IO::SEEK_CUR)
14 end
15
16 f.gets("\x00").unpack1("Z*") if fname == "1"
17 end
18 end