25acbfcded148e9fe46e8f1cd68c2adc94b4ee01
[jalview.git] / srcjar / javajs / util / AU.java
1 /* $RCSfile$
2  * $Author: egonw $
3  * $Date: 2005-11-10 09:52:44 -0600 (Thu, 10 Nov 2005) $
4  * $Revision: 4255 $
5  *
6  * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017
7  * for use in SwingJS via transpilation into JavaScript using Java2Script.
8  *
9  * Copyright (C) 2003-2005  The Jmol Development Team
10  *
11  * Contact: jmol-developers@lists.sf.net
12  *
13  *  This library is free software; you can redistribute it and/or
14  *  modify it under the terms of the GNU Lesser General Public
15  *  License as published by the Free Software Foundation; either
16  *  version 2.1 of the License, or (at your option) any later version.
17  *
18  *  This library is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  *  Lesser General Public License for more details.
22  *
23  *  You should have received a copy of the GNU Lesser General Public
24  *  License along with this library; if not, write to the Free Software
25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27 package javajs.util;
28
29 // 4/23/15 BH getComponentType fix
30
31 import java.lang.reflect.Array;
32
33 import java.util.Arrays;
34 import java.util.Hashtable;
35 import java.util.Map;
36
37
38 final public class AU {
39
40   /**
41    * Very important that this not be used with Int32Array or Float32Array,
42    * because it is not initialize to all zeros in MSIE 9. 
43    * 
44    * @param array
45    * @param minimumLength
46    * @return array
47    */
48   public static Object ensureLength(Object array, int minimumLength) {
49     return (array != null && getLength(array) >= minimumLength ? array 
50         : arrayCopyObject(array, minimumLength));
51   }
52
53   public static String[] ensureLengthS(String[] array, int minimumLength) {
54     return (array != null && array.length >= minimumLength ? array
55         : arrayCopyS(array, minimumLength));
56   }
57
58   public static float[] ensureLengthA(float[] array, int minimumLength) {
59    return (array != null && array.length >= minimumLength ? array: arrayCopyF(array, minimumLength));
60   }
61
62   public static int[] ensureLengthI(int[] array, int minimumLength) {
63     return (array != null && array.length >= minimumLength ? array : arrayCopyI(array, minimumLength));
64   }
65
66   public static short[] ensureLengthShort(short[] array, int minimumLength) {
67     return (array != null && array.length >= minimumLength ? array : arrayCopyShort(array, minimumLength));
68   }
69
70   public static byte[] ensureLengthByte(byte[] array, int minimumLength) {
71     return (array != null && array.length >= minimumLength ? array : arrayCopyByte(array, minimumLength));
72   }
73
74   /**
75    * Very important that this not be used with Int32Array or Float32Array,
76    * because it is not initialized to all zeros in MSIE 9.
77    * 
78    * @param array
79    * @return array
80    */
81   public static Object doubleLength(Object array) {
82     return arrayCopyObject(array, (array == null ? 16 : 2 * getLength(array)));
83   }
84
85   public static String[] doubleLengthS(String[] array) {
86     return arrayCopyS(array, (array == null ? 16 : 2 * array.length));
87   }
88
89   public static float[] doubleLengthF(float[] array) {
90     return arrayCopyF(array, (array == null ? 16 : 2 * array.length));
91   }
92
93   public static int[] doubleLengthI(int[] array) {
94     return arrayCopyI(array, (array == null ? 16 : 2 * array.length));
95   }
96
97   public static short[] doubleLengthShort(short[] array) {
98     return arrayCopyShort(array, (array == null ? 16 : 2 * array.length));
99   }
100
101   public static byte[] doubleLengthByte(byte[] array) {
102     return arrayCopyByte(array, (array == null ? 16 : 2 * array.length));
103   }
104
105   public static boolean[] doubleLengthBool(boolean[] array) {
106     return arrayCopyBool(array, (array == null ? 16 : 2 * array.length));
107   }
108
109   public static Object deleteElements(Object array, int firstElement,
110                                      int nElements) {
111     if (nElements == 0 || array == null)
112       return array;
113     int oldLength = getLength(array);
114     if (firstElement >= oldLength)
115       return array;
116     int n = oldLength - (firstElement + nElements);
117     if (n < 0)
118       n = 0;
119     Object t = newInstanceO(array, firstElement + n);
120     if (firstElement > 0)
121       System.arraycopy(array, 0, t, 0, firstElement);
122     if (n > 0)
123       System.arraycopy(array, firstElement + nElements, t, firstElement, n);
124     return t;
125   }
126
127   /**
128    * note -- cannot copy if array is null! does not copy if length is unchanged
129    * 
130    * @param array
131    * @param newLength
132    * @return array
133    */
134   public static Object arrayCopyObject(Object array, int newLength) {  
135     int oldLength = (array == null ? -1 : getLength(array));
136     if (newLength < 0) newLength = oldLength;
137     if (newLength == oldLength)
138      return array;
139     /**
140      * @j2sNative
141      * 
142      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
143      */
144     {}
145     Object t = newInstanceO(array, newLength);
146     if (oldLength > 0)
147       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
148         : newLength);
149     return t;
150
151   }
152
153   /**
154    * Very important that this not be used with Int32Array or Float32Array,
155    * because those need to be initialized to all zeros in MSIE 9, and
156    * MSIE 9 cannot distinguish Int32Array or Float32Array from Array.
157    * 
158    * @param array
159    * @param n
160    * @return array
161    */
162   private static Object newInstanceO(Object array, int n) {
163     return Array.newInstance(array.getClass().getComponentType(), n);
164   }
165
166   public static int getLength(Object array) {
167     /**
168      * @j2sNative
169      * 
170      *  return array.length
171      *   
172      */
173     {
174       return Array.getLength(array);
175     }
176   }
177
178   public static String[] arrayCopyS(String[] array, int newLength) {
179     int oldLength = (array == null ? -1 : array.length);
180     if (newLength < 0) newLength = oldLength;
181     /**
182      * @j2sNative
183      * 
184      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
185      */
186     {}
187     String[] t = new String[newLength];
188     if (array != null) {
189       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
190           : newLength);
191     }
192     return t;
193   }
194
195   public static int[][] arrayCopyII(int[][] array, int newLength) {
196     int[][] t = newInt2(newLength);
197     if (array != null) {
198       int oldLength = array.length;
199       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
200           : newLength);
201     }
202     return t;
203   }
204
205   public static T3[] arrayCopyPt(T3[] array, int newLength) {
206     if (newLength < 0)
207       newLength = array.length;
208     T3[] t = new T3[newLength];
209     if (array != null) {
210       int oldLength = array.length;
211       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
212           : newLength);
213     }
214     return t;
215   }
216
217   public static float[] arrayCopyF(float[] array, int newLength) {
218     int oldLength = (array == null ? -1 : array.length);
219     if (newLength < 0) newLength = oldLength;
220     /**
221      * @j2sNative
222      * 
223      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
224      */
225     {}
226     float[] t = new float[newLength];
227     if (array != null) {
228       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
229           : newLength);
230     }
231     return t;
232   }
233
234   public static int[] arrayCopyI(int[] array, int newLength) {
235     int oldLength = (array == null ? -1 : array.length);
236     if (newLength < 0) newLength = oldLength;
237     /**
238      * @j2sNative
239      * 
240      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
241      */
242     {}
243     int[] t = new int[newLength];
244     if (array != null) {
245       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
246           : newLength);
247     }
248     return t;
249   }
250
251   /**
252    * a specialized method that allows copying from a starting point either
253    * to the end or to the middle (color schemes, especially)
254    * @param array
255    * @param i0
256    * @param n
257    * @return array or null
258    */
259   public static int[] arrayCopyRangeI(int[] array, int i0, int n) {
260     if (array == null)
261       return null;
262     int oldLength = array.length;
263     if (n == -1) n = oldLength;
264     if (n == -2) n = oldLength / 2;
265     /**
266      * @j2sNative
267      * 
268      * return Clazz.array(-1, array, i0, n);
269      * 
270      */
271     {
272         n -= i0;
273         int[] t = new int[n];
274         System.arraycopy(array, i0, t, 0, n);
275         return t;
276     }
277   }
278
279   public static int[] arrayCopyRangeRevI(int[] array, int i0, int n) {
280     if (array == null)
281       return null;
282     /**
283      * @j2sNative
284      * 
285      * return Clazz.array(-1, array, i0, n).reverse();
286      */
287     {
288         int[] t = arrayCopyRangeI(array, i0, n);
289         if (n < 0)
290           n = array.length;
291         for (int i = n / 2; --i >= 0;)
292           swapInt(t, i, n - 1 - i);
293         return t;
294     }
295   }
296
297   public static short[] arrayCopyShort(short[] array, int newLength) {
298     int oldLength = (array == null ? -1 : array.length);
299     if (newLength < 0) newLength = oldLength;
300     /**
301      * @j2sNative
302      * 
303      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
304      */
305     {}
306     short[] t = new short[newLength];
307     if (array != null) {
308       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
309           : newLength);
310     }
311     return t;
312   }
313
314   public static byte[] arrayCopyByte(byte[] array, int newLength) {
315     int oldLength = (array == null ? -1 : array.length);
316     if (newLength < 0) newLength = oldLength;
317     /**
318      * @j2sNative
319      * 
320      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
321      */
322     {}
323     byte[] t = new byte[newLength];
324     if (array != null) {
325       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
326           : newLength);
327     }
328     return t;
329   }
330
331   public static boolean[] arrayCopyBool(boolean[] array, int newLength) {
332     int oldLength = (array == null ? -1 : array.length);
333     if (newLength < 0) newLength = oldLength;
334     /**
335      * @j2sNative
336      * 
337      *     if (newLength < oldLength) return Clazz.array(-1, array, 0, newLength);
338      */
339     {}
340     boolean[] t = new boolean[newLength];
341     if (array != null) {
342       System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
343           : newLength);
344     }
345     return t;
346   }
347
348   public static void swapInt(int[] array, int indexA, int indexB) {
349     int t = array[indexA];
350     array[indexA] = array[indexB];
351     array[indexB] = t;
352   }
353
354   /*
355   public static void swap(short[] array, int indexA, int indexB) {
356     short t = array[indexA];
357     array[indexA] = array[indexB];
358     array[indexB] = t;
359   }
360
361   public static void swap(float[] array, int indexA, int indexB) {
362     float t = array[indexA];
363     array[indexA] = array[indexB];
364     array[indexB] = t;
365   }
366   */
367   
368   public static String dumpArray(String msg, float[][] A, int x1, int x2, int y1, int y2) {
369     String s = "dumpArray: " + msg + "\n";
370     for (int x = x1; x <= x2; x++)
371       s += "\t*" + x + "*";
372     for (int y = y2; y >= y1; y--) {
373       s += "\n*" + y + "*";
374       for (int x = x1; x <= x2; x++)
375         s += "\t" + (x < A.length && y < A[x].length ? A[x][y] : Float.NaN);
376     }
377     return s;
378   }
379
380   public static String dumpIntArray(int[] A, int n) {
381     String str = "";
382     for (int i = 0; i < n; i++)
383       str += " " + A[i];
384     return str;
385   }
386
387   public static String sortedItem(Lst<String> v, int n) {
388     if (v.size() == 0)
389       return null;
390     if (v.size() == 1)
391       return v.get(0);
392     String[] keys = v.toArray(new String[v.size()]);
393     Arrays.sort(keys);
394     return keys[n % keys.length];
395   }
396
397   /**
398    * Helper method for creating a List<Tx>[] without warnings.
399    * 
400    * @param <type> Type of objects in the list.
401    * @param size Array size.
402    * @return Array of List<type>
403    */
404   @SuppressWarnings("unchecked")
405   public static <type> Lst<type>[] createArrayOfArrayList(int size) {
406     return new Lst[size];
407   }
408
409   /**
410    * Helper method for creating a Map<K, V>[] without warnings.
411    * 
412    * @param <K> Type of object for the keys in the map.
413    * @param <V> Type of object for the values in the map.
414    * @param size Array size.
415    * @return Array of Map<K, V>
416    */
417   @SuppressWarnings("unchecked")
418   public static <K, V> Map<K, V>[] createArrayOfHashtable(int size) {
419     return new Hashtable[size];
420   }
421
422   public static void swap(Object[] o, int i, int j) {
423     Object oi = o[i];
424     o[i] = o[j];
425     o[j] = oi;
426   }
427
428   public static float[][] newFloat2(int n) {
429     return new float[n][];
430   }
431
432         public static boolean[][] newBool2(int n) {
433         return new boolean[n][];
434         }
435
436   public static int[][] newInt2(int n) {
437     return new int[n][];
438   }
439
440   public static int[][][] newInt3(int nx, int ny) {
441     return (ny < 0 ? new int[nx][][] : new int[nx][ny][]);
442   }
443
444   public static float[][][] newFloat3(int nx, int ny) {
445     return (ny < 0 ? new float[nx][][] : new float[nx][ny][]);
446   }
447
448   public static int[][][][] newInt4(int n) {
449     return new int[n][][][];
450   }
451
452   public static short[][] newShort2(int n) {
453     return new short[n][];
454   }
455
456   public static byte[][] newByte2(int n) {
457     return new byte[n][];
458   }
459
460   public static double[][] newDouble2(int n) {
461     return new double[n][];
462   }
463
464   /**
465    * remove all keys from a map that start with given root
466    * @param map
467    * @param root
468    * @return number removed
469    */
470   public static int removeMapKeys(Map<String, ?> map, String root) {
471     Lst<String> list = new Lst<String>();
472     for (String key: map.keySet())
473       if (key.startsWith(root))
474         list.addLast(key);
475     for (int i = list.size(); --i >= 0;)
476       map.remove(list.get(i));
477     return list.size();
478   }
479
480         public static boolean isAS(Object x) {
481                 return x instanceof String[];
482         }
483
484         public static boolean isASS(Object x) {
485                 return x instanceof String[][];
486         }
487
488         public static boolean isAP(Object x) {
489                 return x instanceof T3[];
490         }
491
492         public static boolean isAF(Object x) {
493           return x instanceof float[];
494         }
495
496         public static boolean isAFloat(Object x) {
497           return x instanceof Float[];
498         }
499
500         public static boolean isAD(Object x) {
501           return x instanceof double[];
502         }
503
504         public static boolean isADD(Object x) {
505           return x instanceof double[][];
506         }
507
508         public static boolean isAB(Object x) {
509           return x instanceof byte[];
510         }
511
512         public static boolean isAI(Object x) {
513           return x instanceof int[];
514         }
515
516         public static boolean isAII(Object x) {
517           return (x instanceof int[][]);
518         }
519
520         public static boolean isAFF(Object x) {
521           return x instanceof float[][];
522         }
523
524         public static boolean isAFFF(Object x) {
525           return x instanceof float[][][];
526         }
527         
528         /**
529          * Ensure that we have signed and not unsigned bytes coming out of any
530          * process, but particularly out of file reading.
531          * 
532          * @param b
533          * @return b
534          */
535         public static byte[] ensureSignedBytes(byte[] b) {
536                 if (b != null) {
537                         /**
538                          * @j2sNative
539                          * 
540                          *                      for (var i = b.length; --i >= 0;) { var j = b[i] &
541                          *            0xFF; if (j >= 0x80) j -= 0x100; b[i] = j; }
542                          * 
543                          */
544                         {
545                         }
546                 }
547                 return b;
548         }
549
550
551 }