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.
@@ -11,23 +11,32 @@ end
11
11
  module Omnizip
12
12
  module Implementations
13
13
  module Rust
14
- # The loaded cdylib: one handle, lazily opened, thread-safe
15
- # after initialization (Fiddle::Function is immutable once
16
- # built; compress/decompress are pure C calls).
14
+ # The loaded cdylib binding: one handle, lazily opened. The
15
+ # BINDING LAYER is chosen at load (leptris-ruby's model):
16
+ #
17
+ # 1. Fiddle (MRI stdlib — the zero-gem fast path)
18
+ # 2. the ffi gem (JRuby / TruffleRuby ship it bundled; MRI
19
+ # without fiddle — Ruby 4.0 without the gem — uses it too)
20
+ # 3. unavailable (pure-Ruby core everywhere)
21
+ #
22
+ # OMNIZIP_BINDING=fiddle|ffi forces a layer (spec seam; also the
23
+ # way to prove the ffi path on MRI). `instance` returns a
24
+ # FiddleLibrary or FfiLibrary — both expose the identical
25
+ # surface (compress / decompress / last_error / take_buffer /
26
+ # dylib_version / arch_*), so callers are binding-agnostic.
17
27
  class Library
18
- # Codecs the cdylib dispatches by name.
19
- # Names the cdylib dispatches: the codec-level acceleration
20
- # surface (both directions by default — Rust is the
21
- # authority; Ruby is the fallback).
28
+ # Codecs the cdylib dispatches by name: the codec-level
29
+ # acceleration surface (both directions by default — Rust is
30
+ # the authority; Ruby is the fallback).
22
31
  CODECS = %w[
23
32
  bzip2 zstd lzma xz lzma-alone lzip
24
33
  deflate deflate64 zlib gzip ppmd7 ppmd8
25
34
  ].freeze
26
35
 
27
36
  class << self
28
- # The shared handle, or nil when the cdylib cannot load.
29
- # Load failures are cached: a missing library is a stable
30
- # condition, not something to re-attempt per call.
37
+ # The shared binding, or nil when no layer can load. Load
38
+ # failures are cached per layer: a missing library is a
39
+ # stable condition, not something to re-attempt per call.
31
40
  def instance
32
41
  return @instance if defined?(@instance)
33
42
 
@@ -38,6 +47,13 @@ module Omnizip
38
47
  !instance.nil?
39
48
  end
40
49
 
50
+ # Which binding loaded: "fiddle", "ffi", or nil.
51
+ def binding_layer
52
+ return nil if instance.nil?
53
+
54
+ instance.class.name.end_with?("FfiLibrary") ? "ffi" : "fiddle"
55
+ end
56
+
41
57
  # Whether the cdylib dispatches this codec name — exact, or
42
58
  # a param-carrying prefix ("ppmd7:o6:m16777216" under
43
59
  # "ppmd7").
@@ -45,7 +61,7 @@ module Omnizip
45
61
  CODECS.any? { |c| name == c || name.start_with?("#{c}:") }
46
62
  end
47
63
 
48
- # Drop the cached handle so resolution reruns (test seam:
64
+ # Drop the cached binding so resolution reruns (test seam:
49
65
  # specs exercising fallback/absence paths need a clean
50
66
  # slate; production never calls this).
51
67
  def forget!
@@ -56,39 +72,12 @@ module Omnizip
56
72
  nil
57
73
  end
58
74
 
59
- # Built lazily: the Fiddle::TYPE_* constants only resolve
60
- # after a successful require; environments without fiddle
61
- # (Ruby 4.0 without the gem) never touch this table.
62
- def function_table
63
- {
64
- last_error: ["ozip_last_error", [], Fiddle::TYPE_VOIDP],
65
- free: ["ozip_free", %i[voidp size_t], Fiddle::TYPE_VOID],
66
- compress: [
67
- "ozip_compress",
68
- %i[voidp voidp size_t int voidp],
69
- Fiddle::TYPE_VOIDP,
70
- ],
71
- decompress: [
72
- "ozip_decompress",
73
- %i[voidp voidp size_t size_t voidp],
74
- Fiddle::TYPE_VOIDP,
75
- ],
76
- }
77
- end
78
-
79
75
  # The Rust release the loaded cdylib was built from (e.g.
80
- # "0.21.108"), read through the ozip_version symbol — the
76
+ # "0.21.112"), read through the ozip_version symbol — the
81
77
  # platform-gem smoke gate asserts it matches. nil when the
82
78
  # library is absent or predates the symbol.
83
79
  def dylib_version
84
- handle = instance&.instance_handle
85
- return nil if handle.nil?
86
-
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
80
+ instance&.dylib_version
92
81
  end
93
82
 
94
83
  # Resolve the cdylib path. Precedence:
@@ -133,12 +122,17 @@ module Omnizip
133
122
  path = resolve_path
134
123
  return nil if path.nil?
135
124
 
