omnizip 0.4.8-arm-linux → 0.4.10-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 -0
- data/CHANGELOG.md +27 -0
- data/Gemfile +10 -1
- data/README.adoc +5 -3
- 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/vendor/libomnizip_ffi.so +0 -0
- metadata +18 -1
data/.rubocop.yml
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
2
|
# See https://github.com/metanorma/cimas
|
|
3
|
+
#
|
|
4
|
+
# PINNED SNAPSHOT (2026-09-21): the config used to inherit the
|
|
5
|
+
# oss-guides file over HTTPS directly. A remote main that moves under
|
|
6
|
+
# us — combined with CI's fresh dependency resolution — made rubocop
|
|
7
|
+
# behavior change with zero repo-side diffs (the 2026-09-21
|
|
8
|
+
# Metrics/BlockLength + standard-custom CI breakage). The snapshot is
|
|
9
|
+
# refreshed deliberately: refresh with
|
|
10
|
+
# curl -sL https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml -o .rubocop-oss.yml
|
|
3
11
|
inherit_from:
|
|
4
|
-
-
|
|
12
|
+
- .rubocop-oss.yml
|
|
5
13
|
- .rubocop_todo.yml
|
|
6
14
|
|
|
7
15
|
# local repo-specific modifications
|
|
@@ -10,6 +18,12 @@ inherit_from:
|
|
|
10
18
|
AllCops:
|
|
11
19
|
NewCops: enable
|
|
12
20
|
TargetRubyVersion: 3.0
|
|
21
|
+
# rake rust:build clones omnizip-rs under lib/tasks/build (and a
|
|
22
|
+
# build/ dir may exist at the root) — never lint the vendored
|
|
23
|
+
# checkout's Ruby files.
|
|
24
|
+
Exclude:
|
|
25
|
+
- "build/**/*"
|
|
26
|
+
- "lib/tasks/build/**/*"
|
|
13
27
|
|
|
14
28
|
# 7-Zip SDK uses is_char_state? naming convention (IsCharState in C)
|
|
15
29
|
# We keep this naming to match the SDK reference
|
data/.rubocop_todo.yml
CHANGED
|
@@ -138,6 +138,13 @@ Metrics/AbcSize:
|
|
|
138
138
|
# AllowedMethods: refine
|
|
139
139
|
Metrics/BlockLength:
|
|
140
140
|
Max: 81
|
|
141
|
+
# Merge with the inherited exclusions (oss-guides excludes
|
|
142
|
+
# spec/**/* here) — a bare Exclude key REPLACES the inherited list,
|
|
143
|
+
# which un-excluded every spec and re-activated ~190 dormant
|
|
144
|
+
# offenses under rubocop 1.91 (2026-09-21 CI).
|
|
145
|
+
inherit_mode:
|
|
146
|
+
merge:
|
|
147
|
+
- Exclude
|
|
141
148
|
Exclude:
|
|
142
149
|
- "lib/tasks/platform_gems.rake"
|
|
143
150
|
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
- ffi tier — JRuby/TruffleRuby acceleration (leptris-ruby model):
|
|
12
|
+
the cdylib's C ABI is additionally bound through the `ffi` gem
|
|
13
|
+
(`FfiLibrary`, same surface as the Fiddle binding), with
|
|
14
|
+
`Library` dispatching Fiddle → ffi → pure Ruby and
|
|
15
|
+
`OMNIZIP_BINDING=fiddle|ffi` to force a layer. `ffi` becomes a
|
|
16
|
+
runtime dependency (JRuby/TruffleRuby bundle it).
|
|
17
|
+
- Owned CI build matrix (windows-11-arm, musl containers, armv7
|
|
18
|
+
qemu, JRuby ffi gate) replacing the cimas rake job, whose fresh
|
|
19
|
+
dependency resolution made rubocop break with zero repo-side
|
|
20
|
+
diffs. The installed-gem smoke reports its binding layer.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- `Zlib::RLE` is CRuby-only: `require "omnizip"` raised NameError on
|
|
24
|
+
JRuby (and any engine without CRuby's zlib extension) as soon as
|
|
25
|
+
the Deflate algorithm loaded. RLE/FIXED strategy constants are now
|
|
26
|
+
guarded with their spec-defined values (3 and 4). Found by the new
|
|
27
|
+
JRuby CI leg — the matrix found a bug on day one.
|
|
28
|
+
- RPM archive-tier readiness: the dylib requirement is
|
|
29
|
+
**0.21.112**, not 0.21.111 — 0.21.111's `./`-stripping was half the
|
|
30
|
+
fix (the Ruby handler's names are ABSOLUTE, from the header's
|
|
31
|
+
DIRNAMES/BASENAMES; 0.21.112 normalizes the cpio names to
|
|
32
|
+
`/usr/…`). The tier spec version-guards accordingly, and with
|
|
33
|
+
0.21.112 the rpm tier is fully active (list stays Ruby by design;
|
|
34
|
+
read_entry is accelerated). Ships with the rubocop exclusion for
|
|
35
|
+
the tier spec that a CI-skipped merge dropped.
|
|
36
|
+
|
|
10
37
|
### Added
|
|
11
38
|
- Archive-level tier for every handler: tar, cpio, iso, xar, 7z and
|
|
12
39
|
rar3/4/5 (with `password:` passthrough) route list(names) and
|
data/Gemfile
CHANGED
|
@@ -9,7 +9,16 @@ gemspec
|
|
|
9
9
|
gem "csv"
|
|
10
10
|
gem "rake"
|
|
11
11
|
gem "rspec"
|
|
12
|
-
|
|
12
|
+
# Pinned: CI resolves dependencies fresh (no lockfile), and rubocop
|
|
13
|
+
# 1.91 changed Metrics/BlockLength scoping + plugin loading, which
|
|
14
|
+
# resurrected ~190 dormant spec offenses and crashes on the inherited
|
|
15
|
+
# oss-guides `standard-custom` require. Re-pin after triage upstream.
|
|
16
|
+
gem "rubocop", "1.90.0"
|
|
17
|
+
# rubocop's plugin loader auto-declares this via standard's
|
|
18
|
+
# default_lint_roller_plugin metadata where the gem is present; on
|
|
19
|
+
# runners without it the require crashes rubocop outright. Ship it in
|
|
20
|
+
# the bundle so the load always resolves (its plugin is inert without
|
|
21
|
+
# a .standard.yml).
|
|
13
22
|
gem "rubocop-performance"
|
|
14
23
|
gem "rubocop-rake"
|
|
15
24
|
gem "rubocop-rspec"
|
data/README.adoc
CHANGED
|
@@ -38,9 +38,11 @@ automatically — no Rust toolchain, no compilation:
|
|
|
38
38
|
* arm64-darwin, x86_64-darwin
|
|
39
39
|
* x64-mingw-ucrt, aarch64-mingw-ucrt, x64-mingw32
|
|
40
40
|
|
|
41
|
-
Everywhere else — including
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
Everywhere else — including any platform without a binary — the gem
|
|
42
|
+
stays fully functional on its pure-Ruby core (the acceleration is
|
|
43
|
+
strictly optional). JRuby and TruffleRuby get acceleration too
|
|
44
|
+
whenever a cdylib is available: they bind through the bundled `ffi`
|
|
45
|
+
gem (MRI uses stdlib Fiddle). Three escape hatches:
|
|
44
46
|
|
|
45
47
|
* `OMNIZIP_NO_RUST=1` — force the pure-Ruby core everywhere.
|
|
46
48
|
* `OMNIZIP_FFI_DYLIB=/path/to/libomnizip_ffi` — load a specific build.
|
|
@@ -13,11 +13,13 @@ module Omnizip
|
|
|
13
13
|
BEST_COMPRESSION = Zlib::BEST_COMPRESSION
|
|
14
14
|
DEFAULT_COMPRESSION = Zlib::DEFAULT_COMPRESSION
|
|
15
15
|
|
|
16
|
-
# Compression strategies
|
|
16
|
+
# Compression strategies. RLE and FIXED are CRuby-only Zlib
|
|
17
|
+
# constants (JRuby's zlib omits them — found by the JRuby CI
|
|
18
|
+
# leg); the numeric values are fixed by the zlib spec.
|
|
17
19
|
FILTERED = Zlib::FILTERED
|
|
18
20
|
HUFFMAN_ONLY = Zlib::HUFFMAN_ONLY
|
|
19
|
-
RLE = Zlib::RLE
|
|
20
|
-
FIXED = Zlib::FIXED
|
|
21
|
+
RLE = Zlib.const_defined?(:RLE) ? Zlib::RLE : 3
|
|
22
|
+
FIXED = Zlib.const_defined?(:FIXED) ? Zlib::FIXED : 4
|
|
21
23
|
DEFAULT_STRATEGY = Zlib::DEFAULT_STRATEGY
|
|
22
24
|
|
|
23
25
|
# Buffer size for streaming operations
|
|
@@ -7,64 +7,45 @@ module Omnizip
|
|
|
7
7
|
# format (auto-detected), list entries, read entry bytes. This is
|
|
8
8
|
# the archive-level tier surface — the Ruby core remains the
|
|
9
9
|
# fallback (the cdylib unavailable ⇒ these raise LibraryMissing
|
|
10
|
-
# and callers fall back).
|
|
10
|
+
# and callers fall back). Binding-agnostic: dispatches through
|
|
11
|
+
# whichever backend loaded (Fiddle on MRI, ffi on
|
|
12
|
+
# JRuby/TruffleRuby).
|
|
11
13
|
class Archive
|
|
12
14
|
class LibraryMissing < StandardError; end
|
|
13
15
|
|
|
14
|
-
# Built lazily inside #initialize: the Fiddle::TYPE_* constants
|
|
15
|
-
# only resolve after a successful require, and Ruby 4.0 moved
|
|
16
|
-
# fiddle out of the default gems (same reason
|
|
17
|
-
# Library.function_table is a method, not a constant).
|
|
18
16
|
def initialize(data, password: nil)
|
|
19
17
|
lib = Library.instance
|
|
20
18
|
raise LibraryMissing, "omnizip-ffi cdylib not loaded" unless lib
|
|
21
19
|
|
|
22
20
|
@lib = lib
|
|
23
|
-
|
|
24
|
-
@funcs = funcs.each_with_object({}) do |(key, (name, args, ret)), h|
|
|
25
|
-
h[key] = lib.bind(name, args, ret)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
pw = password&.to_s
|
|
29
|
-
pw_ptr = pw && !pw.empty? ? Fiddle::Pointer[pw] : nil
|
|
30
|
-
@handle = @funcs[:arch_open].call(Fiddle::Pointer[data], data.bytesize, pw_ptr)
|
|
31
|
-
return unless @handle.null?
|
|
32
|
-
|
|
33
|
-
raise Error, @lib.last_error
|
|
21
|
+
@handle = @lib.arch_open(data, password)
|
|
34
22
|
end
|
|
35
23
|
|
|
36
24
|
def entry_count
|
|
37
|
-
@
|
|
25
|
+
@lib.arch_count(@handle)
|
|
38
26
|
end
|
|
39
27
|
|
|
40
28
|
def entry_names
|
|
41
29
|
(0...entry_count).map do |i|
|
|
42
|
-
|
|
43
|
-
next nil if ptr.null?
|
|
44
|
-
|
|
45
|
-
ptr.to_s
|
|
30
|
+
@lib.arch_entry_name(@handle, i)
|
|
46
31
|
end
|
|
47
32
|
end
|
|
48
33
|
|
|
49
34
|
def entry_size(index)
|
|
50
|
-
@
|
|
35
|
+
@lib.arch_entry_size(@handle, index)
|
|
51
36
|
end
|
|
52
37
|
|
|
53
38
|
# Read one entry's uncompressed bytes.
|
|
54
39
|
#
|
|
55
40
|
# @return [String] binary
|
|
56
41
|
def read_entry(index)
|
|
57
|
-
|
|
58
|
-
ptr = @funcs[:arch_read_entry].call(@handle, index, out_len)
|
|
59
|
-
raise Error, @lib.last_error if ptr.null?
|
|
60
|
-
|
|
61
|
-
@lib.take_buffer(ptr, out_len.unpack1("Q"))
|
|
42
|
+
@lib.arch_read_entry(@handle, index)
|
|
62
43
|
end
|
|
63
44
|
|
|
64
45
|
def close
|
|
65
46
|
return unless @handle
|
|
66
47
|
|
|
67
|
-
@
|
|
48
|
+
@lib.arch_close(@handle)
|
|
68
49
|
@handle = nil
|
|
69
50
|
end
|
|
70
51
|
|
|
@@ -74,19 +55,6 @@ module Omnizip
|
|
|
74
55
|
ensure
|
|
75
56
|
archive&.close
|
|
76
57
|
end
|
|
77
|
-
|
|
78
|
-
private
|
|
79
|
-
|
|
80
|
-
def function_table
|
|
81
|
-
{
|
|
82
|
-
arch_open: ["ozip_arch_open", %i[voidp size_t voidp], Fiddle::TYPE_VOIDP],
|
|
83
|
-
arch_count: ["ozip_arch_count", [:voidp], Fiddle::TYPE_SIZE_T],
|
|
84
|
-
arch_entry_name: ["ozip_arch_entry_name", %i[voidp size_t], Fiddle::TYPE_VOIDP],
|
|
85
|
-
arch_entry_size: ["ozip_arch_entry_size", %i[voidp size_t], Fiddle::TYPE_VOIDP],
|
|
86
|
-
arch_read_entry: ["ozip_arch_read_entry", %i[voidp size_t voidp], Fiddle::TYPE_VOIDP],
|
|
87
|
-
arch_close: ["ozip_arch_close", [:voidp], Fiddle::TYPE_VOID],
|
|
88
|
-
}
|
|
89
|
-
end
|
|
90
58
|
end
|
|
91
59
|
end
|
|
92
60
|
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Implementations
|
|
5
|
+
module Rust
|
|
6
|
+
# The ffi-gem binding of the cdylib's C ABI — the JRuby /
|
|
7
|
+
# TruffleRuby acceleration path (leptris-ruby's model): those
|
|
8
|
+
# engines ship no Fiddle, so the Fiddle tier cannot load.
|
|
9
|
+
# Mirrors FiddleLibrary's public surface exactly, so the Library
|
|
10
|
+
# facade and the Archive class are binding-agnostic.
|
|
11
|
+
class FfiLibrary
|
|
12
|
+
attr_reader :mod
|
|
13
|
+
|
|
14
|
+
# Attach via a fresh module: FFI::Library is an extend-time
|
|
15
|
+
# DSL — one module per loaded image, like one Fiddle::Handle.
|
|
16
|
+
def self.attach(path)
|
|
17
|
+
mod = Module.new do
|
|
18
|
+
extend ::FFI::Library
|
|
19
|
+
|
|
20
|
+
ffi_lib path.to_s
|
|
21
|
+
end
|
|
22
|
+
mod.attach_function :ozip_compress,
|
|
23
|
+
%i[string buffer_in size_t int pointer], :pointer
|
|
24
|
+
mod.attach_function :ozip_decompress,
|
|
25
|
+
%i[string buffer_in size_t size_t pointer], :pointer
|
|
26
|
+
mod.attach_function :ozip_last_error, [], :pointer
|
|
27
|
+
mod.attach_function :ozip_free, %i[pointer size_t], :void
|
|
28
|
+
mod.attach_function :ozip_version, [], :pointer
|
|
29
|
+
mod.attach_function :ozip_arch_open,
|
|
30
|
+
%i[buffer_in size_t string], :pointer
|
|
31
|
+
mod.attach_function :ozip_arch_count, [:pointer], :size_t
|
|
32
|
+
mod.attach_function :ozip_arch_entry_name,
|
|
33
|
+
%i[pointer size_t], :pointer
|
|
34
|
+
mod.attach_function :ozip_arch_entry_size,
|
|
35
|
+
%i[pointer size_t], :uint64
|
|
36
|
+
mod.attach_function :ozip_arch_read_entry,
|
|
37
|
+
%i[pointer size_t pointer], :pointer
|
|
38
|
+
mod.attach_function :ozip_arch_close, [:pointer], :void
|
|
39
|
+
mod
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def initialize(path)
|
|
43
|
+
@mod = self.class.attach(path)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def compress(codec, data, level)
|
|
47
|
+
out_len = ::FFI::MemoryPointer.new(:size_t)
|
|
48
|
+
ptr = mod.ozip_compress(codec, data, data.bytesize, level, out_len)
|
|
49
|
+
raise Rust::Error, last_error if ptr.null?
|
|
50
|
+
|
|
51
|
+
take(ptr, out_len.read_ulong)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def decompress(codec, data, expected_len)
|
|
55
|
+
out_len = ::FFI::MemoryPointer.new(:size_t)
|
|
56
|
+
ptr = mod.ozip_decompress(codec, data, data.bytesize,
|
|
57
|
+
expected_len, out_len)
|
|
58
|
+
raise Rust::Error, last_error if ptr.null?
|
|
59
|
+
|
|
60
|
+
take(ptr, out_len.read_ulong)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def last_error
|
|
64
|
+
ptr = mod.ozip_last_error
|
|
65
|
+
ptr.null? ? "unknown error" : ptr.read_string
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Copy out + free one returned buffer: the buffer belongs to
|
|
69
|
+
# the Rust allocator and must never outlive ozip_free.
|
|
70
|
+
def take(ptr, len)
|
|
71
|
+
s = ptr.read_string(len)
|
|
72
|
+
mod.ozip_free(ptr, len)
|
|
73
|
+
s
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def take_buffer(ptr, len)
|
|
77
|
+
take(ptr, len)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The Rust release this cdylib was built from, or nil when the
|
|
81
|
+
# symbol is absent (dylibs older than 0.21.109).
|
|
82
|
+
def dylib_version
|
|
83
|
+
ptr = mod.ozip_version
|
|
84
|
+
ptr.null? ? nil : ptr.read_string
|
|
85
|
+
rescue ::FFI::NotFoundError
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# ---- whole-archive surface (ArchHandle) ----
|
|
90
|
+
# FFI auto-converts a Ruby String for a :pointer argument and
|
|
91
|
+
# nil to NULL, and the handle travels as a naked pointer.
|
|
92
|
+
|
|
93
|
+
def arch_open(data, password)
|
|
94
|
+
ptr = mod.ozip_arch_open(data, data.bytesize, password)
|
|
95
|
+
raise Rust::Error, last_error if ptr.null?
|
|
96
|
+
|
|
97
|
+
ptr
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def arch_count(handle)
|
|
101
|
+
mod.ozip_arch_count(handle)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def arch_entry_name(handle, index)
|
|
105
|
+
ptr = mod.ozip_arch_entry_name(handle, index)
|
|
106
|
+
ptr.null? ? nil : ptr.read_string
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def arch_entry_size(handle, index)
|
|
110
|
+
mod.ozip_arch_entry_size(handle, index)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def arch_read_entry(handle, index)
|
|
114
|
+
out_len = ::FFI::MemoryPointer.new(:size_t)
|
|
115
|
+
ptr = mod.ozip_arch_read_entry(handle, index, out_len)
|
|
116
|
+
raise Rust::Error, last_error if ptr.null?
|
|
117
|
+
|
|
118
|
+
take(ptr, out_len.read_ulong)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def arch_close(handle)
|
|
122
|
+
mod.ozip_arch_close(handle)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Implementations
|
|
5
|
+
module Rust
|
|
6
|
+
# The Fiddle binding of the cdylib's C ABI — the MRI fast path
|
|
7
|
+
# (stdlib, zero gems). One public surface shared with
|
|
8
|
+
# FfiLibrary: codec methods, whole-archive methods, error and
|
|
9
|
+
# version accessors — the binding Library's facade and the
|
|
10
|
+
# Archive class dispatch through.
|
|
11
|
+
class FiddleLibrary
|
|
12
|
+
attr_reader :handle
|
|
13
|
+
|
|
14
|
+
# The shared function table (Fiddle::TYPE_* constants resolve
|
|
15
|
+
# only after a successful require — same reason Library keeps
|
|
16
|
+
# this out of the class body).
|
|
17
|
+
FUNCTION_TABLE = lambda {
|
|
18
|
+
{
|
|
19
|
+
last_error: ["ozip_last_error", [], Fiddle::TYPE_VOIDP],
|
|
20
|
+
free: ["ozip_free", %i[voidp size_t], Fiddle::TYPE_VOID],
|
|
21
|
+
compress: [
|
|
22
|
+
"ozip_compress",
|
|
23
|
+
%i[voidp voidp size_t int voidp],
|
|
24
|
+
Fiddle::TYPE_VOIDP,
|
|
25
|
+
],
|
|
26
|
+
decompress: [
|
|
27
|
+
"ozip_decompress",
|
|
28
|
+
%i[voidp voidp size_t size_t voidp],
|
|
29
|
+
Fiddle::TYPE_VOIDP,
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
FIDDLE_ARG_TYPES = {
|
|
35
|
+
pointer: ->(v) { v.nil? ? nil : Fiddle::Pointer[v] },
|
|
36
|
+
}.freeze
|
|
37
|
+
FIDDLE_RET_TYPES = {
|
|
38
|
+
pointer: Fiddle::TYPE_VOIDP,
|
|
39
|
+
void: Fiddle::TYPE_VOID,
|
|
40
|
+
size_t: Fiddle::TYPE_SIZE_T,
|
|
41
|
+
uint64: Fiddle::TYPE_VOIDP,
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
def initialize(path)
|
|
45
|
+
@handle = Fiddle.dlopen(path.to_s)
|
|
46
|
+
@funcs = FUNCTION_TABLE.call.each_with_object({}) do |(key, (name, args, ret)), h|
|
|
47
|
+
h[key] = Fiddle::Function.new(@handle[name], args, ret)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def compress(codec, data, level)
|
|
52
|
+
out_len = [0].pack("Q")
|
|
53
|
+
ptr = @funcs[:compress].call(codec, data, data.bytesize, level, out_len)
|
|
54
|
+
raise Rust::Error, last_error if ptr.null?
|
|
55
|
+
|
|
56
|
+
take(ptr, out_len.unpack1("Q"))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def decompress(codec, data, expected_len)
|
|
60
|
+
out_len = [0].pack("Q")
|
|
61
|
+
ptr = @funcs[:decompress].call(codec, data, data.bytesize, expected_len, out_len)
|
|
62
|
+
raise Rust::Error, last_error if ptr.null?
|
|
63
|
+
|
|
64
|
+
take(ptr, out_len.unpack1("Q"))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def last_error
|
|
68
|
+
ptr = @funcs[:last_error].call
|
|
69
|
+
ptr.null? ? "unknown error" : ptr.to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Copy out + free one returned buffer: the buffer belongs to
|
|
73
|
+
# the Rust allocator and must never outlive ozip_free.
|
|
74
|
+
def take(ptr, len)
|
|
75
|
+
s = ptr.to_s(len)
|
|
76
|
+
@funcs[:free].call(ptr, len)
|
|
77
|
+
s
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def take_buffer(ptr, len)
|
|
81
|
+
take(ptr, len)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The Rust release this cdylib was built from, or nil when the
|
|
85
|
+
# symbol is absent (dylibs older than 0.21.109).
|
|
86
|
+
def dylib_version
|
|
87
|
+
func = Fiddle::Function.new(@handle["ozip_version"], [], Fiddle::TYPE_VOIDP)
|
|
88
|
+
ptr = func.call
|
|
89
|
+
ptr.null? ? nil : ptr.to_s
|
|
90
|
+
rescue StandardError
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ---- whole-archive surface (ArchHandle) ----
|
|
95
|
+
|
|
96
|
+
def arch_open(data, password)
|
|
97
|
+
pw = password&.to_s
|
|
98
|
+
pw_ptr = pw && !pw.empty? ? Fiddle::Pointer[pw] : nil
|
|
99
|
+
ptr = Fiddle::Function.new(
|
|
100
|
+
@handle["ozip_arch_open"],
|
|
101
|
+
%i[voidp size_t voidp],
|
|
102
|
+
Fiddle::TYPE_VOIDP,
|
|
103
|
+
).call(Fiddle::Pointer[data], data.bytesize, pw_ptr)
|
|
104
|
+
raise Rust::Error, last_error if ptr.null?
|
|
105
|
+
|
|
106
|
+
ptr
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def arch_count(handle)
|
|
110
|
+
fn = Fiddle::Function.new(@handle["ozip_arch_count"], [:voidp], Fiddle::TYPE_SIZE_T)
|
|
111
|
+
fn.call(handle)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def arch_entry_name(handle, index)
|
|
115
|
+
ptr = Fiddle::Function.new(
|
|
116
|
+
@handle["ozip_arch_entry_name"], %i[voidp size_t], Fiddle::TYPE_VOIDP
|
|
117
|
+
).call(handle, index)
|
|
118
|
+
ptr.null? ? nil : ptr.to_s
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def arch_entry_size(handle, index)
|
|
122
|
+
Fiddle::Function.new(
|
|
123
|
+
@handle["ozip_arch_entry_size"], %i[voidp size_t], Fiddle::TYPE_VOIDP
|
|
124
|
+
).call(handle, index)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def arch_read_entry(handle, index)
|
|
128
|
+
out_len = [0].pack("Q")
|
|
129
|
+
ptr = Fiddle::Function.new(
|
|
130
|
+
@handle["ozip_arch_read_entry"], %i[voidp size_t voidp], Fiddle::TYPE_VOIDP
|
|
131
|
+
).call(handle, index, out_len)
|
|
132
|
+
raise Rust::Error, last_error if ptr.null?
|
|
133
|
+
|
|
134
|
+
take(ptr, out_len.unpack1("Q"))
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def arch_close(handle)
|
|
138
|
+
Fiddle::Function.new(@handle["ozip_arch_close"], [:voidp], Fiddle::TYPE_VOID)
|
|
139
|
+
.call(handle)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|