Skip to content

Commit 026fe62

Browse files
committed
WIP
1 parent bfb7577 commit 026fe62

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

bindings/scripts/run_smoke_test.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ case "$LANGUAGE" in
5757
exit 0
5858
;;
5959
ruby)
60-
# A simple test to ensure the library can be loaded and the version function called.
61-
TEST_COMMAND="bundle install --quiet && ruby -r ./lib/imageflow -e 'puts Imageflow.version'"
62-
VERIFY_COMMAND="^[0-9]+\.[0-9]+$"
60+
# Test context creation and the JSON send/receive loop via the version endpoint.
61+
TEST_COMMAND="bundle install --quiet && ruby -r ./lib/imageflow -e 'ctx = Imageflow::Context.new; response = ctx.send_json(\"v1/get_version_info\", nil); if response[\"data\"][\"abi_major\"] == 3; puts \"JSON API version check passed.\"; end'"
62+
VERIFY_COMMAND="JSON API version check passed."
6363
run_test "$TEST_COMMAND" "$VERIFY_COMMAND"
6464
;;
6565
*)

bindings/templates/ruby/lib/imageflow.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,79 @@
22

33
# Require the low-level FFI module
44
require_relative 'imageflow_ffi'
5+
require 'json'
56

67
# Require all the generated data models
78
Dir[File.join(__dir__, 'imageflow', 'models', '*.rb')].each { |file| require file }
89

910
# Imageflow is the top-level module for the public Ruby API.
1011
# It provides a clean, idiomatic interface to the Imageflow library.
1112
module Imageflow
13+
# The Context class manages the lifecycle of a native Imageflow context.
14+
# It ensures that the native context is properly created and destroyed.
15+
class Context
16+
def initialize
17+
major = ImageflowFFI.imageflow_abi_version_major
18+
minor = ImageflowFFI.imageflow_abi_version_minor
19+
@context_ptr = ImageflowFFI.imageflow_context_create(major, minor)
20+
21+
# Automatically free the context when the object is garbage collected.
22+
ObjectSpace.define_finalizer(self, self.class.finalize(@context_ptr))
23+
end
24+
25+
def self.finalize(context_ptr)
26+
proc { ImageflowFFI.imageflow_context_destroy(context_ptr) }
27+
end
28+
29+
# Sends a JSON command to the Imageflow context and returns the response.
30+
#
31+
# @param command [String] The command name (e.g., 'v1/info').
32+
# @param payload [Hash] The command payload, which will be serialized to JSON.
33+
# @return [Hash] The JSON response, parsed into a Ruby Hash.
34+
# @raise [RuntimeError] if the Imageflow library reports an error.
35+
def send_json(command, payload)
36+
json_string = JSON.generate(payload)
37+
json_buffer = FFI::MemoryPointer.from_string(json_string)
38+
39+
# This response pointer must be freed with imageflow_json_response_destroy
40+
response_ptr = ImageflowFFI.imageflow_context_send_json(@context_ptr, command, json_buffer, json_string.bytesize)
41+
42+
# Check for errors after every call that can produce one.
43+
if ImageflowFFI.imageflow_context_has_error(@context_ptr)
44+
error_buffer = FFI::MemoryPointer.new(:char, 1024) # 1KB for error message
45+
bytes_written_ptr = FFI::MemoryPointer.new(:size_t)
46+
ImageflowFFI.imageflow_context_error_write_to_buffer(@context_ptr, error_buffer, error_buffer.size, bytes_written_ptr)
47+
bytes_written = bytes_written_ptr.read(:size_t)
48+
error_message = error_buffer.read_string(bytes_written)
49+
# Always free the response pointer, even if we have an error.
50+
ImageflowFFI.imageflow_json_response_destroy(@context_ptr, response_ptr) if response_ptr && !response_ptr.null?
51+
raise "Imageflow error: #{error_message}"
52+
end
53+
54+
return {} if response_ptr.nil? || response_ptr.null?
55+
56+
begin
57+
status_code_ptr = FFI::MemoryPointer.new(:int)
58+
buffer_ptr_ptr = FFI::MemoryPointer.new(:pointer)
59+
buffer_size_ptr = FFI::MemoryPointer.new(:size_t)
60+
61+
success = ImageflowFFI.imageflow_json_response_read(@context_ptr, response_ptr, status_code_ptr, buffer_ptr_ptr, buffer_size_ptr)
62+
63+
if success
64+
buffer_ptr = buffer_ptr_ptr.read_pointer
65+
buffer_size = buffer_size_ptr.read(:size_t)
66+
json_response_string = buffer_ptr.read_string(buffer_size)
67+
return JSON.parse(json_response_string)
68+
else
69+
return { error: 'Failed to read JSON response from Imageflow' }
70+
end
71+
ensure
72+
# Ensure the response is always destroyed.
73+
ImageflowFFI.imageflow_json_response_destroy(@context_ptr, response_ptr)
74+
end
75+
end
76+
end
77+
1278
class << self
1379
# Returns the version of the Imageflow ABI (Application Binary Interface)
1480
# as a 'major.minor' string.

bindings/templates/ruby/lib/imageflow_ffi.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,15 @@ module ImageflowFFI
2424
# These functions are part of the stable ABI.
2525
attach_function :imageflow_abi_version_major, [], :long
2626
attach_function :imageflow_abi_version_minor, [], :long
27+
28+
# Attach context management functions
29+
attach_function :imageflow_context_create, [:uint, :uint], :pointer
30+
attach_function :imageflow_context_destroy, [:pointer], :void
31+
32+
# Attach JSON and error handling functions
33+
attach_function :imageflow_context_send_json, [:pointer, :string, :pointer, :size_t], :pointer
34+
attach_function :imageflow_json_response_destroy, [:pointer, :pointer], :bool
35+
attach_function :imageflow_json_response_read, [:pointer, :pointer, :pointer, :pointer, :pointer], :bool
36+
attach_function :imageflow_context_has_error, [:pointer], :bool
37+
attach_function :imageflow_context_error_write_to_buffer, [:pointer, :pointer, :size_t, :pointer], :bool
2738
end

0 commit comments

Comments
 (0)