/*
 * @(#)Util.java					0.2-2 23/03/1997
 *
 *  This file is part of the HTTPClient package 
 *  Copyright (C) 1996,1997  Ronald Tschalaer
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 *  MA 02111-1307, USA
 *
 *  For questions, suggestions, bug-reports, enhancement-requests etc.
 *  I may be contacted at:
 *
 *  ronald@innovation.ch
 *  Ronald.Tschalaer@psi.ch
 *
 */

package HTTPClient;


/**
 * This class holds various utility methods.
 *
 * @version	0.2 (bug fix 2)  23/03/1997
 * @author	Ronald Tschal&auml;r
 */

class Util
{
    // Constructors

    /**
     * This class isn't meant to be instantiated.
     */
    private Util() {}


    // Methods

    // this doesn't work!!! Aaaaarrgghhh!
    final static Object[] resizeArray(Object[] src, int new_size)
    {
	Object tmp[] = new Object[new_size];
	System.arraycopy(src, 0, tmp, 0,
			(src.length < new_size ? src.length : new_size));
	return (Object[]) tmp;
    }

    final static NVPair[] resizeArray(NVPair[] src, int new_size)
    {
	NVPair tmp[] = new NVPair[new_size];
	System.arraycopy(src, 0, tmp, 0,
			(src.length < new_size ? src.length : new_size));
	return (NVPair[]) tmp;
    }

    final static AuthorizationInfo[] resizeArray(AuthorizationInfo[] src,
						 int new_size)
    {
	AuthorizationInfo tmp[] = new AuthorizationInfo[new_size];
	System.arraycopy(src, 0, tmp, 0,
			(src.length < new_size ? src.length : new_size));
	return (AuthorizationInfo[]) tmp;
    }

    final static byte[] resizeArray(byte[] src, int new_size)
    {
	byte tmp[] = new byte[new_size];
	System.arraycopy(src, 0, tmp, 0,
			(src.length < new_size ? src.length : new_size));
	return tmp;
    }

    final static char[] resizeArray(char[] src, int new_size)
    {
	char tmp[] = new char[new_size];
	System.arraycopy(src, 0, tmp, 0,
			(src.length < new_size ? src.length : new_size));
	return tmp;
    }


    /**
     * Creates an array of distances to speed up the search in findStr().
     * The returned array should be passed as the second argument to
     * findStr().
     *
     * @param search the search string (same as the first argument to
     *               findStr()).
     * @return an array of distances (to be passed as the second argument to
     *         findStr()).
     */
    final static int[] compile_search(byte[] search)
    {
	int[] cmp = {0, 1, 0, 1, 0, 1};
	int   end;

	for (int idx=0; idx<search.length; idx++)
	{
	    for (end=idx+1; end<search.length; end++)
	    {
		if (search[idx] == search[end])  break;
	    }
	    if (end < search.length)
	    {
		if ((end-idx) > cmp[1])
		{
		    cmp[4] = cmp[2];
		    cmp[5] = cmp[3];
		    cmp[2] = cmp[0];
		    cmp[3] = cmp[1];
		    cmp[0] = idx;
		    cmp[1] = end - idx;
		}
		else if ((end-idx) > cmp[3])
		{
		    cmp[4] = cmp[2];
		    cmp[5] = cmp[3];
		    cmp[2] = idx;
		    cmp[3] = end - idx;
		}
		else if ((end-idx) > cmp[3])
		{
		    cmp[4] = idx;
		    cmp[5] = end - idx;
		}
	    }
	}

	cmp[1] += cmp[0];
	cmp[3] += cmp[2];
	cmp[5] += cmp[4];
	return cmp;
    }

    /**
     * Search for a string. Use compile_search() to first generate the second
     * argument.
     *
     * @param search  the string to search for.
     * @param cmp     the the array returned by compile_search.
     * @param str     the string in which to look for <var>search</var>.
     * @param beg     the position at which to start the search in
     *                <var>str</var>.
     * @param end     the position at which to end the search in <var>str</var>.
     * @return the position in <var>str</var> where <var>search</var> was
     *         found, or -1 if not found.
     */
    final static int findStr(byte[] search, int[] cmp, byte[] str,
				     int beg, int end)
    {
	int c1f  = cmp[0],
	    c1l  = cmp[1],
	    d1   = c1l - c1f,
	    c2f  = cmp[2],
	    c2l  = cmp[3],
	    d2   = c2l - c2f,
	    c3f  = cmp[4],
	    c3l  = cmp[5],
	    d3   = c3l - c3f;

	Find: while (beg+search.length <= end)
	{
	    if (search[c1l] == str[beg+c1l])
	    {
		Comp: if (search[c1f] == str[beg+c1f])
		{
		    for (int idx=0; idx<search.length; idx++)
			if (search[idx] != str[beg+idx])  break Comp;

		    break Find;		// we found it
		}
		beg += d1;
	    }
	    else if (search[c2l] == str[beg+c2l])
		beg += d2;
	    else if (search[c3l] == str[beg+c3l])
		beg += d3;
	    else
		beg++;
	}

	if (beg+search.length > end)
	    return -1;
	else
	    return beg;
    }

}

