1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.jme3.scene.plugins.blender.file; 33 34 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; 35 36 /** 37 * An array that can be dynamically modified/ 38 * @author Marcin Roguski 39 * @param <T> 40 * the type of stored data in the array 41 */ 42 public class DynamicArray<T> implements Cloneable { 43 44 /** An array object that holds the required data. */ 45 private T[] array; 46 /** 47 * This table holds the sizes of dimetions of the dynamic table. It's length specifies the table dimension or a 48 * pointer level. For example: if tableSizes.length == 3 then it either specifies a dynamic table of fixed lengths: 49 * dynTable[a][b][c], where a,b,c are stored in the tableSizes table. 50 */ 51 private int[] tableSizes; 52 53 /** 54 * Constructor. Builds an empty array of the specified sizes. 55 * @param tableSizes 56 * the sizes of the table 57 * @throws BlenderFileException 58 * an exception is thrown if one of the sizes is not a positive number 59 */ 60 @SuppressWarnings("unchecked") 61 public DynamicArray(int[] tableSizes) throws BlenderFileException { 62 this.tableSizes = tableSizes; 63 int totalSize = 1; 64 for (int size : tableSizes) { 65 if (size <= 0) { 66 throw new BlenderFileException("The size of the table must be positive!"); 67 } 68 totalSize *= size; 69 } 70 this.array = (T[]) new Object[totalSize]; 71 } 72 73 /** 74 * Constructor. Builds an empty array of the specified sizes. 75 * @param tableSizes 76 * the sizes of the table 77 * @throws BlenderFileException 78 * an exception is thrown if one of the sizes is not a positive number 79 */ 80 public DynamicArray(int[] tableSizes, T[] data) throws BlenderFileException { 81 this.tableSizes = tableSizes; 82 int totalSize = 1; 83 for (int size : tableSizes) { 84 if (size <= 0) { 85 throw new BlenderFileException("The size of the table must be positive!"); 86 } 87 totalSize *= size; 88 } 89 if (totalSize != data.length) { 90 throw new IllegalArgumentException("The size of the table does not match the size of the given data!"); 91 } 92 this.array = data; 93 } 94 95 @Override 96 public Object clone() throws CloneNotSupportedException { 97 return super.clone(); 98 } 99 100 /** 101 * This method returns a value on the specified position. The dimension of the table is not taken into 102 * consideration. 103 * @param position 104 * the position of the data 105 * @return required data 106 */ 107 public T get(int position) { 108 return array[position]; 109 } 110 111 /** 112 * This method returns a value on the specified position in multidimensional array. Be careful not to exceed the 113 * table boundaries. Check the table's dimension first. 114 * @param position 115 * the position of the data indices of data position 116 * @return required data required data 117 */ 118 public T get(int... position) { 119 if (position.length != tableSizes.length) { 120 throw new ArrayIndexOutOfBoundsException("The table accepts " + tableSizes.length + " indexing number(s)!"); 121 } 122 int index = 0; 123 for (int i = 0; i < position.length - 1; ++i) { 124 index += position[i] * tableSizes[i + 1]; 125 } 126 index += position[position.length - 1]; 127 return array[index]; 128 } 129 130 /** 131 * This method returns the total amount of data stored in the array. 132 * @return the total amount of data stored in the array 133 */ 134 public int getTotalSize() { 135 return array.length; 136 } 137 138 @Override 139 public String toString() { 140 StringBuilder result = new StringBuilder(); 141 if (array instanceof Character[]) {//in case of character array we convert it to String 142 for (int i = 0; i < array.length && (Character) array[i] != '\0'; ++i) {//strings are terminater with '0' 143 result.append(array[i]); 144 } 145 } else { 146 result.append('['); 147 for (int i = 0; i < array.length; ++i) { 148 result.append(array[i].toString()); 149 if (i + 1 < array.length) { 150 result.append(','); 151 } 152 } 153 result.append(']'); 154 } 155 return result.toString(); 156 } 157 }