001: /****************************************************************************
002: * N I C E *
003: * A high-level object-oriented research language *
004: * (c) Daniel Bonniot 2004 *
005: * *
006: * This package is free software; you can redistribute it and/or modify *
007: * it under the terms of the GNU General Public License as published by *
008: * Free Software Foundation; either version 2 of the License, or (at your *
009: * option) any later version. *
010: * *
011: * As a special exception, the copyright holders of this library give you *
012: * permission to link this library with independent modules to produce an *
013: * executable, regardless of the license terms of these independent *
014: * modules, and to copy and distribute the resulting executable under *
015: * terms of your choice. *
016: ****************************************************************************/package nice.lang;
017:
018: import java.lang.reflect.Array;
019: import java.util.*;
020:
021: /**
022: Class used to wrap native arrays when considered as part of the
023: collection hierarchy.
024:
025: @version: $Date: 2004/06/27 20:33:05 $
026: @author Daniel Bonniot (d.bonniot@mail.dotcom.fr)
027: */
028: public class rawArray extends java.util.AbstractList {
029: protected rawArray(Object value) {
030: this .value = value;
031: }
032:
033: public final Object value;
034:
035: public Object value() {
036: return value;
037: }
038:
039: public static rawArray make(Object value) {
040: if (value == null)
041: return null;
042:
043: if (value instanceof Object[])
044: return new rawObjectArray((Object[]) value);
045:
046: if (value instanceof int[])
047: return new rawIntArray((int[]) value);
048:
049: if (value instanceof byte[])
050: return new rawByteArray((byte[]) value);
051:
052: if (value instanceof long[])
053: return new rawLongArray((long[]) value);
054:
055: if (value instanceof char[])
056: return new rawCharArray((char[]) value);
057:
058: if (value instanceof boolean[])
059: return new rawBooleanArray((boolean[]) value);
060:
061: if (value instanceof double[])
062: return new rawDoubleArray((double[]) value);
063:
064: if (value instanceof float[])
065: return new rawFloatArray((float[]) value);
066:
067: if (value instanceof short[])
068: return new rawShortArray((short[]) value);
069:
070: return new rawArray(value);
071: }
072:
073: /****************************************************************
074: * Implementation of java.util.List
075: ****************************************************************/
076:
077: public int size() {
078: return Array.getLength(value);
079: }
080:
081: public Object get(int index) {
082: return Array.get(value, index);
083: }
084:
085: public Object set(int index, Object element) {
086: Object res = get(index);
087: Array_set(value, index, element);
088: return res;
089: }
090:
091: // CONVERSIONS
092:
093: public static boolean[] convert_boolean(Object[] array) {
094: if (array == null)
095: return null;
096:
097: boolean[] res = new boolean[array.length];
098: for (int i = array.length; --i >= 0;) {
099: Object o = array[i];
100: res[i] = ((Boolean) o).booleanValue();
101: }
102:
103: return res;
104: }
105:
106: public static char[] convert_char(Object[] array) {
107: if (array == null)
108: return null;
109:
110: char[] res = new char[array.length];
111: for (int i = array.length; --i >= 0;) {
112: Object o = array[i];
113: res[i] = ((Character) o).charValue();
114: }
115:
116: return res;
117: }
118:
119: public static byte[] convert_byte(Object[] array) {
120: if (array == null)
121: return null;
122:
123: byte[] res = new byte[array.length];
124: for (int i = array.length; --i >= 0;) {
125: Object o = array[i];
126: res[i] = ((Number) o).byteValue();
127: }
128:
129: return res;
130: }
131:
132: public static short[] convert_short(Object[] array) {
133: if (array == null)
134: return null;
135:
136: short[] res = new short[array.length];
137: for (int i = array.length; --i >= 0;) {
138: Object o = array[i];
139: res[i] = ((Number) o).shortValue();
140: }
141:
142: return res;
143: }
144:
145: public static int[] convert_int(Object[] array) {
146: if (array == null)
147: return null;
148:
149: int[] res = new int[array.length];
150: for (int i = array.length; --i >= 0;) {
151: Object o = array[i];
152: res[i] = ((Number) o).intValue();
153: }
154:
155: return res;
156: }
157:
158: public static long[] convert_long(Object[] array) {
159: if (array == null)
160: return null;
161:
162: long[] res = new long[array.length];
163: for (int i = array.length; --i >= 0;) {
164: Object o = array[i];
165: res[i] = ((Number) o).longValue();
166: }
167:
168: return res;
169: }
170:
171: public static float[] convert_float(Object[] array) {
172: if (array == null)
173: return null;
174:
175: float[] res = new float[array.length];
176: for (int i = array.length; --i >= 0;) {
177: Object o = array[i];
178: res[i] = ((Number) o).floatValue();
179: }
180:
181: return res;
182: }
183:
184: public static double[] convert_double(Object[] array) {
185: if (array == null)
186: return null;
187:
188: double[] res = new double[array.length];
189: for (int i = array.length; --i >= 0;) {
190: Object o = array[i];
191: res[i] = ((Number) o).doubleValue();
192: }
193:
194: return res;
195: }
196:
197: /****************************************************************
198: * Conversion from generic Object array
199: ****************************************************************/
200:
201: public static boolean[] gconvert_boolean(Object array) {
202: if (array == null)
203: return null;
204:
205: int len = Array.getLength(array);
206: boolean[] res = new boolean[len];
207: for (int i = len; --i >= 0;) {
208: Object o = Array.get(array, i);
209: res[i] = ((Boolean) o).booleanValue();
210: }
211:
212: return res;
213: }
214:
215: public static char[] gconvert_char(Object array) {
216: if (array == null)
217: return null;
218:
219: int len = Array.getLength(array);
220: char[] res = new char[len];
221: for (int i = len; --i >= 0;) {
222: Object o = Array.get(array, i);
223: res[i] = ((Character) o).charValue();
224: }
225:
226: return res;
227: }
228:
229: public static byte[] gconvert_byte(Object array) {
230: if (array == null)
231: return null;
232:
233: int len = Array.getLength(array);
234: byte[] res = new byte[len];
235: for (int i = len; --i >= 0;) {
236: Object o = Array.get(array, i);
237: res[i] = ((Number) o).byteValue();
238: }
239:
240: return res;
241: }
242:
243: public static short[] gconvert_short(Object array) {
244: if (array == null)
245: return null;
246:
247: int len = Array.getLength(array);
248: short[] res = new short[len];
249: for (int i = len; --i >= 0;) {
250: Object o = Array.get(array, i);
251: res[i] = ((Number) o).shortValue();
252: }
253:
254: return res;
255: }
256:
257: public static int[] gconvert_int(Object array) {
258: if (array == null)
259: return null;
260:
261: int len = Array.getLength(array);
262: int[] res = new int[len];
263: for (int i = len; --i >= 0;) {
264: Object o = Array.get(array, i);
265: res[i] = ((Number) o).intValue();
266: }
267:
268: return res;
269: }
270:
271: public static long[] gconvert_long(Object array) {
272: if (array == null)
273: return null;
274:
275: int len = Array.getLength(array);
276: long[] res = new long[len];
277: for (int i = len; --i >= 0;) {
278: Object o = Array.get(array, i);
279: res[i] = ((Number) o).longValue();
280: }
281:
282: return res;
283: }
284:
285: public static float[] gconvert_float(Object array) {
286: if (array == null)
287: return null;
288:
289: int len = Array.getLength(array);
290: float[] res = new float[len];
291: for (int i = len; --i >= 0;) {
292: Object o = Array.get(array, i);
293: res[i] = ((Number) o).floatValue();
294: }
295:
296: return res;
297: }
298:
299: public static double[] gconvert_double(Object array) {
300: if (array == null)
301: return null;
302:
303: int len = Array.getLength(array);
304: double[] res = new double[len];
305: for (int i = len; --i >= 0;) {
306: Object o = Array.get(array, i);
307: res[i] = ((Number) o).doubleValue();
308: }
309:
310: return res;
311: }
312:
313: /**
314: Return a T[] array,
315: where T is given by componentClass (T should not be primitive),
316: holding the same elements as <code>array</code>.
317: */
318: public static Object[] gconvert(Object array, String componentClass) {
319: if (array == null)
320: return null;
321:
322: try {
323: int len = Array.getLength(array);
324: Object[] res = (Object[]) java.lang.reflect.Array
325: .newInstance(Class.forName(componentClass), len);
326:
327: // If the components are primitive arrays, we must recursively
328: // convert them.
329: boolean primitiveArray = componentClass.charAt(0) == '['
330: && componentClass.charAt(1) != 'L'
331: && componentClass.charAt(1) != '[';
332:
333: boolean collection = componentClass
334: .equals("java.util.Collection")
335: || componentClass.equals("java.util.List");
336:
337: for (int i = len; --i >= 0;) {
338: Object value = Array.get(array, i);
339:
340: if (primitiveArray)
341: value = convertPrimitive(value, componentClass
342: .substring(1));
343: else if (collection)
344: value = rawArray.make(value);
345:
346: Array.set(res, i, value);
347: }
348:
349: return res;
350: } catch (ClassNotFoundException e) {
351: throw new Error("Could not find class " + componentClass
352: + " during array conversion");
353: }
354: }
355:
356: private static Object convertPrimitive(Object array,
357: String component) {
358: switch (component.charAt(0)) {
359: case 'Z':
360: return gconvert_boolean(array);
361: case 'B':
362: return gconvert_byte(array);
363: case 'S':
364: return gconvert_short(array);
365: case 'I':
366: return gconvert_int(array);
367: case 'J':
368: return gconvert_long(array);
369: case 'F':
370: return gconvert_float(array);
371: case 'D':
372: return gconvert_double(array);
373: default:
374: throw new Error("Unexpected error in array conversion");
375: }
376: }
377:
378: /****************************************************************
379: * Utility functions
380: ****************************************************************/
381:
382: /**
383: Variant of java.lang.reflect.Array.set that is more flexible about how
384: the primitive values are boxed.
385: */
386: public static void Array_set(Object array, int index, Object value) {
387: if (array instanceof Object[])
388: ((Object[]) array)[index] = value;
389: else if (array instanceof int[])
390: ((int[]) array)[index] = ((Number) value).intValue();
391: else if (array instanceof byte[])
392: ((byte[]) array)[index] = ((Number) value).byteValue();
393: else if (array instanceof long[])
394: ((long[]) array)[index] = ((Number) value).longValue();
395: else if (array instanceof char[])
396: ((char[]) array)[index] = ((Character) value).charValue();
397: else if (array instanceof boolean[])
398: ((boolean[]) array)[index] = ((Boolean) value)
399: .booleanValue();
400: else if (array instanceof double[])
401: ((double[]) array)[index] = ((Number) value).doubleValue();
402: else if (array instanceof float[])
403: ((float[]) array)[index] = ((Number) value).floatValue();
404: else if (array instanceof short[])
405: ((short[]) array)[index] = ((Number) value).shortValue();
406: else
407: throw new IllegalArgumentException();
408: }
409:
410: }
|