ByteArrays.java :  » REST » alc-rest » jaxlib » array » Java Open Source

Java Open Source » REST » alc rest 
alc rest » jaxlib » array » ByteArrays.java
/*
 * ByteArrays.java
 *
 * Copyright (c) Jrg Wamer
 * This library is free software. You can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 2 or above
 * as published by the Free Software Foundation.
 * For more information please visit <http://jaxlib.sourceforge.net>.
 */
package jaxlib.array;

import java.io.UnsupportedEncodingException;
import java.util.NoSuchElementException;
import java.util.Random;

import jaxlib.util.sorting.SortAlgorithm;
import jaxlib.jaxlib_private.CheckArg;
import jaxlib.lang.UnexpectedError;
import jaxlib.text.SimpleIntegerFormat;



/**
 * Provides routines for working with <tt>byte[]</tt> arrays.
 *
 * @author  <a href="mailto:joerg.wassmer@web.de">Jrg Wamer</a>
 * @since   JaXLib 1.0
 * @version $Id: ByteArrays.java,v 1.1.1.1 2004/08/02 20:56:08 joerg_wassmer Exp $
 */
public class ByteArrays extends Object
{

  public static final byte[] EMPTY_ARRAY = new byte[0];

  static final int FILL_LIMIT             = 64;
  static final int NATIVE_ARRAYCOPY_LIMIT = 16;



  protected ByteArrays() throws InstantiationException
  {
    throw new InstantiationException();
  }





  /**
   * @see #binarySearch(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearch(byte[] data, byte key) 
  {
    return binarySearch(data, 0, data.length, key);
  }
  
    
  /**
   * Searches the specified range of specified array for the specified value using the binary search algorithm.  
   * The array <strong>must</strong> be sorted (as by the <tt>sort</tt> method) prior to making this call.  If it
   * is not sorted, the results are undefined.  If the array contains multiple elements with the specified value, there 
   * is no guarantee which one will be found.
   *
   * @param   data      the array to be searched.
   * @param   fromIndex index of first element inclusive to search for.
   * @param   toIndex   index of last element exclusive to search for.
   * @param   key       the value to be searched for.
   *  
   * @return  index of the search key, if it is contained in the array; otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  
   *          The <i>insertion point</i> is defined as the point at which the key would be inserted into the array: 
   *          the index of the first element greater than the key, or <tt>array.length()</tt>, if all elements in the array in 
   *          specified range are less than the specified key.  Note that this guarantees that the return value will be &gt;= 0 if
   *          and only if the key is found.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value 
   *                                    (<tt>(fromIndex &lt; 0 || toIndex &gt; data.length || fromIndex &gt; toIndex)</tt>).
   * @throws NullPointerException       if <tt>data == null</tt>.
   *
   * @see java.util.Arrays#binarySearch(byte[],byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearch(byte[] data, int fromIndex, int toIndex, byte key)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
            
    --toIndex;
    while (fromIndex <= toIndex)
    {
      int mid = (fromIndex + toIndex) >> 1;
      byte e = data[mid];
      if (key > e)
        fromIndex = mid + 1;
      else if (key < e)
        toIndex = mid - 1;
      else
        return mid; // key found
      
    }
    return ~fromIndex;

        
  }
  
  
  /**
   * Similar to <tt>binarySearch()</tt>, but guarantees to return the first index of searched element.
   *
   * @see #binarySearchLast(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearchFirst(byte[] data, byte key)  
  {
    return binarySearchFirst(data, 0, data.length, key);
  }
  
  
  /**
   * Similar to <tt>binarySearch()</tt>, but guarantees to return the first index of searched element.
   *
   * @see #binarySearchLast(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearchFirst(byte[] data, int fromIndex, int toIndex, byte key)
  {
    int high = binarySearch(data, fromIndex, toIndex, key);    
    if (high <= fromIndex)
      return high;

    int low    = fromIndex;      
    int result = high;
    high--;

        
    while (low <= high)
    {
      int mid = (low + high) >> 1;
      byte e = data[mid];
      if (key > e)
        low = mid + 1;
      else if (key == e)
      {
        result = mid;
        low = fromIndex;
        high = mid - 1;
      }
      else
      {
        throw new IllegalArgumentException(
          "Array not properly sorted ascending between " + fromIndex + " and " + toIndex + ": " + data
        );
      }
    }

        
    return result;

  }


  
  /**
   * Similar to <tt>binarySearch()</tt>, but guarantees to return the last index of searched element.
   *
   * @see #binarySearchFirst(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearchLast(byte[] data, byte key) 
  {
    return binarySearchLast(data, 0, data.length, key);
  }
  
  
  /**
   * Similar to <tt>binarySearch()</tt>, but guarantees to return the last index of searched element.
   *
   * @see #binarySearchFirst(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int binarySearchLast(byte[] data, int fromIndex, int toIndex, byte key)
  {
    int low = binarySearch(data, fromIndex, toIndex, key);
    if (low < 0)
      return low;

    int result = low;
    low++;
    int high = toIndex - 1;
        
    while (low <= high)
    {
      int mid = (low + high) >> 1;
      byte e = data[mid];
      if (key < e)
        high = mid - 1;
      else if (key == e)
      {
        result = mid;
        low = mid+1;
        high = toIndex-1;
      }
      else
      {
        throw new IllegalArgumentException(
          "Array not properly sorted ascending between " + fromIndex + " and " + toIndex + ": " + data
        );
      }
    }

        
    return result;

  }




  /**
   * Returns a new array which is equal to specified one.
   *
   * @throws NullPointerException       if <tt>src == null</tt>.
   *
   * @see #clone(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static byte[] clone(byte[] src)
  {
    int remaining = src.length;
    if (remaining > NATIVE_ARRAYCOPY_LIMIT)
      return (byte[]) src.clone();
    else
    {
      byte[] a = new byte[remaining];
      while (--remaining >= 0)
        a[remaining] = src[remaining];
      return a;
    }
  }
  
  
  /**
   * Returns a new array which is equal to the specified range of specified array.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value 
   *                                    (<tt>(fromIndex &lt; 0 || toIndex &gt; src.length || fromIndex &gt; toIndex)</tt>).
   * @throws NullPointerException       if <tt>src == null</tt>.
   *
   * @see #clone(byte[])
   *
   * @since JaXLib 1.0
   */
  public static byte[] clone(byte[] src, int fromIndex, int toIndex)
  {
    CheckArg.range(src.length, fromIndex, toIndex);    
    byte[] dest = new byte[toIndex - fromIndex];
    copyFast(src, fromIndex, toIndex, dest, 0);
    return dest;
  }





