cabriolet 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cabriolet/algorithm_factory.rb +2 -2
- data/lib/cabriolet/base_compressor.rb +6 -6
- data/lib/cabriolet/cab/decompressor.rb +4 -4
- data/lib/cabriolet/cab/extractor.rb +10 -3
- data/lib/cabriolet/cab/parser.rb +3 -0
- data/lib/cabriolet/cli.rb +4 -4
- data/lib/cabriolet/decompressors/lzx.rb +20 -1
- data/lib/cabriolet/decompressors/mszip.rb +15 -0
- data/lib/cabriolet/decompressors/quantum.rb +33 -34
- data/lib/cabriolet/file_manager.rb +4 -4
- data/lib/cabriolet/format_base.rb +4 -4
- data/lib/cabriolet/hlp/compressor.rb +2 -2
- data/lib/cabriolet/plugin.rb +2 -2
- data/lib/cabriolet/streaming.rb +2 -2
- data/lib/cabriolet/validator.rb +2 -2
- data/lib/cabriolet/version.rb +1 -1
- data/lib/cabriolet.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb8a4d045d1bc49ab6448b9d1890524386e743d27249ad5dd5c5e630140e8a20
|
|
4
|
+
data.tar.gz: c63202e8fe947a0d14b3f4ffaca42feae67dc04e392ce3f9eac00d90ab0293b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6f6111054718818537222c48d986ef6a6112c89b9ea019ba748176402142316e7c2eef54979904e3bc7078f8d3b809193afcfe4acf971e9498d5cf4e7c4020dd
|
|
7
|
+
data.tar.gz: 8c0f0b712a10a5751f267cb67afe3c7d369ef6f06df0f961a2e92168f288c667fd97503e4fbfb95531898a8fec4303202e29b093814618c0065a7fbba8e3701f
|
|
@@ -91,7 +91,7 @@ module Cabriolet
|
|
|
91
91
|
# compressor = factory.create(3, :compressor,
|
|
92
92
|
# io, input, output, 8192)
|
|
93
93
|
def create(type, category, io_system, input, output, buffer_size,
|
|
94
|
-
**
|
|
94
|
+
**)
|
|
95
95
|
validate_category!(category)
|
|
96
96
|
|
|
97
97
|
normalized_type = normalize_type(type)
|
|
@@ -103,7 +103,7 @@ module Cabriolet
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
algorithm_info[:class].new(io_system, input, output, buffer_size,
|
|
106
|
-
**
|
|
106
|
+
**)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# Check if an algorithm is registered
|
|
@@ -57,8 +57,8 @@ module Cabriolet
|
|
|
57
57
|
# @param options [Hash] Format-specific options
|
|
58
58
|
# @return [FileEntry] Added entry
|
|
59
59
|
# @raise [ArgumentError] if file doesn't exist
|
|
60
|
-
def add_file(source_path, archive_path = nil, **
|
|
61
|
-
@file_manager.add_file(source_path, archive_path, **
|
|
60
|
+
def add_file(source_path, archive_path = nil, **)
|
|
61
|
+
@file_manager.add_file(source_path, archive_path, **)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# Add file from memory to archive
|
|
@@ -67,8 +67,8 @@ module Cabriolet
|
|
|
67
67
|
# @param archive_path [String] Path in archive
|
|
68
68
|
# @param options [Hash] Format-specific options
|
|
69
69
|
# @return [FileEntry] Added entry
|
|
70
|
-
def add_data(data, archive_path, **
|
|
71
|
-
@file_manager.add_data(data, archive_path, **
|
|
70
|
+
def add_data(data, archive_path, **)
|
|
71
|
+
@file_manager.add_data(data, archive_path, **)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Generate archive (Template Method)
|
|
@@ -165,7 +165,7 @@ module Cabriolet
|
|
|
165
165
|
# @option options [Integer] :window_bits Window size in bits
|
|
166
166
|
# @option options [Integer] :mode Algorithm mode
|
|
167
167
|
# @return [String] Compressed data
|
|
168
|
-
def compress_data(data, algorithm:, **
|
|
168
|
+
def compress_data(data, algorithm:, **)
|
|
169
169
|
input = System::MemoryHandle.new(data)
|
|
170
170
|
output = System::MemoryHandle.new("", Constants::MODE_WRITE)
|
|
171
171
|
|
|
@@ -176,7 +176,7 @@ module Cabriolet
|
|
|
176
176
|
input,
|
|
177
177
|
output,
|
|
178
178
|
data.bytesize,
|
|
179
|
-
|
|
179
|
+
**,
|
|
180
180
|
)
|
|
181
181
|
|
|
182
182
|
compressor.compress
|
|
@@ -36,9 +36,9 @@ module Cabriolet
|
|
|
36
36
|
# @param output_path [String] Where to write the file
|
|
37
37
|
# @param options [Hash] Extraction options
|
|
38
38
|
# @return [Integer] Number of bytes extracted
|
|
39
|
-
def extract_file(file, output_path, **
|
|
39
|
+
def extract_file(file, output_path, **)
|
|
40
40
|
extractor = Extractor.new(@io_system, self)
|
|
41
|
-
extractor.extract_file(file, output_path, **
|
|
41
|
+
extractor.extract_file(file, output_path, **)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Extract all files from the cabinet
|
|
@@ -47,9 +47,9 @@ module Cabriolet
|
|
|
47
47
|
# @param output_dir [String] Directory to extract to
|
|
48
48
|
# @param options [Hash] Extraction options
|
|
49
49
|
# @return [Integer] Number of files extracted
|
|
50
|
-
def extract_all(cabinet, output_dir, **
|
|
50
|
+
def extract_all(cabinet, output_dir, **)
|
|
51
51
|
extractor = Extractor.new(@io_system, self)
|
|
52
|
-
extractor.extract_all(cabinet, output_dir, **
|
|
52
|
+
extractor.extract_all(cabinet, output_dir, **)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# Create appropriate decompressor for a folder
|
|
@@ -60,7 +60,8 @@ module Cabriolet
|
|
|
60
60
|
begin
|
|
61
61
|
write_file_data(output_fh, filelen)
|
|
62
62
|
rescue DecompressionError
|
|
63
|
-
handle_extraction_error(output_fh, output_path, file.filename,
|
|
63
|
+
handle_extraction_error(output_fh, output_path, file.filename,
|
|
64
|
+
salvage, filelen)
|
|
64
65
|
ensure
|
|
65
66
|
output_fh.close
|
|
66
67
|
end
|
|
@@ -72,6 +73,7 @@ module Cabriolet
|
|
|
72
73
|
def reset_state
|
|
73
74
|
@current_input&.close
|
|
74
75
|
@current_input = nil
|
|
76
|
+
@current_decomp&.free # Free decompressor buffers to prevent memory leaks
|
|
75
77
|
@current_decomp = nil
|
|
76
78
|
@current_folder = nil
|
|
77
79
|
@current_offset = 0
|
|
@@ -136,6 +138,9 @@ module Cabriolet
|
|
|
136
138
|
warn "Salvage: #{failed_count} file(s) skipped due to extraction errors" if failed_count.positive?
|
|
137
139
|
|
|
138
140
|
count
|
|
141
|
+
ensure
|
|
142
|
+
# Clean up resources to prevent memory leaks
|
|
143
|
+
reset_state
|
|
139
144
|
end
|
|
140
145
|
|
|
141
146
|
private
|
|
@@ -264,7 +269,8 @@ module Cabriolet
|
|
|
264
269
|
# @param filelen [Integer] Number of bytes to write
|
|
265
270
|
def write_file_data(output_fh, filelen)
|
|
266
271
|
unless @current_decomp
|
|
267
|
-
raise DecompressionError,
|
|
272
|
+
raise DecompressionError,
|
|
273
|
+
"Decompressor not available (state was reset)"
|
|
268
274
|
end
|
|
269
275
|
|
|
270
276
|
@current_decomp.instance_variable_set(:@output, output_fh)
|
|
@@ -279,7 +285,8 @@ module Cabriolet
|
|
|
279
285
|
# @param filename [String] Filename for error messages
|
|
280
286
|
# @param salvage [Boolean] Salvage mode flag
|
|
281
287
|
# @raise [DecompressionError] If not in salvage mode
|
|
282
|
-
def handle_extraction_error(output_fh, output_path, filename, salvage,
|
|
288
|
+
def handle_extraction_error(output_fh, output_path, filename, salvage,
|
|
289
|
+
_filelen)
|
|
283
290
|
output_fh.close
|
|
284
291
|
if salvage
|
|
285
292
|
::File.write(output_path, "", mode: "wb")
|
data/lib/cabriolet/cab/parser.rb
CHANGED
data/lib/cabriolet/cli.rb
CHANGED
|
@@ -422,11 +422,11 @@ module Cabriolet
|
|
|
422
422
|
# @param command [Symbol] Command to execute
|
|
423
423
|
# @param file [String] File path
|
|
424
424
|
# @param args [Array] Additional arguments
|
|
425
|
-
def run_dispatcher(command, file,
|
|
425
|
+
def run_dispatcher(command, file, *, **options)
|
|
426
426
|
setup_verbose(options[:verbose])
|
|
427
427
|
|
|
428
428
|
dispatcher = Commands::CommandDispatcher.new(**options)
|
|
429
|
-
dispatcher.dispatch(command, file,
|
|
429
|
+
dispatcher.dispatch(command, file, *, **options)
|
|
430
430
|
end
|
|
431
431
|
|
|
432
432
|
# Run command with explicit format override
|
|
@@ -435,12 +435,12 @@ module Cabriolet
|
|
|
435
435
|
# @param format [Symbol] Format to force
|
|
436
436
|
# @param file [String] File path
|
|
437
437
|
# @param args [Array] Additional arguments
|
|
438
|
-
def run_with_format(command, format, file,
|
|
438
|
+
def run_with_format(command, format, file, *, **options)
|
|
439
439
|
setup_verbose(options[:verbose])
|
|
440
440
|
options[:format] = format.to_s
|
|
441
441
|
|
|
442
442
|
dispatcher = Commands::CommandDispatcher.new(**options)
|
|
443
|
-
dispatcher.dispatch(command, file,
|
|
443
|
+
dispatcher.dispatch(command, file, *, **options)
|
|
444
444
|
end
|
|
445
445
|
|
|
446
446
|
# Detect format from output file extension
|
|
@@ -178,6 +178,23 @@ module Cabriolet
|
|
|
178
178
|
@output_length = length if length.positive?
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
+
# Free resources used by the decompressor
|
|
182
|
+
#
|
|
183
|
+
# Releases large memory buffers to prevent memory leaks when
|
|
184
|
+
# the decompressor is no longer needed.
|
|
185
|
+
#
|
|
186
|
+
# @return [void]
|
|
187
|
+
def free
|
|
188
|
+
@window = nil
|
|
189
|
+
@e8_buf = nil
|
|
190
|
+
@pending_frame_data = nil
|
|
191
|
+
@bitstream = nil
|
|
192
|
+
@maintree_lengths = nil
|
|
193
|
+
@length_lengths = nil
|
|
194
|
+
@pretree_lengths = nil
|
|
195
|
+
@aligned_lengths = nil
|
|
196
|
+
end
|
|
197
|
+
|
|
181
198
|
# Decompress LZX data
|
|
182
199
|
#
|
|
183
200
|
# Per libmspack lzxd.c: the decompressor always decodes full frames
|
|
@@ -201,7 +218,9 @@ module Cabriolet
|
|
|
201
218
|
if @pending_frame_data
|
|
202
219
|
avail = @pending_frame_data.bytesize - @pending_frame_offset
|
|
203
220
|
write_amount = [bytes, avail].min
|
|
204
|
-
io_system.write(output,
|
|
221
|
+
io_system.write(output,
|
|
222
|
+
@pending_frame_data[@pending_frame_offset,
|
|
223
|
+
write_amount])
|
|
205
224
|
total_written += write_amount
|
|
206
225
|
@offset += write_amount
|
|
207
226
|
@pending_frame_offset += write_amount
|
|
@@ -83,6 +83,21 @@ salvage: false, **_kwargs)
|
|
|
83
83
|
@debug_mszip_symbols = ENV.fetch("DEBUG_MSZIP_SYMBOLS", nil)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
# Free resources used by the decompressor
|
|
87
|
+
#
|
|
88
|
+
# Releases memory buffers to prevent memory leaks when
|
|
89
|
+
# the decompressor is no longer needed.
|
|
90
|
+
#
|
|
91
|
+
# @return [void]
|
|
92
|
+
def free
|
|
93
|
+
@window = nil
|
|
94
|
+
@bitstream = nil
|
|
95
|
+
@literal_lengths = nil
|
|
96
|
+
@distance_lengths = nil
|
|
97
|
+
@literal_tree = nil
|
|
98
|
+
@distance_tree = nil
|
|
99
|
+
end
|
|
100
|
+
|
|
86
101
|
# Decompress MSZIP data
|
|
87
102
|
#
|
|
88
103
|
# @param bytes [Integer] Number of bytes to decompress
|
|
@@ -2,30 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "../quantum_shared"
|
|
4
4
|
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Build new string content
|
|
15
|
-
prefix = byteslice(0, index)
|
|
16
|
-
middle = other_string.byteslice(other_index, other_length)
|
|
17
|
-
suffix = byteslice((index + length)..-1)
|
|
18
|
-
new_content = prefix + middle + suffix
|
|
19
|
-
|
|
20
|
-
# Modify receiver in place
|
|
21
|
-
clear
|
|
22
|
-
self << new_content
|
|
23
|
-
|
|
24
|
-
self
|
|
5
|
+
# Helper for 5-argument bytesplice (added in Ruby 3.3)
|
|
6
|
+
# Ruby 3.2 has bytesplice but only 2-3 argument forms
|
|
7
|
+
unless String.method_defined?(:window_splice)
|
|
8
|
+
class String
|
|
9
|
+
# Copy bytes from source string into self at specified position
|
|
10
|
+
# Works on all Ruby versions including 3.2 which lacks 5-arg bytesplice
|
|
11
|
+
def window_splice(dest_idx, dest_len, src, src_idx, src_len)
|
|
12
|
+
self[dest_idx, dest_len] = src.byteslice(src_idx, src_len)
|
|
25
13
|
end
|
|
26
14
|
end
|
|
27
|
-
|
|
28
|
-
String.prepend(StringBytespliceCompat)
|
|
29
15
|
end
|
|
30
16
|
|
|
31
17
|
module Cabriolet
|
|
@@ -61,11 +47,7 @@ module Cabriolet
|
|
|
61
47
|
@window_size = 1 << window_bits
|
|
62
48
|
|
|
63
49
|
# Initialize window (must be binary to avoid UTF-8 character vs byte mismatch)
|
|
64
|
-
@window =
|
|
65
|
-
("\0" * @window_size).b
|
|
66
|
-
else
|
|
67
|
-
String.new("\0" * @window_size, encoding: Encoding::BINARY)
|
|
68
|
-
end
|
|
50
|
+
@window = ("\0" * @window_size).b
|
|
69
51
|
@window_posn = 0
|
|
70
52
|
@frame_todo = FRAME_SIZE
|
|
71
53
|
|
|
@@ -82,6 +64,21 @@ module Cabriolet
|
|
|
82
64
|
initialize_models
|
|
83
65
|
end
|
|
84
66
|
|
|
67
|
+
# Free resources used by the decompressor
|
|
68
|
+
#
|
|
69
|
+
# Releases memory buffers to prevent memory leaks when
|
|
70
|
+
# the decompressor is no longer needed.
|
|
71
|
+
#
|
|
72
|
+
# @return [void]
|
|
73
|
+
def free
|
|
74
|
+
@window = nil
|
|
75
|
+
@bitstream = nil
|
|
76
|
+
@m0sym = @m1sym = @m2sym = @m3sym = nil
|
|
77
|
+
@m4sym = @m5sym = @m6sym = @m6lsym = nil
|
|
78
|
+
@model0 = @model1 = @model2 = @model3 = nil
|
|
79
|
+
@model4 = @model5 = @model6 = @model6len = nil
|
|
80
|
+
end
|
|
81
|
+
|
|
85
82
|
# Decompress Quantum data
|
|
86
83
|
#
|
|
87
84
|
# @param bytes [Integer] Number of bytes to decompress
|
|
@@ -402,7 +399,7 @@ module Cabriolet
|
|
|
402
399
|
end
|
|
403
400
|
end
|
|
404
401
|
|
|
405
|
-
# Bulk copy using
|
|
402
|
+
# Bulk copy using window_splice for better performance on longer matches
|
|
406
403
|
def copy_match_bulk(offset, length)
|
|
407
404
|
if offset > @window_posn
|
|
408
405
|
# Match wraps around window
|
|
@@ -417,21 +414,23 @@ module Cabriolet
|
|
|
417
414
|
|
|
418
415
|
if copy_len < length
|
|
419
416
|
# Copy from end, then from beginning
|
|
420
|
-
@window.
|
|
421
|
-
|
|
417
|
+
@window.window_splice(@window_posn, copy_len, @window, src_pos,
|
|
418
|
+
copy_len)
|
|
422
419
|
@window_posn += copy_len
|
|
423
420
|
remaining = length - copy_len
|
|
424
|
-
@window.
|
|
421
|
+
@window.window_splice(@window_posn, remaining, @window, 0,
|
|
422
|
+
remaining)
|
|
425
423
|
@window_posn += remaining
|
|
426
424
|
else
|
|
427
425
|
# Copy entirely from end
|
|
428
|
-
@window.
|
|
426
|
+
@window.window_splice(@window_posn, length, @window, src_pos,
|
|
427
|
+
length)
|
|
429
428
|
@window_posn += length
|
|
430
429
|
end
|
|
431
430
|
else
|
|
432
|
-
# Normal copy - use
|
|
431
|
+
# Normal copy - use window_splice for bulk operation
|
|
433
432
|
src_pos = @window_posn - offset
|
|
434
|
-
@window.
|
|
433
|
+
@window.window_splice(@window_posn, length, @window, src_pos, length)
|
|
435
434
|
@window_posn += length
|
|
436
435
|
end
|
|
437
436
|
end
|
|
@@ -29,13 +29,13 @@ module Cabriolet
|
|
|
29
29
|
# @param options [Hash] Format-specific options
|
|
30
30
|
# @return [FileEntry] Added entry
|
|
31
31
|
# @raise [ArgumentError] if file doesn't exist
|
|
32
|
-
def add_file(source_path, archive_path = nil, **
|
|
32
|
+
def add_file(source_path, archive_path = nil, **)
|
|
33
33
|
archive_path ||= File.basename(source_path)
|
|
34
34
|
|
|
35
35
|
entry = FileEntry.new(
|
|
36
36
|
source: source_path,
|
|
37
37
|
archive_path: archive_path,
|
|
38
|
-
|
|
38
|
+
**,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
@entries << entry
|
|
@@ -48,11 +48,11 @@ module Cabriolet
|
|
|
48
48
|
# @param archive_path [String] Path in archive
|
|
49
49
|
# @param options [Hash] Format-specific options
|
|
50
50
|
# @return [FileEntry] Added entry
|
|
51
|
-
def add_data(data, archive_path, **
|
|
51
|
+
def add_data(data, archive_path, **)
|
|
52
52
|
entry = FileEntry.new(
|
|
53
53
|
data: data,
|
|
54
54
|
archive_path: archive_path,
|
|
55
|
-
|
|
55
|
+
**,
|
|
56
56
|
)
|
|
57
57
|
|
|
58
58
|
@entries << entry
|
|
@@ -44,7 +44,7 @@ module Cabriolet
|
|
|
44
44
|
# @param size [Integer] Data size
|
|
45
45
|
# @param options [Hash] Additional options for the compressor
|
|
46
46
|
# @return [Object] Compressor instance
|
|
47
|
-
def create_compressor(algorithm, input, output, size, **
|
|
47
|
+
def create_compressor(algorithm, input, output, size, **)
|
|
48
48
|
@algorithm_factory.create(
|
|
49
49
|
algorithm,
|
|
50
50
|
:compressor,
|
|
@@ -52,7 +52,7 @@ module Cabriolet
|
|
|
52
52
|
input,
|
|
53
53
|
output,
|
|
54
54
|
size,
|
|
55
|
-
|
|
55
|
+
**,
|
|
56
56
|
)
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -64,7 +64,7 @@ module Cabriolet
|
|
|
64
64
|
# @param size [Integer] Data size
|
|
65
65
|
# @param options [Hash] Additional options for the decompressor
|
|
66
66
|
# @return [Object] Decompressor instance
|
|
67
|
-
def create_decompressor(algorithm, input, output, size, **
|
|
67
|
+
def create_decompressor(algorithm, input, output, size, **)
|
|
68
68
|
@algorithm_factory.create(
|
|
69
69
|
algorithm,
|
|
70
70
|
:decompressor,
|
|
@@ -72,7 +72,7 @@ module Cabriolet
|
|
|
72
72
|
input,
|
|
73
73
|
output,
|
|
74
74
|
size,
|
|
75
|
-
|
|
75
|
+
**,
|
|
76
76
|
)
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -45,8 +45,8 @@ module Cabriolet
|
|
|
45
45
|
# @param output_file [String] Output file path
|
|
46
46
|
# @param options [Hash] Format options
|
|
47
47
|
# @return [Integer] Bytes written
|
|
48
|
-
def generate(output_file, **
|
|
49
|
-
@quickhelp.generate(output_file, **
|
|
48
|
+
def generate(output_file, **)
|
|
49
|
+
@quickhelp.generate(output_file, **)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Create a Windows Help format HLP file
|
data/lib/cabriolet/plugin.rb
CHANGED
|
@@ -190,10 +190,10 @@ module Cabriolet
|
|
|
190
190
|
# @example Register a format-specific decompressor
|
|
191
191
|
# register_algorithm(:special, SpecialDecompressor,
|
|
192
192
|
# category: :decompressor, format: :cab)
|
|
193
|
-
def register_algorithm(type, klass, **
|
|
193
|
+
def register_algorithm(type, klass, **)
|
|
194
194
|
raise PluginError, "Plugin manager not available" unless @manager
|
|
195
195
|
|
|
196
|
-
Cabriolet.algorithm_factory.register(type, klass, **
|
|
196
|
+
Cabriolet.algorithm_factory.register(type, klass, **)
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
# Register a format handler
|
data/lib/cabriolet/streaming.rb
CHANGED
|
@@ -188,9 +188,9 @@ module Cabriolet
|
|
|
188
188
|
# @param paths [Array<String>] Array of archive paths
|
|
189
189
|
# @yield [file, archive_path] Yields each file with its archive path
|
|
190
190
|
# @return [Hash] Processing statistics
|
|
191
|
-
def process_archives(paths, &
|
|
191
|
+
def process_archives(paths, &)
|
|
192
192
|
paths.each do |path|
|
|
193
|
-
process_archive(path, &
|
|
193
|
+
process_archive(path, &)
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
@stats
|
data/lib/cabriolet/validator.rb
CHANGED
data/lib/cabriolet/version.rb
CHANGED
data/lib/cabriolet.rb
CHANGED
|
@@ -169,7 +169,7 @@ module Cabriolet
|
|
|
169
169
|
# @example
|
|
170
170
|
# archive = Cabriolet.open('unknown.archive')
|
|
171
171
|
# archive.files.each { |f| puts f.name }
|
|
172
|
-
def open(path, **
|
|
172
|
+
def open(path, **)
|
|
173
173
|
parser_class = FormatDetector.parser_for(path)
|
|
174
174
|
|
|
175
175
|
unless parser_class
|
|
@@ -178,7 +178,7 @@ module Cabriolet
|
|
|
178
178
|
"Unable to detect format or no parser available for: #{path} (detected: #{format || 'unknown'})"
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
parser_class.new(**
|
|
181
|
+
parser_class.new(**).parse(path)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
# Detect format of an archive file
|
|
@@ -209,9 +209,9 @@ module Cabriolet
|
|
|
209
209
|
# @example Parallel extraction with 8 workers
|
|
210
210
|
# stats = Cabriolet.extract('file.chm', 'docs/', workers: 8)
|
|
211
211
|
# puts "Extracted #{stats[:extracted]} files"
|
|
212
|
-
def extract(archive_path, output_dir, **
|
|
212
|
+
def extract(archive_path, output_dir, **)
|
|
213
213
|
archive = open(archive_path)
|
|
214
|
-
extractor = Extraction::Extractor.new(archive, output_dir, **
|
|
214
|
+
extractor = Extraction::Extractor.new(archive, output_dir, **)
|
|
215
215
|
extractor.extract_all
|
|
216
216
|
end
|
|
217
217
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cabriolet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bindata
|