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