Class: FFIGen::FunctionOrCallback

Inherits:
Type
  • Object
show all
Defined in:
lib/ffi_gen.rb,
lib/ffi_gen/java_output.rb,
lib/ffi_gen/ruby_output.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(generator, name, parameters, return_type, is_callback, blocking, function_description, return_value_description) ⇒ FunctionOrCallback

Returns a new instance of FunctionOrCallback.



114
115
116
117
118
119
120
121
122
123
# File 'lib/ffi_gen.rb', line 114

def initialize(generator, name, parameters, return_type, is_callback, blocking, function_description, return_value_description)
  @generator = generator
  @name = name
  @parameters = parameters
  @return_type = return_type
  @is_callback = is_callback
  @blocking = blocking
  @function_description = function_description
  @return_value_description = return_value_description
end

Instance Attribute Details

#function_descriptionObject (readonly)

Returns the value of attribute function_description.



112
113
114
# File 'lib/ffi_gen.rb', line 112

def function_description
  @function_description
end

#nameObject (readonly)

Returns the value of attribute name.



112
113
114
# File 'lib/ffi_gen.rb', line 112

def name
  @name
end

#parametersObject (readonly)

Returns the value of attribute parameters.



112
113
114
# File 'lib/ffi_gen.rb', line 112

def parameters
  @parameters
end

#return_typeObject (readonly)

Returns the value of attribute return_type.



112
113
114
# File 'lib/ffi_gen.rb', line 112

def return_type
  @return_type
end

#return_value_descriptionObject (readonly)

Returns the value of attribute return_value_description.



112
113
114
# File 'lib/ffi_gen.rb', line 112

def return_value_description
  @return_value_description
end

Instance Method Details

#java_descriptionObject



252
253
254
# File 'lib/ffi_gen/java_output.rb', line 252

def java_description
  "Proc(_callback_#{java_name}_)"
end

#java_jna_return_typeObject



245
246
247
248
249
250
# File 'lib/ffi_gen/java_output.rb', line 245

def java_jna_return_type
  if @return_type.is_a? ByReferenceType and not @return_type.inner_type.fields.empty?
    return "#{@return_type.java_jna_type}.ByReference"
  end
  @return_type.java_jna_type
end

#java_jna_typeObject



241
242
243
# File 'lib/ffi_gen/java_output.rb', line 241

def java_jna_type
  java_name
end

#java_nameObject



236
237
238
239
# File 'lib/ffi_gen/java_output.rb', line 236

def java_name
  n = (@is_callback ? (@generator.module_name + 'Interface.') : '') + @name.to_java_downcase
  @java_name ||= n
end

#ruby_descriptionObject



183
184
185
# File 'lib/ffi_gen/ruby_output.rb', line 183

def ruby_description
  "Proc(_callback_#{ruby_name}_)"
end

#ruby_ffi_return_typeObject



172
173
174
175
176
177
# File 'lib/ffi_gen/ruby_output.rb', line 172

def ruby_ffi_return_type
  if @return_type.is_a? ByReferenceType and not @return_type.inner_type.fields.empty?
    return @return_type.inner_type
  end
  @return_type
end

#ruby_ffi_typeObject



179
180
181
# File 'lib/ffi_gen/ruby_output.rb', line 179

def ruby_ffi_type
  ":#{ruby_name}"
end

#ruby_nameObject



168
169
170
# File 'lib/ffi_gen/ruby_output.rb', line 168

def ruby_name
  @ruby_name ||= @name.to_ruby_downcase
end

#write_java(writer) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/ffi_gen/java_output.rb', line 167

