omnizip 0.4.9-arm-linux → 0.4.11-arm-linux
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/.rubocop-oss.yml +814 -0
- data/.rubocop.yml +15 -1
- data/.rubocop_todo.yml +7 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +23 -1
- data/README.adoc +101 -1282
- data/docs/compatibility.adoc +1 -2
- data/docs/lychee.toml +1 -7
- data/lib/omnizip/algorithms/deflate/constants.rb +5 -3
- data/lib/omnizip/implementations/rust/archive.rb +9 -41
- data/lib/omnizip/implementations/rust/ffi_library.rb +127 -0
- data/lib/omnizip/implementations/rust/fiddle_library.rb +144 -0
- data/lib/omnizip/implementations/rust/library.rb +39 -104
- data/lib/omnizip/implementations/rust.rb +2 -0
- data/lib/omnizip/version.rb +1 -1
- data/lib/tasks/docs.rake +146 -0
- data/readme-docs/rar-archives.adoc +505 -0
- data/scripts/generate_rar_oracle_fixtures.rb +177 -0
- data/vendor/libomnizip_ffi.so +0 -0
- metadata +21 -74
- data/TODO.refactor/00-overview.md +0 -67
- data/TODO.refactor/01-registry-base-class.md +0 -81
- data/TODO.refactor/02-error-hierarchy.md +0 -57
- data/TODO.refactor/03-autoload-entry-point.md +0 -69
- data/TODO.refactor/04-filter-base-consolidation.md +0 -49
- data/TODO.refactor/05-send-private-methods.md +0 -64
- data/TODO.refactor/06-instance-variable-access.md +0 -69
- data/TODO.refactor/07-respond-to-replacement.md +0 -237
- data/TODO.refactor/08-spec-doubles.md +0 -27
- data/TODO.refactor/09-cli-shared-module.md +0 -35
- data/TODO.refactor/10-format-detector-ocp.md +0 -34
- data/TODO.refactor/11-convenience-decoupling.md +0 -38
- data/TODO.refactor/12-thread-safety.md +0 -8
- data/TODO.refactor/13-lutaml-model-migration.md +0 -158
- data/TODO.refactor/14-add-missing-specs.md +0 -25
- data/docs/.github/workflows/docs.yml +0 -142
- data/docs/.gitignore +0 -21
- data/docs/Gemfile +0 -13
- data/docs/README.md +0 -101
- data/docs/_config.yml +0 -112
- data/docs/comparison/feature-matrix.adoc +0 -694
- data/docs/comparison/index.adoc +0 -113
- data/docs/comparison/vs-7zip.adoc +0 -309
- data/docs/comparison/vs-peazip.adoc +0 -77
- data/docs/comparison/vs-rubyzip.adoc +0 -342
- data/docs/comparison/vs-winrar.adoc +0 -100
- data/docs/concepts/index.adoc +0 -129
- data/docs/developer/architecture.adoc +0 -256
- data/docs/developer/contributing.adoc +0 -158
- data/docs/developer/index.adoc +0 -25
- data/docs/developer/testing.adoc +0 -212
- data/docs/getting-started/basic-usage.adoc +0 -263
- data/docs/getting-started/index.adoc +0 -42
- data/docs/getting-started/installation.adoc +0 -138
- data/docs/getting-started/quick-start.adoc +0 -183
- data/docs/getting-started/your-first-archive.adoc +0 -219
- data/docs/guides/advanced-features/encryption.adoc +0 -277
- data/docs/guides/advanced-features/index.adoc +0 -59
- data/docs/guides/advanced-features/parallel-processing.adoc +0 -144
- data/docs/guides/advanced-features/progress-tracking.adoc +0 -124
- data/docs/guides/advanced-features/streaming.adoc +0 -142
- data/docs/guides/archive-formats/gzip-format.adoc +0 -105
- data/docs/guides/archive-formats/index.adoc +0 -160
- data/docs/guides/archive-formats/ole-format.adoc +0 -151
- data/docs/guides/archive-formats/rar-format.adoc +0 -104
- data/docs/guides/archive-formats/rar5.adoc +0 -521
- data/docs/guides/archive-formats/rpm-format.adoc +0 -108
- data/docs/guides/archive-formats/seven-zip-format.adoc +0 -35
- data/docs/guides/archive-formats/tar-format.adoc +0 -106
- data/docs/guides/archive-formats/xz-format.adoc +0 -118
- data/docs/guides/archive-formats/zip-format.adoc +0 -35
- data/docs/guides/compression-algorithms/bzip2.adoc +0 -114
- data/docs/guides/compression-algorithms/deflate.adoc +0 -313
- data/docs/guides/compression-algorithms/index.adoc +0 -190
- data/docs/guides/compression-algorithms/lzma.adoc +0 -394
- data/docs/guides/compression-algorithms/lzma2.adoc +0 -244
- data/docs/guides/compression-algorithms/ppmd.adoc +0 -313
- data/docs/guides/compression-algorithms/zstandard.adoc +0 -296
- data/docs/guides/creating-archives.adoc +0 -348
- data/docs/guides/extracting-archives.adoc +0 -53
- data/docs/guides/format-conversion.adoc +0 -64
- data/docs/guides/index.adoc +0 -49
- data/docs/guides/migration-rubyzip.adoc +0 -217
- data/docs/guides/parity-archives.adoc +0 -605
- data/docs/guides/performance-tuning.adoc +0 -88
- data/docs/index.adoc +0 -228
- data/docs/reference/api/overview.adoc +0 -187
- data/docs/reference/cli/compress-command.adoc +0 -114
- data/docs/reference/cli/overview.adoc +0 -140
- data/docs/reference/index.adoc +0 -26
- data/docs/resources/faq.adoc +0 -185
- data/docs/resources/quick-reference.adoc +0 -222
- data/docs/troubleshooting/index.adoc +0 -207
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Progress Tracking
|
|
3
|
-
nav_order: 3
|
|
4
|
-
parent: Advanced Features
|
|
5
|
-
grand_parent: Guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
== Purpose
|
|
9
|
-
|
|
10
|
-
Long compression and extraction jobs benefit from progress feedback.
|
|
11
|
-
Omnizip ships a standalone tracker — +Omnizip::Progress+ — with
|
|
12
|
-
percentage, throughput, and ETA calculation. The convenience methods
|
|
13
|
-
do not emit progress themselves: wrap your own loop with a tracker.
|
|
14
|
-
|
|
15
|
-
== Basic Tracking
|
|
16
|
-
|
|
17
|
-
Create a tracker, update it as work completes, read live stats:
|
|
18
|
-
|
|
19
|
-
[source,ruby]
|
|
20
|
-
----
|
|
21
|
-
tracker = Omnizip::Progress.track(total_files: 100, total_bytes: 1_000_000)
|
|
22
|
-
|
|
23
|
-
tracker.update(files: 10, bytes: 100_000, current_file: "file.txt")
|
|
24
|
-
|
|
25
|
-
tracker.percentage # => 10.0
|
|
26
|
-
tracker.elapsed_seconds
|
|
27
|
-
tracker.eta_seconds
|
|
28
|
-
tracker.eta_formatted # => "2m 30s"
|
|
29
|
-
----
|
|
30
|
-
|
|
31
|
-
== Reporters
|
|
32
|
-
|
|
33
|
-
=== Callback Reporter
|
|
34
|
-
|
|
35
|
-
Yield progress to a block:
|
|
36
|
-
|
|
37
|
-
[source,ruby]
|
|
38
|
-
----
|
|
39
|
-
tracker = Omnizip::Progress.track(total_files: 100,
|
|
40
|
-
total_bytes: 1_000_000) do |progress|
|
|
41
|
-
puts "#{progress.percentage}% complete"
|
|
42
|
-
end
|
|
43
|
-
----
|
|
44
|
-
|
|
45
|
-
=== Console Reporter
|
|
46
|
-
|
|
47
|
-
Render a terminal progress bar:
|
|
48
|
-
|
|
49
|
-
[source,ruby]
|
|
50
|
-
----
|
|
51
|
-
tracker = Omnizip::Progress.track(
|
|
52
|
-
total_files: 100,
|
|
53
|
-
total_bytes: 1_000_000,
|
|
54
|
-
reporter: :console
|
|
55
|
-
)
|
|
56
|
-
----
|
|
57
|
-
|
|
58
|
-
=== Log Reporter
|
|
59
|
-
|
|
60
|
-
Write updates to a log file (pass the reporter instance):
|
|
61
|
-
|
|
62
|
-
[source,ruby]
|
|
63
|
-
----
|
|
64
|
-
reporter = Omnizip::Progress::LogReporter.new(
|
|
65
|
-
log_file: 'compress.log', verbose: true
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
tracker = Omnizip::Progress.track(
|
|
69
|
-
total_files: 100,
|
|
70
|
-
total_bytes: 1_000_000,
|
|
71
|
-
reporter: reporter
|
|
72
|
-
)
|
|
73
|
-
----
|
|
74
|
-
|
|
75
|
-
== Wrapping a Compression Job
|
|
76
|
-
|
|
77
|
-
Track a directory compression file by file:
|
|
78
|
-
|
|
79
|
-
[source,ruby]
|
|
80
|
-
----
|
|
81
|
-
files = Dir.glob('data/**/*').select { |f| File.file?(f) }
|
|
82
|
-
tracker = Omnizip::Progress.track(
|
|
83
|
-
total_files: files.size,
|
|
84
|
-
total_bytes: files.sum { |f| File.size(f) },
|
|
85
|
-
reporter: :console
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
Omnizip::Archive.create('backup.zip') do |archive|
|
|
89
|
-
files.each do |file|
|
|
90
|
-
archive.add_file(file, file.delete_prefix('data/'))
|
|
91
|
-
tracker.update(files: 1, bytes: File.size(file), current_file: file)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
----
|
|
95
|
-
|
|
96
|
-
== Web Application Integration
|
|
97
|
-
|
|
98
|
-
Broadcast progress from a background job:
|
|
99
|
-
|
|
100
|
-
[source,ruby]
|
|
101
|
-
----
|
|
102
|
-
class ArchiveJob < ApplicationJob
|
|
103
|
-
def perform(user_id, file_paths)
|
|
104
|
-
tracker = Omnizip::Progress.track(total_files: file_paths.size)
|
|
105
|
-
|
|
106
|
-
file_paths.each_with_index do |path, i|
|
|
107
|
-
process_file(path)
|
|
108
|
-
tracker.update(files: 1, current_file: path)
|
|
109
|
-
|
|
110
|
-
ActionCable.server.broadcast("archive_#{user_id}", {
|
|
111
|
-
status: 'processing',
|
|
112
|
-
files_done: i + 1,
|
|
113
|
-
total_files: file_paths.size,
|
|
114
|
-
percentage: tracker.percentage
|
|
115
|
-
})
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
----
|
|
120
|
-
|
|
121
|
-
== See Also
|
|
122
|
-
|
|
123
|
-
* link:streaming.html[Streaming Operations] - Memory-efficient processing
|
|
124
|
-
* link:parallel-processing.html[Parallel Processing] - Multi-core strategies
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Streaming Operations
|
|
3
|
-
nav_order: 1
|
|
4
|
-
parent: Advanced Features
|
|
5
|
-
grand_parent: Guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
== Purpose
|
|
9
|
-
|
|
10
|
-
== Purpose
|
|
11
|
-
|
|
12
|
-
Streaming operations allow you to process archives without loading entire files into memory. This is essential for handling large archives, web applications, and memory-constrained environments.
|
|
13
|
-
|
|
14
|
-
Omnizip's streaming classes live under +Omnizip::Zip+ (streaming is a ZIP feature; the 7z and TAR writers accept buffered adds through the link:../creating-archives.html[Archive facade]).
|
|
15
|
-
|
|
16
|
-
== Creating Archives with Streaming
|
|
17
|
-
|
|
18
|
-
=== Stream to File
|
|
19
|
-
|
|
20
|
-
Create ZIP archives by streaming entries one at a time:
|
|
21
|
-
|
|
22
|
-
[source,ruby]
|
|
23
|
-
----
|
|
24
|
-
require 'omnizip/zip/output_stream'
|
|
25
|
-
|
|
26
|
-
Omnizip::Zip::OutputStream.open('backup.zip') do |stream|
|
|
27
|
-
Dir.glob('logs/*.log').each do |file|
|
|
28
|
-
stream.put_next_entry(File.basename(file))
|
|
29
|
-
File.open(file, 'rb') do |f|
|
|
30
|
-
stream.write(f.read)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
----
|
|
35
|
-
|
|
36
|
-
Per-entry compression method and level are supported:
|
|
37
|
-
|
|
38
|
-
[source,ruby]
|
|
39
|
-
----
|
|
40
|
-
stream.put_next_entry('data.bin', compression: :zstandard, level: 3)
|
|
41
|
-
----
|
|
42
|
-
|
|
43
|
-
=== Stream to Memory
|
|
44
|
-
|
|
45
|
-
Create ZIP archives in memory with +Omnizip::Buffer+:
|
|
46
|
-
|
|
47
|
-
[source,ruby]
|
|
48
|
-
----
|
|
49
|
-
zip_data = Omnizip::Buffer.create(:zip) do |archive|
|
|
50
|
-
archive.add('report.txt', generate_report)
|
|
51
|
-
archive.add('data.json', export_data.to_json)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
send_data zip_data.read, filename: 'export.zip' # StringIO
|
|
55
|
-
|
|
56
|
-
# Or straight from a Hash
|
|
57
|
-
zip_data = Omnizip::Buffer.create_from_hash(
|
|
58
|
-
'report.txt' => generate_report,
|
|
59
|
-
'data.json' => export_data.to_json
|
|
60
|
-
)
|
|
61
|
-
----
|
|
62
|
-
|
|
63
|
-
== Reading Archives with Streaming
|
|
64
|
-
|
|
65
|
-
=== Extract While Reading
|
|
66
|
-
|
|
67
|
-
Process each file as it's read from the archive:
|
|
68
|
-
|
|
69
|
-
[source,ruby]
|
|
70
|
-
----
|
|
71
|
-
require 'omnizip/zip/input_stream'
|
|
72
|
-
|
|
73
|
-
Omnizip::Zip::InputStream.open('large-archive.zip') do |stream|
|
|
74
|
-
while (entry = stream.get_next_entry)
|
|
75
|
-
next if entry.directory?
|
|
76
|
-
|
|
77
|
-
case entry.name
|
|
78
|
-
when /\.csv$/
|
|
79
|
-
import_csv_data(stream.read)
|
|
80
|
-
when /\.json$/
|
|
81
|
-
process_json(stream.read)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
----
|
|
86
|
-
|
|
87
|
-
=== Extract to Memory
|
|
88
|
-
|
|
89
|
-
Read all entries into a Hash without touching the filesystem:
|
|
90
|
-
|
|
91
|
-
[source,ruby]
|
|
92
|
-
----
|
|
93
|
-
files = Omnizip::Buffer.extract_to_memory(File.binread('backup.zip'))
|
|
94
|
-
|
|
95
|
-
files.each do |filename, content|
|
|
96
|
-
process_file(filename, content)
|
|
97
|
-
end
|
|
98
|
-
----
|
|
99
|
-
|
|
100
|
-
== Web Application Examples
|
|
101
|
-
|
|
102
|
-
=== Rails Upload Processing
|
|
103
|
-
|
|
104
|
-
[source,ruby]
|
|
105
|
-
----
|
|
106
|
-
class ArchiveController < ApplicationController
|
|
107
|
-
def upload
|
|
108
|
-
uploaded = params[:archive]
|
|
109
|
-
|
|
110
|
-
files = Omnizip::Buffer.extract_to_memory(uploaded.read)
|
|
111
|
-
|
|
112
|
-
files.each do |filename, content|
|
|
113
|
-
process_file(filename, content)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
render json: { processed: files.count }
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
----
|
|
120
|
-
|
|
121
|
-
=== API Response Streaming
|
|
122
|
-
|
|
123
|
-
[source,ruby]
|
|
124
|
-
----
|
|
125
|
-
get '/export' do
|
|
126
|
-
content_type 'application/zip'
|
|
127
|
-
attachment 'export.zip'
|
|
128
|
-
|
|
129
|
-
zip_data = Omnizip::Buffer.create(:zip) do |archive|
|
|
130
|
-
User.find_each do |user|
|
|
131
|
-
archive.add("#{user.id}.json", user.to_json)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
zip_data.read
|
|
136
|
-
end
|
|
137
|
-
----
|
|
138
|
-
|
|
139
|
-
== See Also
|
|
140
|
-
|
|
141
|
-
* link:parallel-processing.html[Parallel Processing] - Multi-core strategies
|
|
142
|
-
* link:../creating-archives.html[Creating Archives] - Block-style archive facade
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: GZIP Format
|
|
3
|
-
nav_order: 5
|
|
4
|
-
parent: Archive Formats
|
|
5
|
-
grand_parent: Guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
== Purpose
|
|
9
|
-
|
|
10
|
-
GZIP is the standard compression format on Unix/Linux systems for single files. It uses the Deflate algorithm and is widely supported across all platforms.
|
|
11
|
-
|
|
12
|
-
== Key Characteristics
|
|
13
|
-
|
|
14
|
-
[cols="1,3"]
|
|
15
|
-
|===
|
|
16
|
-
|Property |Value
|
|
17
|
-
|
|
18
|
-
|Compression
|
|
19
|
-
|Deflate
|
|
20
|
-
|
|
21
|
-
|Encryption
|
|
22
|
-
|None
|
|
23
|
-
|
|
24
|
-
|Archive Support
|
|
25
|
-
|Single file only (use with TAR for multiple files)
|
|
26
|
-
|
|
27
|
-
|Large Files
|
|
28
|
-
|Yes
|
|
29
|
-
|
|
30
|
-
|Best For
|
|
31
|
-
|Single file compression, web servers, Unix systems
|
|
32
|
-
|===
|
|
33
|
-
|
|
34
|
-
== Basic Usage
|
|
35
|
-
|
|
36
|
-
=== Compress a File
|
|
37
|
-
|
|
38
|
-
[source,ruby]
|
|
39
|
-
----
|
|
40
|
-
# Compress single file
|
|
41
|
-
Omnizip.compress_file('data.txt', 'data.txt.gz')
|
|
42
|
-
|
|
43
|
-
# With compression level
|
|
44
|
-
Omnizip.compress_file('data.txt', 'data.txt.gz',
|
|
45
|
-
level: 9 # Maximum compression
|
|
46
|
-
)
|
|
47
|
-
----
|
|
48
|
-
|
|
49
|
-
=== Decompress a File
|
|
50
|
-
|
|
51
|
-
[source,ruby]
|
|
52
|
-
----
|
|
53
|
-
# Decompress GZIP file
|
|
54
|
-
Omnizip.decompress_file('data.txt.gz', 'data.txt')
|
|
55
|
-
|
|
56
|
-
# Decompress to automatically named file
|
|
57
|
-
Omnizip.decompress_file('data.txt.gz') # Creates data.txt
|
|
58
|
-
----
|
|
59
|
-
|
|
60
|
-
== GZIP vs Other Formats
|
|
61
|
-
|
|
62
|
-
[cols="2,1,1,1"]
|
|
63
|
-
|===
|
|
64
|
-
|Feature |GZIP |XZ |ZIP
|
|
65
|
-
|
|
66
|
-
|Compression
|
|
67
|
-
|Good
|
|
68
|
-
|Excellent
|
|
69
|
-
|Good
|
|
70
|
-
|
|
71
|
-
|Speed
|
|
72
|
-
|Fast
|
|
73
|
-
|Slow
|
|
74
|
-
|Fast
|
|
75
|
-
|
|
76
|
-
|Archive Support
|
|
77
|
-
|No
|
|
78
|
-
|No
|
|
79
|
-
|Yes
|
|
80
|
-
|
|
81
|
-
|Unix Standard
|
|
82
|
-
|Yes
|
|
83
|
-
|Growing
|
|
84
|
-
|No
|
|
85
|
-
|===
|
|
86
|
-
|
|
87
|
-
== Streaming Compression
|
|
88
|
-
|
|
89
|
-
GZIP supports streaming for large files:
|
|
90
|
-
|
|
91
|
-
[source,ruby]
|
|
92
|
-
----
|
|
93
|
-
# Stream compress large file
|
|
94
|
-
File.open('large.bin', 'rb') do |input|
|
|
95
|
-
File.open('large.bin.gz', 'wb') do |output|
|
|
96
|
-
Omnizip::Formats::Gzip.compress_stream(input, output)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
----
|
|
100
|
-
|
|
101
|
-
== See Also
|
|
102
|
-
|
|
103
|
-
* link:tar-format.html[TAR Format] - Multi-file archives with GZIP
|
|
104
|
-
* link:xz-format.html[XZ Format] - Better compression alternative
|
|
105
|
-
* link:deflate.html[Deflate Algorithm] - Compression algorithm details
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Archive Formats
|
|
3
|
-
nav_order: 20
|
|
4
|
-
parent: Guides
|
|
5
|
-
has_children: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
== Archive Formats Overview
|
|
9
|
-
|
|
10
|
-
Omnizip supports 12 archive formats for different use cases. Each format has unique features, compression options, and compatibility characteristics.
|
|
11
|
-
|
|
12
|
-
== Format Comparison
|
|
13
|
-
|
|
14
|
-
[cols="1,1,1,2"]
|
|
15
|
-
|===
|
|
16
|
-
|Format |Compression |Encryption |Best For
|
|
17
|
-
|
|
18
|
-
|link:seven-zip-format.html[7z]
|
|
19
|
-
|Multiple (LZMA2, etc.)
|
|
20
|
-
|AES-256
|
|
21
|
-
|Software distribution, backups
|
|
22
|
-
|
|
23
|
-
|link:zip-format.html[ZIP]
|
|
24
|
-
|Deflate, PPMd
|
|
25
|
-
|AES (WinZip), Traditional
|
|
26
|
-
|Cross-platform compatibility
|
|
27
|
-
|
|
28
|
-
|link:rar-format.html[RAR]
|
|
29
|
-
|RAR (proprietary)
|
|
30
|
-
|AES-256
|
|
31
|
-
|Binary distribution, multi-volume
|
|
32
|
-
|
|
33
|
-
|link:tar-format.html[TAR]
|
|
34
|
-
|External (gzip, bzip2, xz)
|
|
35
|
-
|None
|
|
36
|
-
|Unix backups, software packaging
|
|
37
|
-
|
|
38
|
-
|link:gzip-format.html[GZIP]
|
|
39
|
-
|Deflate
|
|
40
|
-
|None
|
|
41
|
-
|Single file compression
|
|
42
|
-
|
|
43
|
-
|link:xz-format.html[XZ]
|
|
44
|
-
|LZMA2
|
|
45
|
-
|None
|
|
46
|
-
|System package compression
|
|
47
|
-
|
|
48
|
-
|link:rpm-format.html[RPM]
|
|
49
|
-
|gzip, bzip2, xz, zstd
|
|
50
|
-
|GPG signatures
|
|
51
|
-
|Linux package management
|
|
52
|
-
|
|
53
|
-
|link:ole-format.html[OLE]
|
|
54
|
-
|None (internal structure)
|
|
55
|
-
|Document-specific
|
|
56
|
-
|Windows compound files, MSI
|
|
57
|
-
|===
|
|
58
|
-
|
|
59
|
-
== Choosing a Format
|
|
60
|
-
|
|
61
|
-
=== By Use Case
|
|
62
|
-
|
|
63
|
-
[cols="1,2"]
|
|
64
|
-
|===
|
|
65
|
-
|Use Case |Recommended Format
|
|
66
|
-
|
|
67
|
-
|Cross-platform distribution
|
|
68
|
-
|ZIP (universal compatibility)
|
|
69
|
-
|
|
70
|
-
|Maximum compression
|
|
71
|
-
|7z with LZMA2 (level 9)
|
|
72
|
-
|
|
73
|
-
|Large file splitting
|
|
74
|
-
|RAR (multi-volume support) or 7z
|
|
75
|
-
|
|
76
|
-
|Unix/Linux backups
|
|
77
|
-
|TAR with XZ or BZip2
|
|
78
|
-
|
|
79
|
-
|Single file compression
|
|
80
|
-
|GZIP or XZ
|
|
81
|
-
|
|
82
|
-
|Software packages
|
|
83
|
-
|7z or TAR.XZ
|
|
84
|
-
|
|
85
|
-
|Linux package management
|
|
86
|
-
|RPM
|
|
87
|
-
|
|
88
|
-
|Windows compound documents
|
|
89
|
-
|OLE (MSI, DOC, XLS, PPT)
|
|
90
|
-
|===
|
|
91
|
-
|
|
92
|
-
=== By Compatibility
|
|
93
|
-
|
|
94
|
-
[cols="1,4"]
|
|
95
|
-
|===
|
|
96
|
-
|Platform |Best Format
|
|
97
|
-
|
|
98
|
-
|Windows
|
|
99
|
-
|ZIP (native), 7z (7-Zip), RAR (WinRAR)
|
|
100
|
-
|
|
101
|
-
|macOS
|
|
102
|
-
|ZIP (native), 7z, TAR.GZ
|
|
103
|
-
|
|
104
|
-
|Linux
|
|
105
|
-
|TAR.GZ, TAR.XZ, ZIP, 7z
|
|
106
|
-
|
|
107
|
-
|Universal
|
|
108
|
-
|ZIP (supported everywhere)
|
|
109
|
-
|===
|
|
110
|
-
|
|
111
|
-
== Format Features
|
|
112
|
-
|
|
113
|
-
=== 7z Format
|
|
114
|
-
|
|
115
|
-
* **Compression**: LZMA, LZMA2, BZip2, PPMd, Deflate, Zstandard
|
|
116
|
-
* **Encryption**: AES-256 with header encryption
|
|
117
|
-
* **Solid Archives**: Yes (better compression)
|
|
118
|
-
* **Multi-Volume**: Yes
|
|
119
|
-
* **Large Files**: Yes (up to 16 billion GB)
|
|
120
|
-
|
|
121
|
-
=== ZIP Format
|
|
122
|
-
|
|
123
|
-
* **Compression**: Deflate, Deflate64, PPMd, BZip2
|
|
124
|
-
* **Encryption**: AES-256 (WinZip), Traditional (weak)
|
|
125
|
-
* **ZIP64**: Yes (files >4GB)
|
|
126
|
-
* **Universal Support**: Yes
|
|
127
|
-
|
|
128
|
-
=== RAR Format
|
|
129
|
-
|
|
130
|
-
* **Compression**: Proprietary RAR algorithm
|
|
131
|
-
* **Encryption**: AES-256
|
|
132
|
-
* **Multi-Volume**: Excellent support
|
|
133
|
-
* **Recovery Records**: Error correction
|
|
134
|
-
|
|
135
|
-
=== TAR Format
|
|
136
|
-
|
|
137
|
-
* **Compression**: External (GZIP, BZip2, XZ)
|
|
138
|
-
* **Encryption**: None
|
|
139
|
-
* **POSIX**: Full support
|
|
140
|
-
* **Unix Standard**: Yes
|
|
141
|
-
|
|
142
|
-
=== RPM Format
|
|
143
|
-
|
|
144
|
-
* **Compression**: gzip, bzip2, xz, zstd (payload)
|
|
145
|
-
* **Encryption**: GPG signatures
|
|
146
|
-
* **Payload**: CPIO archive
|
|
147
|
-
* **Metadata**: Rich package information
|
|
148
|
-
|
|
149
|
-
=== OLE Format
|
|
150
|
-
|
|
151
|
-
* **Structure**: FAT-like file system
|
|
152
|
-
* **Streams**: Multiple streams and sub-storages
|
|
153
|
-
* **Types**: MSI, DOC, XLS, PPT, MSG
|
|
154
|
-
* **Metadata**: Summary information streams
|
|
155
|
-
|
|
156
|
-
== See Also
|
|
157
|
-
|
|
158
|
-
* link:../compression-algorithms/[Compression Algorithms] - Choose the right compression
|
|
159
|
-
* link:../../compatibility.html[Compatibility] - Detailed format support matrix
|
|
160
|
-
* link:../advanced-features/encryption.html[Encryption] - Secure your archives
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: OLE Format
|
|
3
|
-
nav_order: 10
|
|
4
|
-
parent: Archive Formats
|
|
5
|
-
grand_parent: Guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
[[ole-format]]
|
|
9
|
-
== Purpose
|
|
10
|
-
|
|
11
|
-
OLE (Object Linking and Embedding) Compound Document format is used
|
|
12
|
-
by Microsoft for storing structured data in a single file. Common OLE
|
|
13
|
-
files include MSI (Windows Installer packages), DOC (legacy Word),
|
|
14
|
-
XLS (legacy Excel), PPT (legacy PowerPoint) and THM (theme) files.
|
|
15
|
-
|
|
16
|
-
The API is stream-oriented: open the compound document, list
|
|
17
|
-
streams and storages by path, and read the streams you need.
|
|
18
|
-
|
|
19
|
-
== Basic Usage
|
|
20
|
-
|
|
21
|
-
=== Open an OLE File
|
|
22
|
-
|
|
23
|
-
[source,ruby]
|
|
24
|
-
----
|
|
25
|
-
# Open OLE compound document (block form closes automatically)
|
|
26
|
-
Omnizip::Formats::Ole.open('document.doc') do |ole|
|
|
27
|
-
puts ole.list.inspect
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Non-block form: close explicitly
|
|
31
|
-
ole = Omnizip::Formats::Ole.open('document.doc')
|
|
32
|
-
ole.close
|
|
33
|
-
----
|
|
34
|
-
|
|
35
|
-
=== List Entries
|
|
36
|
-
|
|
37
|
-
[source,ruby]
|
|
38
|
-
----
|
|
39
|
-
# Top-level streams and storages
|
|
40
|
-
Omnizip::Formats::Ole.list('document.doc')
|
|
41
|
-
|
|
42
|
-
# Inside a nested storage
|
|
43
|
-
Omnizip::Formats::Ole.list('document.doc', '/ObjectPool')
|
|
44
|
-
----
|
|
45
|
-
|
|
46
|
-
=== Read Stream Data
|
|
47
|
-
|
|
48
|
-
[source,ruby]
|
|
49
|
-
----
|
|
50
|
-
# \x01SummaryInformation holds document metadata
|
|
51
|
-
summary = Omnizip::Formats::Ole.read('document.doc',
|
|
52
|
-
"\x01SummaryInformation")
|
|
53
|
-
puts "Summary size: #{summary.bytesize} bytes"
|
|
54
|
-
|
|
55
|
-
# WordDocument stream (main content)
|
|
56
|
-
content = Omnizip::Formats::Ole.read('document.doc', 'WordDocument')
|
|
57
|
-
puts "Document content size: #{content.bytesize} bytes"
|
|
58
|
-
|
|
59
|
-
# Write a stream to disk
|
|
60
|
-
File.binwrite('workbook.bin',
|
|
61
|
-
Omnizip::Formats::Ole.read('spreadsheet.xls', 'Workbook'))
|
|
62
|
-
----
|
|
63
|
-
|
|
64
|
-
=== Entry Introspection
|
|
65
|
-
|
|
66
|
-
[source,ruby]
|
|
67
|
-
----
|
|
68
|
-
info = Omnizip::Formats::Ole.info('document.doc', 'WordDocument')
|
|
69
|
-
puts info.inspect
|
|
70
|
-
|
|
71
|
-
Omnizip::Formats::Ole.exist?('document.doc', 'WordDocument') # => true
|
|
72
|
-
Omnizip::Formats::Ole.file?('document.doc', 'WordDocument') # => true
|
|
73
|
-
Omnizip::Formats::Ole.directory?('document.doc', 'ObjectPool') # => true
|
|
74
|
-
----
|
|
75
|
-
|
|
76
|
-
== MSI Package Inspection
|
|
77
|
-
|
|
78
|
-
MSI files are OLE compound documents; the installer tables live in
|
|
79
|
-
storages and streams you can walk with +list+:
|
|
80
|
-
|
|
81
|
-
[source,ruby]
|
|
82
|
-
----
|
|
83
|
-
Omnizip::Formats::Ole.open('installer.msi') do |msi|
|
|
84
|
-
msi.list('/').each { |entry| puts entry }
|
|
85
|
-
summary = msi.read("\x05SummaryInformation") rescue nil
|
|
86
|
-
tables = msi.read('_Tables') rescue nil
|
|
87
|
-
puts "Tables stream size: #{tables&.bytesize}" if tables
|
|
88
|
-
end
|
|
89
|
-
----
|
|
90
|
-
|
|
91
|
-
== Storage Structure
|
|
92
|
-
|
|
93
|
-
OLE files have a hierarchical structure like a file system:
|
|
94
|
-
|
|
95
|
-
----
|
|
96
|
-
Root Storage/
|
|
97
|
-
├── \x01SummaryInformation (document metadata)
|
|
98
|
-
├── WordDocument (main content)
|
|
99
|
-
├── Data/
|
|
100
|
-
│ └── Mso1Table
|
|
101
|
-
└── ObjectPool/
|
|
102
|
-
└── Ole10Native
|
|
103
|
-
----
|
|
104
|
-
|
|
105
|
-
Stream paths use `/` separators (e.g. +"ObjectPool/Ole10Native"+).
|
|
106
|
-
|
|
107
|
-
== File Format Detection
|
|
108
|
-
|
|
109
|
-
OLE files carry the signature +D0 CF 11 E0 A1 B1 1A E1+ in the first
|
|
110
|
-
8 bytes:
|
|
111
|
-
|
|
112
|
-
[source,ruby]
|
|
113
|
-
----
|
|
114
|
-
File.open('document.doc', "rb") do |f|
|
|
115
|
-
magic = f.read(8)
|
|
116
|
-
ole = magic == "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1".b
|
|
117
|
-
puts(ole ? "OLE compound document" : "not OLE")
|
|
118
|
-
end
|
|
119
|
-
----
|
|
120
|
-
|
|
121
|
-
== Supported File Types
|
|
122
|
-
|
|
123
|
-
[cols="2,1,1"]
|
|
124
|
-
|===
|
|
125
|
-
|Format |Extension |Read Support
|
|
126
|
-
|
|
127
|
-
|Microsoft Word
|
|
128
|
-
|.doc
|
|
129
|
-
|Yes
|
|
130
|
-
|
|
131
|
-
|Microsoft Excel
|
|
132
|
-
|.xls
|
|
133
|
-
|Yes
|
|
134
|
-
|
|
135
|
-
|Microsoft PowerPoint
|
|
136
|
-
|.ppt
|
|
137
|
-
|Yes
|
|
138
|
-
|
|
139
|
-
|Windows Installer
|
|
140
|
-
|.msi
|
|
141
|
-
|Yes
|
|
142
|
-
|
|
143
|
-
|Generic OLE
|
|
144
|
-
|.ole
|
|
145
|
-
|Yes
|
|
146
|
-
|===
|
|
147
|
-
|
|
148
|
-
== See Also
|
|
149
|
-
|
|
150
|
-
* link:seven-zip-format.html[7z Format] - Can contain OLE files
|
|
151
|
-
* link:zip-format.html[ZIP Format] - Modern Office uses ZIP (docx, xlsx, pptx)
|