  /**
   * Returns true if specified <tt>container</tt> array contains all elements of specified <tt>source</tt> array.
   * Same as <tt>containAll(source, 0, source.length, container, 0, container.length)</tt>.
   *
   * @param source    the array with the elements to check if they are contained in <tt>container</tt>.
   * @param container the array to check if it contains all the elements of the <tt>source</tt> array.
   *
   * @return <tt>true</tt> if all elements of <tt>source</tt> array are contained in <tt>container</tt> array.
   *
   * @throws NullPointerException       if <tt>source == null || container == null</tt>.
   *
   * @see #containsAll(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static boolean containsAll(byte[] source, byte[] container)
  {
    return containsAll(source, 0, source.length, container, 0, container.length);
  }

  
  /**
   * Returns true if specified range of specified <tt>container</tt> array contains all elements of specified range of specified <tt>source</tt> array.
   *
   * @param source          the array with the elements to check if they are contained in <tt>container</tt>.
   * @param sourceFromIndex index of first element in <tt>source</tt> array.
   * @param sourceToIndex   index after last element in <tt>source</tt> array.
   * @param container       the array to check if it contains all the elements of the <tt>source</tt> array.
   * @param fromIndex       index of first element in <tt>container</tt> array.
   * @param toIndex         index after last element in <tt>container</tt> array.
   *
   * @return <tt>true</tt> if all elements of specified range of <tt>source</tt> array are contained in specified range of <tt>container</tt> array.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value 
   *                                    (<tt>(fromIndex &lt; 0 || toIndex &gt; container.length || fromIndex &gt; toIndex)
   *                                    || (sourceFromIndex &lt; 0 || sourceToIndex &gt; source.length || sourceFromIndex &gt; sourceToIndex)</tt>).
   * @throws NullPointerException       if <tt>source == null || container == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static boolean containsAll(byte[] source, int sourceFromIndex, int sourceToIndex, byte[] container, int fromIndex, int toIndex)
  {
    Boolean fastShot = CheckArg.subListContainsSubList(source, source.length, sourceFromIndex, sourceToIndex, container, container.length, fromIndex, toIndex);
    if (fastShot != null)
      return fastShot == Boolean.TRUE ? true : false;
        
    final int sourceLen = sourceToIndex - sourceFromIndex;
    final byte first = source[sourceFromIndex++];
      
    if (sourceLen == 1)
    {
      while (fromIndex < toIndex)
        if (container[fromIndex++] == first)
          return true;
      return false;
    }
    else if (toIndex - fromIndex == 1)
    {
      if (container[fromIndex] != first)
        return false;
      while (sourceFromIndex < sourceToIndex)
        if (source[sourceFromIndex++] != first)
          return false;
      return true;
    }
    else if (sourceLen == 2)
    {      
      byte second = source[sourceFromIndex++];      
      for (int i = fromIndex; i < toIndex; i++)
      {
        byte e = container[i];
        if (e == first || e == second)
        {
          if (first == second)
            return true;
          else
          {
            e = e == first ? second : first;
            while (++i < toIndex)
              if (container[i] == e)
                return true;
            return false;
          }
        }
      }
      return false;
    }
    else
    {
      // With following long values we construct a "mini-bitset" for keeping track of already found bytes.
      // So we need to query each array index one time only.
      long b0 = 0; // -128....-64
      long b1 = 0; //  -64......0
      long b2 = 0; //    0.....64
      long b3 = 0; //   64....128
      while (fromIndex < toIndex)
      {
        byte e = container[fromIndex++];
        if (e < 0)
        {
          if (e < -64)
            b0 |= 1L << (e + 128);
          else
            b1 |= 1L << -e;
        }
        else
        {
          if (e < 64)
            b2 |= 1L << e;
          else
            b3 |= 1L << (e - 127);
        }
        if (e == first)
        {
          byte p = e;
          SOURCE: while (sourceFromIndex < sourceToIndex)
          {
            final byte n = source[sourceFromIndex++];
            if (n == p || n == first)
              continue SOURCE;
            else
            {
              if ((n < 0) 
                ? ((n < -64) ? ((b0 & (1L << (n + 128))) != 0) : ((b1 & (1L << -n)) != 0))
                : ((n < 64) ? ((b2 & (1L << n)) != 0) : ((b3 & (1L << (n - 127))) != 0))
              )
              {
                continue SOURCE;
              }
              p = n;
              while (fromIndex < toIndex)
              {
                e = container[fromIndex++];
                if (e < 0)
                {
                  if (e < -64)
                    b0 |= 1L << (e + 128);
                  else
                    b1 |= 1L << -e;
                }
                else
                {
                  if (e < 64)
                    b2 |= 1L << e;
                  else
                    b3 |= 1L << (e - 127);
                }
                if (e == n)
                  continue SOURCE;
              }
              return false;
            }
          }
          return true;
        }
      }
    }
    return false;            
  }




  /**
   * Copies range of specified array to another position in the same array.
   *
   * @param data      the array.
   * @param fromIndex first index inclusive to copy.
   * @param toIndex   last index exclusive to copy.
   * @param destIndex the destination index where to copy elements between <tt>fromIndex</tt> and <tt>toIndex</tt> to.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value 
   *                                    (<tt>(fromIndex &lt; 0 || toIndex &gt; data.length || fromIndex &gt; toIndex || destIndex < 0 || destIndex ;gt data.length)</tt>),
   *                                    or if the range between <tt>destIndex</tt> and <tt>data.length</tt> is to small to hold
   *                                    the source range.
   * @throws NullPointerException       if <tt>data == null</tt>.
   *
   * @see #copy(byte[],int,int,byte[],int) for copying ranges between two different arrays.
   *
   * @since JaXLib 1.0
   */  
  public static void copy(byte[] data, int fromIndex, int toIndex, int destIndex)
  {
    CheckArg.copyRangeIntern(data.length, fromIndex, toIndex, destIndex);
    copyFast(data, fromIndex, toIndex, destIndex);
  }



