class FFIGen::StructOrUnion

Attributes

description[RW]
fields[R]
name[RW]
oo_functions[R]
written[R]

Public Class Methods

new(generator, name, is_union) click to toggle source
# File lib/ffi_gen.rb, line 100
def initialize(generator, name, is_union)
  @generator = generator
  @name = name
  @is_union = is_union
  @description = []
  @fields = []
  @oo_functions = []
  @written = false
end

Public Instance Methods

java_description() click to toggle source
# File lib/ffi_gen/java_output.rb, line 161
def java_description
  java_name
end
java_jna_type() click to toggle source
# File lib/ffi_gen/java_output.rb, line 157
def java_jna_type
  java_name
end
java_name() click to toggle source
# File lib/ffi_gen/java_output.rb, line 153
def java_name
  @java_name ||= @name.to_java_classname
end
ruby_description() click to toggle source
# File lib/ffi_gen/ruby_output.rb, line 141
def ruby_description
  @written ? ruby_name : "FFI::Pointer(*#{ruby_name})"
end
ruby_ffi_type() click to toggle source
# File lib/ffi_gen/ruby_output.rb, line 137
def ruby_ffi_type
  @written ? ruby_name : ":pointer"
end
ruby_name() click to toggle source
# File lib/ffi_gen/ruby_output.rb, line 133
def ruby_name
  @ruby_name ||= @name.to_ruby_classname
end
write_java(writer) click to toggle source
# File lib/ffi_gen/java_output.rb, line 108
def write_java(writer)
  writer.comment do
    writer.write_description @description
    unless @fields.empty?
      writer.puts "", "= Fields:"
      @fields.each do |field|
        writer.puts ":#{field[:name].to_java_downcase} ::"
        writer.write_description field[:comment], false, "  (#{field[:type].java_description}) ", "  "
      end
    end
  end
  
  writer.puts "public static class #{java_name} extends #{@is_union ? 'Union' : (@fields.empty? ? 'PointerType' : 'Structure')} {"
  writer.indent do
    @fields.each do |field|
      if field[:type].is_a? ByReferenceType and not field[:type].inner_type.fields.empty?
        writer.puts "public volatile #{field[:type].java_jna_type}.ByReference #{field[:name].to_java_downcase};"
      else
        writer.puts "public volatile #{field[:type].java_jna_type} #{field[:name].to_java_downcase};"
      end
    end
    writer.puts "// hidden structure" if @fields.empty?

    writer.puts "protected List<String> getFieldOrder() {"
    writer.indent do
      fs = @fields.map{|f| '"' + f[:name].to_java_downcase + '"'}.join(", ")
      writer.puts "return Arrays.asList(new String[] { #{fs} } );"
    end
    writer.puts "}"

    if not @fields.empty?
      writer.puts "public static class ByValue extends #{java_name} implements Structure.ByValue {}"
      writer.puts "public static class ByReference extends #{java_name} implements Structure.ByReference {"
      writer.indent do
        writer.puts "public ByReference() { }"
        writer.puts "public ByReference(Pointer p) { super(p); read(); }"
      end
      writer.puts "}"
      writer.puts "public #{java_name}() { }"
      writer.puts "public #{java_name}(Pointer p) { super(p); read(); }"
    end
  end
  writer.puts "}", ""
end
write_ruby(writer) click to toggle source
# File lib/ffi_gen/ruby_output.rb, line 83
def write_ruby(writer)
  writer.comment do
    writer.write_description @description
    unless @fields.empty?
      writer.puts "", "= Fields:"
      @fields.each do |field|
        writer.puts ":#{field[:name].to_ruby_downcase} ::"
        writer.write_description field[:comment], false, "  (#{field[:type].ruby_description}) ", "  "
      end
    end
  end

  @fields << { name: Name.new(["dummy"]), type: PrimitiveType.new(:char_s) } if @fields.empty?

  unless @oo_functions.empty?
    writer.puts "module #{ruby_name}Wrappers"
    writer.indent do
      @oo_functions.each_with_index do |(name, function), index|
        parameter_names = function.parameters[1..-1].map { |parameter| parameter[:name].to_ruby_downcase }
        writer.puts "" unless index == 0
        writer.comment do
          function.parameters[1..-1].each do |parameter|
            writer.write_description parameter[:description], false, "@param [#{parameter[:type].ruby_description}] #{parameter[:name].to_ruby_downcase} ", "  "
          end
          return_type = function.return_type.is_a?(StructOrUnion) ? function.return_type.ruby_name : function.return_type.ruby_description
          writer.write_description function.return_value_description, false, "@return [#{return_type}] ", "  "
        end
        writer.puts "def #{name.to_ruby_downcase}(#{parameter_names.join(', ')})"
        writer.indent do
          cast = function.ruby_ffi_return_type.is_a?(StructOrUnion) ? "#{function.return_type.ruby_name}.new " : ""
          writer.puts "#{cast}#{@generator.module_name}.#{function.ruby_name}(#{(["self"] + parameter_names).join(', ')})"
        end
        writer.puts "end"
      end
    end
    writer.puts "end", ""
  end

  writer.puts "class #{ruby_name} < #{@is_union ? 'FFI::Union' : 'FFI::Struct'}"
  writer.indent do
    writer.puts "include #{ruby_name}Wrappers" unless @oo_functions.empty?
    writer.write_array @fields, ",", "layout ", "       " do |field|
      ":#{field[:name].to_ruby_downcase}, #{field[:type].ruby_ffi_type}"
    end
  end
  writer.puts "end", ""

  @written = true
end