/* Copyright (c) 2007 Wayne Meissner, All Rights Reserved * * The contents of this file is dual-licensed under 2 * alternative Open Source/Free licenses: LGPL 2.1 or later and * Apache License 2.0. (starting with JNA version 4.0.0). * * You can freely decide which license you want to apply to * the project. * * You may obtain a copy of the LGPL License at: * * http://www.gnu.org/licenses/licenses.html * * A copy is also included in the downloadable source code package * containing JNA, in file "LGPL2.1". * * You may obtain a copy of the Apache License at: * * http://www.apache.org/licenses/ * * A copy is also included in the downloadable source code package * containing JNA, in file "AL2.0". */ package com.sun.jna; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** Provide custom mappings to and from native types. The default lookup * checks classes corresponding to converters in the order added; if the * class to be converted is an instance of the converter's registered class, * the converter will be used.<p> * Derived classes should install additional converters using * {@link #addToNativeConverter} * and/or {@link #addFromNativeConverter} in the default constructor. Classes * for primitive types will automatically register for the corresponding * Object type and vice versa (i.e. you don't have to register both * <code>int.class</code> and <code>Integer.class</code>). * If you want different mapping behavior than the default, simply override * {@link #getToNativeConverter} and {@link #getFromNativeConverter}. * @see Library#OPTION_TYPE_MAPPER */ public class DefaultTypeMapper implements TypeMapper { private static class Entry { public Class<?> type; public Object converter; public Entry(Class<?> type, Object converter) { this.type = type; this.converter = converter; } } private List<Entry> toNativeConverters = new ArrayList<Entry>(); private List<Entry> fromNativeConverters = new ArrayList<Entry>(); private Class<?> getAltClass(Class<?> cls) { if (cls == Boolean.class) { return boolean.class; } else if (cls == boolean.class) { return Boolean.class; } else if (cls == Byte.class) { return byte.class; } else if (cls == byte.class) { return Byte.class; } else if (cls == Character.class) { return char.class; } else if (cls == char.class) { return Character.class; } else if (cls == Short.class) { return short.class; } else if (cls == short.class) { return Short.class; } else if (cls == Integer.class) { return int.class; } else if (cls == int.class) { return Integer.class; } else if (cls == Long.class) { return long.class; } else if (cls == long.class) { return Long.class; } else if (cls == Float.class) { return float.class; } else if (cls == float.class) { return Float.class; } else if (cls == Double.class) { return double.class; } else if (cls == double.class) { return Double.class; } return null; } /** Add a {@link ToNativeConverter} to define the conversion into a native * type from arguments of the given Java type. Converters are * checked for in the order added. * @param cls Java class requiring conversion * @param converter {@link ToNativeConverter} to transform an object of * the given Java class into its native-compatible form. */ public void addToNativeConverter(Class<?> cls, ToNativeConverter converter) { toNativeConverters.add(new Entry(cls, converter)); Class<?> alt = getAltClass(cls); if (alt != null) { toNativeConverters.add(new Entry(alt, converter)); } } /** * Add a {@link FromNativeConverter} to convert a native result type into the * given Java type. Converters are checked for in the order added. * * @param cls Java class for the Java representation of a native type. * @param converter {@link FromNativeConverter} to transform a * native-compatible type into its Java equivalent. */ public void addFromNativeConverter(Class<?> cls, FromNativeConverter converter) { fromNativeConverters.add(new Entry(cls, converter)); Class<?> alt = getAltClass(cls); if (alt != null) { fromNativeConverters.add(new Entry(alt, converter)); } } /** * Add a {@link TypeConverter} to provide bidirectional mapping between * a native and Java type. * * @param cls Java class representation for a native type * @param converter {@link TypeConverter} to translate between native and * Java types. */ public void addTypeConverter(Class<?> cls, TypeConverter converter) { addFromNativeConverter(cls, converter); addToNativeConverter(cls, converter); } private Object lookupConverter(Class<?> javaClass, Collection<? extends Entry> converters) { for (Entry entry : converters) { if (entry.type.isAssignableFrom(javaClass)) { return entry.converter; } } return null; } @Override public FromNativeConverter getFromNativeConverter(Class<?> javaType) { return (FromNativeConverter)lookupConverter(javaType, fromNativeConverters); } @Override public ToNativeConverter getToNativeConverter(Class<?> javaType) { return (ToNativeConverter)lookupConverter(javaType, toNativeConverters); } }