Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.ext.ffi.jffi;
  
  import org.jruby.*;
 
 import java.util.Map;


 
 public class DataConverters {
     @SuppressWarnings("unchecked")
     private static final Map<RubyHashNativeDataConverterenumConverters = Collections.synchronizedMap(new WeakIdentityHashMap());
 
     static boolean isEnumConversionRequired(Type typeRubyHash enums) {
         if (type instanceof Type.Builtin && enums != null && !enums.isEmpty()) {
             switch (type.getNativeType()) {
                 case :
                 case :
                 case :
                 case :
                 case :
                 case :
                 case :
                 case :
                 case :
                 case :
                     return true;
                     
                 default:
                     return false;
             }
         }
         return false;
     }
    
 
     static NativeDataConverter getResultConverter(Type type) {
         if (type instanceof Type.Builtin) {
             return null;
         
         } else if (type instanceof MappedType) {
             return new MappedDataConverter((MappedTypetype);
         
         } else if (type instanceof CallbackInfo) {
             return new CallbackDataConverter((CallbackInfotype);
         }
         
         return null;
     }
 
 
     static NativeDataConverter getParameterConverter(Type type) {
         if (type instanceof MappedType) {
             return new MappedDataConverter((MappedTypetype);
 
         } else if (type instanceof CallbackInfo) {
             return new CallbackDataConverter((CallbackInfotype);
         }
 
         return null;
     }
 
     static NativeDataConverter getParameterConverter(Type typeRubyHash enums) {
         if (isEnumConversionRequired(typeenums)) {
             NativeDataConverter converter = .get(enums);
             if (converter != null) {
                 return converter;
             }
             .put(enumsconverter = new IntOrEnumConverter(.enums));
             return converter;
         
         } else {
             return getParameterConverter(type);
         }
     }
 
     public static final class IntOrEnumConverter extends NativeDataConverter {
         private final NativeType nativeType;
         private final RubyHash enums;
         private volatile IdentityHashMap<RubySymbolRubyIntegersymbolToValue = new IdentityHashMap<RubySymbolRubyInteger>();
 
         public IntOrEnumConverter(NativeType nativeTypeRubyHash enums) {
             this. = nativeType;
             this. = enums;
         }
 
         @Override
         public NativeType nativeType() {
             return ;
        }
        @Override
        public IRubyObject fromNative(ThreadContext contextIRubyObject obj) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        @Override
        public IRubyObject toNative(ThreadContext contextIRubyObject obj) {
            // Fast path - handle fixnums quickly
            if (obj instanceof RubyFixnum) {
                return obj;
            }
            return lookupOrConvert(obj);
        }
        IRubyObject lookupOrConvert(IRubyObject obj) {
            if (obj instanceof RubySymbol) {
                IRubyObject value;
                if ((value = .get(obj)) != null) {
                    return value;
                }
                return lookupAndCacheValue(obj);
            } else {
                return obj.convertToInteger();
            }
        }
        private synchronized IRubyObject lookupAndCacheValue(IRubyObject obj) {
            IRubyObject value = .fastARef(obj);
            if (value.isNil() || !(value instanceof RubyInteger)) {
                throw obj.getRuntime().newArgumentError("invalid enum value, " + obj.inspect());
            }
            s2v.put((RubySymbolobj, (RubyIntegervalue);
            this. = new IdentityHashMap<RubySymbolRubyInteger>(s2v);
            return value;
        }
    }
    
    public static final class MappedDataConverter extends NativeDataConverter {
        private final MappedType converter;
        public MappedDataConverter(MappedType converter) {
            super(converter.isReferenceRequired(), converter.isPostInvokeRequired());
            this. = converter;
        }
        
        public NativeType nativeType() {
            return .getRealType().getNativeType();
        }
        public IRubyObject fromNative(ThreadContext contextIRubyObject obj) {
            return .fromNative(contextobj);
        }
        public IRubyObject toNative(ThreadContext contextIRubyObject obj) {
            return .toNative(contextobj);
        }
    }
    
    public static final class CallbackDataConverter extends NativeDataConverter {
        private final CachingCallSite callSite = new FunctionalCachingCallSite("call");
        private final NativeCallbackFactory callbackFactory;
        private final NativeFunctionInfo functionInfo;
        public CallbackDataConverter(CallbackInfo cbInfo) {
            this. = CallbackManager.getInstance().getCallbackFactory(cbInfo.getRuntime(), cbInfo);
            this. = new NativeFunctionInfo(cbInfo.getRuntime(),
                    cbInfo.getReturnType(), cbInfo.getParameterTypes(),
                    cbInfo.isStdcall() ? . : .);
        }
        
        public NativeType nativeType() {
            return .;
        }
        public IRubyObject fromNative(ThreadContext contextIRubyObject obj) {
            if (!(obj instanceof Pointer)) {
                throw context.runtime.newTypeError("internal error: non-pointer");
            }
            Pointer ptr = (Pointerobj;
            if (ptr.getAddress() == 0) {
                return context.runtime.getNil();
            }
            return new org.jruby.ext.ffi.jffi.Function(context.runtime,
                    context.runtime.getModule("FFI").getClass("Function"),
                    new CodeMemoryIO(context.runtimeptr), null);
        }
        public IRubyObject toNative(ThreadContext contextIRubyObject obj) {
            if (obj instanceof Pointer || obj.isNil()) {
                return obj;
            
            } else if (obj instanceof RubyObject) {
                return .getCallback((RubyObjectobj);
            } else {
                throw context.runtime.newTypeError("wrong argument type.  Expected callable object");
            }
        }
    }
    
    public static final class ChainedDataConverter extends NativeDataConverter {
        private final NativeDataConverter upper;
        private final NativeDataConverter lower;
        public ChainedDataConverter(NativeDataConverter firstNativeDataConverter second) {
            super(first.isReferenceRequired() || second.isReferenceRequired(), first.isPostInvokeRequired() || second.isPostInvokeRequired());
            this. = first;
            this. = second;
        }
        
        public NativeType nativeType() {
            return .nativeType();
        }
        public IRubyObject fromNative(ThreadContext contextIRubyObject obj) {
            return .fromNative(context.fromNative(contextobj));
        }
        public IRubyObject toNative(ThreadContext contextIRubyObject obj) {
            return .toNative(context.toNative(contextobj));
        }
    }
New to GrepCode? Check out our FAQ X