Class: Cabriolet::SZDD::Parser

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

Overview

Parser reads and parses SZDD file headers

SZDD files are single-file compressed archives using LZSS compression. There are two format variants:

  • NORMAL: Used by MS-DOS EXPAND.EXE (signature: SZDDx88xF0x27x33)

  • QBASIC: Used by QBasic (signature: SZDD x88xF0x27x33xD1)

Constant Summary collapse

COMPRESSION_MODE_NORMAL =

Expected compression mode for NORMAL format

0x41

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_system) ⇒ Parser

Initialize a new parser

Parameters:



20
21
22
# File 'lib/cabriolet/szdd/parser.rb', line 20

def initialize(io_system)
  @io_system = io_system
end

Instance Attribute Details

#io_systemObject (readonly)

Returns the value of attribute io_system.



12
13
14
# File 'lib/cabriolet/szdd/parser.rb', line 12

def io_system
  @io_system
end

Instance Method Details

#data_offset(format) ⇒ Integer

Get the data offset for the compressed data

Parameters:

  • format (Symbol)

    Format type (:normal or :qbasic)

Returns:

  • (Integer)

    Offset in bytes where compressed data starts



62
63
64
# File 'lib/cabriolet/szdd/parser.rb', line 62

def data_offset(format)
  format == Models::SZDDHeader::FORMAT_NORMAL ? 14 : 12
end

#parse(filename) ⇒ Models::SZDDHeader

Parse an SZDD file and return header information

Parameters:

  • filename (String)

    Path to the SZDD file

Returns:

Raises:

  • (Errors::ParseError)

    if the file is not a valid SZDD



29
30
31
32
33
34
# File 'lib/cabriolet/szdd/parser.rb', line 29

def parse(filename)
  handle = @io_system.open(filename, Constants::MODE_READ)
  header = parse_handle(handle, filename)
  @io_system.close(handle)
  header
end

#parse_handle(handle, filename = nil) ⇒ Models::SZDDHeader

Parse SZDD header from an already-open handle

Parameters:

Returns:

Raises:

  • (Errors::ParseError)

    if not a valid SZDD



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/cabriolet/szdd/parser.rb', line 42

def parse_handle(handle, filename = nil)
  # Read signature (8 bytes)
  signature = @io_system.read(handle, 8)
  raise ParseError, "Cannot read SZDD signature" if
    signature.bytesize < 8

  # Determine format based on signature
  if signature == Binary::SZDDStructures::SIGNATURE_NORMAL
    parse_normal_header(handle, filename)
  elsif signature == Binary::SZDDStructures::SIGNATURE_QBASIC
    parse_qbasic_header(handle, filename)
  else
    raise ParseError, "Invalid SZDD signature"
  end
end