class GirFFI::Builders::ArgumentBuilder

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

Public Instance Methods

capture_variable_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 29
def capture_variable_name
  nil
end
method_argument_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 11
def method_argument_name
  name if has_input_value? && !array_length_parameter?
end
post_conversion() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 51
def post_conversion
  if 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 15
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 33
def pre_conversion
  pr = []
  case direction
  when :in
    pr << fixed_array_size_check if needs_size_check?
    pr << array_length_assignment if array_length_parameter?
    pr << "#{call_argument_name} = #{ingoing_convertor.conversion}"
  when :inout
    pr << fixed_array_size_check if needs_size_check?
    pr << array_length_assignment if array_length_parameter?
    pr << out_parameter_preparation
    pr << "#{call_argument_name}.set_value #{ingoing_convertor.conversion}"
  when :out
    pr << out_parameter_preparation
  end
  pr
end
return_value_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 23
def return_value_name
  if has_output_value?
    post_converted_name unless array_length_parameter?
  end
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 85
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 119
def array_length_assignment
  arrname = @array_arg.name
  "#{name} = #{arrname}.nil? ? 0 : #{arrname}.length"
end
array_length_parameter?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 93
def array_length_parameter?
  @array_arg
end
caller_allocated_object?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 137
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 101
def fixed_array_size_check
  size = type_info.array_fixed_size
  "GirFFI::ArgHelper.check_fixed_array_size #{size}, #{name}, \"#{name}\""
end
has_input_value?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 115
def has_input_value?
  (direction == :inout || direction == :in) && !skipped?
end
has_output_value?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 111
def has_output_value?
  (direction == :inout || direction == :out) && !skipped?
end
has_post_conversion?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 62
def has_post_conversion?
  has_output_value? && !caller_allocated_object?
end
ingoing_convertor() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 142
def ingoing_convertor
  if skipped?
    NullConvertor.new('0')
  elsif closure?
    ClosureToPointerConvertor.new(pre_convertor_argument)
  elsif @type_info.needs_ruby_to_c_conversion_for_functions?
    RubyToCConvertor.new(@type_info, pre_convertor_argument)
  else
    NullConvertor.new(pre_convertor_argument)
  end
end
length_argument_name() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 89
def length_argument_name
  length_arg && length_arg.post_converted_name
end
needs_out_conversion?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 77
def needs_out_conversion?
  @type_info.needs_c_to_ruby_conversion_for_functions?
end
needs_size_check?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 97
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 124
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
            "GirFFI::InOutPointer.for #{type_info.tag_or_class.inspect}"
          end
  "#{call_argument_name} = #{value}"
end
output_value() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 66
def output_value
  base = "#{call_argument_name}.to_value"
  if needs_out_conversion?
    CToRubyConvertor.new(@type_info, base, length_argument_name).conversion
  elsif allocated_by_them?
    "GirFFI::InOutPointer.new(#{type_info.tag_or_class[1].inspect}, #{base}).to_value"
  else
    base
  end
end
pre_convertor_argument() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 154
def pre_convertor_argument
  if ownership_transfer == :everything && specialized_type_tag == :object
    "#{name}.ref"
  else
    name
  end
end
skipped?() click to toggle source
# File lib/gir_ffi/builders/argument_builder.rb, line 106
def skipped?
  @arginfo.skip? ||
    @array_arg && @array_arg.specialized_type_tag == :strv
end