001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.java.util;
032:
033: import java.util.*;
034:
035: /**
036: * @author Taras Puchko
037: */
038: public class _Arrays {
039:
040: private static final String NULL = "null";
041: private static final String EMPTY_ARRAY = "[]";
042: private static final char LEFT_BRACKET = '[';
043: private static final char RIGHT_BRACKET = ']';
044: private static final String SEPARATOR = ", ";
045:
046: public static boolean deepEquals(Object[] a1, Object[] a2) {
047: return isEqual(a1, a2);
048: }
049:
050: public static int deepHashCode(Object[] a) {
051: if (a == null)
052: return 0;
053: int hashCode = 1;
054: for (Object element : a) {
055: hashCode = 31 * hashCode + getHashCode(element);
056: }
057: return hashCode;
058: }
059:
060: public static String deepToString(Object[] a) {
061: if (a == null)
062: return NULL;
063: StringBuilder builder = new StringBuilder();
064: appendArray(builder, a, new HashSet<Object[]>());
065: return builder.toString();
066: }
067:
068: public static int hashCode(boolean[] a) {
069: if (a == null)
070: return 0;
071: int hashCode = 1;
072: for (boolean element : a) {
073: hashCode = 31 * hashCode + (element ? 1231 : 1237);
074: }
075: return hashCode;
076: }
077:
078: public static int hashCode(byte[] a) {
079: if (a == null)
080: return 0;
081: int hashCode = 1;
082: for (byte element : a) {
083: hashCode = 31 * hashCode + element;
084: }
085: return hashCode;
086: }
087:
088: public static int hashCode(char[] a) {
089: if (a == null)
090: return 0;
091: int hashCode = 1;
092: for (char element : a) {
093: hashCode = 31 * hashCode + element;
094: }
095: return hashCode;
096: }
097:
098: public static int hashCode(double[] a) {
099: if (a == null)
100: return 0;
101: int hashCode = 1;
102: for (double element : a) {
103: long longBits = Double.doubleToLongBits(element);
104: hashCode = 31 * hashCode
105: + (int) (longBits ^ (longBits >>> 32));
106: }
107: return hashCode;
108: }
109:
110: public static int hashCode(float[] a) {
111: if (a == null)
112: return 0;
113: int hashCode = 1;
114: for (float element : a) {
115: hashCode = 31 * hashCode + Float.floatToIntBits(element);
116: }
117: return hashCode;
118: }
119:
120: public static int hashCode(int[] a) {
121: if (a == null)
122: return 0;
123: int hashCode = 1;
124: for (int element : a) {
125: hashCode = 31 * hashCode + element;
126: }
127: return hashCode;
128: }
129:
130: public static int hashCode(long[] a) {
131: if (a == null)
132: return 0;
133: int hashCode = 1;
134: for (long element : a) {
135: hashCode = 31 * hashCode
136: + (int) (element ^ (element >>> 32));
137: }
138: return hashCode;
139: }
140:
141: public static int hashCode(Object[] a) {
142: if (a == null)
143: return 0;
144: int hashCode = 1;
145: for (Object element : a) {
146: hashCode = 31 * hashCode
147: + (element == null ? 0 : element.hashCode());
148: }
149: return hashCode;
150: }
151:
152: public static int hashCode(short[] a) {
153: if (a == null)
154: return 0;
155: int hashCode = 1;
156: for (short element : a) {
157: hashCode = 31 * hashCode + element;
158: }
159: return hashCode;
160: }
161:
162: public static String toString(boolean[] a) {
163: if (a == null)
164: return NULL;
165: if (a.length == 0)
166: return EMPTY_ARRAY;
167: StringBuilder builder = new StringBuilder();
168: builder.append(LEFT_BRACKET).append(a[0]);
169: for (int i = 1; i < a.length; i++) {
170: builder.append(SEPARATOR).append(a[i]);
171: }
172: return builder.append(RIGHT_BRACKET).toString();
173: }
174:
175: public static String toString(byte[] a) {
176: if (a == null)
177: return NULL;
178: if (a.length == 0)
179: return EMPTY_ARRAY;
180: StringBuilder builder = new StringBuilder();
181: builder.append(LEFT_BRACKET).append(a[0]);
182: for (int i = 1; i < a.length; i++) {
183: builder.append(SEPARATOR).append(a[i]);
184: }
185: return builder.append(RIGHT_BRACKET).toString();
186: }
187:
188: public static String toString(char[] a) {
189: if (a == null)
190: return NULL;
191: if (a.length == 0)
192: return EMPTY_ARRAY;
193: StringBuilder builder = new StringBuilder();
194: builder.append(LEFT_BRACKET).append(a[0]);
195: for (int i = 1; i < a.length; i++) {
196: builder.append(SEPARATOR).append(a[i]);
197: }
198: return builder.append(RIGHT_BRACKET).toString();
199: }
200:
201: public static String toString(double[] a) {
202: if (a == null)
203: return NULL;
204: if (a.length == 0)
205: return EMPTY_ARRAY;
206: StringBuilder builder = new StringBuilder();
207: builder.append(LEFT_BRACKET).append(a[0]);
208: for (int i = 1; i < a.length; i++) {
209: builder.append(SEPARATOR).append(a[i]);
210: }
211: return builder.append(RIGHT_BRACKET).toString();
212: }
213:
214: public static String toString(float[] a) {
215: if (a == null)
216: return NULL;
217: if (a.length == 0)
218: return EMPTY_ARRAY;
219: StringBuilder builder = new StringBuilder();
220: builder.append(LEFT_BRACKET).append(a[0]);
221: for (int i = 1; i < a.length; i++) {
222: builder.append(SEPARATOR).append(a[i]);
223: }
224: return builder.append(RIGHT_BRACKET).toString();
225: }
226:
227: public static String toString(int[] a) {
228: if (a == null)
229: return NULL;
230: if (a.length == 0)
231: return EMPTY_ARRAY;
232: StringBuilder builder = new StringBuilder();
233: builder.append(LEFT_BRACKET).append(a[0]);
234: for (int i = 1; i < a.length; i++) {
235: builder.append(SEPARATOR).append(a[i]);
236: }
237: return builder.append(RIGHT_BRACKET).toString();
238: }
239:
240: public static String toString(long[] a) {
241: if (a == null)
242: return NULL;
243: if (a.length == 0)
244: return EMPTY_ARRAY;
245: StringBuilder builder = new StringBuilder();
246: builder.append(LEFT_BRACKET).append(a[0]);
247: for (int i = 1; i < a.length; i++) {
248: builder.append(SEPARATOR).append(a[i]);
249: }
250: return builder.append(RIGHT_BRACKET).toString();
251: }
252:
253: public static String toString(Object[] a) {
254: if (a == null)
255: return NULL;
256: if (a.length == 0)
257: return EMPTY_ARRAY;
258: StringBuilder builder = new StringBuilder();
259: builder.append(LEFT_BRACKET).append(a[0]);
260: for (int i = 1; i < a.length; i++) {
261: builder.append(SEPARATOR).append(a[i]);
262: }
263: return builder.append(RIGHT_BRACKET).toString();
264: }
265:
266: public static String toString(short[] a) {
267: if (a == null)
268: return NULL;
269: if (a.length == 0)
270: return EMPTY_ARRAY;
271: StringBuilder builder = new StringBuilder();
272: builder.append(LEFT_BRACKET).append(a[0]);
273: for (int i = 1; i < a.length; i++) {
274: builder.append(SEPARATOR).append(a[i]);
275: }
276: return builder.append(RIGHT_BRACKET).toString();
277: }
278:
279: private static void appendArray(StringBuilder builder, Object[] a,
280: Set<Object[]> history) {
281: int length = a.length;
282: if (length == 0) {
283: builder.append(EMPTY_ARRAY);
284: return;
285: }
286: if (!history.add(a)) {
287: builder.append("[...]");
288: return;
289: }
290: appendObject(builder.append(LEFT_BRACKET), a[0], history);
291: for (int i = 1; i < length; i++) {
292: appendObject(builder.append(SEPARATOR), a[i], history);
293: }
294: builder.append(RIGHT_BRACKET);
295: }
296:
297: private static void appendObject(StringBuilder builder, Object o,
298: Set<Object[]> history) {
299: if (o instanceof Object[]) {
300: appendArray(builder, (Object[]) o, history);
301: } else {
302: builder.append(getString(o));
303: }
304: }
305:
306: private static int getHashCode(Object o) {
307: if (o == null)
308: return 0;
309: if (o instanceof Object[])
310: return deepHashCode((Object[]) o);
311: if (o instanceof boolean[])
312: return hashCode((boolean[]) o);
313: if (o instanceof byte[])
314: return hashCode((byte[]) o);
315: if (o instanceof char[])
316: return hashCode((char[]) o);
317: if (o instanceof double[])
318: return hashCode((double[]) o);
319: if (o instanceof float[])
320: return hashCode((float[]) o);
321: if (o instanceof int[])
322: return hashCode((int[]) o);
323: if (o instanceof long[])
324: return hashCode((long[]) o);
325: if (o instanceof short[])
326: return hashCode((short[]) o);
327: return o.hashCode();
328: }
329:
330: private static String getString(Object o) {
331: if (o == null)
332: return null;
333: if (o instanceof boolean[])
334: return toString((boolean[]) o);
335: if (o instanceof byte[])
336: return toString((byte[]) o);
337: if (o instanceof char[])
338: return toString((char[]) o);
339: if (o instanceof double[])
340: return toString((double[]) o);
341: if (o instanceof float[])
342: return toString((float[]) o);
343: if (o instanceof int[])
344: return toString((int[]) o);
345: if (o instanceof long[])
346: return toString((long[]) o);
347: if (o instanceof short[])
348: return toString((short[]) o);
349: return o.toString();
350: }
351:
352: private static boolean isEqual(Object o1, Object o2) {
353: if (o1 == o2)
354: return true;
355: if (o1 == null || o2 == null)
356: return false;
357: if (o1 instanceof Object[] && o2 instanceof Object[]) {
358: Object[] a1 = (Object[]) o1;
359: Object[] a2 = (Object[]) o2;
360: int length = a1.length;
361: if (length != a2.length)
362: return false;
363: for (int i = 0; i < length; i++) {
364: if (!isEqual(a1[i], a2[i]))
365: return false;
366: }
367: return true;
368: }
369: if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
370: return Arrays.equals(((boolean[]) o1), ((boolean[]) o2));
371: }
372: if (o1 instanceof byte[] && o2 instanceof byte[]) {
373: return Arrays.equals(((byte[]) o1), ((byte[]) o2));
374: }
375: if (o1 instanceof char[] && o2 instanceof char[]) {
376: return Arrays.equals(((char[]) o1), ((char[]) o2));
377: }
378: if (o1 instanceof double[] && o2 instanceof double[]) {
379: return Arrays.equals(((double[]) o1), ((double[]) o2));
380: }
381: if (o1 instanceof float[] && o2 instanceof float[]) {
382: return Arrays.equals(((float[]) o1), ((float[]) o2));
383: }
384: if (o1 instanceof int[] && o2 instanceof int[]) {
385: return Arrays.equals(((int[]) o1), ((int[]) o2));
386: }
387: if (o1 instanceof long[] && o2 instanceof long[]) {
388: return Arrays.equals(((long[]) o1), ((long[]) o2));
389: }
390: if (o1 instanceof short[] && o2 instanceof short[]) {
391: return Arrays.equals(((short[]) o1), ((short[]) o2));
392: }
393: return o1.equals(o2);
394: }
395:
396: }
|