Module: ObjC

Extended by:
FFI::Library
Defined in:
lib/cocoa/objc.rb,
lib/cocoa/objc/method_def.rb

Defined Under Namespace

Classes: MethodDef

Class Method Summary collapse

Class Method Details

.ffi_to_ruby_value(method, ffi_value, type) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/cocoa/objc.rb', line 100

def self.ffi_to_ruby_value method,ffi_value,type
  case type
  when '@'
    return nil if ffi_value.address == 0
    return ffi_value if method == :NSStringFromClass
    ObjC.object_to_instance(ffi_value)
  when '^v', 'Q', 'q', 'D', 'd', 'B', 'I', 'i'
    ffi_value
  when /^\^{([^=]*)=.*}$/
    return nil if ffi_value.address == 0
    ObjC.object_to_instance(ffi_value)
  when '*'
    ffi_value.read_string
  when '#'
    ffi_value
  when /^{([^=]*)=.*}$/
    ffi_value
  else
    raise type.inspect
  end
end

.msgSend_stret(return_type, id, selector, *args) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/cocoa/objc.rb', line 23

def self.msgSend_stret( return_type, id, selector, *args )
  selector = sel_registerName(selector) if selector.is_a? String
  method = "objc_msgSend_stret_for_#{return_type.name.underscore.gsub('/','_')}".to_sym
  unless respond_to? method
    attach_function method, :objc_msgSend_stret, [:pointer, :pointer, :varargs], return_type.by_value
  end
  send(method, id, selector, *args )
end

.NSString_to_String(nsstring_pointer) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/cocoa/objc.rb', line 37

def self.NSString_to_String( nsstring_pointer )
  c_string = msgSend_pointer( nsstring_pointer, "UTF8String")
  if c_string.null?
    return "(NULL)"
  else
    return c_string.read_string()
  end
end

.objc_type(type, default = 'i') ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cocoa/objc.rb', line 122

def self.objc_type type,default='i'
  case type
  when nil
    default
  when '@', 'v', 'q', 'Q', '^v', 'B'
    type
  when /^{([^=]*)=.*}$/
    type
  when /^\^{([^=]*)=.*}$/
    type
  else
    raise type.inspect
  end
end

.object_to_instance(ret) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/cocoa/objc.rb', line 72

def self.object_to_instance ret
  klass_name = NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"class")))
  return self if klass_name == '(NULL)'
  instance = begin
    Cocoa::const_get(klass_name).new(true)
  rescue
    begin
      Object.const_get(klass_name.gsub(/__/,'::')).new(true)
    rescue
      klass_name = if klass_name =~ /^__NSCF/
        "NS#{klass_name[6..-1]}" 
      elsif klass_name[0]=='_'
        if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
          superklass.name.split('::').last
        else
          "FIX_#{klass_name}" 
        end
      else
        klass_name
      end
      klass = smart_constantize(ret,klass_name)
      klass.new(true)
    end
  end
  instance.object = ret
  instance
end

.smart_constantize(ret, klass_name) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/cocoa/objc.rb', line 46

def self.smart_constantize ret,klass_name
  begin
    Cocoa.const_get(klass_name)
  rescue
    _superclass = ObjC.msgSend_pointer(ret,'superclass')
    superclass_name = ObjC::NSString_to_String(Cocoa::NSStringFromClass(_superclass))
    superclass_name = if superclass_name =~ /^__NSCF/
      "NS#{klass_name[6..-1]}" 
    elsif superclass_name[0]=='_'
      if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
        superklass.name.split('::').last
      else
        "FIX_#{superclass_name}" 
      end
    else
      superclass_name
    end
    superclass = Cocoa::const_get(superclass_name) rescue smart_constantize(_superclass,superclass_name)
    proxy = Class.new(superclass)
    Cocoa.const_set(klass_name, proxy)
    klass = Cocoa.const_get(klass_name)
    superclass.inherited(klass)
    klass
  end
end

.String_to_NSString(string) ⇒ Object



32
33
34
35
# File 'lib/cocoa/objc.rb', line 32

def self.String_to_NSString( string )
  nsstring_class = objc_getClass("NSString")
  msgSend_pointer(nsstring_class, "stringWithUTF8String:", :string, string )
end