Home | History | Annotate | Download | only in util
      1 package org.bouncycastle.util;
      2 
      3 import java.math.BigInteger;
      4 import java.util.NoSuchElementException;
      5 
      6 /**
      7  * General array utilities.
      8  */
      9 public final class Arrays
     10 {
     11     private Arrays()
     12     {
     13         // static class, hide constructor
     14     }
     15 
     16     public static boolean areEqual(
     17         boolean[]  a,
     18         boolean[]  b)
     19     {
     20         if (a == b)
     21         {
     22             return true;
     23         }
     24 
     25         if (a == null || b == null)
     26         {
     27             return false;
     28         }
     29 
     30         if (a.length != b.length)
     31         {
     32             return false;
     33         }
     34 
     35         for (int i = 0; i != a.length; i++)
     36         {
     37             if (a[i] != b[i])
     38             {
     39                 return false;
     40             }
     41         }
     42 
     43         return true;
     44     }
     45 
     46     public static boolean areEqual(
     47         char[]  a,
     48         char[]  b)
     49     {
     50         if (a == b)
     51         {
     52             return true;
     53         }
     54 
     55         if (a == null || b == null)
     56         {
     57             return false;
     58         }
     59 
     60         if (a.length != b.length)
     61         {
     62             return false;
     63         }
     64 
     65         for (int i = 0; i != a.length; i++)
     66         {
     67             if (a[i] != b[i])
     68             {
     69                 return false;
     70             }
     71         }
     72 
     73         return true;
     74     }
     75 
     76     public static boolean areEqual(
     77         byte[]  a,
     78         byte[]  b)
     79     {
     80         if (a == b)
     81         {
     82             return true;
     83         }
     84 
     85         if (a == null || b == null)
     86         {
     87             return false;
     88         }
     89 
     90         if (a.length != b.length)
     91         {
     92             return false;
     93         }
     94 
     95         for (int i = 0; i != a.length; i++)
     96         {
     97             if (a[i] != b[i])
     98             {
     99                 return false;
    100             }
    101         }
    102 
    103         return true;
    104     }
    105 
    106     public static boolean areEqual(
    107         short[]  a,
    108         short[]  b)
    109     {
    110         if (a == b)
    111         {
    112             return true;
    113         }
    114 
    115         if (a == null || b == null)
    116         {
    117             return false;
    118         }
    119 
    120         if (a.length != b.length)
    121         {
    122             return false;
    123         }
    124 
    125         for (int i = 0; i != a.length; i++)
    126         {
    127             if (a[i] != b[i])
    128             {
    129                 return false;
    130             }
    131         }
    132 
    133         return true;
    134     }
    135 
    136     /**
    137      * A constant time equals comparison - does not terminate early if
    138      * test will fail.
    139      *
    140      * @param a first array
    141      * @param b second array
    142      * @return true if arrays equal, false otherwise.
    143      */
    144     public static boolean constantTimeAreEqual(
    145         byte[]  a,
    146         byte[]  b)
    147     {
    148         if (a == b)
    149         {
    150             return true;
    151         }
    152 
    153         if (a == null || b == null)
    154         {
    155             return false;
    156         }
    157 
    158         if (a.length != b.length)
    159         {
    160             return false;
    161         }
    162 
    163         int nonEqual = 0;
    164 
    165         for (int i = 0; i != a.length; i++)
    166         {
    167             nonEqual |= (a[i] ^ b[i]);
    168         }
    169 
    170         return nonEqual == 0;
    171     }
    172 
    173     public static boolean areEqual(
    174         int[]  a,
    175         int[]  b)
    176     {
    177         if (a == b)
    178         {
    179             return true;
    180         }
    181 
    182         if (a == null || b == null)
    183         {
    184             return false;
    185         }
    186 
    187         if (a.length != b.length)
    188         {
    189             return false;
    190         }
    191 
    192         for (int i = 0; i != a.length; i++)
    193         {
    194             if (a[i] != b[i])
    195             {
    196                 return false;
    197             }
    198         }
    199 
    200         return true;
    201     }
    202 
    203     public static boolean areEqual(
    204         long[]  a,
    205         long[]  b)
    206     {
    207         if (a == b)
    208         {
    209             return true;
    210         }
    211 
    212         if (a == null || b == null)
    213         {
    214             return false;
    215         }
    216 
    217         if (a.length != b.length)
    218         {
    219             return false;
    220         }
    221 
    222         for (int i = 0; i != a.length; i++)
    223         {
    224             if (a[i] != b[i])
    225             {
    226                 return false;
    227             }
    228         }
    229 
    230         return true;
    231     }
    232 
    233     public static boolean areEqual(Object[] a, Object[] b)
    234     {
    235         if (a == b)
    236         {
    237             return true;
    238         }
    239         if (a == null || b == null)
    240         {
    241             return false;
    242         }
    243         if (a.length != b.length)
    244         {
    245             return false;
    246         }
    247         for (int i = 0; i != a.length; i++)
    248         {
    249             Object objA = a[i], objB = b[i];
    250             if (objA == null)
    251             {
    252                 if (objB != null)
    253                 {
    254                     return false;
    255                 }
    256             }
    257             else if (!objA.equals(objB))
    258             {
    259                 return false;
    260             }
    261         }
    262         return true;
    263     }
    264 
    265     public static int compareUnsigned(byte[] a, byte[] b)
    266     {
    267         if (a == b)
    268         {
    269             return 0;
    270         }
    271         if (a == null)
    272         {
    273             return -1;
    274         }
    275         if (b == null)
    276         {
    277             return 1;
    278         }
    279         int minLen = Math.min(a.length, b.length);
    280         for (int i = 0; i < minLen; ++i)
    281         {
    282             int aVal = a[i] & 0xFF, bVal = b[i] & 0xFF;
    283             if (aVal < bVal)
    284             {
    285                 return -1;
    286             }
    287             if (aVal > bVal)
    288             {
    289                 return 1;
    290             }
    291         }
    292         if (a.length < b.length)
    293         {
    294             return -1;
    295         }
    296         if (a.length > b.length)
    297         {
    298             return 1;
    299         }
    300         return 0;
    301     }
    302 
    303     public static boolean contains(short[] a, short n)
    304     {
    305         for (int i = 0; i < a.length; ++i)
    306         {
    307             if (a[i] == n)
    308             {
    309                 return true;
    310             }
    311         }
    312         return false;
    313     }
    314 
    315     public static boolean contains(int[] a, int n)
    316     {
    317         for (int i = 0; i < a.length; ++i)
    318         {
    319             if (a[i] == n)
    320             {
    321                 return true;
    322             }
    323         }
    324         return false;
    325     }
    326 
    327     public static void fill(
    328         byte[] array,
    329         byte value)
    330     {
    331         for (int i = 0; i < array.length; i++)
    332         {
    333             array[i] = value;
    334         }
    335     }
    336 
    337     public static void fill(
    338         char[] array,
    339         char value)
    340     {
    341         for (int i = 0; i < array.length; i++)
    342         {
    343             array[i] = value;
    344         }
    345     }
    346 
    347     public static void fill(
    348         long[] array,
    349         long value)
    350     {
    351         for (int i = 0; i < array.length; i++)
    352         {
    353             array[i] = value;
    354         }
    355     }
    356 
    357     public static void fill(
    358         short[] array,
    359         short value)
    360     {
    361         for (int i = 0; i < array.length; i++)
    362         {
    363             array[i] = value;
    364         }
    365     }
    366 
    367     public static void fill(
    368         int[] array,
    369         int value)
    370     {
    371         for (int i = 0; i < array.length; i++)
    372         {
    373             array[i] = value;
    374         }
    375     }
    376 
    377     public static int hashCode(byte[] data)
    378     {
    379         if (data == null)
    380         {
    381             return 0;
    382         }
    383 
    384         int i = data.length;
    385         int hc = i + 1;
    386 
    387         while (--i >= 0)
    388         {
    389             hc *= 257;
    390             hc ^= data[i];
    391         }
    392 
    393         return hc;
    394     }
    395 
    396     public static int hashCode(byte[] data, int off, int len)
    397     {
    398         if (data == null)
    399         {
    400             return 0;
    401         }
    402 
    403         int i = len;
    404         int hc = i + 1;
    405 
    406         while (--i >= 0)
    407         {
    408             hc *= 257;
    409             hc ^= data[off + i];
    410         }
    411 
    412         return hc;
    413     }
    414 
    415     public static int hashCode(char[] data)
    416     {
    417         if (data == null)
    418         {
    419             return 0;
    420         }
    421 
    422         int i = data.length;
    423         int hc = i + 1;
    424 
    425         while (--i >= 0)
    426         {
    427             hc *= 257;
    428             hc ^= data[i];
    429         }
    430 
    431         return hc;
    432     }
    433 
    434     public static int hashCode(int[][] ints)
    435     {
    436         int hc = 0;
    437 
    438         for (int i = 0; i != ints.length; i++)
    439         {
    440             hc = hc * 257 + hashCode(ints[i]);
    441         }
    442 
    443         return hc;
    444     }
    445 
    446     public static int hashCode(int[] data)
    447     {
    448         if (data == null)
    449         {
    450             return 0;
    451         }
    452 
    453         int i = data.length;
    454         int hc = i + 1;
    455 
    456         while (--i >= 0)
    457         {
    458             hc *= 257;
    459             hc ^= data[i];
    460         }
    461 
    462         return hc;
    463     }
    464 
    465     public static int hashCode(int[] data, int off, int len)
    466     {
    467         if (data == null)
    468         {
    469             return 0;
    470         }
    471 
    472         int i = len;
    473         int hc = i + 1;
    474 
    475         while (--i >= 0)
    476         {
    477             hc *= 257;
    478             hc ^= data[off + i];
    479         }
    480 
    481         return hc;
    482     }
    483 
    484     public static int hashCode(long[] data)
    485     {
    486         if (data == null)
    487         {
    488             return 0;
    489         }
    490 
    491         int i = data.length;
    492         int hc = i + 1;
    493 
    494         while (--i >= 0)
    495         {
    496             long di = data[i];
    497             hc *= 257;
    498             hc ^= (int)di;
    499             hc *= 257;
    500             hc ^= (int)(di >>> 32);
    501         }
    502 
    503         return hc;
    504     }
    505 
    506     public static int hashCode(long[] data, int off, int len)
    507     {
    508         if (data == null)
    509         {
    510             return 0;
    511         }
    512 
    513         int i = len;
    514         int hc = i + 1;
    515 
    516         while (--i >= 0)
    517         {
    518             long di = data[off + i];
    519             hc *= 257;
    520             hc ^= (int)di;
    521             hc *= 257;
    522             hc ^= (int)(di >>> 32);
    523         }
    524 
    525         return hc;
    526     }
    527 
    528     public static int hashCode(short[][][] shorts)
    529     {
    530         int hc = 0;
    531 
    532         for (int i = 0; i != shorts.length; i++)
    533         {
    534             hc = hc * 257 + hashCode(shorts[i]);
    535         }
    536 
    537         return hc;
    538     }
    539 
    540     public static int hashCode(short[][] shorts)
    541     {
    542         int hc = 0;
    543 
    544         for (int i = 0; i != shorts.length; i++)
    545         {
    546             hc = hc * 257 + hashCode(shorts[i]);
    547         }
    548 
    549         return hc;
    550     }
    551 
    552     public static int hashCode(short[] data)
    553     {
    554         if (data == null)
    555         {
    556             return 0;
    557         }
    558 
    559         int i = data.length;
    560         int hc = i + 1;
    561 
    562         while (--i >= 0)
    563         {
    564             hc *= 257;
    565             hc ^= (data[i] & 0xff);
    566         }
    567 
    568         return hc;
    569     }
    570 
    571     public static int hashCode(Object[] data)
    572     {
    573         if (data == null)
    574         {
    575             return 0;
    576         }
    577 
    578         int i = data.length;
    579         int hc = i + 1;
    580 
    581         while (--i >= 0)
    582         {
    583             hc *= 257;
    584             hc ^= data[i].hashCode();
    585         }
    586 
    587         return hc;
    588     }
    589 
    590     public static byte[] clone(byte[] data)
    591     {
    592         if (data == null)
    593         {
    594             return null;
    595         }
    596         byte[] copy = new byte[data.length];
    597 
    598         System.arraycopy(data, 0, copy, 0, data.length);
    599 
    600         return copy;
    601     }
    602 
    603     public static char[] clone(char[] data)
    604     {
    605         if (data == null)
    606         {
    607             return null;
    608         }
    609         char[] copy = new char[data.length];
    610 
    611         System.arraycopy(data, 0, copy, 0, data.length);
    612 
    613         return copy;
    614     }
    615 
    616     public static byte[] clone(byte[] data, byte[] existing)
    617     {
    618         if (data == null)
    619         {
    620             return null;
    621         }
    622         if ((existing == null) || (existing.length != data.length))
    623         {
    624             return clone(data);
    625         }
    626         System.arraycopy(data, 0, existing, 0, existing.length);
    627         return existing;
    628     }
    629 
    630     public static byte[][] clone(byte[][] data)
    631     {
    632         if (data == null)
    633         {
    634             return null;
    635         }
    636 
    637         byte[][] copy = new byte[data.length][];
    638 
    639         for (int i = 0; i != copy.length; i++)
    640         {
    641             copy[i] = clone(data[i]);
    642         }
    643 
    644         return copy;
    645     }
    646 
    647     public static byte[][][] clone(byte[][][] data)
    648     {
    649         if (data == null)
    650         {
    651             return null;
    652         }
    653 
    654         byte[][][] copy = new byte[data.length][][];
    655 
    656         for (int i = 0; i != copy.length; i++)
    657         {
    658             copy[i] = clone(data[i]);
    659         }
    660 
    661         return copy;
    662     }
    663 
    664     public static int[] clone(int[] data)
    665     {
    666         if (data == null)
    667         {
    668             return null;
    669         }
    670         int[] copy = new int[data.length];
    671 
    672         System.arraycopy(data, 0, copy, 0, data.length);
    673 
    674         return copy;
    675     }
    676 
    677     public static long[] clone(long[] data)
    678     {
    679         if (data == null)
    680         {
    681             return null;
    682         }
    683         long[] copy = new long[data.length];
    684 
    685         System.arraycopy(data, 0, copy, 0, data.length);
    686 
    687         return copy;
    688     }
    689 
    690     public static long[] clone(long[] data, long[] existing)
    691     {
    692         if (data == null)
    693         {
    694             return null;
    695         }
    696         if ((existing == null) || (existing.length != data.length))
    697         {
    698             return clone(data);
    699         }
    700         System.arraycopy(data, 0, existing, 0, existing.length);
    701         return existing;
    702     }
    703 
    704     public static short[] clone(short[] data)
    705     {
    706         if (data == null)
    707         {
    708             return null;
    709         }
    710         short[] copy = new short[data.length];
    711 
    712         System.arraycopy(data, 0, copy, 0, data.length);
    713 
    714         return copy;
    715     }
    716 
    717     public static BigInteger[] clone(BigInteger[] data)
    718     {
    719         if (data == null)
    720         {
    721             return null;
    722         }
    723         BigInteger[] copy = new BigInteger[data.length];
    724 
    725         System.arraycopy(data, 0, copy, 0, data.length);
    726 
    727         return copy;
    728     }
    729 
    730     public static byte[] copyOf(byte[] data, int newLength)
    731     {
    732         byte[] tmp = new byte[newLength];
    733 
    734         if (newLength < data.length)
    735         {
    736             System.arraycopy(data, 0, tmp, 0, newLength);
    737         }
    738         else
    739         {
    740             System.arraycopy(data, 0, tmp, 0, data.length);
    741         }
    742 
    743         return tmp;
    744     }
    745 
    746     public static char[] copyOf(char[] data, int newLength)
    747     {
    748         char[] tmp = new char[newLength];
    749 
    750         if (newLength < data.length)
    751         {
    752             System.arraycopy(data, 0, tmp, 0, newLength);
    753         }
    754         else
    755         {
    756             System.arraycopy(data, 0, tmp, 0, data.length);
    757         }
    758 
    759         return tmp;
    760     }
    761 
    762     public static int[] copyOf(int[] data, int newLength)
    763     {
    764         int[] tmp = new int[newLength];
    765 
    766         if (newLength < data.length)
    767         {
    768             System.arraycopy(data, 0, tmp, 0, newLength);
    769         }
    770         else
    771         {
    772             System.arraycopy(data, 0, tmp, 0, data.length);
    773         }
    774 
    775         return tmp;
    776     }
    777 
    778     public static long[] copyOf(long[] data, int newLength)
    779     {
    780         long[] tmp = new long[newLength];
    781 
    782         if (newLength < data.length)
    783         {
    784             System.arraycopy(data, 0, tmp, 0, newLength);
    785         }
    786         else
    787         {
    788             System.arraycopy(data, 0, tmp, 0, data.length);
    789         }
    790 
    791         return tmp;
    792     }
    793 
    794     public static BigInteger[] copyOf(BigInteger[] data, int newLength)
    795     {
    796         BigInteger[] tmp = new BigInteger[newLength];
    797 
    798         if (newLength < data.length)
    799         {
    800             System.arraycopy(data, 0, tmp, 0, newLength);
    801         }
    802         else
    803         {
    804             System.arraycopy(data, 0, tmp, 0, data.length);
    805         }
    806 
    807         return tmp;
    808     }
    809 
    810     /**
    811      * Make a copy of a range of bytes from the passed in data array. The range can
    812      * extend beyond the end of the input array, in which case the return array will
    813      * be padded with zeroes.
    814      *
    815      * @param data the array from which the data is to be copied.
    816      * @param from the start index at which the copying should take place.
    817      * @param to the final index of the range (exclusive).
    818      *
    819      * @return a new byte array containing the range given.
    820      */
    821     public static byte[] copyOfRange(byte[] data, int from, int to)
    822     {
    823         int newLength = getLength(from, to);
    824 
    825         byte[] tmp = new byte[newLength];
    826 
    827         if (data.length - from < newLength)
    828         {
    829             System.arraycopy(data, from, tmp, 0, data.length - from);
    830         }
    831         else
    832         {
    833             System.arraycopy(data, from, tmp, 0, newLength);
    834         }
    835 
    836         return tmp;
    837     }
    838 
    839     public static int[] copyOfRange(int[] data, int from, int to)
    840     {
    841         int newLength = getLength(from, to);
    842 
    843         int[] tmp = new int[newLength];
    844 
    845         if (data.length - from < newLength)
    846         {
    847             System.arraycopy(data, from, tmp, 0, data.length - from);
    848         }
    849         else
    850         {
    851             System.arraycopy(data, from, tmp, 0, newLength);
    852         }
    853 
    854         return tmp;
    855     }
    856 
    857     public static long[] copyOfRange(long[] data, int from, int to)
    858     {
    859         int newLength = getLength(from, to);
    860 
    861         long[] tmp = new long[newLength];
    862 
    863         if (data.length - from < newLength)
    864         {
    865             System.arraycopy(data, from, tmp, 0, data.length - from);
    866         }
    867         else
    868         {
    869             System.arraycopy(data, from, tmp, 0, newLength);
    870         }
    871 
    872         return tmp;
    873     }
    874 
    875     public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
    876     {
    877         int newLength = getLength(from, to);
    878 
    879         BigInteger[] tmp = new BigInteger[newLength];
    880 
    881         if (data.length - from < newLength)
    882         {
    883             System.arraycopy(data, from, tmp, 0, data.length - from);
    884         }
    885         else
    886         {
    887             System.arraycopy(data, from, tmp, 0, newLength);
    888         }
    889 
    890         return tmp;
    891     }
    892 
    893     private static int getLength(int from, int to)
    894     {
    895         int newLength = to - from;
    896         if (newLength < 0)
    897         {
    898             StringBuffer sb = new StringBuffer(from);
    899             sb.append(" > ").append(to);
    900             throw new IllegalArgumentException(sb.toString());
    901         }
    902         return newLength;
    903     }
    904 
    905     public static byte[] append(byte[] a, byte b)
    906     {
    907         if (a == null)
    908         {
    909             return new byte[]{ b };
    910         }
    911 
    912         int length = a.length;
    913         byte[] result = new byte[length + 1];
    914         System.arraycopy(a, 0, result, 0, length);
    915         result[length] = b;
    916         return result;
    917     }
    918 
    919     public static short[] append(short[] a, short b)
    920     {
    921         if (a == null)
    922         {
    923             return new short[]{ b };
    924         }
    925 
    926         int length = a.length;
    927         short[] result = new short[length + 1];
    928         System.arraycopy(a, 0, result, 0, length);
    929         result[length] = b;
    930         return result;
    931     }
    932 
    933     public static int[] append(int[] a, int b)
    934     {
    935         if (a == null)
    936         {
    937             return new int[]{ b };
    938         }
    939 
    940         int length = a.length;
    941         int[] result = new int[length + 1];
    942         System.arraycopy(a, 0, result, 0, length);
    943         result[length] = b;
    944         return result;
    945     }
    946 
    947     public static String[] append(String[] a, String b)
    948     {
    949         if (a == null)
    950         {
    951             return new String[]{ b };
    952         }
    953 
    954         int length = a.length;
    955         String[] result = new String[length + 1];
    956         System.arraycopy(a, 0, result, 0, length);
    957         result[length] = b;
    958         return result;
    959     }
    960 
    961 
    962 
    963     public static byte[] concatenate(byte[] a, byte[] b)
    964     {
    965         if (a != null && b != null)
    966         {
    967             byte[] rv = new byte[a.length + b.length];
    968 
    969             System.arraycopy(a, 0, rv, 0, a.length);
    970             System.arraycopy(b, 0, rv, a.length, b.length);
    971 
    972             return rv;
    973         }
    974         else if (b != null)
    975         {
    976             return clone(b);
    977         }
    978         else
    979         {
    980             return clone(a);
    981         }
    982     }
    983 
    984     public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
    985     {
    986         if (a != null && b != null && c != null)
    987         {
    988             byte[] rv = new byte[a.length + b.length + c.length];
    989 
    990             System.arraycopy(a, 0, rv, 0, a.length);
    991             System.arraycopy(b, 0, rv, a.length, b.length);
    992             System.arraycopy(c, 0, rv, a.length + b.length, c.length);
    993 
    994             return rv;
    995         }
    996         else if (a == null)
    997         {
    998             return concatenate(b, c);
    999         }
   1000         else if (b == null)
   1001         {
   1002             return concatenate(a, c);
   1003         }
   1004         else
   1005         {
   1006             return concatenate(a, b);
   1007         }
   1008     }
   1009 
   1010     public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
   1011     {
   1012         if (a != null && b != null && c != null && d != null)
   1013         {
   1014             byte[] rv = new byte[a.length + b.length + c.length + d.length];
   1015 
   1016             System.arraycopy(a, 0, rv, 0, a.length);
   1017             System.arraycopy(b, 0, rv, a.length, b.length);
   1018             System.arraycopy(c, 0, rv, a.length + b.length, c.length);
   1019             System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
   1020 
   1021             return rv;
   1022         }
   1023         else if (d == null)
   1024         {
   1025             return concatenate(a, b, c);
   1026         }
   1027         else if (c == null)
   1028         {
   1029             return concatenate(a, b, d);
   1030         }
   1031         else if (b == null)
   1032         {
   1033             return concatenate(a, c, d);
   1034         }
   1035         else
   1036         {
   1037             return concatenate(b, c, d);
   1038         }
   1039     }
   1040 
   1041     public static byte[] concatenate(byte[][] arrays)
   1042     {
   1043         int size = 0;
   1044         for (int i = 0; i != arrays.length; i++)
   1045         {
   1046             size += arrays[i].length;
   1047         }
   1048 
   1049         byte[] rv = new byte[size];
   1050 
   1051         int offSet = 0;
   1052         for (int i = 0; i != arrays.length; i++)
   1053         {
   1054             System.arraycopy(arrays[i], 0, rv, offSet, arrays[i].length);
   1055             offSet += arrays[i].length;
   1056         }
   1057 
   1058         return rv;
   1059     }
   1060 
   1061     public static int[] concatenate(int[] a, int[] b)
   1062     {
   1063         if (a == null)
   1064         {
   1065             return clone(b);
   1066         }
   1067         if (b == null)
   1068         {
   1069             return clone(a);
   1070         }
   1071 
   1072         int[] c = new int[a.length + b.length];
   1073         System.arraycopy(a, 0, c, 0, a.length);
   1074         System.arraycopy(b, 0, c, a.length, b.length);
   1075         return c;
   1076     }
   1077 
   1078     public static byte[] prepend(byte[] a, byte b)
   1079     {
   1080         if (a == null)
   1081         {
   1082             return new byte[]{ b };
   1083         }
   1084 
   1085         int length = a.length;
   1086         byte[] result = new byte[length + 1];
   1087         System.arraycopy(a, 0, result, 1, length);
   1088         result[0] = b;
   1089         return result;
   1090     }
   1091 
   1092     public static short[] prepend(short[] a, short b)
   1093     {
   1094         if (a == null)
   1095         {
   1096             return new short[]{ b };
   1097         }
   1098 
   1099         int length = a.length;
   1100         short[] result = new short[length + 1];
   1101         System.arraycopy(a, 0, result, 1, length);
   1102         result[0] = b;
   1103         return result;
   1104     }
   1105 
   1106     public static int[] prepend(int[] a, int b)
   1107     {
   1108         if (a == null)
   1109         {
   1110             return new int[]{ b };
   1111         }
   1112 
   1113         int length = a.length;
   1114         int[] result = new int[length + 1];
   1115         System.arraycopy(a, 0, result, 1, length);
   1116         result[0] = b;
   1117         return result;
   1118     }
   1119 
   1120     public static byte[] reverse(byte[] a)
   1121     {
   1122         if (a == null)
   1123         {
   1124             return null;
   1125         }
   1126 
   1127         int p1 = 0, p2 = a.length;
   1128         byte[] result = new byte[p2];
   1129 
   1130         while (--p2 >= 0)
   1131         {
   1132             result[p2] = a[p1++];
   1133         }
   1134 
   1135         return result;
   1136     }
   1137 
   1138     public static int[] reverse(int[] a)
   1139     {
   1140         if (a == null)
   1141         {
   1142             return null;
   1143         }
   1144 
   1145         int p1 = 0, p2 = a.length;
   1146         int[] result = new int[p2];
   1147 
   1148         while (--p2 >= 0)
   1149         {
   1150             result[p2] = a[p1++];
   1151         }
   1152 
   1153         return result;
   1154     }
   1155 
   1156     /**
   1157      * Iterator backed by a specific array.
   1158      */
   1159     public static class Iterator<T>
   1160         implements java.util.Iterator<T>
   1161     {
   1162         private final T[] dataArray;
   1163 
   1164         private int position = 0;
   1165 
   1166         /**
   1167          * Base constructor.
   1168          * <p>
   1169          * Note: the array is not cloned, changes to it will affect the values returned by next().
   1170          * </p>
   1171          *
   1172          * @param dataArray array backing the iterator.
   1173          */
   1174         public Iterator(T[] dataArray)
   1175         {
   1176             this.dataArray = dataArray;
   1177         }
   1178 
   1179         public boolean hasNext()
   1180         {
   1181             return position < dataArray.length;
   1182         }
   1183 
   1184         public T next()
   1185         {
   1186             if (position == dataArray.length)
   1187             {
   1188                 throw new NoSuchElementException("Out of elements: " + position);
   1189             }
   1190 
   1191             return dataArray[position++];
   1192         }
   1193 
   1194         public void remove()
   1195         {
   1196             throw new UnsupportedOperationException("Cannot remove element from an Array.");
   1197         }
   1198     }
   1199 }
   1200