Module: Qpid::Proton::Util::SWIGClassHelper

Included in:
Disposition, SASL, Terminus
Defined in:
lib/util/wrapper.rb

Overview

Class methods to help wrapper classes define forwarding methods to proton-C functions

The extending class must define PROTON_METHOD_PREFIX, the functions here make it easy to define ruby methods to forward calls to C functions.

Constant Summary collapse

RBCTX =
self.hash.to_i
@@registry =

Store ruby wrappers as attachments so they can be retrieved from the C pointer.

Wrappers are stored in a registry using a key. The key is then attached to the Proton structure as a record. That record lives for as long as the Proton structure lives, and when the structure is released the record acts as hook to also delete the Ruby wrapper object from the registry.

{}

Instance Method Summary collapse

Instance Method Details

#fetch_instance(impl, attachment_method = nil) ⇒ Object

Retrieves the wrapper object with the supplied Proton struct.

Parameters:

  • impl (Object)

    The wrapper for the Proton struct.

  • attachment_method (Symbol) (defaults to: nil)

    The Proton attachment method.

Returns:

  • (Object)

    The Ruby wrapper object.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/util/wrapper.rb', line 87

def fetch_instance(impl, attachment_method = nil)
  # if the impl has a wrapper already attached, then return it
  if impl.instance_variable_defined?(:@proton_wrapper)
    return impl.instance_variable_get(:@proton_wrapper)
  end
  unless attachment_method.nil?
    record = Cproton.__send__(attachment_method, impl)
    rbkey = Cproton.pni_void2rbkey(Cproton.pn_record_get(record, RBCTX))
    # if we don't have a key, then we don't have an object
    return nil if rbkey.nil?
    registry_key = Cproton.Pn_rbkey_get_key_value(rbkey)
  else
    registry_key = get_key(impl)
  end
  # if the object's not in the registry then return
  return nil unless @@registry.has_key?(registry_key)

  result = @@registry[registry_key]
  # result = nil unless result.weakref_alive?
  if result.nil?
    raise Qpid::Proton::ProtonError.new("missing object for key=#{registry_key}")
  else
    # update the impl since the Swig wrapper for it may have changed
    result.impl = impl
  end
  return result
end

#get_key(impl) ⇒ Object



54
55
56
# File 'lib/util/wrapper.rb', line 54

def get_key(impl)
  ("%032x" % Cproton.pni_address_of(impl))
end

#proton_caller(*names) ⇒ Object



37
# File 'lib/util/wrapper.rb', line 37

def proton_caller(*names) names.each { |name| proton_forward(name, name) }; end

#proton_forward(name, pn_name) ⇒ Object

Define ruby method name to forward arguments to CProton.PROTON_METHOD_PREFIX_pn_name(@impl, …)



31
32
33
34
35
# File 'lib/util/wrapper.rb', line 31

def proton_forward(name, pn_name)
  pn_name = pn_name[0..-2] if pn_name.to_s.end_with? "?" # Drop trailing ? for ruby bool methods
  pn_name = "#{self::PROTON_METHOD_PREFIX}_#{pn_name}".to_sym
  define_method(name.to_sym) { |*args| Cproton.__send__(pn_name, @impl, *args) }
end

#proton_get(*names) ⇒ Object



39
# File 'lib/util/wrapper.rb', line 39

def proton_get(*names) names.each { |name| proton_forward(name, "get_#{name}") }; end

#proton_is(*names) ⇒ Object



40
# File 'lib/util/wrapper.rb', line 40

def proton_is(*names) names.each { |name| proton_forward("#{name}?", "is_#{name}") }; end

#proton_set(*names) ⇒ Object



38
# File 'lib/util/wrapper.rb', line 38

def proton_set(*names) names.each { |name| proton_forward("#{name}=", "set_#{name}") }; end

#proton_set_get(*names) ⇒ Object



41
# File 'lib/util/wrapper.rb', line 41

def proton_set_get(*names) names.each { |name| proton_get(name); proton_set(name) }; end

#proton_set_is(*names) ⇒ Object



42
# File 'lib/util/wrapper.rb', line 42

def proton_set_is(*names) names.each { |name| proton_is(name); proton_set(name) }; end

#store_instance(object, attachment_method = nil) ⇒ Object

Stores the given object for later retrieval.

Parameters:

  • object (Object)

    The object.

  • attachment_method (Symbol) (defaults to: nil)

    The Proton attachment method.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/util/wrapper.rb', line 64

def store_instance(object, attachment_method = nil)
  # ensure the impl has a reference to the wrapper object
  object.impl.instance_eval { @proton_wrapper = object }
  registry_key = get_key(object.impl)
  unless attachment_method.nil?
    record = Cproton.__send__(attachment_method, object.impl)
    rbkey = Cproton.Pn_rbkey_new
    Cproton.Pn_rbkey_set_registry(rbkey, Cproton.pn_rb2void(Qpid::Proton::Util::Wrapper.registry))
    Cproton.Pn_rbkey_set_method(rbkey, "delete")
    Cproton.Pn_rbkey_set_key_value(rbkey, registry_key)
    Cproton.pn_record_def(record, RBCTX, Cproton.Pn_rbkey__class());
    Cproton.pn_record_set(record, RBCTX, rbkey)
  end
  @@registry[registry_key] = object
end