def write_java(writer)
  if @is_callback
    writer.puts "public static interface #{java_name.split('.').last} extends Callback {"
    writer.indent do
      jna_signature = "#{@parameters.map{ |parameter| "#{parameter[:type].java_jna_type} #{parameter[:name].to_java_downcase}" }.join(', ')}"
      writer.puts "#{java_jna_return_type} invoke(#{jna_signature});"
    end
    writer.puts "}", ""
    return
  end

  jna_signature = "#{@parameters.map{ |parameter| "#{parameter[:type].java_jna_type} #{parameter[:name].to_java_downcase}" }.join(', ')}"
  writer.puts "@NativeName(\"#{@name.raw}\")", "#{java_jna_return_type} #{java_name}(#{jna_signature});", ""
end

#write_ruby(writer) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/ffi_gen/ruby_output.rb', line 147

def write_ruby(writer)
  writer.puts "@blocking = true" if @blocking
  writer.comment do
    writer.write_description @function_description
    writer.puts "", "<em>This entry is only for documentation and no real method.</em>" if @is_callback
    writer.puts "", "@method #{@is_callback ? "_callback_#{ruby_name}_" : ruby_name}(#{@parameters.map{ |parameter| parameter[:name].to_ruby_downcase }.join(', ')})"
    @parameters.each do |parameter|
      writer.write_description parameter[:description], false, "@param [#{parameter[:type].ruby_description}] #{parameter[:name].to_ruby_downcase} ", "  "
    end
    writer.write_description @return_value_description, false, "@return [#{@return_type.ruby_description}] ", "  "
    writer.puts "@scope class"
  end

  ffi_signature = "[#{@parameters.map{ |parameter| parameter[:type].ruby_ffi_type }.join(', ')}], #{@return_type.ruby_ffi_type}"
  if @is_callback
    writer.puts "callback :#{ruby_name}, #{ffi_signature}", ""
  else
    writer.puts "attach_function :#{ruby_name}, :#{@name.raw}, #{ffi_signature}", ""
  end
end

#write_static_java(writer) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/ffi_gen/java_output.rb', line 182

def write_static_java(writer)
  return if @is_callback # must be in Library
  
  replace = {}
  parameters = []
  lp = nil
  @parameters.each do |p|
    if lp and lp[:type].is_a?(PointerType) and lp[:type].pointee_type.respond_to?(:clang_type) and lp[:type].pointee_type.clang_type == :u_char and [:u_long, :u_long_long].include?(p[:type].clang_type)
      n = lp[:name].to_java_downcase
      replace[n] = "bytesToPointer(#{n})"
      replace[p[:name].to_java_downcase] = "#{n}.length";
      d = lp.dup
      d[:type] = ArrayType.new(lp[:type].pointee_type, nil)
      parameters << d
      lp = nil
    else
      if lp
        parameters << lp
      end
      lp = p
    end
  end
  if lp
    parameters << lp
  end
  
  writer.comment do
    writer.write_description @function_description
    writer.puts "", "<em>This entry is only for documentation and no real method.</em>" if @is_callback
    writer.puts "", "@method #{@is_callback ? "_callback_#{java_name}_" : java_name}(#{parameters.map{ |parameter| parameter[:name].to_java_downcase }.join(', ')})"
    parameters.each do |parameter|
      writer.write_description parameter[:description], false, "@param [#{parameter[:type].java_description}] #{parameter[:name].to_java_downcase} ", "  "
    end
    writer.write_description @return_value_description, false, "@return [#{@return_type.java_description}] ", "  "
    writer.puts "@scope class"
  end
  
  args = @parameters.map{ |parameter|
    n = parameter[:name].to_java_downcase
    replace[n] || n
  }.join(', ')
  jna_signature = "#{parameters.map{ |parameter| "#{parameter[:type].java_jna_type} #{parameter[:name].to_java_downcase}" }.join(', ')}"
  writer.puts "public static #{java_jna_return_type} #{java_name}(#{jna_signature}) {"
  writer.indent do
    call = "INSTANCE.#{java_name}(#{args});"
    if @return_type.respond_to? :clang_type and @return_type.clang_type == :void
      writer.puts call
    else
      writer.puts "return #{call}"
    end
  end
  writer.puts "}", ""
end