136
- handle = Fiddle.dlopen(path.to_s)
137
- funcs = function_table.each_with_object({}) do |(key, (name, args, ret)), h|
138
- h[key] = Fiddle::Function.new(handle[name], args, ret)
125
+ forced = ENV.fetch("OMNIZIP_BINDING", nil)
126
+ if forced != "ffi" && defined?(Fiddle)
127
+ return FiddleLibrary.new(path)
139
128
  end
140
- new(funcs, handle)
141
- rescue StandardError => e # includes Fiddle::DLError
129
+
130
+ # The ffi path: JRuby/TruffleRuby bundle the gem; MRI
131
+ # needs it installed (it is a runtime dependency). A
132
+ # forced layer must not silently fall back to another.
133
+ require "ffi"
134
+ FfiLibrary.new(path)
135
+ rescue LoadError, StandardError => e # Fiddle::DLError, FFI::LoadError, ...
142
136
  warn "omnizip: rust backend unavailable (#{e.message}); using pure Ruby" if ENV["OMNIZIP_BACKEND"] == "rust"
143
137
  nil
144
138
  end
@@ -152,65 +146,6 @@ module Omnizip
152
146
  end
153
147
  end
154
148
  end
155
-
156
- def initialize(functions, handle = nil)
157
- @functions = functions.freeze
158
- @handle = handle
159
- end
160
-
161
- def compress(codec, data, level)
162
- out_len = [0].pack("Q")
163
- ptr = call(:compress, codec, data, data.bytesize, level, out_len)
164
- take(ptr, out_len.unpack1("Q"))
165
- end
166
-
167
- def decompress(codec, data, expected_len)
168
- out_len = [0].pack("Q")
169
- ptr = call(:decompress, codec, data, data.bytesize, expected_len, out_len)
170
- take(ptr, out_len.unpack1("Q"))
171
- end
172
-
173
- # Bind one extra C symbol from the loaded cdylib (the archive
174
- # surface uses this; Fiddle::Function is immutable once built).
175
- def bind(symbol, args, ret)
176
- handle = instance_handle
177
- raise Error, "cdylib not loaded" if handle.nil?
178
-
179
- Fiddle::Function.new(handle[symbol.to_s], args, ret)
180
- end
181
-
182
- def last_error
183
- ptr = @functions[:last_error].call
184
- ptr.null? ? "unknown error" : ptr.to_s
185
- end
186
-
187
- # The raw Fiddle::Handle (for extra symbol binds).
188
- def instance_handle
189
- @handle
190
- end
191
-
192
- # Copy out + free one returned buffer (public seam for the
193
- # archive surface).
194
- def take_buffer(ptr, len)
195
- take(ptr, len)
196
- end
197
-
198
- private
199
-
200
- def call(name, codec, input, input_len, a, out_len)
201
- ptr = @functions[name].call(codec, input, input_len, a, out_len)
202
- raise Error, last_error if ptr.null?
203
-
204
- ptr
205
- end
206
-
207
- # Copy out + free in one breath: the buffer belongs to the
208
- # Rust allocator and must never outlive ozip_free.
209
- def take(ptr, len)
210
- string = ptr.to_s(len)
211
- @functions[:free].call(ptr, len)
212
- string
213
- end
214
149
  end
215
150
 
216
151
  # Raised when a codec call fails; #message carries the Rust
@@ -20,6 +20,8 @@ module Omnizip
20
20
  # fallback on any Rust error.
21
21
  module Rust
22
22
  autoload :Library, "omnizip/implementations/rust/library"
23
+ autoload :FiddleLibrary, "omnizip/implementations/rust/fiddle_library"
24
+ autoload :FfiLibrary, "omnizip/implementations/rust/ffi_library"
23
25
  autoload :Archive, "omnizip/implementations/rust/archive"
24
26
  end
25
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Omnizip
4
- VERSION = "0.4.8"
4
+ VERSION = "0.4.10"
5
5
  end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnizip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.4.10
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.
@@ -57,6 +57,20 @@ dependencies:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
59
  version: 0.2.4
60
+ - !ruby/object:Gem::Dependency
61
+ name: ffi
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.15'
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.15'
60
74
  - !ruby/object:Gem::Dependency
61
75
  name: lutaml-model
62
76
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +125,7 @@ extensions: []
111
125
  extra_rdoc_files: []
112
126
  files:
113
127
  - ".rspec"
128
+ - ".rubocop-oss.yml"
114
129
  - ".rubocop.yml"
115
130
  - ".rubocop_todo.yml"
116
131
  - CHANGELOG.md
@@ -601,6 +616,8 @@ files:
601
616
  - lib/omnizip/implementations/base/state_machine_base.rb
602
617
  - lib/omnizip/implementations/rust.rb
603
618
  - lib/omnizip/implementations/rust/archive.rb
619
+ - lib/omnizip/implementations/rust/ffi_library.rb
620
+ - lib/omnizip/implementations/rust/fiddle_library.rb
604
621
  - lib/omnizip/implementations/rust/library.rb
605
622
  - lib/omnizip/implementations/seven_zip.rb
606
623
  - lib/omnizip/implementations/seven_zip/lzma.rb