Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  
  package org.jruby.ext.ffi;
  
  import java.nio.ByteOrder;
  
  import org.jruby.*;
 import static org.jruby.runtime.Visibility.*;
 
 @JRubyClass(name="FFI::Struct", parent="Object")
 public class Struct extends RubyObject implements StructLayout.Storage {
     private StructLayout layout;
     private AbstractMemory memory;
     private volatile Object[] referenceCache;
     private volatile IRubyObject[] valueCache;
     
     private static final class Allocator implements ObjectAllocator {
         public final IRubyObject allocate(Ruby runtimeRubyClass klass) {
             return new Struct(runtimeklass);
         }
         private static final ObjectAllocator INSTANCE = new Allocator();
     }

    
Registers the StructLayout class in the JRuby runtime.

Parameters:
runtime The JRuby runtime to register the new class in.
Returns:
The new class
 
     public static RubyClass createStructClass(Ruby runtimeRubyModule module) {
         
         RubyClass result = runtime.defineClassUnder("Struct"runtime.getObject(),
                 .module);
         result.defineAnnotatedMethods(Struct.class);
         result.defineAnnotatedConstants(Struct.class);
         
         return result;
     }

    
Creates a new StructLayout instance using defaults.

Parameters:
runtime The runtime for the StructLayout
 
     Struct(Ruby runtime) {
         this(runtimeruntime.getFFI().);
     }

    
Creates a new StructLayout instance.

Parameters:
runtime The runtime for the StructLayout
klass the ruby class to use for the StructLayout
 
     Struct(Ruby runtimeRubyClass klass) {
         this(runtimeklassgetStructLayout(runtimeklass), null);
     }

    
Creates a new StructLayout instance.

Parameters:
runtime The runtime for the StructLayout
klass the ruby class to use for the StructLayout
 
     Struct(Ruby runtimeRubyClass klassStructLayout layoutIRubyObject memory) {
         super(runtimeklass);
         this. = layout;
 
         if (!(memory == null || memory instanceof AbstractMemory)) {
             throw runtime.newTypeError("wrong argument type "
                     + memory.getMetaClass().getName() + " (expected Pointer or Buffer)");
         }
 
         this. = (AbstractMemorymemory;
     }
 
     static final boolean isStruct(Ruby runtimeRubyClass klass) {
         return klass.isKindOfModule(runtime.getFFI().);
     }
 
     static final int getStructSize(Ruby runtimeIRubyObject structClass) {
         return getStructLayout(runtimestructClass).getSize();
     }
     
     static final StructLayout getStructLayout(Ruby runtimeIRubyObject structClass) {
         try {
             Object layout = ((RubyClassstructClass).getFFIHandle();
             if (layout instanceof StructLayout) {
                 return (StructLayoutlayout;
             }
 
             layout = ((RubyClassstructClass).getInstanceVariable("@layout");
             if (!(layout instanceof StructLayout)) {
                 throw runtime.newRuntimeError("no valid struct layout for " + ((RubyClassstructClass).getName());
            }
            // Cache the layout on the Struct metaclass for faster retrieval next time
            ((RubyClassstructClass).setFFIHandle(layout);
            return (StructLayoutlayout;
        } catch (RaiseException ex) {
            throw runtime.newRuntimeError("No layout set for struct " + ((RubyClassstructClass).getName());
        } catch (ClassCastException ex) {
            if (!(structClass instanceof RubyClass)) {
                throw runtime.newTypeError("wrong argument type "
                        + structClass.getMetaClass().getName() + " (expected subclass of Struct)");
            }
            throw runtime.newRuntimeError("invalid layout set for struct " + ((RubyClassstructClass).getName());
        }
    }
    @JRubyMethod(name = "initialize", visibility = )
    public IRubyObject initialize(ThreadContext context) {
         = MemoryPointer.allocate(context.runtime.getSize(), 1, true);
        return this;
    }
    @JRubyMethod(name = "initialize", visibility = )
    public IRubyObject initialize(ThreadContext contextIRubyObject ptr) {
        
        if (!(ptr instanceof AbstractMemory)) {
            if (ptr.isNil()) {
                return initialize(context);
            }
            throw context.runtime.newTypeError("wrong argument type "
                    + ptr.getMetaClass().getName() + " (expected Pointer or Buffer)");
        }
        if (((AbstractMemoryptr).getSize() < .getSize()) {
            throw context.runtime.newArgumentError("memory object has insufficient space for "
                    + getMetaClass().getName());
        }
         = (AbstractMemoryptr;
        
        return this;
    }
    @JRubyMethod(name = "initialize", visibility = , required = 1, rest = true)
    public IRubyObject initialize(ThreadContext contextIRubyObject[] args) {
        if (args.length > 1) {
            IRubyObject result = getMetaClass().callMethod(context"layout"args[1] instanceof RubyArray
                ? ((RubyArrayargs[1]).toJavaArrayUnsafe()
                : java.util.Arrays.copyOfRange(args, 1, args.length));
            if (!(result instanceof StructLayout)) {
                throw context.runtime.newTypeError("Struct.layout did not return a FFI::StructLayout instance");
            }
             = (StructLayoutresult;
        }
        return initialize(contextargs[0]);
    }
    @JRubyMethod(name = "initialize_copy", visibility = )
    public IRubyObject initialize_copy(ThreadContext contextIRubyObject other) {
        if (other == this) {
            return this;
        }
        if (!(other instanceof Struct)) {
            throw context.runtime.newTypeError("not an instance of Struct");
        }
        Struct orig = (Structother;
         = (AbstractMemoryorig.getMemory().slice(context.runtime, 0, .getSize()).dup();
        if (orig.referenceCache != null) {
             = new Object[.getReferenceFieldCount()];
            System.arraycopy(orig.referenceCache, 0, , 0, .);
        }
        return this;
    }
    private static final Struct allocateStruct(ThreadContext contextIRubyObject klassint flags) {
        Ruby runtime = context.runtime;
        StructLayout layout = getStructLayout(runtimeklass);
        return new Struct(runtime, (RubyClassklasslayoutnew Buffer(runtimelayout.getSize(), flags));
    }
    @JRubyMethod(name = { "new_in""alloc_in" }, meta = true)
    public static IRubyObject allocateIn(ThreadContext contextIRubyObject klass) {
        return allocateStruct(contextklass.);
    }
    @JRubyMethod(name = { "new_in""alloc_in" }, meta = true)
    public static IRubyObject allocateIn(ThreadContext contextIRubyObject klassIRubyObject clearArg) {
        return allocateStruct(contextklass.);
    }
    @JRubyMethod(name = { "new_out""alloc_out" }, meta = true)
    public static IRubyObject allocateOut(ThreadContext contextIRubyObject klass) {
        return allocateStruct(contextklass.);
    }
    @JRubyMethod(name = { "new_out""alloc_out" }, meta = true)
    public static IRubyObject allocateOut(ThreadContext contextIRubyObject klassIRubyObject clearArg) {
        return allocateStruct(contextklass.);
    }
    @JRubyMethod(name = { "new_inout""alloc_inout" }, meta = true)
    public static IRubyObject allocateInOut(ThreadContext contextIRubyObject klass) {
        return allocateStruct(contextklass. | .);
    }
    @JRubyMethod(name = { "new_inout""alloc_inout" }, meta = true)
    public static IRubyObject allocateInOut(ThreadContext contextIRubyObject klassIRubyObject clearArg) {
        return allocateStruct(contextklass. | .);
    }
    @JRubyMethod(name = { "size" }, meta = true)
    public static IRubyObject size(ThreadContext contextIRubyObject structClass) {
        if (!(structClass instanceof RubyClass)) {
            throw context.runtime.newTypeError(structClasscontext.runtime.getClassClass());
        }
        RubyClass klass = (RubyClassstructClass;
        Object obj = klass.getFFIHandle();
        if (obj instanceof StructLayout) {
            return ((StructLayoutobj).size(context);
        }
        if ((obj = ((RubyClassstructClass).getInstanceVariable("@layout")) instanceof StructLayout) {
            return ((StructLayoutobj).size(context);
        } else {
            obj = ((RubyClassstructClass).getInstanceVariable("@size");
        }
        return obj instanceof RubyFixnum ? (RubyFixnumobj : RubyFixnum.zero(context.runtime);
    }
    @JRubyMethod(name = { "alignment""align" }, meta = true)
    public static IRubyObject alignment(ThreadContext contextIRubyObject structClass) {
        return getStructLayout(context.runtimestructClass).alignment(context);
    }
    @JRubyMethod(name = { "layout=" }, meta = true)
    public static IRubyObject set_layout(ThreadContext contextIRubyObject structClassIRubyObject layout) {
        if (!(structClass instanceof RubyClass)) {
            throw context.runtime.newTypeError(structClasscontext.runtime.getClassClass());
        }
        if (!(layout instanceof StructLayout)) {
            throw context.runtime.newTypeError(layout,
                    context.runtime.getModule("FFI").getClass("StructLayout"));
        }
        RubyClass klass = (RubyClassstructClass;
        klass.setFFIHandle(layout);
        klass.setInstanceVariable("@layout"layout);
        return structClass;
    }
    @JRubyMethod(name = "members", meta = true)
    public static IRubyObject members(ThreadContext contextIRubyObject structClass) {
        return getStructLayout(context.runtimestructClass).members(context);
    }
    @JRubyMethod(name = "offsets", meta = true)
    public static IRubyObject offsets(ThreadContext contextIRubyObject structClass) {
        return getStructLayout(context.runtimestructClass).offsets(context);
    }
    @JRubyMethod(name = "offset_of", meta = true)
    public static IRubyObject offset_of(ThreadContext contextIRubyObject structClassIRubyObject fieldName) {
        return getStructLayout(context.runtimestructClass).offset_of(contextfieldName);
    }
    /* ------------- instance methods ------------- */
    @JRubyMethod(name = "[]")
    public IRubyObject getFieldValue(ThreadContext contextIRubyObject fieldName) {
        return .getMember(context.runtimefieldName).get(contextthisgetMemory());
    }
    @JRubyMethod(name = "[]=")
    public IRubyObject setFieldValue(ThreadContext contextIRubyObject fieldNameIRubyObject fieldValue) {
        .getMember(context.runtimefieldName).put(contextthisgetMemory(), fieldValue);
        return fieldValue;
    }
    @JRubyMethod(name = { "cspec""layout" })
    public IRubyObject getLayout(ThreadContext context) {
        return ;
    }
    @JRubyMethod(name = { "pointer""to_ptr" })
    public IRubyObject pointer(ThreadContext context) {
        return getMemory();
    }
    
    @JRubyMethod(name = "members")
    public IRubyObject members(ThreadContext context) {
        return .members(context);
    }
    @JRubyMethod(name = "values")
    public IRubyObject values(ThreadContext context) {
        IRubyObject[] values = new IRubyObject[.getFieldCount()];
        int i = 0;
        for (StructLayout.Member m : .getMembers()) {
            values[i++] = m.get(contextthisgetMemory());
        }
        return RubyArray.newArrayNoCopy(context.runtimevalues);
    }
    @JRubyMethod(name = "offsets")
    public IRubyObject offsets(ThreadContext context) {
        return .offsets(context);
    }
    @JRubyMethod(name = "offset_of")
    public IRubyObject offset_of(ThreadContext contextIRubyObject fieldName) {
        return .offset_of(contextfieldName);
    }
    @JRubyMethod(name = "size")
    public IRubyObject size(ThreadContext context) {
        return .size(context);
    }
    @JRubyMethod(name = { "alignment" })
    public IRubyObject alignment(ThreadContext context) {
        return .alignment(context);
    }
    @JRubyMethod(name="null?")
    public IRubyObject null_p(ThreadContext context) {
        return context.runtime.newBoolean(getMemory().getMemoryIO().isNull());
    }
    @JRubyMethod(name = "order", required = 0)
    public final IRubyObject order(ThreadContext context) {
        return context.runtime.newSymbol(getMemoryIO().order().equals(.) ? "little" : "big");
    }
    @JRubyMethod(name = "order", required = 1)
    public final IRubyObject order(ThreadContext contextIRubyObject byte_order) {
        ByteOrder order = Util.parseByteOrder(context.runtimebyte_order);
        return new Struct(context.runtimegetMetaClass(), ,
                getMemory().order(context.runtimeorder));
    }
    @JRubyMethod(name = "clear")
    public IRubyObject clear(ThreadContext context) {
        getMemoryIO().setMemory(0, ., (byte) 0);
        return this;
    }
    public final AbstractMemory getMemory() {
        return  != null ?  : ( = MemoryPointer.allocate(getRuntime(), .getSize(), 1, true));
    }
    final MemoryIO getMemoryIO() {
        return getMemory().getMemoryIO();
    }
    public final IRubyObject getCachedValue(StructLayout.Member member) {
        return  != null ? [.getCacheableFieldIndex(member)] : null;
    }
    public final void putCachedValue(StructLayout.Member memberIRubyObject value) {
        getValueCacheForWrite()[.getCacheableFieldIndex(member)] = value;
    }
    private IRubyObject[] getValueCacheForWrite() {
        return  != null ?  : initValueCache();
    }
            = AtomicReferenceFieldUpdater.newUpdater(Struct.classIRubyObject[].class"valueCache");
    private IRubyObject[] initValueCache() {
        return ;
    }
    private Object[] getReferenceCache() {
        return  != null ?  : initReferenceCache();
    }
            = AtomicReferenceFieldUpdater.newUpdater(Struct.classObject[].class"referenceCache");
    private Object[] initReferenceCache() {
        return ;
    }
    
    public void putReference(StructLayout.Member memberObject value) {
        getReferenceCache()[.getReferenceFieldIndex(member)] = value;
    }
New to GrepCode? Check out our FAQ X