All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robovm.rt.bro.ArrayMarshalers Maven / Gradle / Ivy

/*
 * Copyright (C) 2013 Trillian Mobile AB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.robovm.rt.bro;

import org.robovm.rt.VM;
import org.robovm.rt.bro.annotation.MarshalsArray;
import org.robovm.rt.bro.annotation.MarshalsPointer;

/**
 * Contains marshalers for arrays of primitive types.
 */
public class ArrayMarshalers {

    private static void checkDimensions(String type, String suffix, int actual, int expected) {
        if (actual != expected) {
            throw new IllegalArgumentException("Expected " + type + "[" 
                    + expected + "]" + suffix + ". Got " 
                    + type + "[" + actual + "]" + suffix);
        }
    }

    /**
     * Marshals to/from {@code byte[]}, {@code byte[][]} and {@code byte[][][]}.
     */
    public static class ByteArrayMarshaler {
        private static final String TYPE = "byte";
        private static final int SHIFT = 0;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final byte[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static byte[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final byte[] o = new byte[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final byte[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static byte[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final byte[][] o = new byte[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final byte[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static byte[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final byte[][][] o = new byte[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final byte[][][] o, long handle, long flags, int d1, int d2, int d3) {
            byte[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code short[]}, {@code short[][]} and {@code short[][][]}.
     */
    public static class ShortArrayMarshaler {
        private static final String TYPE = "short";
        private static final int SHIFT = 1;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final short[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static short[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final short[] o = new short[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final short[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static short[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final short[][] o = new short[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final short[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static short[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final short[][][] o = new short[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final short[][][] o, long handle, long flags, int d1, int d2, int d3) {
            short[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code char[]}, {@code char[][]} and {@code char[][][]}.
     */
    public static class CharArrayMarshaler {
        private static final String TYPE = "char";
        private static final int SHIFT = 1;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final char[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static char[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final char[] o = new char[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final char[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static char[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final char[][] o = new char[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final char[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static char[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final char[][][] o = new char[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final char[][][] o, long handle, long flags, int d1, int d2, int d3) {
            char[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code int[]}, {@code int[][]} and {@code int[][][]}.
     */
    public static class IntArrayMarshaler {
        private static final String TYPE = "int";
        private static final int SHIFT = 2;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final int[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static int[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final int[] o = new int[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final int[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static int[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final int[][] o = new int[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final int[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static int[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final int[][][] o = new int[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final int[][][] o, long handle, long flags, int d1, int d2, int d3) {
            int[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code long[]}, {@code long[][]} and {@code long[][][]}.
     */
    public static class LongArrayMarshaler {
        private static final String TYPE = "long";
        private static final int SHIFT = 3;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final long[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static long[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final long[] o = new long[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final long[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static long[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final long[][] o = new long[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final long[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static long[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final long[][][] o = new long[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final long[][][] o, long handle, long flags, int d1, int d2, int d3) {
            long[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code float[]}, {@code float[][]} and
     * {@code float[][][]}.
     */
    public static class FloatArrayMarshaler {
        private static final String TYPE = "float";
        private static final int SHIFT = 2;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final float[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static float[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final float[] o = new float[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final float[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static float[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final float[][] o = new float[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final float[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static float[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final float[][][] o = new float[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final float[][][] o, long handle, long flags, int d1, int d2, int d3) {
            float[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }
    
    /**
     * Marshals to/from {@code double[]}, {@code double[][]} and
     * {@code double[][][]}.
     */
    public static class DoubleArrayMarshaler {
        private static final String TYPE = "double";
        private static final int SHIFT = 3;
        @MarshalsPointer(supportedCallTypes = MarshalerFlags.CALL_TYPE_BRIDGE)
        public static long toNative(final double[] o, long flags) {
            if (o == null) {
                return 0L;
            }
            return VM.getArrayValuesAddress(o);
        }
        @MarshalsArray
        public static double[] toObject(Class arrayClass, long handle, long flags, int d1) {
            final double[] o = new double[d1];
            final int off = d1 << SHIFT;
            VM.memcpy(VM.getArrayValuesAddress(o), handle, off);
            return o;
        }
        @MarshalsArray
        public static void toNative(final double[] o, long handle, long flags, int d1) {
            final int off = d1 << SHIFT;
            checkDimensions(TYPE, "", o.length, d1);
            VM.memcpy(handle, VM.getArrayValuesAddress(o), off);
        }
        @MarshalsArray
        public static double[][] toObject(Class arrayClass, long handle, long flags, int d1, int d2) {
            final double[][] o = new double[d1][d2];
            final int off = d2 << SHIFT;
            for (int i = 0; i < d1; i++) {
                VM.memcpy(VM.getArrayValuesAddress(o[i]), handle, off);
                handle += off;
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final double[][] o, long handle, long flags, int d1, int d2) {
            final int off = d2 << SHIFT;
            checkDimensions(TYPE, "[]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                checkDimensions(TYPE + "[]", "", o[i].length, d2);
            }
            for (int i = 0; i < len1; i++) {
                VM.memcpy(handle, VM.getArrayValuesAddress(o[i]), off);
                handle += off;
            }
        }
        @MarshalsArray
        public static double[][][] toObject(Class arrayClass, long handle, long flags, int d1, int d2, int d3) {
            final double[][][] o = new double[d1][d2][d3];
            final int off = d3 << SHIFT;
            for (int i = 0; i < d1; i++) {
                for (int j = 0; j < d2; j++) {
                    VM.memcpy(VM.getArrayValuesAddress(o[i][j]), handle, off);
                    handle += off;
                }
            }
            return o;
        }
        @MarshalsArray
        public static void toNative(final double[][][] o, long handle, long flags, int d1, int d2, int d3) {
            double[][] p;
            final int off = d3 << SHIFT;
            checkDimensions(TYPE, "[][]", o.length, d1);
            int len1 = o.length;
            for (int i = 0; i < len1; i++) {
                p = o[i];
                checkDimensions(TYPE + "[]", "[]", p.length, d2);
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    checkDimensions(TYPE + "[][]", "", p[j].length, d3);
                }
            }
            for (int i = 0; i < len1; i++) {
                p = o[i];
                int len2 = p.length;
                for (int j = 0; j < len2; j++) {
                    VM.memcpy(handle, VM.getArrayValuesAddress(p[j]), off);
                    handle += off;
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy