Class: Cabriolet::FormatDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/cabriolet/format_detector.rb

Overview

Detects archive format based on magic bytes and file structure

Constant Summary collapse

MAGIC_SIGNATURES =

Magic byte signatures for supported formats

{
  "MSCF" => :cab,
  "ITSF" => :chm,
  "\x3F\x5F" => :hlp,       # ?_
  "\x4C\x4E" => :hlp,       # LN (alternative HLP signature)
  "KWAJ" => :kwaj,
  "SZDD" => :szdd,
  "\x88\xF0\x27\x00" => :szdd, # Alternative SZDD signature
  "ITOLITLS" => :lit,
  "\x00\x00\x00\x00" => :oab, # OAB has null header start
}.freeze
EXTENSION_MAP =

File extension to format mapping (fallback)

{
  ".cab" => :cab,
  ".chm" => :chm,
  ".hlp" => :hlp,
  ".kwj" => :kwaj,
  ".kwaj" => :kwaj,
  ".lit" => :lit,
  ".oab" => :oab,
  ".szdd" => :szdd,
}.freeze

Class Method Summary collapse

Class Method Details

.detect(path) ⇒ Symbol?

Detect format from file path

Parameters:

  • path (String)

    Path to the archive file

Returns:

  • (Symbol, nil)

    Detected format or nil if unknown



36
37
38
39
40
41
42
43
44
45
# File 'lib/cabriolet/format_detector.rb', line 36

def detect(path)
  return nil unless File.exist?(path)

  # Try magic byte detection first
  format = detect_by_magic_bytes(path)
  return format if format

  # Fallback to extension-based detection
  detect_by_extension(path)
end

.detect_from_io(io) ⇒ Symbol?

Detect format from IO stream

Parameters:

  • io (IO)

    IO object to read from

Returns:

  • (Symbol, nil)

    Detected format or nil if unknown



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/cabriolet/format_detector.rb', line 51

def detect_from_io(io)
  original_pos = io.pos

  # Read first 16 bytes for magic byte checking
  magic_bytes = io.read(16)
  io.seek(original_pos) if original_pos

  return nil unless magic_bytes && magic_bytes.size >= 4

  detect_magic_bytes(magic_bytes)
end

.format_to_parser(format) ⇒ Class?

Convert format symbol to parser class

Parameters:

  • format (Symbol)

    Format symbol

Returns:

  • (Class, nil)

    Parser class



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/cabriolet/format_detector.rb', line 76

def format_to_parser(format)
  case format
  when :cab
    Cabriolet::CAB::Parser
  when :chm
    Cabriolet::CHM::Parser
  when :hlp
    Cabriolet::HLP::Parser
  when :kwaj
    Cabriolet::KWAJ::Parser
  when :szdd
    Cabriolet::SZDD::Parser
  when :lit
    # LIT parser to be implemented
    nil
  when :oab
    # OAB parser to be implemented
    nil
  end
end

.parser_for(path) ⇒ Class?

Detect format and return appropriate parser class

Parameters:

  • path (String)

    Path to the archive file

Returns:

  • (Class, nil)

    Parser class or nil if unknown format



67
68
69
70
# File 'lib/cabriolet/format_detector.rb', line 67

def parser_for(path)
  format = detect(path)
  format_to_parser(format) if format
end