Module: GirFFI::ArgHelper

Defined in:
lib/gir_ffi/arg_helper.rb

Constant Summary collapse

OBJECT_STORE =
{}
POINTER_SIZE =
FFI.type_size(:pointer)
SIMPLE_G_TYPES =
[
  :gint8, :gint16, :gint, :gint32, :gint64,
  :guint8, :guint16, :guint32, :guint64,
  :gfloat, :gdouble
]

Class Method Summary collapse

Class Method Details

.allocate_array_of_type(type, length) ⇒ Object



94
95
96
# File 'lib/gir_ffi/arg_helper.rb', line 94

def self.allocate_array_of_type type, length
  AllocationHelper.safe_malloc FFI.type_size(type) * length
end

.cast_from_pointer(type, it) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/gir_ffi/arg_helper.rb', line 109

def self.cast_from_pointer type, it
  case type
  when :utf8, :filename
    ptr_to_utf8 it
  when :gint32
    cast_pointer_to_int32 it
  else
    # FIXME: Only handles symbolic types.
    it.address
  end
end

.cast_pointer_to_int32(ptr) ⇒ Object



129
130
131
# File 'lib/gir_ffi/arg_helper.rb', line 129

def self.cast_pointer_to_int32 ptr
  cast_uint32_to_int32(ptr.address & 0xffffffff)
end

.cast_uint32_to_int32(val) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/gir_ffi/arg_helper.rb', line 121

def self.cast_uint32_to_int32 val
  if val >= 0x80000000
    -(0x100000000-val)
  else
    val
  end
end

.check_error(errpp) ⇒ Object



83
84
85
86
# File 'lib/gir_ffi/arg_helper.rb', line 83

def self.check_error errpp
  err = GLib::Error.wrap(errpp.read_pointer)
  raise err.message if err
end

.check_fixed_array_size(size, arr, name) ⇒ Object



88
89
90
91
92
# File 'lib/gir_ffi/arg_helper.rb', line 88

def self.check_fixed_array_size size, arr, name
  unless arr.size == size
    raise ArgumentError, "#{name} should have size #{size}"
  end
end

.object_pointer_to_object(optr) ⇒ Object



98
99
100
101
# File 'lib/gir_ffi/arg_helper.rb', line 98

def self.object_pointer_to_object optr
  gtype = GObject.type_from_instance_pointer optr
  wrap_object_pointer_by_gtype optr, gtype
end

.object_to_inptr(obj) ⇒ Object

FIXME: Hideous TODO: Move this implementation to InPointer



19
20
21
22
23
24
25
26
# File 'lib/gir_ffi/arg_helper.rb', line 19

def self.object_to_inptr obj
  return nil if obj.nil?
  return obj.to_ptr if obj.respond_to? :to_ptr
  return obj if obj.is_a? FFI::Pointer

  FFI::Pointer.new(obj.object_id).tap {|ptr|
    OBJECT_STORE[ptr.address] = obj }
end

.ptr_to_enum_array(enum, ptr, size) ⇒ Object



65
66
67
# File 'lib/gir_ffi/arg_helper.rb', line 65

def self.ptr_to_enum_array enum, ptr, size
  ptr.get_array_of_int32(0, size).map {|val| enum[val] }
end

.ptr_to_interface_array(klass, ptr, size) ⇒ Object



51
52
53
54
55
56
# File 'lib/gir_ffi/arg_helper.rb', line 51

def self.ptr_to_interface_array klass, ptr, size
  struct_size = klass::Struct.size
  size.times.map do |idx|
    klass.wrap(ptr + struct_size * idx)
  end
end

.ptr_to_interface_pointer_array(klass, ptr, size) ⇒ Object



58
59
60
61
62
63
# File 'lib/gir_ffi/arg_helper.rb', line 58

def self.ptr_to_interface_pointer_array klass, ptr, size
  ptrs = ptr.read_array_of_pointer(size)
  ptrs.map do |optr|
    klass.wrap(optr)
  end
end

.ptr_to_typed_array(type, ptr, size) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/gir_ffi/arg_helper.rb', line 28

def self.ptr_to_typed_array type, ptr, size
  return [] if ptr.nil? or ptr.null?

  case type
  when Class
    ptr_to_interface_array type, ptr, size
  when Module
    ptr_to_enum_array type, ptr, size
  when Array
    ptr_to_interface_pointer_array type[1], ptr, size
  when :utf8
    ptr_to_utf8_array ptr, size
  else
    ffi_type = TypeMap.map_basic_type type
    ptr.send "get_array_of_#{ffi_type}", 0, size
  end
end

.ptr_to_utf8(ptr) ⇒ Object



70
71
72
# File 'lib/gir_ffi/arg_helper.rb', line 70

def self.ptr_to_utf8 ptr
  ptr.null? ? nil : ptr.read_string
end

.ptr_to_utf8_array(ptr, size) ⇒ Object



46
47
48
49
# File 'lib/gir_ffi/arg_helper.rb', line 46

def self.ptr_to_utf8_array ptr, size
  ptrs = ptr.read_array_of_pointer(size)
  ptrs.map { |pt| ptr_to_utf8 pt }
end

.ptr_to_utf8_length(ptr, len) ⇒ Object



79
80
81
# File 'lib/gir_ffi/arg_helper.rb', line 79

def self.ptr_to_utf8_length ptr, len
  ptr.null? ? nil : ptr.read_string(len)
end

.wrap_object_pointer_by_gtype(optr, gtype) ⇒ Object



103
104
105
106
107
# File 'lib/gir_ffi/arg_helper.rb', line 103

def self.wrap_object_pointer_by_gtype optr, gtype
  return nil if optr.null?
  klass = Builder.build_by_gtype gtype
  klass.direct_wrap optr
end