Class: Omnizip::FormatDetector
- Inherits:
-
Object
- Object
- Omnizip::FormatDetector
- Defined in:
- lib/omnizip/format_detector.rb
Overview
Detects archive format from file signature/magic bytes
This class identifies archive formats based on their file signatures. It distinguishes between XZ Utils format (.xz) and 7-Zip format (.7z) which are DIFFERENT implementations of LZMA/LZMA2 compression.
Constant Summary collapse
- XZ_SIGNATURE =
XZ Utils format signature: "\xFD7zXZ\x00"
[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00].freeze
- SEVEN_ZIP_SIGNATURE =
7-Zip format signature: "7z\xBC\xAF\x27\x1C"
[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C].freeze
- RAR5_SIGNATURE =
RAR5 format signature: "Rar!\x1A\x07\x01\x00"
[0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00].freeze
- RAR4_SIGNATURE =
RAR4 format signature: "Rar!\x1A\x07\x00"
[0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00].freeze
- ZIP_SIGNATURE =
ZIP format signature: "PK\x03\x04"
[0x50, 0x4B, 0x03, 0x04].freeze
- GZIP_SIGNATURE =
GZIP format signature: "\x1F\x8B"
[0x1F, 0x8B].freeze
- BZIP2_SIGNATURE =
BZIP2 format signature: "BZ"
[0x42, 0x5A].freeze
- READER_FOR_FORMAT =
Mapping of detected format symbols to (extension, constant-path) tuples. The constant path is resolved lazily so autoload fires only when a format is actually requested.
{ xz: ["omnizip/formats/xz", "Omnizip::Formats::Xz"], seven_zip: ["omnizip/formats/seven_zip", "Omnizip::Formats::SevenZip::Reader"], rar5: ["omnizip/formats/rar5", "Omnizip::Formats::Rar5::Reader"], rar4: ["omnizip/formats/rar3", "Omnizip::Formats::Rar3::Reader"], zip: ["omnizip/formats/zip", "Omnizip::Formats::Zip::Reader"], gzip: ["omnizip/formats/gzip", "Omnizip::Formats::Gzip"], bzip2: ["omnizip/formats/bzip2_file", "Omnizip::Formats::Bzip2File"], }.freeze
Class Method Summary collapse
-
.detect(file_path) ⇒ Symbol?
Detect archive format from file path.
-
.rar4?(file_path) ⇒ Boolean
Check if file is RAR4 format.
-
.rar5?(file_path) ⇒ Boolean
Check if file is RAR5 format.
-
.reader_for(file_path) ⇒ Class?
Get the appropriate reader class for the format.
-
.seven_zip?(file_path) ⇒ Boolean
Check if file is 7-Zip format.
-
.xz?(file_path) ⇒ Boolean
Check if file is XZ Utils format.
Class Method Details
.detect(file_path) ⇒ Symbol?
Detect archive format from file path
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/omnizip/format_detector.rb', line 46 def self.detect(file_path) return nil unless File.exist?(file_path) header = File.binread(file_path, 16) return nil if header.nil? || header.empty? bytes = header.bytes case bytes in [0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, *] :xz in [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C, *] :seven_zip in [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00, *] :rar5 in [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00, *] :rar4 in [0x50, 0x4B, 0x03, 0x04, *] :zip in [0x1F, 0x8B, *] :gzip in [0x42, 0x5A, *] :bzip2 else # Check for LZMA_Alone format (13-byte header with properties) detect_lzma_alone(bytes) end end |
.rar4?(file_path) ⇒ Boolean
Check if file is RAR4 format
103 104 105 |
# File 'lib/omnizip/format_detector.rb', line 103 def self.rar4?(file_path) detect(file_path) == :rar4 end |
.rar5?(file_path) ⇒ Boolean
Check if file is RAR5 format
95 96 97 |
# File 'lib/omnizip/format_detector.rb', line 95 def self.rar5?(file_path) detect(file_path) == :rar5 end |
.reader_for(file_path) ⇒ Class?
Get the appropriate reader class for the format
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/omnizip/format_detector.rb', line 124 def self.reader_for(file_path) format = detect(file_path) return nil unless format mapping = READER_FOR_FORMAT[format] return nil unless mapping _path, const_path = mapping Object.const_get(const_path) end |
.seven_zip?(file_path) ⇒ Boolean
Check if file is 7-Zip format
87 88 89 |
# File 'lib/omnizip/format_detector.rb', line 87 def self.seven_zip?(file_path) detect(file_path) == :seven_zip end |
.xz?(file_path) ⇒ Boolean
Check if file is XZ Utils format
79 80 81 |
# File 'lib/omnizip/format_detector.rb', line 79 def self.xz?(file_path) detect(file_path) == :xz end |