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



117
118
119
# File 'lib/gir_ffi/arg_helper.rb', line 117

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

.cast_from_pointer(type, it) ⇒ Object



132
133
134
135
136
137
138
139
140
141
# File 'lib/gir_ffi/arg_helper.rb', line 132

def self.cast_from_pointer type, it
  case type
  when :utf8, :filename
    ptr_to_utf8 it
  when :gint32
    cast_pointer_to_int32 it
  else
    it.address
  end
end

.cast_pointer_to_int32(ptr) ⇒ Object



151
152
153
# File 'lib/gir_ffi/arg_helper.rb', line 151

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

.cast_uint32_to_int32(val) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/gir_ffi/arg_helper.rb', line 143

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

.check_error(errpp) ⇒ Object



106
107
108
109
# File 'lib/gir_ffi/arg_helper.rb', line 106

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



111
112
113
114
115
# File 'lib/gir_ffi/arg_helper.rb', line 111

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



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

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



81
82
83
# File 'lib/gir_ffi/arg_helper.rb', line 81

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

.ptr_to_interface_array(klass, ptr, size) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/gir_ffi/arg_helper.rb', line 65

def self.ptr_to_interface_array klass, ptr, size
  return [] if ptr.nil? or ptr.null?
  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



73
74
75
76
77
78
79
# File 'lib/gir_ffi/arg_helper.rb', line 73

def self.ptr_to_interface_pointer_array klass, ptr, size
  return [] if ptr.nil? or ptr.null?
  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
# File 'lib/gir_ffi/arg_helper.rb', line 28

def self.ptr_to_typed_array type, ptr, size
  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 FFI::Enum
    ptr_to_enum_array type, ptr, size
  when :utf8
    ptr_to_utf8_array ptr, size
  else
    self.send "ptr_to_#{type}_array", ptr, size
  end
end

.ptr_to_utf8(ptr) ⇒ Object



86
87
88
# File 'lib/gir_ffi/arg_helper.rb', line 86

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

.ptr_to_utf8_array(ptr, size) ⇒ Object



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

def self.ptr_to_utf8_array ptr, size
  return [] if ptr.nil? or ptr.null?
  ptrs = ptr.read_array_of_pointer(size)
  ptrs.map { |pt| ptr_to_utf8 pt }
end

.ptr_to_utf8_length(ptr, len) ⇒ Object



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

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

.setup_ptr_to_type_array_handler_for(*types) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/gir_ffi/arg_helper.rb', line 45

def self.setup_ptr_to_type_array_handler_for *types
  types.flatten.each do |type|
    ffi_type = TypeMap.map_basic_type type
    defn =
      "def self.ptr_to_#{type}_array ptr, size
        return [] if ptr.nil? or ptr.null?
        ptr.get_array_of_#{ffi_type}(0, size)
      end"
    eval defn
  end
end

.wrap_object_pointer_by_gtype(optr, gtype) ⇒ Object



126
127
128
129
130
# File 'lib/gir_ffi/arg_helper.rb', line 126

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