proofmode 0.8.0
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 +7 -0
- data/lib/libproofmode.so +0 -0
- data/lib/proofmode.rb +1499 -0
- data/lib/proofmode_callbacks.rb +208 -0
- data/proofmode.gemspec +22 -0
- metadata +62 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Foreign callback support for ProofModeCallbacks.
|
|
2
|
+
#
|
|
3
|
+
# The UniFFI Ruby backend does not generate vtable callback infrastructure
|
|
4
|
+
# for traits with `#[uniffi::export(with_foreign)]`. This file adds that
|
|
5
|
+
# support so Ruby code can implement ProofModeCallbacks and pass instances
|
|
6
|
+
# to generate_proof / check_files.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# require "proofmode"
|
|
10
|
+
# require "proofmode_callbacks"
|
|
11
|
+
#
|
|
12
|
+
# Then subclass Proofmode::ProofModeCallbacks and override the 7 methods.
|
|
13
|
+
|
|
14
|
+
require "proofmode"
|
|
15
|
+
|
|
16
|
+
module Proofmode
|
|
17
|
+
# Thread-safe handle map for storing foreign (Ruby) callback objects.
|
|
18
|
+
class CallbackHandleMap
|
|
19
|
+
def initialize
|
|
20
|
+
@mutex = Mutex.new
|
|
21
|
+
@map = {}
|
|
22
|
+
@next_handle = 1
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def insert(obj)
|
|
26
|
+
@mutex.synchronize do
|
|
27
|
+
handle = (@next_handle << 1) | 1 # odd handles = foreign
|
|
28
|
+
@next_handle += 1
|
|
29
|
+
@map[handle] = obj
|
|
30
|
+
handle
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get(handle)
|
|
35
|
+
@mutex.synchronize do
|
|
36
|
+
@map.fetch(handle) { raise "CallbackHandleMap: unknown handle #{handle}" }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def remove(handle)
|
|
41
|
+
@mutex.synchronize do
|
|
42
|
+
@map.delete(handle)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def clone_handle(handle)
|
|
47
|
+
@mutex.synchronize do
|
|
48
|
+
obj = @map.fetch(handle) { raise "CallbackHandleMap: unknown handle #{handle}" }
|
|
49
|
+
new_handle = (@next_handle << 1) | 1
|
|
50
|
+
@next_handle += 1
|
|
51
|
+
@map[new_handle] = obj
|
|
52
|
+
new_handle
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
CALLBACK_HANDLE_MAP = CallbackHandleMap.new
|
|
58
|
+
|
|
59
|
+
# Access the private UniFFILib module using const_get
|
|
60
|
+
_uniffi_lib = const_get(:UniFFILib)
|
|
61
|
+
|
|
62
|
+
# Define vtable callback functions using FFI::Function.
|
|
63
|
+
# Each function receives a handle, arguments as RustBuffers, an out_return
|
|
64
|
+
# pointer, and a call_status pointer.
|
|
65
|
+
|
|
66
|
+
_vtable_free = FFI::Function.new(:void, [:uint64]) do |handle|
|
|
67
|
+
CALLBACK_HANDLE_MAP.remove(handle)
|
|
68
|
+
rescue => e
|
|
69
|
+
$stderr.puts "proofmode vtable free error: #{e}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
_vtable_clone = FFI::Function.new(:uint64, [:uint64]) do |handle|
|
|
73
|
+
CALLBACK_HANDLE_MAP.clone_handle(handle)
|
|
74
|
+
rescue => e
|
|
75
|
+
$stderr.puts "proofmode vtable clone error: #{e}"
|
|
76
|
+
0
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
_vtable_get_location = FFI::Function.new(:void, [:uint64, :pointer, :pointer]) do |handle, out_return, _call_status|
|
|
80
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
81
|
+
result = obj.get_location
|
|
82
|
+
buf = RustBuffer.alloc_from_OptionalTypeLocationData(result)
|
|
83
|
+
# Copy RustBuffer struct bytes into the out_return pointer
|
|
84
|
+
out_return.put_uint64(0, buf[:capacity])
|
|
85
|
+
out_return.put_uint64(8, buf[:len])
|
|
86
|
+
out_return.put_pointer(16, buf[:data])
|
|
87
|
+
rescue => e
|
|
88
|
+
$stderr.puts "proofmode vtable get_location error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
_vtable_get_device_info = FFI::Function.new(:void, [:uint64, :pointer, :pointer]) do |handle, out_return, _call_status|
|
|
92
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
93
|
+
result = obj.get_device_info
|
|
94
|
+
buf = RustBuffer.alloc_from_OptionalTypeDeviceData(result)
|
|
95
|
+
out_return.put_uint64(0, buf[:capacity])
|
|
96
|
+
out_return.put_uint64(8, buf[:len])
|
|
97
|
+
out_return.put_pointer(16, buf[:data])
|
|
98
|
+
rescue => e
|
|
99
|
+
$stderr.puts "proofmode vtable get_device_info error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
_vtable_get_network_info = FFI::Function.new(:void, [:uint64, :pointer, :pointer]) do |handle, out_return, _call_status|
|
|
103
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
104
|
+
result = obj.get_network_info
|
|
105
|
+
buf = RustBuffer.alloc_from_OptionalTypeNetworkData(result)
|
|
106
|
+
out_return.put_uint64(0, buf[:capacity])
|
|
107
|
+
out_return.put_uint64(8, buf[:len])
|
|
108
|
+
out_return.put_pointer(16, buf[:data])
|
|
109
|
+
rescue => e
|
|
110
|
+
$stderr.puts "proofmode vtable get_network_info error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# save_data: (handle, hash_buf, filename_buf, data_buf, out_return_i8_ptr, call_status_ptr)
|
|
114
|
+
# The RustBuffer args are passed by value. In Ruby FFI, callback functions
|
|
115
|
+
# receive by-value structs as pointers that we need to cast.
|
|
116
|
+
_vtable_save_data = FFI::Function.new(:void, [:uint64, RustBuffer.by_value, RustBuffer.by_value, RustBuffer.by_value, :pointer, :pointer]) do |handle, hash_buf, filename_buf, data_buf, out_return, _call_status|
|
|
117
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
118
|
+
hash_str = hash_buf.consumeIntoString
|
|
119
|
+
filename_str = filename_buf.consumeIntoString
|
|
120
|
+
data_bytes = data_buf.consumeIntoBytes
|
|
121
|
+
result = obj.save_data(hash_str, filename_str, data_bytes)
|
|
122
|
+
out_return.put_int8(0, result ? 1 : 0)
|
|
123
|
+
rescue => e
|
|
124
|
+
$stderr.puts "proofmode vtable save_data error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
_vtable_save_text = FFI::Function.new(:void, [:uint64, RustBuffer.by_value, RustBuffer.by_value, RustBuffer.by_value, :pointer, :pointer]) do |handle, hash_buf, filename_buf, text_buf, out_return, _call_status|
|
|
128
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
129
|
+
hash_str = hash_buf.consumeIntoString
|
|
130
|
+
filename_str = filename_buf.consumeIntoString
|
|
131
|
+
text_str = text_buf.consumeIntoString
|
|
132
|
+
result = obj.save_text(hash_str, filename_str, text_str)
|
|
133
|
+
out_return.put_int8(0, result ? 1 : 0)
|
|
134
|
+
rescue => e
|
|
135
|
+
$stderr.puts "proofmode vtable save_text error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
_vtable_sign_data = FFI::Function.new(:void, [:uint64, RustBuffer.by_value, :pointer, :pointer]) do |handle, data_buf, out_return, _call_status|
|
|
139
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
140
|
+
data_bytes = data_buf.consumeIntoBytes
|
|
141
|
+
result = obj.sign_data(data_bytes)
|
|
142
|
+
buf = RustBuffer.alloc_from_Optionalbytes(result)
|
|
143
|
+
out_return.put_uint64(0, buf[:capacity])
|
|
144
|
+
out_return.put_uint64(8, buf[:len])
|
|
145
|
+
out_return.put_pointer(16, buf[:data])
|
|
146
|
+
rescue => e
|
|
147
|
+
$stderr.puts "proofmode vtable sign_data error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
_vtable_report_progress = FFI::Function.new(:void, [:uint64, RustBuffer.by_value, :pointer, :pointer]) do |handle, message_buf, _out_return, _call_status|
|
|
151
|
+
obj = CALLBACK_HANDLE_MAP.get(handle)
|
|
152
|
+
message_str = message_buf.consumeIntoString
|
|
153
|
+
obj.report_progress(message_str)
|
|
154
|
+
rescue => e
|
|
155
|
+
$stderr.puts "proofmode vtable report_progress error: #{e}\n#{e.backtrace.first(5).join("\n")}"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Build the vtable as an array of function pointers.
|
|
159
|
+
# Layout order: free, clone, get_location, get_device_info, get_network_info,
|
|
160
|
+
# save_data, save_text, sign_data, report_progress
|
|
161
|
+
vtable_fns = [
|
|
162
|
+
_vtable_free,
|
|
163
|
+
_vtable_clone,
|
|
164
|
+
_vtable_get_location,
|
|
165
|
+
_vtable_get_device_info,
|
|
166
|
+
_vtable_get_network_info,
|
|
167
|
+
_vtable_save_data,
|
|
168
|
+
_vtable_save_text,
|
|
169
|
+
_vtable_sign_data,
|
|
170
|
+
_vtable_report_progress,
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
# Keep references alive to prevent GC
|
|
174
|
+
VTABLE_REFS = vtable_fns.freeze
|
|
175
|
+
|
|
176
|
+
# Allocate persistent memory for the vtable (array of function pointers)
|
|
177
|
+
VTABLE_PTR = FFI::MemoryPointer.new(:pointer, vtable_fns.length, true)
|
|
178
|
+
vtable_fns.each_with_index do |fn, i|
|
|
179
|
+
VTABLE_PTR.put_pointer(i * FFI::Pointer.size, fn)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Register the vtable with Rust
|
|
183
|
+
_rust_call_status = const_get(:RustCallStatus).new
|
|
184
|
+
_uniffi_lib.uniffi_proofmode_fn_init_callback_vtable_proofmodecallbacks(
|
|
185
|
+
VTABLE_PTR, _rust_call_status
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# Patch ProofModeCallbacks to support foreign (Ruby) implementations
|
|
189
|
+
class ProofModeCallbacks
|
|
190
|
+
class << self
|
|
191
|
+
def uniffi_check_lower(inst)
|
|
192
|
+
unless inst.is_a?(self)
|
|
193
|
+
raise TypeError, "Expected a ProofModeCallbacks instance, got #{inst}"
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def uniffi_lower(inst)
|
|
198
|
+
if inst.instance_variable_defined?(:@handle)
|
|
199
|
+
# Rust-created object
|
|
200
|
+
inst.uniffi_clone_handle
|
|
201
|
+
else
|
|
202
|
+
# Ruby-created (foreign) object
|
|
203
|
+
CALLBACK_HANDLE_MAP.insert(inst)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
data/proofmode.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "proofmode"
|
|
3
|
+
s.version = "0.8.0"
|
|
4
|
+
s.summary = "Ruby bindings for ProofMode"
|
|
5
|
+
s.description = "Capture, share, and preserve verifiable photos and videos using ProofMode"
|
|
6
|
+
s.authors = ["Guardian Project"]
|
|
7
|
+
s.email = "support@guardianproject.info"
|
|
8
|
+
s.homepage = "https://proofmode.org"
|
|
9
|
+
s.license = "Apache-2.0"
|
|
10
|
+
|
|
11
|
+
s.files = Dir["lib/**/*"] + ["proofmode.gemspec"]
|
|
12
|
+
s.require_paths = ["lib"]
|
|
13
|
+
|
|
14
|
+
s.required_ruby_version = ">= 2.7.0"
|
|
15
|
+
|
|
16
|
+
s.add_dependency "ffi", "~> 1.15"
|
|
17
|
+
|
|
18
|
+
s.metadata = {
|
|
19
|
+
"source_code_uri" => "https://gitlab.com/guardianproject/proofmode/proofmode-rust",
|
|
20
|
+
"bug_tracker_uri" => "https://gitlab.com/guardianproject/proofmode/proofmode-rust/-/issues"
|
|
21
|
+
}
|
|
22
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: proofmode
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.8.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Guardian Project
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: ffi
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.15'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.15'
|
|
27
|
+
description: Capture, share, and preserve verifiable photos and videos using ProofMode
|
|
28
|
+
email: support@guardianproject.info
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- lib/libproofmode.so
|
|
34
|
+
- lib/proofmode.rb
|
|
35
|
+
- lib/proofmode_callbacks.rb
|
|
36
|
+
- proofmode.gemspec
|
|
37
|
+
homepage: https://proofmode.org
|
|
38
|
+
licenses:
|
|
39
|
+
- Apache-2.0
|
|
40
|
+
metadata:
|
|
41
|
+
source_code_uri: https://gitlab.com/guardianproject/proofmode/proofmode-rust
|
|
42
|
+
bug_tracker_uri: https://gitlab.com/guardianproject/proofmode/proofmode-rust/-/issues
|
|
43
|
+
post_install_message:
|
|
44
|
+
rdoc_options: []
|
|
45
|
+
require_paths:
|
|
46
|
+
- lib
|
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: 2.7.0
|
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
requirements: []
|
|
58
|
+
rubygems_version: 3.4.19
|
|
59
|
+
signing_key:
|
|
60
|
+
specification_version: 4
|
|
61
|
+
summary: Ruby bindings for ProofMode
|
|
62
|
+
test_files: []
|