Package java.lang.reflect

Source Code of java.lang.reflect.NativeArray

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package java.lang.reflect;

import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.classmgr.VmClassLoader;
import org.jnode.vm.classmgr.VmArrayClass;
import org.jnode.vm.facade.VmUtils;
import org.jnode.vm.VmImpl;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* @see java.lang.reflect.Array
*/
class NativeArray { //TODO OPTIMIZE IT!

    /**
     * @see java.lang.reflect.Array#getLength(java.lang.Object)
     */
    private static int getLength(Object arg1) {
        if (arg1 instanceof Object[])
            return ((Object[]) arg1).length;
        if (arg1 instanceof boolean[])
            return ((boolean[]) arg1).length;
        if (arg1 instanceof byte[])
            return ((byte[]) arg1).length;
        if (arg1 instanceof char[])
            return ((char[]) arg1).length;
        if (arg1 instanceof short[])
            return ((short[]) arg1).length;
        if (arg1 instanceof int[])
            return ((int[]) arg1).length;
        if (arg1 instanceof long[])
            return ((long[]) arg1).length;
        if (arg1 instanceof float[])
            return ((float[]) arg1).length;
        if (arg1 instanceof double[])
            return ((double[]) arg1).length;
        if (arg1 == null)
            throw new NullPointerException();
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#get(java.lang.Object, int)
     */
    private static Object get(Object arg1, int arg2) {
        if (arg1 instanceof Object[])
            return ((Object[]) arg1)[arg2];
        if (arg1 instanceof boolean[])
            return ((boolean[]) arg1)[arg2] ? Boolean.TRUE : Boolean.FALSE;
        if (arg1 instanceof byte[])
            return ((byte[]) arg1)[arg2];
        if (arg1 instanceof char[])
            return ((char[]) arg1)[arg2];
        if (arg1 instanceof short[])
            return ((short[]) arg1)[arg2];
        if (arg1 instanceof int[])
            return ((int[]) arg1)[arg2];
        if (arg1 instanceof long[])
            return ((long[]) arg1)[arg2];
        if (arg1 instanceof float[])
            return ((float[]) arg1)[arg2];
        if (arg1 instanceof double[])
            return ((double[]) arg1)[arg2];
        if (arg1 == null)
            throw new NullPointerException();
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#getBoolean(java.lang.Object, int)
     */
    private static boolean getBoolean(Object arg1, int arg2) {
        if (arg1 instanceof boolean[])
            return ((boolean[]) arg1)[arg2];
        if (arg1 == null)
            throw new NullPointerException();
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#getByte(java.lang.Object, int)
     */
    private static byte getByte(Object arg1, int arg2) {
        if (arg1 instanceof byte[])
            return ((byte[]) arg1)[arg2];
        if (arg1 == null)
            throw new NullPointerException();
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#getChar(java.lang.Object, int)
     */
    private static char getChar(Object arg1, int arg2) {
        if (arg1 instanceof char[])
            return ((char[]) arg1)[arg2];
        if (arg1 == null)
            throw new NullPointerException();
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#getShort(java.lang.Object, int)
     */
    private static short getShort(Object arg1, int arg2) {
        if (arg1 instanceof short[])
            return ((short[]) arg1)[arg2];
        return getByte(arg1, arg2);
    }

    /**
     * @see java.lang.reflect.Array#getInt(java.lang.Object, int)
     */
    private static int getInt(Object arg1, int arg2) {
        if (arg1 instanceof int[])
            return ((int[]) arg1)[arg2];
        if (arg1 instanceof char[])
            return ((char[]) arg1)[arg2];
        return getShort(arg1, arg2);
    }

    /**
     * @see java.lang.reflect.Array#getLong(java.lang.Object, int)
     */
    private static long getLong(Object arg1, int arg2) {
        if (arg1 instanceof long[])
            return ((long[]) arg1)[arg2];
        return getInt(arg1, arg2);
    }

    /**
     * @see java.lang.reflect.Array#getFloat(java.lang.Object, int)
     */
    private static float getFloat(Object arg1, int arg2) {
        if (arg1 instanceof float[])
            return ((float[]) arg1)[arg2];
        return getLong(arg1, arg2);
    }

    /**
     * @see java.lang.reflect.Array#getDouble(java.lang.Object, int)
     */
    private static double getDouble(Object arg1, int arg2) {
        if (arg1 instanceof double[])
            return ((double[]) arg1)[arg2];
        return getFloat(arg1, arg2);
    }

    /**
     * @see java.lang.reflect.Array#set(java.lang.Object, int, java.lang.Object)
     */
    private static void set(Object arg1, int arg2, Object arg3) {
        if (arg1 instanceof Object[]) {
            // Too bad the API won't let us throw the easier ArrayStoreException!
            if (arg3 != null
                && !arg1.getClass().getComponentType().isInstance(arg3))
                throw new IllegalArgumentException();
            ((Object[]) arg1)[arg2] = arg3;
        } else if (arg3 instanceof Byte)
            setByte(arg1, arg2, (Byte) arg3);
        else if (arg3 instanceof Short)
            setShort(arg1, arg2, (Short) arg3);
        else if (arg3 instanceof Integer)
            setInt(arg1, arg2, (Integer) arg3);
        else if (arg3 instanceof Long)
            setLong(arg1, arg2, (Long) arg3);
        else if (arg3 instanceof Float)
            setFloat(arg1, arg2, (Float) arg3);
        else if (arg3 instanceof Double)
            setDouble(arg1, arg2, (Double) arg3);
        else if (arg3 instanceof Character)
            setChar(arg1, arg2, (Character) arg3);
        else if (arg3 instanceof Boolean)
            setBoolean(arg1, arg2, (Boolean) arg3);
        else if (arg1 == null)
            throw new NullPointerException();
        else
            throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#setBoolean(java.lang.Object, int, boolean)
     */
    private static void setBoolean(Object arg1, int arg2, boolean arg3) {
        if (arg1 instanceof boolean[])
            ((boolean[]) arg1)[arg2] = arg3;
        else if (arg1 == null)
            throw new NullPointerException();
        else
            throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#setByte(java.lang.Object, int, byte)
     */
    private static void setByte(Object arg1, int arg2, byte arg3) {
        if (arg1 instanceof byte[])
            ((byte[]) arg1)[arg2] = arg3;
        else
            setShort(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setChar(java.lang.Object, int, char)
     */
    private static void setChar(Object arg1, int arg2, char arg3) {
        if (arg1 instanceof char[])
            ((char[]) arg1)[arg2] = arg3;
        else
            setInt(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setShort(java.lang.Object, int, short)
     */
    private static void setShort(Object arg1, int arg2, short arg3) {
        if (arg1 instanceof short[])
            ((short[]) arg1)[arg2] = arg3;
        else
            setInt(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setInt(java.lang.Object, int, int)
     */
    private static void setInt(Object arg1, int arg2, int arg3) {
        if (arg1 instanceof int[])
            ((int[]) arg1)[arg2] = arg3;
        else
            setLong(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setLong(java.lang.Object, int, long)
     */
    private static void setLong(Object arg1, int arg2, long arg3) {
        if (arg1 instanceof long[])
            ((long[]) arg1)[arg2] = arg3;
        else
            setFloat(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setFloat(java.lang.Object, int, float)
     */
    private static void setFloat(Object arg1, int arg2, float arg3) {
        if (arg1 instanceof float[])
            ((float[]) arg1)[arg2] = arg3;
        else
            setDouble(arg1, arg2, arg3);
    }

    /**
     * @see java.lang.reflect.Array#setDouble(java.lang.Object, int, double)
     */
    private static void setDouble(Object arg1, int arg2, double arg3) {
        if (arg1 instanceof double[])
            ((double[]) arg1)[arg2] = arg3;
        else if (arg1 == null)
            throw new NullPointerException();
        else
            throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#newArray(java.lang.Class, int)
     */
    private static Object newArray(Class<?> arg1, int arg2) {
        if (!((Class<?>) arg1).isPrimitive())
            return createObjectArray((Class<?>) arg1, arg2);
        if ((Class<?>) arg1 == boolean.class)
            return new boolean[arg2];
        if ((Class<?>) arg1 == byte.class)
            return new byte[arg2];
        if ((Class<?>) arg1 == char.class)
            return new char[arg2];
        if ((Class<?>) arg1 == short.class)
            return new short[arg2];
        if ((Class<?>) arg1 == int.class)
            return new int[arg2];
        if ((Class<?>) arg1 == long.class)
            return new long[arg2];
        if ((Class<?>) arg1 == float.class)
            return new float[arg2];
        if ((Class<?>) arg1 == double.class)
            return new double[arg2];
        // assert componentType == void.class
        throw new IllegalArgumentException();
    }

    /**
     * @see java.lang.reflect.Array#multiNewArray(java.lang.Class, int[])
     */
    private static Object multiNewArray(Class<?> arg1, int[] arg2) {
        if (arg2.length <= 0)
            throw new IllegalArgumentException("Empty dimensions array.");

        if (arg2.length - 1 == 0)
            return newInstance((Class<?>) arg1, arg2[0]);

        Object toAdd = createMultiArray((Class<?>) arg1, arg2, arg2.length - 1 - 1);
        Class<?> thisType = toAdd.getClass();
        Object[] retval
            = (Object[]) createObjectArray(thisType, arg2[(arg2.length - 1)]);
        if (arg2[(arg2.length - 1)] > 0)
            retval[0] = toAdd;
        int i = arg2[(arg2.length - 1)];
        while (--i > 0)
            retval[i] = createMultiArray((Class<?>) arg1, arg2, arg2.length - 1 - 1);
        return retval;
    }

    static Object createMultiArray(Class<?> type, int[] dimensions,
                                   int index) {
        if (index == 0)
            return newInstance(type, dimensions[0]);

        Object toAdd = createMultiArray(type, dimensions, index - 1);
        Class<?> thisType = toAdd.getClass();
        Object[] retval
            = (Object[]) createObjectArray(thisType, dimensions[index]);
        if (dimensions[index] > 0)
            retval[0] = toAdd;
        int i = dimensions[index];
        while (--i > 0)
            retval[i] = createMultiArray(type, dimensions, index - 1);
        return retval;
    }

    /**
     * Creates a new single-dimensioned array.
     *
     * @param componentType the type of the array to create
     * @param length        the length of the array to create
     * @return the created array, cast to an Object
     * @throws NullPointerException       if <code>componentType</code> is null
     * @throws IllegalArgumentException   if <code>componentType</code> is
     *                                    <code>Void.TYPE</code>
     * @throws NegativeArraySizeException when length is less than 0
     * @throws OutOfMemoryError           if memory allocation fails
     */
    public static Object newInstance(Class<?> componentType, int length) {
        if (!componentType.isPrimitive())
            return createObjectArray(componentType, length);
        if (componentType == boolean.class)
            return new boolean[length];
        if (componentType == byte.class)
            return new byte[length];
        if (componentType == char.class)
            return new char[length];
        if (componentType == short.class)
            return new short[length];
        if (componentType == int.class)
            return new int[length];
        if (componentType == long.class)
            return new long[length];
        if (componentType == float.class)
            return new float[length];
        if (componentType == double.class)
            return new double[length];
        // assert componentType == void.class
        throw new IllegalArgumentException();
    }

    /**
     * Dynamically create an array of objects.
     *
     * @param type guaranteed to be a valid object type
     * @param dim  the length of the array
     * @return the new array
     * @throws NegativeArraySizeException if dim is negative
     * @throws OutOfMemoryError           if memory allocation fails
     */
    static Object createObjectArray(final Class<?> type, int dim) {
        final VmType<?> vmClass = AccessController.doPrivileged(
            new PrivilegedAction<VmType<?>>() {
                public VmType<?> run() {
                    return VmType.fromClass(type);
                }
            });

        final String arrClsName = vmClass.getArrayClassName();
        final VmType<?> arrCls;
        try {
            final VmClassLoader curLoader = vmClass.getLoader();
            arrCls = curLoader.loadClass(arrClsName, true);
            if (arrCls == null) {
                throw new NoClassDefFoundError(arrClsName);
            }
        } catch (ClassNotFoundException ex) {
            throw new NoClassDefFoundError(arrClsName);
        }

        return VmUtils.getVm().getHeapManager().newArray((VmArrayClass<?>) arrCls, dim);
    }

}
TOP

Related Classes of java.lang.reflect.NativeArray

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.