class GirFFI::Builders::ArgumentBuilder

Implements building pre- and post-processing statements for arguments.

Constants

DESTROY_NOTIFIER

Public Instance Methods

allow_none?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 22
def allow_none?
  arginfo.may_be_null?
end
block_argument?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 18
def block_argument?
  specialized_type_tag == :callback
end
capture_variable_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 38
def capture_variable_name
  nil
end
method_argument_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 14
def method_argument_name
  name if has_input_value? && !helper_argument?
end
post_conversion() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 55
def post_conversion
  if direction == :error
    ["GirFFI::ArgHelper.check_error(#{call_argument_name})"]
  elsif has_post_conversion?
    value = output_value
    ["#{post_converted_name} = #{value}"]
  else
    []
  end
end
post_converted_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 26
def post_converted_name
  @post_converted_name ||= if has_post_conversion?
                             new_variable
                           else
                             call_argument_name
                           end
end
pre_conversion() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 42
def pre_conversion
  case direction
  when :in
    pre_conversion_in
  when :inout
    pre_conversion_inout
  when :out
    pre_conversion_out
  when :error
    pre_conversion_error
  end
end
return_value_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 34
def return_value_name
  post_converted_name if has_output_value? && !array_length_parameter?
end

Private Instance Methods

allocated_by_them?() click to toggle source

Check if an out argument needs to be allocated by them, the callee. Since caller_allocates is false by default, we must also check that the type is a pointer. For example, an out parameter of type gint8* will always be allocated by the caller (that's us).

# File lib/gir_ffi/builders/argument_builder.rb, line 140
def allocated_by_them?
  !arginfo.caller_allocates? && type_info.pointer?
end
array_length_assignment() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 178
def array_length_assignment
  arrname = array_arg.name
  "#{name} = #{arrname}.nil? ? 0 : #{arrname}.length"
end
callback_argument_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 235
def callback_argument_name
  related_callback_builder.call_argument_name
end
caller_allocated_object?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 201
def caller_allocated_object?
  [:struct, :array].include?(specialized_type_tag) &&
    arginfo.caller_allocates?
end
fixed_array_size_check() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 152
def fixed_array_size_check
  size = type_info.array_fixed_size
  "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{name}, \"#{name}\""
end
gvalue?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 132
def gvalue?
  type_info.gvalue?
end
has_ingoing_component?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 174
def has_ingoing_component?
  (direction == :inout || direction == :in)
end
has_input_value?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 170
def has_input_value?
  has_ingoing_component? && !skipped_in?
end
has_output_value?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 166
def has_output_value?
  (direction == :inout || direction == :out) && !skipped_out?
end
has_post_conversion?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 98
def has_post_conversion?
  has_output_value? && (!caller_allocated_object? || gvalue?)
end
ingoing_convertor() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 208
def ingoing_convertor
  if skipped_in?
    NullConvertor.new("0")
  elsif destroy_notifier?
    NullConvertor.new(DESTROY_NOTIFIER)
  elsif user_data?
    ClosureToPointerConvertor.new(callback_argument_name)
  elsif needs_ruby_to_c_conversion?
    RubyToCConvertor.new(type_info, pre_convertor_argument,
                         ownership_transfer: ownership_transfer)
  else
    NullConvertor.new(pre_convertor_argument)
  end
end
ingoing_value_storage() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 93
def ingoing_value_storage
  PointerValueConvertor.new(type_spec)
    .value_to_pointer(call_argument_name, ingoing_convertor.conversion)
end
length_argument_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 144
def length_argument_name
  length_arg&.post_converted_name
end
needs_out_conversion?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 128
def needs_out_conversion?
  type_info.needs_c_to_ruby_conversion_for_functions?
end
needs_ruby_to_c_conversion?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 231
def needs_ruby_to_c_conversion?
  type_info.needs_ruby_to_c_conversion_for_functions?
end
needs_size_check?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 148
def needs_size_check?
  specialized_type_tag == :c && type_info.array_fixed_size > -1
end
out_parameter_preparation() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 183
def out_parameter_preparation
  value = if caller_allocated_object?
            if specialized_type_tag == :array
              "#{argument_class_name}.new #{type_info.element_type.inspect}"
            else
              "#{argument_class_name}.new"
            end
          else
            ffi_type_spec = TypeMap.type_specification_to_ffi_type type_spec
            "FFI::MemoryPointer.new #{ffi_type_spec.inspect}"
          end
  "#{call_argument_name} = #{value}"
end
outgoing_convertor(base) click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 115
def outgoing_convertor(base)
  FullCToRubyConvertor.new(type_info, base, length_argument_name,
                           ownership_transfer: arginfo.ownership_transfer)
end
output_value() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 102
def output_value
  return "#{call_argument_name}.get_value" if caller_allocated_object? && gvalue?

  base = pointer_to_value_method_call call_argument_name, type_spec
  if needs_out_conversion?
    outgoing_convertor(base).conversion
  elsif allocated_by_them? && specialized_type_tag != :void
    pointer_to_value_method_call base, sub_type_spec
  else
    base
  end
end
pointer_to_value_method_call(ptr_exp, spec) click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 124
def pointer_to_value_method_call(ptr_exp, spec)
  PointerValueConvertor.new(spec).pointer_to_value(ptr_exp)
end
pre_conversion_error() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 89
def pre_conversion_error
  ["#{call_argument_name} = FFI::MemoryPointer.new(:pointer).write_pointer nil"]
end
pre_conversion_in() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 68
def pre_conversion_in
  pr = []
  pr << fixed_array_size_check if needs_size_check?
  pr << array_length_assignment if array_length_parameter?
  pr << "#{call_argument_name} = #{ingoing_convertor.conversion}"
  pr
end
pre_conversion_inout() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 76
def pre_conversion_inout
  pr = []
  pr << fixed_array_size_check if needs_size_check?
  pr << array_length_assignment if array_length_parameter?
  pr << out_parameter_preparation
  pr << ingoing_value_storage
  pr
end
pre_conversion_out() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 85
def pre_conversion_out
  [out_parameter_preparation]
end
pre_convertor_argument() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 223
def pre_convertor_argument
  if ownership_transfer == :everything && specialized_type_tag == :object
    "#{name} && #{name}.ref"
  else
    name
  end
end
skipped_in?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 157
def skipped_in?
  arginfo.skip?
end
skipped_out?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 161
def skipped_out?
  arginfo.skip? ||
    array_arg && array_arg.specialized_type_tag == :strv
end
sub_type_spec() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 120
def sub_type_spec
  type_spec[1]
end
type_spec() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 197
def type_spec
  type_info.tag_or_class
end