-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.utils.datastructures;\r
-\r
-import java.io.PrintStream;\r
-import java.lang.reflect.Array;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.Iterator;\r
-import java.util.NoSuchElementException;\r
-\r
-/**\r
- * Multi-dimension array utils.\r
- * \r
- * @See {@link Array} related\r
- * @See {@link Arrays} related\r
- * @See {@link Collections} related\r
- * @author Toni Kalajainen (toni.kalajainen@vtt.fi)\r
- */\r
-public class MultiDimensionArrayUtils {\r
-\r
- \r
- /**\r
- * Print multi-dimension array\r
- * @param o\r
- */\r
- public static void printArrayDeep(Object v, PrintStream out)\r
- {\r
- ArrayIterator<Boolean> i = arrayIterator(v, getArrayLengths(v));\r
- while (i.hasNext())\r
- System.out.println(Arrays.toString(i.getIndices())+" = "+i.next());\r
- } \r
- \r
- /**\r
- * Get array length of each dimension of a multi-dimension array.\r
- * \r
- * @param value multi-dimension array\r
- * @return lengths of each dimension\r
- */\r
- public static int[] getArrayLengths(Object value)\r
- { \r
- int dim = getDimension(value.getClass());\r
- int result[] = new int[ dim ];\r
- if (dim==0) return result;\r
- \r
- Object o = value;\r
- for (int i=0; i<dim; i++) \r
- {\r
- result[i] = Array.getLength(o);\r
- if (result[i]==0) break;\r
- o = Array.get(o, 0);\r
- }\r
- \r
- return result;\r
- }\r
- \r
- /**\r
- * Get the number of dimensions in a multi-dimension array.\r
- * \r
- * @param value multi-dimension array\r
- * @return the number of dimensions\r
- */\r
- public static int getDimension(Class<?> clazz)\r
- { \r
- String signature = clazz.getName();\r
- int dim = 0;\r
- for (; dim<signature.length(); dim++) \r
- if (signature.charAt(dim)!='[') break; \r
- return dim;\r
- }\r
- \r
- \r
- /**\r
- * Deep create multi-level array\r
- * \r
- * @param componentType component type\r
- * @param dims dimension lengths\r
- * @return multi-level array\r
- */\r
- public static Object[] createMultiDimArray(Class<?> componentType, int[] dims)\r
- {\r
- // Java 1.6.0\r
- return (Object[]) Array.newInstance(componentType, dims);\r
- \r
- /*\r
- // Older than 1.6.0\r
- if (dims==null || componentType==null || dims.length==0) throw new IllegalArgumentException();\r
- if (dims.length==1) \r
- return Array.newInstance(componentType, dims[0]);\r
- \r
- int[][] dimArrays = new int[dims.length][];\r
- dimArrays[0] = dims;\r
- for (int j=1; j<dims.length; j++)\r
- {\r
- dimArrays[j] = new int[dims.length-j];\r
- System.arraycopy(dims, 1, dimArrays[j], 0, dims.length-j);\r
- }\r
- return _createMultiDimArray(componentType, dimArrays, 0);\r
- */\r
- }\r
-/* \r
- private static Object[] _createMultiDimArray(Class<?> componentType, int[][] dimArrays, int lvl)\r
- {\r
- int[] dims = dimArrays[lvl];\r
- int len = dims[0];\r
- Object[] result = (Object[]) Array.newInstance(componentType, dims);\r
- if (lvl<dimArrays.length-1)\r
- for (int i=0; i<len; i++)\r
- result[i] = _createMultiDimArray(componentType, dimArrays, lvl+1);\r
- return result;\r
- }\r
-*/ \r
- \r
- /**\r
- * Returns the total number of elements in a multi-dimension array\r
- * \r
- * @param dims lengths of each dimension\r
- * @return total number of elements\r
- */\r
- public static int getLength(int[] dims)\r
- {\r
- int len = dims[0];\r
- for (int i=1; i<dims.length; i++)\r
- len *= dims[i];\r
- return len; \r
- }\r
-\r
- /**\r
- * Get the component type of an array class\r
- * \r
- * @param clazz (array) class\r
- * @return component type\r
- */\r
- public static Class<?> getComponentType(Class<?> clazz)\r
- {\r
- Class<?> result = clazz;\r
- while (result.isArray())\r
- result = result.getComponentType();\r
- return result;\r
- }\r
- \r
- /**\r
- * Demux single-dimension array (x[]) to a multi-dimension array (x[][][])\r
- * \r
- * @param src single-dimension array\r
- * @param dims\r
- * @return multi-dimension array\r
- */\r
- public static Object demuxArray(Object src, int[] dims)\r
- {\r
- return demuxArray(src, dims, getComponentType(src.getClass()));\r
- }\r
-\r
- /**\r
- * Demux single-dimension array (x[]) to a multi-dimension array (x[][][])\r
- * \r
- * @param src single-dimension array\r
- * @param dims \r
- * @param componentType\r
- * @return multi-dimension array\r
- */\r
- public static Object demuxArray(Object src, int[] dims, Class<?> componentType)\r
- {\r
- Object dst = Array.newInstance(componentType, dims);\r
- _fillDemux(0, dims, src, 0, dst);\r
- return dst;\r
- }\r
- \r
- /**\r
- * Demuxes single dimension array into a multi-dimension array\r
- * \r
- * @param src one dimension array (e.g. int[])\r
- * @param dimensions length of each dimension\r
- * @param dst multi-dimension array to be filled (use createMultiDimArray())\r
- */\r
- public static void demuxArray(Object src, int[] dims, Object dst)\r
- {\r
- if (Array.getLength(src) != getLength(dims)) \r
- throw new IllegalArgumentException("The length of src does not match the length of dst"); \r
- _fillDemux(0, dims, src, 0, dst);\r
- }\r
- \r
- private static int _fillDemux(int lvl, int[] dims, Object src, int srcIndex, Object dst)\r
- {\r
- // lower level\r
- if (lvl==dims.length-1) {\r
- int len = dims[dims.length-1]; \r
- System.arraycopy(src, srcIndex, dst, 0, len);\r
- return srcIndex + len;\r
- }\r
- // higher level\r
- for (int i=0; i<dims[lvl]; i++)\r
- srcIndex = _fillDemux(lvl+1, dims, src, srcIndex, Array.get(dst, i));\r
- \r
- return srcIndex;\r
- }\r
-\r
- /**\r
- * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])\r
- * \r
- * @param src multi-dimension array\r
- * @return single-dimension array\r
- */\r
- public static Object muxArray(Object src)\r
- {\r
- return muxArray(src, getArrayLengths(src), getComponentType(src.getClass()));\r
- } \r
- \r
- /**\r
- * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])\r
- * \r
- * @param src multi-dimension array\r
- * @param dims\r
- * @return single-dimension array\r
- */\r
- public static Object muxArray(Object src, int[] dims)\r
- {\r
- return muxArray(src, dims, getComponentType(src.getClass()));\r
- } \r
- \r
- /**\r
- * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])\r
- * \r
- * @param src multi-dimension array\r
- * @param dims\r
- * @param componentType\r
- * @return single-dimension array\r
- */\r
- public static Object muxArray(Object src, int[] dims, Class<?> componentType)\r
- {\r
- int len = getLength(dims);\r
- Object dst = Array.newInstance(componentType, len);\r
- muxArray(src, dims, dst);\r
- return dst;\r
- }\r
- \r
- /**\r
- * Multiplexes multi-dimension array into a single-dimension array\r
- * \r
- * @param src multi-dimension array\r
- * @param dims dimensions\r
- * @param dst single-dimension array\r
- */\r
- public static void muxArray(Object src, int[] dims, Object dst)\r
- {\r
- int len = getLength(dims);\r
- if (Array.getLength(dst) != len) \r
- throw new IllegalArgumentException("The length of src does not match the length of dst");\r
- \r
- _fillMux(0, dims, src, dst, 0);\r
- }\r
- \r
- private static int _fillMux(int lvl, int[] dims, Object src, Object dst, int dstIndex)\r
- {\r
- if (lvl == dims.length-1)\r
- {\r
- int len = dims[lvl];\r
- System.arraycopy(src, 0, dst, dstIndex, len);\r
- return dstIndex + len;\r
- }\r
- \r
- for (int i=0; i<dims[lvl]; i++)\r
- dstIndex += _fillMux(lvl+1, dims, Array.get(src, i), dst, dstIndex);\r
- \r
- return 0;\r
- }\r
- \r
- public static <R> ArrayIterator<R> arrayIterator(Object array, int[] dimLens)\r
- {\r
- return new ArrayIterator<R>(array, dimLens);\r
- }\r
- \r
- public static class ArrayIterator<T> implements Iterator<T>\r
- {\r
- Object v;\r
- int[] dims;\r
- int[] indices;\r
- Object[] arrays;\r
- int lastIndex, len;\r
- boolean hasNext = true;\r
- \r
- ArrayIterator(Object array, int[] dimLens)\r
- {\r
- this.v = array;\r
- this.dims = dimLens;\r
- this.indices = new int[dimLens.length];\r
- this.arrays = new Object[dimLens.length];\r
- lastIndex = dimLens.length-1;\r
- @SuppressWarnings("unused")\r
- int len = dimLens[0];\r
- for (int i=0; i<=lastIndex; i++)\r
- if (dimLens[i]==0) hasNext = false;\r
- for (int i=1; i<=lastIndex; i++) \r
- len *= dimLens[i];\r
- arrays[0] = (Object[]) v;\r
- for (int i=1; i<dimLens.length; i++)\r
- arrays[i] = ((Object[])arrays[i-1])[0]; \r
- }\r
- \r
- public int[] getIndices()\r
- {\r
- return indices; \r
- }\r
- \r
- @Override\r
- public boolean hasNext() {\r
- return hasNext;\r
- }\r
-\r
- private void _next() {\r
- int index = lastIndex; \r
- while (++indices[index] >= dims[index])\r
- {\r
- indices[index] = 0;\r
- index--;\r
- if (index<0) {\r
- hasNext = false;\r
- return;\r
- }\r
- arrays[index+1] = ((Object[]) arrays[index])[indices[index]];\r
- }\r
- if (index<lastIndex)\r
- for (int i=index+1; i<=lastIndex; i++)\r
- arrays[i] = ((Object[])arrays[i-1])[indices[i-1]]; \r
- }\r
- \r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public T next() {\r
- if (!hasNext)\r
- throw new NoSuchElementException();\r
- \r
- T result = (T) Array.get(Array.get(arrays, lastIndex), indices[lastIndex]);\r
- _next();\r
- return result;\r
- }\r
-\r
- @Override\r
- public void remove() {\r
- throw new UnsupportedOperationException("Cannot remove array element");\r
- } \r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.utils.datastructures;
+
+import java.io.PrintStream;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Multi-dimension array utils.
+ *
+ * @See {@link Array} related
+ * @See {@link Arrays} related
+ * @See {@link Collections} related
+ * @author Toni Kalajainen (toni.kalajainen@vtt.fi)
+ */
+public class MultiDimensionArrayUtils {
+
+
+ /**
+ * Print multi-dimension array
+ * @param o
+ */
+ public static void printArrayDeep(Object v, PrintStream out)
+ {
+ ArrayIterator<Boolean> i = arrayIterator(v, getArrayLengths(v));
+ while (i.hasNext())
+ System.out.println(Arrays.toString(i.getIndices())+" = "+i.next());
+ }
+
+ /**
+ * Get array length of each dimension of a multi-dimension array.
+ *
+ * @param value multi-dimension array
+ * @return lengths of each dimension
+ */
+ public static int[] getArrayLengths(Object value)
+ {
+ int dim = getDimension(value.getClass());
+ int result[] = new int[ dim ];
+ if (dim==0) return result;
+
+ Object o = value;
+ for (int i=0; i<dim; i++)
+ {
+ result[i] = Array.getLength(o);
+ if (result[i]==0) break;
+ o = Array.get(o, 0);
+ }
+
+ return result;
+ }
+
+ /**
+ * Get the number of dimensions in a multi-dimension array.
+ *
+ * @param value multi-dimension array
+ * @return the number of dimensions
+ */
+ public static int getDimension(Class<?> clazz)
+ {
+ String signature = clazz.getName();
+ int dim = 0;
+ for (; dim<signature.length(); dim++)
+ if (signature.charAt(dim)!='[') break;
+ return dim;
+ }
+
+
+ /**
+ * Deep create multi-level array
+ *
+ * @param componentType component type
+ * @param dims dimension lengths
+ * @return multi-level array
+ */
+ public static Object[] createMultiDimArray(Class<?> componentType, int[] dims)
+ {
+ // Java 1.6.0
+ return (Object[]) Array.newInstance(componentType, dims);
+
+ /*
+ // Older than 1.6.0
+ if (dims==null || componentType==null || dims.length==0) throw new IllegalArgumentException();
+ if (dims.length==1)
+ return Array.newInstance(componentType, dims[0]);
+
+ int[][] dimArrays = new int[dims.length][];
+ dimArrays[0] = dims;
+ for (int j=1; j<dims.length; j++)
+ {
+ dimArrays[j] = new int[dims.length-j];
+ System.arraycopy(dims, 1, dimArrays[j], 0, dims.length-j);
+ }
+ return _createMultiDimArray(componentType, dimArrays, 0);
+ */
+ }
+/*
+ private static Object[] _createMultiDimArray(Class<?> componentType, int[][] dimArrays, int lvl)
+ {
+ int[] dims = dimArrays[lvl];
+ int len = dims[0];
+ Object[] result = (Object[]) Array.newInstance(componentType, dims);
+ if (lvl<dimArrays.length-1)
+ for (int i=0; i<len; i++)
+ result[i] = _createMultiDimArray(componentType, dimArrays, lvl+1);
+ return result;
+ }
+*/
+
+ /**
+ * Returns the total number of elements in a multi-dimension array
+ *
+ * @param dims lengths of each dimension
+ * @return total number of elements
+ */
+ public static int getLength(int[] dims)
+ {
+ int len = dims[0];
+ for (int i=1; i<dims.length; i++)
+ len *= dims[i];
+ return len;
+ }
+
+ /**
+ * Get the component type of an array class
+ *
+ * @param clazz (array) class
+ * @return component type
+ */
+ public static Class<?> getComponentType(Class<?> clazz)
+ {
+ Class<?> result = clazz;
+ while (result.isArray())
+ result = result.getComponentType();
+ return result;
+ }
+
+ /**
+ * Demux single-dimension array (x[]) to a multi-dimension array (x[][][])
+ *
+ * @param src single-dimension array
+ * @param dims
+ * @return multi-dimension array
+ */
+ public static Object demuxArray(Object src, int[] dims)
+ {
+ return demuxArray(src, dims, getComponentType(src.getClass()));
+ }
+
+ /**
+ * Demux single-dimension array (x[]) to a multi-dimension array (x[][][])
+ *
+ * @param src single-dimension array
+ * @param dims
+ * @param componentType
+ * @return multi-dimension array
+ */
+ public static Object demuxArray(Object src, int[] dims, Class<?> componentType)
+ {
+ Object dst = Array.newInstance(componentType, dims);
+ _fillDemux(0, dims, src, 0, dst);
+ return dst;
+ }
+
+ /**
+ * Demuxes single dimension array into a multi-dimension array
+ *
+ * @param src one dimension array (e.g. int[])
+ * @param dimensions length of each dimension
+ * @param dst multi-dimension array to be filled (use createMultiDimArray())
+ */
+ public static void demuxArray(Object src, int[] dims, Object dst)
+ {
+ if (Array.getLength(src) != getLength(dims))
+ throw new IllegalArgumentException("The length of src does not match the length of dst");
+ _fillDemux(0, dims, src, 0, dst);
+ }
+
+ private static int _fillDemux(int lvl, int[] dims, Object src, int srcIndex, Object dst)
+ {
+ // lower level
+ if (lvl==dims.length-1) {
+ int len = dims[dims.length-1];
+ System.arraycopy(src, srcIndex, dst, 0, len);
+ return srcIndex + len;
+ }
+ // higher level
+ for (int i=0; i<dims[lvl]; i++)
+ srcIndex = _fillDemux(lvl+1, dims, src, srcIndex, Array.get(dst, i));
+
+ return srcIndex;
+ }
+
+ /**
+ * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])
+ *
+ * @param src multi-dimension array
+ * @return single-dimension array
+ */
+ public static Object muxArray(Object src)
+ {
+ return muxArray(src, getArrayLengths(src), getComponentType(src.getClass()));
+ }
+
+ /**
+ * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])
+ *
+ * @param src multi-dimension array
+ * @param dims
+ * @return single-dimension array
+ */
+ public static Object muxArray(Object src, int[] dims)
+ {
+ return muxArray(src, dims, getComponentType(src.getClass()));
+ }
+
+ /**
+ * Multiplex multi-dimension array (x[][][]) to single-dimension array (x[])
+ *
+ * @param src multi-dimension array
+ * @param dims
+ * @param componentType
+ * @return single-dimension array
+ */
+ public static Object muxArray(Object src, int[] dims, Class<?> componentType)
+ {
+ int len = getLength(dims);
+ Object dst = Array.newInstance(componentType, len);
+ muxArray(src, dims, dst);
+ return dst;
+ }
+
+ /**
+ * Multiplexes multi-dimension array into a single-dimension array
+ *
+ * @param src multi-dimension array
+ * @param dims dimensions
+ * @param dst single-dimension array
+ */
+ public static void muxArray(Object src, int[] dims, Object dst)
+ {
+ int len = getLength(dims);
+ if (Array.getLength(dst) != len)
+ throw new IllegalArgumentException("The length of src does not match the length of dst");
+
+ _fillMux(0, dims, src, dst, 0);
+ }
+
+ private static int _fillMux(int lvl, int[] dims, Object src, Object dst, int dstIndex)
+ {
+ if (lvl == dims.length-1)
+ {
+ int len = dims[lvl];
+ System.arraycopy(src, 0, dst, dstIndex, len);
+ return dstIndex + len;
+ }
+
+ for (int i=0; i<dims[lvl]; i++)
+ dstIndex += _fillMux(lvl+1, dims, Array.get(src, i), dst, dstIndex);
+
+ return 0;
+ }
+
+ public static <R> ArrayIterator<R> arrayIterator(Object array, int[] dimLens)
+ {
+ return new ArrayIterator<R>(array, dimLens);
+ }
+
+ public static class ArrayIterator<T> implements Iterator<T>
+ {
+ Object v;
+ int[] dims;
+ int[] indices;
+ Object[] arrays;
+ int lastIndex, len;
+ boolean hasNext = true;
+
+ ArrayIterator(Object array, int[] dimLens)
+ {
+ this.v = array;
+ this.dims = dimLens;
+ this.indices = new int[dimLens.length];
+ this.arrays = new Object[dimLens.length];
+ lastIndex = dimLens.length-1;
+ @SuppressWarnings("unused")
+ int len = dimLens[0];
+ for (int i=0; i<=lastIndex; i++)
+ if (dimLens[i]==0) hasNext = false;
+ for (int i=1; i<=lastIndex; i++)
+ len *= dimLens[i];
+ arrays[0] = (Object[]) v;
+ for (int i=1; i<dimLens.length; i++)
+ arrays[i] = ((Object[])arrays[i-1])[0];
+ }
+
+ public int[] getIndices()
+ {
+ return indices;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ private void _next() {
+ int index = lastIndex;
+ while (++indices[index] >= dims[index])
+ {
+ indices[index] = 0;
+ index--;
+ if (index<0) {
+ hasNext = false;
+ return;
+ }
+ arrays[index+1] = ((Object[]) arrays[index])[indices[index]];
+ }
+ if (index<lastIndex)
+ for (int i=index+1; i<=lastIndex; i++)
+ arrays[i] = ((Object[])arrays[i-1])[indices[i-1]];
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T next() {
+ if (!hasNext)
+ throw new NoSuchElementException();
+
+ T result = (T) Array.get(Array.get(arrays, lastIndex), indices[lastIndex]);
+ _next();
+ return result;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Cannot remove array element");
+ }
+ }
+
+}