Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  
  package org.jruby.ext.ffi.jffi;
  
  import org.jruby.Ruby;
  import org.jruby.RubyHash;
 
 @JRubyClass(name="FFI::Function", parent="FFI::Pointer")
 public final class Function extends org.jruby.ext.ffi.AbstractInvoker {
     
     private final com.kenai.jffi.Function function;
     private final NativeFunctionInfo functionInfo;
     private final IRubyObject enums;
     private final boolean saveError;
     private volatile boolean autorelease = true;
 
     public static RubyClass createFunctionClass(Ruby runtimeRubyModule module) {
         RubyClass result = module.defineClassUnder("Function",
                 module.getClass("Pointer"),
                 .);
         result.defineAnnotatedMethods(AbstractInvoker.class);
         result.defineAnnotatedMethods(Function.class);
         result.defineAnnotatedConstants(Function.class);
 
         return result;
     }
     
     Function(Ruby runtimeRubyClass klassDirectMemoryIO address,
             Type returnTypeType[] parameterTypesCallingConvention convention,
             IRubyObject enumsboolean saveError) {
         super(runtimeklassparameterTypes.lengthaddress);
 
         this. = new NativeFunctionInfo(runtimereturnTypeparameterTypesconvention);
 
          = new com.kenai.jffi.Function(address.getAddress(), 
                 ...saveError);
         
         this. = enums;
         this. = saveError;
         // Wire up Function#call(*args) to use the super-fast native invokers
     }
 
     Function(Ruby runtimeRubyClass klassDirectMemoryIO address,
             NativeFunctionInfo functionInfoIRubyObject enums) {
         super(runtimeklassfunctionInfo.parameterTypes.lengthaddress);
 
         this. = functionInfo;
 
          = new com.kenai.jffi.Function(address.getAddress(), 
                 functionInfo.jffiReturnTypefunctionInfo.jffiParameterTypesfunctionInfo.convention);
         this. = enums;
         this. = true;
         // Wire up Function#call(*args) to use the super-fast native invokers
     }
     
     @JRubyMethod(name = { "new" }, meta = true, required = 2, optional = 2)
     public static IRubyObject newInstance(ThreadContext contextIRubyObject recvIRubyObject[] argsBlock block) {
         DirectMemoryIO fptr = null;
         RubyHash options = null;
         Object proc = null;
         int optionsIndex = 2;
 
         Type returnType = org.jruby.ext.ffi.Util.findType(contextargs[0]);
 
         if (!(args[1] instanceof RubyArray)) {
             throw context.runtime.newTypeError("Invalid parameter array "
                     + args[1].getMetaClass().getName() + " (expected Array)");
         }
 
         RubyArray paramTypes = (RubyArrayargs[1];
         Type[] parameterTypes = new Type[paramTypes.size()];
         for (int i = 0; i < parameterTypes.length; ++i) {
             parameterTypes[i] = org.jruby.ext.ffi.Util.findType(contextparamTypes.entry(i));
         }
 
         if (args.length > 2 && args[2] instanceof Pointer) {
             fptr = new CodeMemoryIO(context.runtime, (Pointerargs[2]);
             optionsIndex = 3;
         } else if (args.length > 2 && (args[2] instanceof RubyProc || args[2].respondsTo("call"))) {
             proc = args[2];
            optionsIndex = 3;
        } else if (block.isGiven()) {
            proc = block;
            optionsIndex = 2;
        } else {
            throw context.runtime.newTypeError("Invalid function address "
                    + args[0].getMetaClass().getName() + " (expected FFI::Pointer)");
        }    
        // Get the convention from the options hash
        String convention = "default";
        IRubyObject enums = null;
        boolean saveError = true;
        if (args.length > optionsIndex && args[optionsIndexinstanceof RubyHash) {
            options = (RubyHashargs[optionsIndex];
            IRubyObject rbConvention = options.fastARef(context.runtime.newSymbol("convention"));
            if (rbConvention != null && !rbConvention.isNil()) {
                convention = rbConvention.asJavaString();
            }
            IRubyObject rbSaveErrno = options.fastARef(context.runtime.newSymbol("save_errno"));
            if (rbSaveErrno != null && !rbSaveErrno.isNil()) {
                saveError = rbSaveErrno.isTrue();
            }
            enums = options.fastARef(context.runtime.newSymbol("enums"));
            if (enums != null && !enums.isNil() && !(enums instanceof RubyHash)) {
                throw context.runtime.newTypeError("wrong type for options[:enum] "
                        + enums.getMetaClass().getName() + " (expected Hash)");
            }
        }
        CallingConvention callConvention = "stdcall".equals(convention)
                        ? . : .;
        if (fptr == null && proc != null) {
            fptr = CallbackManager.getInstance().newClosure(context.runtime,
                    returnTypeparameterTypesproccallConvention);
        }
        return new Function(context.runtime, (RubyClassrecvfptr,
                    returnTypeparameterTypescallConventionenumssaveError);
    }
    @JRubyMethod(name = "free")
    public final IRubyObject free(ThreadContext context) {
        if (getMemoryIO() instanceof AllocatedDirectMemoryIO) {
            ((AllocatedDirectMemoryIOgetMemoryIO()).free();
        } else {
            throw context.runtime.newRuntimeError("cannot free non-allocated function");
        }
        
        // Replace memory object with one that throws an exception on any access
        setMemoryIO(new FreedMemoryIO(context.runtime));
        return context.runtime.getNil();
    }
    @JRubyMethod(name = "autorelease=", required = 1)
    public final IRubyObject autorelease(ThreadContext contextIRubyObject release) {
        if ( != release.isTrue() && getMemoryIO() instanceof AllocatedDirectMemoryIO) {
            ((AllocatedDirectMemoryIOgetMemoryIO()).setAutoRelease( = release.isTrue());
        }
        return context.runtime.getNil();
    }
    @JRubyMethod(name = { "autorelease?""autorelease" })
    public final IRubyObject autorelease_p(ThreadContext context) {
        return context.runtime.newBoolean();
    }
    @Override
    public DynamicMethod createDynamicMethod(RubyModule module) {
        return MethodFactory.createDynamicMethod(getRuntime(), module,
                    ..., !);
    }
    
New to GrepCode? Check out our FAQ X