Class: Cabriolet::HLP::QuickHelp::Decompressor

Inherits:
Object
  • Object
show all
Defined in:
lib/cabriolet/hlp/quickhelp/decompressor.rb

Overview

Decompressor for QuickHelp (.HLP) files

Extracts and decompresses topics from QuickHelp databases. Topics can be extracted by index or context string.

Each topic contains formatted text lines with:

  • Text content

  • Style attributes (bold, italic, underline)

  • Hyperlinks to other topics or external contexts

  • Control commands (title, popup, etc.)

Constant Summary collapse

DEFAULT_BUFFER_SIZE =

Input buffer size for decompression

2048

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_system = nil, algorithm_factory = nil) ⇒ Decompressor

Initialize a new HLP decompressor



34
35
36
37
38
39
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 34

def initialize(io_system = nil, algorithm_factory = nil)
  @io_system = io_system || System::IOSystem.new
  @algorithm_factory = algorithm_factory || Cabriolet.algorithm_factory
  @parser = Parser.new(@io_system)
  @buffer_size = DEFAULT_BUFFER_SIZE
end

Instance Attribute Details

#buffer_sizeObject

Returns the value of attribute buffer_size.



24
25
26
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 24

def buffer_size
  @buffer_size
end

#io_systemObject (readonly)

Returns the value of attribute io_system.



23
24
25
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 23

def io_system
  @io_system
end

#parserObject (readonly)

Returns the value of attribute parser.



23
24
25
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 23

def parser
  @parser
end

Instance Method Details

#close(_header) ⇒ void

This method returns an undefined value.

Close an HLP file (no-op for compatibility)



56
57
58
59
60
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 56

def close(_header)
  # No resources to free in the header itself
  # File handles are managed separately during extraction
  nil
end

#extract_all(header, output_dir) ⇒ Integer

Extract all topics to a directory

Raises:

  • (Errors::DecompressionError)

    if extraction fails



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 189

def extract_all(header, output_dir)
  raise ArgumentError, "Header must not be nil" unless header

  unless output_dir
    raise ArgumentError,
          "Output directory must not be nil"
  end

  # Create output directory if needed
  FileUtils.mkdir_p(output_dir)

  extracted = 0
  header.topics.each_with_index do |topic, index|
    # Decompress and parse topic
    decompressed_data = decompress_topic(header, topic)
    parse_topic_text(topic, decompressed_data, header.control_char)

    # Write topic to file
    output_path = ::File.join(output_dir,
                              "topic_#{index.to_s.rjust(4, '0')}.txt")
    File.write(output_path, topic.plain_text)
    extracted += 1
  end

  extracted
end

#extract_file(header, hlp_file, output_path) ⇒ void

This method returns an undefined value.

Extract a file (topic) from HLP archive

This is a wrapper around extract_topic_text for API consistency with other format decompressors.

Raises:

  • (ArgumentError)

    if parameters are invalid

  • (Errors::DecompressionError)

    if extraction fails



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

def extract_file(header, hlp_file, output_path)
  raise ArgumentError, "Header must not be nil" unless header
  raise ArgumentError, "HLP file must not be nil" unless hlp_file
  raise ArgumentError, "Output path must not be nil" unless output_path

  # Find topic by file index
  topic = header.topics[hlp_file.index] if hlp_file.respond_to?(:index)
  if hlp_file.respond_to?(:offset)
    topic ||= header.topics.find do |t|
      t.offset == hlp_file.offset
    end
  end

  unless topic
    raise Errors::DecompressionError, "Topic not found for file"
  end

  # Extract topic text
  content = extract_topic_text(header, topic)

  # Write to output file
  File.write(output_path, content)
end

#extract_file_to_memory(header, hlp_file) ⇒ String

Extract a file (topic) to memory

This is a wrapper around extract_topic_text for API consistency with other format decompressors.

Raises:

  • (ArgumentError)

    if parameters are invalid

  • (Errors::DecompressionError)

    if extraction fails



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 107

def extract_file_to_memory(header, hlp_file)
  raise ArgumentError, "Header must not be nil" unless header
  raise ArgumentError, "HLP file must not be nil" unless hlp_file

  # Find topic by file index
  topic = header.topics[hlp_file.index] if hlp_file.respond_to?(:index)
  if hlp_file.respond_to?(:offset)
    topic ||= header.topics.find do |t|
      t.offset == hlp_file.offset
    end
  end

  unless topic
    raise Errors::DecompressionError, "Topic not found for file"
  end

  # Extract and return topic text
  extract_topic_text(header, topic)
end

#extract_topic_by_context(header, context_string) ⇒ String?

Extract topic text by context string

Raises:

  • (Errors::DecompressionError)

    if extraction fails



151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 151

def extract_topic_by_context(header, context_string)
  raise ArgumentError, "Header must not be nil" unless header

  unless context_string
    raise ArgumentError,
          "Context string must not be nil"
  end

  # Find topic index from context map
  topic_index = find_topic_index(header, context_string)
  return nil unless topic_index

  extract_topic_by_index(header, topic_index)
end

#extract_topic_by_index(header, topic_index) ⇒ String

Extract topic text by topic index

Raises:

  • (Errors::DecompressionError)

    if extraction fails



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 133

def extract_topic_by_index(header, topic_index)
  raise ArgumentError, "Header must not be nil" unless header

  if topic_index.negative? || topic_index >= header.topic_count
    raise ArgumentError,
          "Topic index out of range"
  end

  topic = header.topics[topic_index]
  extract_topic_text(header, topic)
end

#extract_topic_text(header, topic) ⇒ String

Extract and parse topic text with formatting

Raises:

  • (Errors::DecompressionError)

    if extraction fails



172
173
174
175
176
177
178
179
180
181
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 172

def extract_topic_text(header, topic)
  raise ArgumentError, "Header must not be nil" unless header
  raise ArgumentError, "Topic must not be nil" unless topic

  # Decompress and parse topic
  decompressed_data = decompress_topic(header, topic)
  parse_topic_text(topic, decompressed_data, header.control_char)

  topic.plain_text
end

#open(filename) ⇒ Models::HLPHeader

Open and parse an HLP file

Raises:

  • (Errors::ParseError)

    if the file is not a valid HLP



46
47
48
49
50
# File 'lib/cabriolet/hlp/quickhelp/decompressor.rb', line 46

def open(filename)
  header = @parser.parse(filename)
  header.filename = filename
  header
end