  /**
   * Same as <tt>copy()</tt>, but avoids range checking.
   * The behaviour of this method is undefined for illegal indices.
   *
   * @since JaXLib 1.0
   */
  public static void copyFast(byte[] data, int fromIndex, int toIndex, int destIndex)
  {
    if ((toIndex - fromIndex) <= NATIVE_ARRAYCOPY_LIMIT)
    { 
      if (destIndex < fromIndex)
      {
        while (fromIndex < toIndex)
          data[destIndex++] = data[fromIndex++];
      }
      else
      {
        destIndex += (toIndex - fromIndex);
        while (fromIndex < toIndex)
          data[--destIndex] = data[--toIndex];
      }
    }
    else
      System.arraycopy(data, fromIndex, data, destIndex, toIndex - fromIndex); 
  }




  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, byte[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, byte[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, byte[] dest, int destIndex)
  {

    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex);
        
    if (src == dest)
    {
      copyFast(src, fromIndex, toIndex, destIndex);
      return;
    }
        
    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
  }
  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, double[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, double[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, double[] dest, int destIndex)
  {
    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex); 
    
    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
   }
  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, float[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, float[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, float[] dest, int destIndex)
  {
    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex);     
    
    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
  }
  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, int[] dest, int destIndex)
  {
    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex);
        
    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
  }
  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, long[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, long[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, long[] dest, int destIndex)
  {
    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex);
     
    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
  }
  
  /**
   * Copies all elements of source array to destination array.
   * Source and destination indices are zero.
   *
   * @throws IndexOutOfBoundsException  if <tt>dest.length < src.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, short[] dest)
  {
    copy(src, 0, src.length, dest, 0);
  }

  /**
   * Copies all elements of source array starting with first element to destination array at specified index.
   *
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + src.length > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, short[] dest, int destIndex)
  {
    copy(src, 0, src.length, dest, destIndex);
  }


  /**
   * Copies elements of source array in specified range to destination array at specified destination index.
   *
   * @throws IndexOutOfBoundsException  for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; src.length 
   *                                    || fromIndex &gt; toIndex)</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex < 0 || destIndex > dest.length</tt>.
   * @throws IndexOutOfBoundsException  if <tt>destIndex + (toIndex - fromIndex) > dest.length</tt>.
   * @throws NullPointerException       if <tt>src == null || dest == null</tt>.
   *
   * @see System#arraycopy
   *
   * @since JaXLib 1.0
   */
  public static void copy(byte[] src, int fromIndex, int toIndex, short[] dest, int destIndex)
  {
    CheckArg.copyRangeTo(src.length, fromIndex, toIndex, dest.length, destIndex);

    while (fromIndex < toIndex)
      dest[destIndex++] = src[fromIndex++];
  }



  /**
   * Same as <tt>copy()</tt>, but avoids range check.
   * The behaviour of this method is undefined for illegal indices.
   *
   * @since JaXLib 1.0
   */
  public static void copyFast(byte[] src, int fromIndex, int toIndex, byte[] dest, int destIndex)
  {
    if (src == dest)
      copyFast(src, fromIndex, toIndex, destIndex);
    else if ((toIndex - fromIndex) <= NATIVE_ARRAYCOPY_LIMIT)
    {
      while (fromIndex < toIndex)
        dest[destIndex++] = src[fromIndex++];
    }
    else
      System.arraycopy(src, fromIndex, dest, destIndex, toIndex - fromIndex);
  }





  /**
   * @see #count(byte[],int,int,byte)
   *
   * @since JaxLib 1.00
   */
  public static int count(byte[] a, byte e)
  {
    return countUp(a, 0, a.length, e, -1);
  }

  /**
   * Counts each element in specified array which are equal to specified value.
   *
   * @param   data      The array to search in.
   * @param   fromIndex The first index to look in.
   * @param   toIndex   The lastIndex (exclusive) to look in.
   * @param   e         The element to count.
   *
   * @return  Count of elements in array which are equal to <tt>e</tt>.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaxLib 1.00
   */
  public static int count(byte[] data, int fromIndex, int toIndex, byte e)
  {
    return countUp(data, fromIndex, toIndex, e, -1);
  }


  /**
   * @see #countUp(byte[],int,int,byte,int)
   *
   * @since JaxLib 1.00
   */
  public static int countUp(byte[] data, byte e, int maxCount)
  {
    return countUp(data, 0, data.length, e, maxCount);
  }

  /**
   * Counts a maximum amount of elements in specified array specified object is equal to.
   *
   * @param   data      The array to search in.
   * @param   fromIndex The first index to look in.
   * @param   toIndex   The lastIndex (exclusive) to look in.
   * @param   e         The element to count.
   * @param   maxCount  The maximum count of elements to search for, or <tt>-1</tt> to search all.
   *
   * @return  Count of elements in array which are equal to <tt>e</tt>, but not more than <tt>maxCount</tt>.
   *
   * @throws  IllegalArgumentException    if <tt>maxCount &lt; -1</tt>.
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaxLib 1.00
   */
  public static int countUp(byte[] data, int fromIndex, int toIndex, byte e, int maxCount)
  {
    CheckArg.maxCount(maxCount);
    CheckArg.range(data.length, fromIndex, toIndex);
    if (maxCount == 0)
      return 0;
    
    int count = 0;        
    while (fromIndex < toIndex)
    {
      if ((e == data[fromIndex++]) && (++count == maxCount))
        return count;
    }       
    return count;
  }




  /**
   * Returns an array containing same elements in same order as specified one, but of length not less than specified minimum capacity.
   * 
   * @return  The same array as specified, if its <tt>length >= minCapacity</tt>, or a new one with <tt>length == minCapacity</tt>.
   *
   * @throws  IllegalArgumentException  if <tt>minCapacity < 0</tt>.
   * @throws  NullPointerException      if <tt>data == null</tt>.
   *
   * @see #ensureCapacity(byte[],int,float)
   *
   * @since JaXLib 1.0
   */
  public static byte[] ensureCapacity(byte[] data, int minCapacity)
  {
    CheckArg.count(minCapacity);
    if (minCapacity > data.length)
    {
      byte[] b = new byte[minCapacity];
      copy(data, b);
      return b;
    }
    else
      return data;
  }

  /**
   * Returns an array containing same elements in same order as specified one, but of length not less than specified minimum capacity.
   * 
   * @return  The same array as specified, if its <tt>length >= minCapacity</tt>, or a new one with <tt>length == minCapacity + (minCapacity * growFactor)</tt>.
   *
   * @throws  IllegalArgumentException  if <tt>minCapacity < 0 || growFactor < 0</tt>.
   * @throws  NullPointerException      if <tt>data == null</tt>.
   *
   * @see #ensureCapacity(byte[],int)
   *
   * @since JaXLib 1.0
   */
  public static byte[] ensureCapacity(byte[] data, int minCapacity, float growFactor)
  {
    CheckArg.count(minCapacity);
    if (growFactor < 0)
      throw new IllegalArgumentException("growFactor(" + growFactor + ") < 0.");
    if (minCapacity > data.length)
    {
      byte[] b = new byte[(int) (minCapacity + (minCapacity * growFactor))];
      copy(data, b);
      return b;
    }
    else
      return data;
  }
  
  
  /**
   * Returns <tt>true</tt> if the specified two arrays are identical, or are of equal length and containing equal elements in equal order.
   *
   * @see java.util.Arrays#equals(byte[],byte[]) 
   * @see #equals(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static boolean equals(byte[] a, byte[] b)
  {
    if (a == b)
      return true;
    if ((a == null) || (b == null))
      return false;
    int i = a.length;  
    if (b.length != i)
      return false;
     
    while(--i >= 0)
      if (a[i] != b[i])
        return false;
      
    return true;
  }

  
  /**
   * Checks if sequence in specified range of array <tt>a</tt> equals the sequence in specified range of array <tt>b</tt>.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>a == null || b == null</tt>.
   *
   * @see #equals(byte[],byte[])
   *
   * @since JaXLib 1.0
   */
  public static boolean equals(byte[] a, int fromIndex, int toIndex, byte[] b, int bFromIndex, int bToIndex)
  {
    CheckArg.range(a.length, fromIndex, toIndex);
    CheckArg.range(b.length, bFromIndex, bToIndex);
    if (toIndex - fromIndex != bToIndex - bFromIndex)
      return false;
    if (fromIndex == bFromIndex && toIndex == bToIndex && a == b)
      return true;
    
    while (fromIndex < toIndex)
      if (a[fromIndex++] != b[bFromIndex++])
        return false;
    
    return true;
  }
  
  

  public static int hashCode(byte[] data)
  {
    return hashCode(data, 0, data.length);
  }

  public static int hashCode(byte[] data, int fromIndex, int toIndex)
  {
    int hashCode = 1;
    while (fromIndex < toIndex)
      hashCode = (31 * hashCode) + jaxlib.lang.Bytes.hashCode(data[fromIndex++]);
    return hashCode;
  }

  
  
  /**
   * @see #fill(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static void fill(byte[] data, byte e)
  {
    fillFast(data, 0, data.length, e);
  }
  
  /**
   * Assigns the specified value to each element of the specified range of the specified array.  
   * The range to be filled extends from index <tt>fromIndex</tt>, inclusive, to index <tt>toIndex</tt>, exclusive.  
   * (If <tt>fromIndex==toIndex</tt>, the range to be filled is empty.)
   *
   * @param data      the array to be filled.
   * @param fromIndex the index of the first element (inclusive) to be filled with the specified value.
   * @param toIndex   the index of the last element (exclusive) to be filled with the specified value.
   * @param e         the value to be stored in all elements of the array in specified range.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void fill(byte[] data, int fromIndex, int toIndex, byte e)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    fillFast(data, fromIndex, toIndex, e);
  }
  
  /**
   * Same as <tt>fill()</tt>, but avoids range checking.
   * The behaviour of this method is undefined for illegal indices.
   *
   * @since JaXLib 1.0
   */
  public static void fillFast(byte[] data, int fromIndex, int toIndex, byte e)
  {
    if (toIndex - fromIndex < FILL_LIMIT)
    {
      while (fromIndex < toIndex)
        data[fromIndex++] = e;
    }
    else
    {
      int start = fromIndex;
      // fill first block, avoid native copy
      for (int hi = fromIndex + NATIVE_ARRAYCOPY_LIMIT; fromIndex < hi; fromIndex++)
        data[fromIndex] = e;
      int len = fromIndex - start;  
      // sequentially copy block using native copy; at each step the length of the block grows.
      while (fromIndex < toIndex)
      {
        System.arraycopy(data, start, data, fromIndex, Math.min(len, toIndex - fromIndex));
        fromIndex += len;
        len <<= 1;
      }
    }
  }    




  /**
   * @see #indexOf(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int indexOf(byte[] data, byte e)
  {
    return indexOf(data, 0, data.length, e);
  }

    
  /**
   * Returns the index in specified array of the first occurrence of the specified element, or <tt>-1</tt> if the array does not contain
   * the element in specified range.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the first element (inclusive) to compare against <tt>e</tt>.
   * @param toIndex   the index of the last element (exclusive) to compare against <tt>e</tt>.
   * @param e         the element to search.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @see #lastIndexOf(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int indexOf(byte[] data, int fromIndex, int toIndex, byte e)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    
        
    while (fromIndex < toIndex)
    {
      if (e == data[fromIndex])
        return fromIndex;
      fromIndex++;
    }

        
    return -1;
  }



  /**
   * @see #lastIndexOf(byte[],int,int,byte)
   *
   * @since JaXLib 1.0
   */
  public static int lastIndexOf(byte[] data, byte e)
  {
    return lastIndexOf(data, 0, data.length, e);
  }


  /**
   * Returns the index in specified array of the last occurrence of the specified element, or <tt>-1</tt> if the array does not contain
   * the element in specified range.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the most left element (inclusive) to compare against <tt>e</tt>.
   * @param toIndex   the index of the most right element (exclusive) to compare against <tt>e</tt>.
   * @param e         the element to search.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static int lastIndexOf(byte[] data, int fromIndex, int toIndex, byte e)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
        
    while (fromIndex <= --toIndex)
      if (e == data[toIndex])
        return toIndex;
            
    return -1;
  }






  /**
   * @see #indexOfMax(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int indexOfMax(byte[] data)
  {
    return indexOfMax(data, 0, data.length);
  }
  

  /**
   * Returns the index of the greatest element of specified range in specified array.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the first element (inclusive) to check.
   * @param toIndex   the index of the last element (exclusive) to check.
   *
   * @return  The greatest element found.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NoSuchElementException      if <tt>fromIndex == toIndex</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static int indexOfMax(byte[] data, int fromIndex, int toIndex)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    if (fromIndex == toIndex)
      return -1;

    int index = fromIndex;  
    byte max = data[fromIndex];    

    while (++fromIndex < toIndex)
    {      
      byte e = data[fromIndex];
      if (e > max)
      {
        
        if (e == Byte.MAX_VALUE)
          return fromIndex;
       
        max = e;
        index = fromIndex;
      }
    }
    return index;
  }





  /**
   * @see #indexOfMin(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int indexOfMin(byte[] data)
  {
    return indexOfMin(data, 0, data.length);
  }


  /**
   * Returns the index of the smallest element of specified range in specified array.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the first element (inclusive) to check.
   * @param toIndex   the index of the last element (exclusive) to check.
   *
   * @return  The smallest element found.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NoSuchElementException      if <tt>fromIndex == toIndex</tt>.
   * @throws  NullPointerException        if <tt>c == null || data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static int indexOfMin(byte[] data, int fromIndex, int toIndex)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    if (fromIndex == toIndex)
      return -1;

    int index = fromIndex;  
    byte min = data[fromIndex];

    while (++fromIndex < toIndex)
    {
      byte e = data[fromIndex];
      if (e < min)
      {
        
        if (e == Byte.MIN_VALUE)
          return fromIndex;
        
        min = e;
        index = fromIndex;
      }
    }
    return index;
  }



  /**
   * @see #max(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static byte max(byte[] data)
  {
    return max(data, 0, data.length);
  }


  /**
   * Returns the geatest element of specified range in specified array.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the first element (inclusive) to check.
   * @param toIndex   the index of the last element (exclusive) to check.
   *
   * @return  The smallest element found.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NoSuchElementException      if <tt>fromIndex == toIndex</tt>.
   * @throws  NullPointerException        if <tt>c == null || data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static byte max(byte[] data, int fromIndex, int toIndex)
  {
    int index = indexOfMax(data, fromIndex, toIndex);
    if (index >= 0)
      return data[index];
    else
      throw new NoSuchElementException();
  }


  /**
   * @see #min(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static byte min(byte[] data)
  {
    return min(data, 0, data.length);
  }


  /**
   * Returns the smallest element of specified range in specified array.
   *
   * @param data      the array to search in.
   * @param fromIndex the index of the first element (inclusive) to check.
   * @param toIndex   the index of the last element (exclusive) to check.
   *
   * @return  The smallest element found.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NoSuchElementException      if <tt>fromIndex == toIndex</tt>.
   * @throws  NullPointerException        if <tt>c == null || data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static byte min(byte[] data, int fromIndex, int toIndex)
  {
    int index = indexOfMin(data, fromIndex, toIndex);
    if (index >= 0)
      return data[index];
    else
      throw new NoSuchElementException();
  }







  /**
   * @see #indexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int indexOf(byte[] data, byte[] seq)
  {
    return indexOf(data, 0, data.length, seq, 0, seq.length);
  }

  /**
   * @see #indexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int indexOf(byte[] data, byte[] seq, int seqFromIndex, int seqToIndex)
  {
    return indexOf(data, 0, data.length, seq, seqFromIndex, seqToIndex);
  }

  
  
  /**
   * Searches for first occurence of specified range of specified <tt>seq</tt>uence in specified range of specified <tt>data</tt> array.
   * <br>
   * For <tt>(seqFromIndex == seqToIndex) || (fromIndex == toIndex)</tt> this method returns <tt>-1</tt>.
   *
   * @param data          the array where to search for the sequence.
   * @param fromIndex     the index (inclusive) of first element to compare against searched sequence.  
   * @param toIndex       the index (exclusive) of last element to compare against searched sequence.
   * @param seq           the array containing the sequence to search for.
   * @param seqFromIndex  the index (inclusive) of the first element of sequence to search for.
   * @param seqToIndex    the index (exclusive) of the last element of sequence to search for.
   *
   * @return Index of match if found, otherwise <tt>-1</tt>.
   *
   * @throws IndexOutOfBoundsException    for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; array.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws NullPointerException         if <tt>seq == null || data == null</tt>.
   *
   * @see #lastIndexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int indexOf(byte[] data, int fromIndex, int toIndex, byte[] seq, int seqFromIndex, int seqToIndex)
  {
    Boolean fastShot = CheckArg.indexOfSequence(data, data.length, fromIndex, toIndex, seq, seq.length, seqFromIndex, seqToIndex);
    if (fastShot != null)
      return fastShot == Boolean.TRUE ? fromIndex : -1;
          
    // search

    final int seqLen = seqToIndex - seqFromIndex; // length of sequence
    if (seqLen == 1)
      return indexOf(data, fromIndex, toIndex, seq[seqFromIndex]);

              
    final int  seqHi  = seqToIndex - 1;  
    final byte first  = seq[seqFromIndex]; // first element to search
    final byte second = seq[seqFromIndex+1]; // second element to search
    int seqIndex      = seqFromIndex;
    byte next         = first;
    int nextFirstData = -1; // index of next known occurence of first element of sequence in data
    
    for (int i = fromIndex; i < toIndex; i++)
    {
      byte e = data[i];
      if (nextFirstData == -1 && e == first)
        nextFirstData = i;
      
      if (e == next)
      {
        if (seqIndex == seqHi)
          return fromIndex; // matching sequence found
        else
          next = seq[++seqIndex];        
      }
      else // mismatch
      {        
        if (nextFirstData == -1)
        {
          fromIndex = i + 1;
          next      = first;
          seqIndex  = seqFromIndex;
        }
        else
        {
          fromIndex     = i = nextFirstData;
          nextFirstData = -1;        
          seqIndex      = seqFromIndex + 1;
          next          = second;
        }
        if (toIndex - fromIndex < seqLen)
          break;
      }
    }

        
    return -1;
  }




  /**
   * @see #lastIndexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int lastIndexOf(byte[] data, byte[] seq)
  {
    return lastIndexOf(data, 0, data.length, seq, 0, seq.length);
  }

  /**
   * @see #lastIndexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int lastIndexOf(byte[] data, byte[] seq, int seqFromIndex, int seqToIndex)
  {
    return lastIndexOf(data, 0, data.length, seq, seqFromIndex, seqToIndex);
  }

    
  
  /**
   * Searches for last occurence of specified range of specified <tt>seq</tt>uence in specified range of specified <tt>data</tt> array.
   * <br>
   * For <tt>(seqFromIndex == seqToIndex) || (fromIndex == toIndex)</tt> this method returns <tt>-1</tt>.
   *
   * @param data          the array where to search for the sequence.
   * @param fromIndex     the index (inclusive) of most left element to compare against searched sequence.  
   * @param toIndex       the index (exclusive) of most right element to compare against searched sequence.
   * @param seq           the array containing the sequence to search for.
   * @param seqFromIndex  the index (inclusive) of the first element of sequence to search for.
   * @param seqToIndex    the index (exclusive) of the last element of sequence to search for.
   *
   * @return Index of match if found, otherwise <tt>-1</tt>.
   *
   * @throws IndexOutOfBoundsException    for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; array.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws NullPointerException         if <tt>seq == null || data == null</tt>.
   *
   * @see #indexOf(byte[],int,int,byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static int lastIndexOf(byte[] data, int fromIndex, int toIndex, byte[] seq, int seqFromIndex, int seqToIndex)
  {
    final int seqLen = seqToIndex - seqFromIndex;
    Boolean fastShot = CheckArg.lastIndexOfSequence(data, data.length, fromIndex, toIndex, seq, seq.length, seqFromIndex, seqToIndex);
    if (fastShot != null)
      return (fastShot == Boolean.TRUE) ? (toIndex - seqLen) : -1;
      
    // search
            
    if (seqLen == 1)
      return lastIndexOf(data, fromIndex, toIndex, seq[seqFromIndex]);

        
    final int  seqHi  = seqToIndex - 1;  
    final byte first  = seq[seqHi]; // first element to search
    final byte second = seq[seqHi - 1]; // second element to search
    int seqIndex      = seqHi;
    byte next         = first;
    int nextFirstData = -1; // index of next known occurence of first element of sequence in data
    
    for (int i = toIndex - 1; i >= fromIndex; i--)
    {
      byte e = data[i];
      if (nextFirstData == -1 && e == first)
        nextFirstData = i;
      
      if (e == next)
      {
        if (seqIndex == seqFromIndex)
          return toIndex - seqLen; // matching sequence found
        else
          next = seq[--seqIndex];        
      }
      else // mismatch
      {        
        if (nextFirstData == -1)
        {
          toIndex   = i;
          next      = first;
          seqIndex  = seqHi;
        }
        else
        {
          toIndex       = nextFirstData + 1;
          i             = nextFirstData;
          nextFirstData = -1;        
          seqIndex      = seqHi - 1;
          next          = second;
        }
        if (toIndex - fromIndex < seqLen)
          break;
      }
    }

        
    return -1;
  }






  /**
   * Creates an array of specified length filled with specified element.
   *
   * @param n   length of array to be created.
   * @param e   element to fill the array with.
   *
   * @throws NegativeArraySizeException if <tt>n < 0</tt>.
   *
   * @since JaXLib 1.0
   */
  public static byte[] nCopies(int n, byte e)
  {
    byte[] data = new byte[n];
    
    if (e != 0)        
      fillFast(data, 0, n, e);

    return data;
  }





  public static int replaceEach(byte[] data, byte oldValue, byte newValue)
  {
    return replaceEach(data, 0, data.length, oldValue, newValue);
  }

  public static int replaceEach(byte[] data, int fromIndex, int toIndex, byte oldValue, byte newValue)
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    if ((fromIndex == toIndex) || (oldValue == newValue))
      return 0;

    int count = 0;
    while (fromIndex <= --toIndex)
    {
      if (oldValue == data[toIndex])
      {
        data[toIndex] = newValue;
        count++;
      }
    }
    return count;
  }



  /**
   * Reverses the order of the elements of specified array.
   *
   * @see #reverse(byte[],int,int)
   *
   * @since JaXLib 1.0
   */
  public static void reverse(byte[] a)
  {
    reverse(a, 0, a.length);
  }
  
  
  /**
   * Reverses the order of the elements of specified array in specified range.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void reverse(byte[] data, int fromIndex, int toIndex)
  {
    CheckArg.rangeFromTo(fromIndex, toIndex);    
    while (fromIndex < --toIndex)
      swap(data, fromIndex++, toIndex);
  }
    
  
  /**
   * Same as <code>rotate(data, 0, data.length, distance)</code>.
   *
   * @see #rotate(byte[],int,int,int)
   *
   * @since JaXLib 1.0
   */
  public static void rotate(byte[] data, int distance)
  {
    rotate(data, 0, data.length, distance);
  }
  
  
  /**
   * Rotates the elements in the specified range of array by the specified distance.
   * After calling this method, the element at index <tt>i</tt> will be the element previously at index <tt>(i - distance)</tt> mod
   * <tt>toIndex-fromIndex</tt>, for all values of <tt>i</tt> between <tt>fromIndex</tt> and <tt>toIndex-1</tt>, inclusive. 
   * <p>
   * For example, suppose <tt>array</tt> comprises<tt> [t, a, n, k, s]</tt>.<br>
   * After invoking <tt>rotate(1, array, 0, array.length)</tt> (or <tt>rotate(-4, array, 0, array.length)</tt>), 
   * <tt>array</tt> will comprise <tt>[s, t, a, n, k]</tt>.
   * </p><p>
   * To move more than one element forward, increase the absolute value of the rotation distance.  
   * To move elements backward, use a positive shift distance.
   * </p>
   *
   * @param data      the array containing the elements to be rotated.
   * @param fromIndex index (inclusive) containing the first element of the range to be rotated.
   * @param toIndex   index (exclusive) containing the last element of the range to be rotated.
   * @param distance  the distance to rotate the specified range of array. There are no constraints on this value; 
   *                  it may be zero, negative, or greater than <tt>data.length</tt>.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void rotate(byte[] data, int fromIndex, int toIndex, int distance) 
  {
    CheckArg.range(data.length, fromIndex, toIndex);
    int count = toIndex - fromIndex;
    if (count == 0)
      return;
    distance = distance % count;
    if (distance < 0)
      distance += count;
    if (distance == 0)
      return;
    
    for (int cycleStart = 0, nMoved = 0; nMoved != count; cycleStart++) 
    {
      byte displaced = data[cycleStart + fromIndex];
      int i = cycleStart;
      do 
      {
        i += distance;
        if (i >= count)
          i -= count;
        byte t = data[i + fromIndex];
        data[i + fromIndex] = displaced;
        displaced = t;
        nMoved++;
      } while (i != cycleStart);
    }
  }
  

  /**
   * @see #shuffle(byte[],int,int,Random)
   *
   * @since JaXLib 1.0
   */
  public static void shuffle(byte[] data)
  {
    shuffle(data, 0, data.length, null);
  }

  /**
   * @see #shuffle(byte[],int,int,Random)
   *
   * @since JaXLib 1.0
   */
  public static void shuffle(byte[] data, Random r)
  {
    shuffle(data, 0, data.length, r);
  }
  
  
  /**
   * Shuffles elements of specified array in specified range.
   *
   * @param r The random number generator to use for creating random indices (optional).
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void shuffle(byte[] a, int fromIndex, int toIndex, Random r)
  {
    CheckArg.range(a.length, fromIndex, toIndex);
    if (r == null)
      r = new Random();
    int count = toIndex - fromIndex;
    for (int i = count; i > 1; i--)
      swap(a, (fromIndex + i) - 1, fromIndex + r.nextInt(i));
  }
  
  

  /**
   * Sorts specified array using {@link SortAlgorithm#getDefault() default} sort algorithm.
   *
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void sort(byte[] data)
  {
    SortAlgorithm.getDefault().apply(data);
  }
  
  /**
   * Sorts specified range of specified array using {@link SortAlgorithm#getDefault() default} sort algorithm.
   *
   * @throws  IndexOutOfBoundsException   for an illegal endpoint index value <tt>(fromIndex &lt; 0 || toIndex &gt; data.length 
   *                                      || fromIndex &gt; toIndex)</tt>.
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void sort(byte[] data, int fromIndex, int toIndex)
  {
    SortAlgorithm.getDefault().apply(data, fromIndex, toIndex);
  }
  
  
  
  /**
   * Replaces element of specified array at <tt>index1</tt> with element at <tt>index2</tt>, and vice-versa.
   *
   * @throws  IndexOutOfBoundsException   for an illegal index value <tt>(index &lt; 0 || index &ge; data.length)</tt>. 
   * @throws  NullPointerException        if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void swap(byte[] data, int index1, int index2)
  {
    byte t = data[index1];
    data[index1] = data[index2];
    data[index2] = t;
  }  
  
  
  /**
   * Replaces element of specified first array at <tt>index1</tt> with element of specified second array at <tt>index2</tt>, and vice-versa.
   *
   * @throws  IndexOutOfBoundsException   for an illegal index value <tt>(index &lt; 0 || index &ge; array.length)</tt>. 
   * @throws  NullPointerException        if <tt>(a == null) || (b == null)</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void swap(byte[] a, int index1, byte[] b, int index2)
  {
    byte t = a[index1];
    a[index1] = b[index2];
    b[index2] = t;
  }  
  
  
  /**
   * Swaps <code>a[0 .. length]</code> with <code>b[0 .. length]</code>.
   *
   * @throws IllegalArgumentException if <code>a.length != b.length</code>.
   * @throws NullPointerException     if <code>(a == null) || (b == null)</code>.
   */
  public static void swap(byte[] a, byte[] b)
  {
    if (a != b)
    {
      swapRanges(a, 0, b, 0, Math.max(a.length, b.length));
    }
  }
  
  
  /**
   * Swaps data[index1 to (index1 + count-1)] with data[index2 to (index2 + count-1)].
   *
   * @throws IllegalArgumentException   if <tt>count < 0</tt>
   * @throws IndexOutOfBoundsException  for an illegal index value <tt>(index &lt; 0 || index &ge; data.length)</tt>. 
   * @throws IndexOutOfBoundsException  if <tt>(index1 + count > data.length) || (index2 + count > data.length)</tt>.
   * @throws NullPointerException       if <tt>data == null</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void swapRanges(byte[] data, int index1, int index2, int count)
  {
    CheckArg.swapRanges(count, data.length, index1, index2);
    if (index1 != index2)
    {
      while (count-- > 0)
        swap(data, index1++, index2++);
    }
  }



  /**
   * Swaps a[index1 to (index1 + count-1)] with b[index2 to (index2 + count-1)].
   *
   * @throws IllegalArgumentException   if <tt>count < 0</tt>
   * @throws IndexOutOfBoundsException  for an illegal index value <tt>(index &lt; 0 || index &ge; array.length)</tt>. 
   * @throws IndexOutOfBoundsException  if <tt>(index1 + count &gt; a.length) || (index2 + count &gt; b.length)</tt>.
   * @throws NullPointerException       if <tt>(a == null) || (b == null)</tt>.
   *
   * @since JaXLib 1.0
   */
  public static void swapRanges(byte[] a, int index1, byte[] b, int index2, int count)
  {
    if (a == b)
    {
      swapRanges(a, index1, index2, count);
      return;
    }    
    CheckArg.swapRanges(count, a.length, index1, b.length, index2);
    
    while (count-- > 0)      
      swap(a, index1++, b, index2++);
  }


  /**
   * Converts the values in the specified array to their hexadecimal representation, using 
   * two characters for each byte.
   *
   * @since JaXLib 1.0
   */
  public static String toHexString(byte[] a)
  {
    return toHexString(a, 0, a.length);
  }

  
  /**
   * Converts the values in the specified subsequence in specified array to their hexadecimal 
   * representation, using two characters for each byte.
   *
   * @since JaXLib 1.0
   */
  public static String toHexString(byte[] a, int fromIndex, int toIndex)
  {
    CheckArg.range(a, fromIndex, toIndex);
    if (fromIndex == toIndex)      
      return "";

    char[] b = new char[(toIndex - fromIndex) * 2];
    int k = 0;
    while (fromIndex < toIndex)
    {
      int e = a[fromIndex++] & 0xFF;
      int t = e >> 4;
      b[k++] = (char) ((t < 10) ? ('0' + t) : (('a' - 10) + t));
      t = e & 0xf;
      b[k++] = (char) ((t < 10) ? ('0' + t) : (('a' - 10) + t));
    }
    
    return new String(b);
  }
  


}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.