package httpRecorder.proxy;

/*
 * Disclaimer:
 * The following source code is sample code created by IBM Corporation.  
 * This sample code is not part of any standard IBM product and is provided 
 * to you solely for the purpose of assisting you in the development of your 
 * applications.  The code is provided 'AS IS', without warranty or condition 
 * of any kind.  IBM shall not be liable for any damages arising out of your 
 * use of the sample code, even if IBM has been advised of the possibility of 
 * such damages.
 */

import java.io.IOException;
import java.io.InputStream;

/**
 * Utitly class with some generic methods
 */
public class ProxyUtil
{
	public static final int ENTIRE_LINE = -1;

	public static String readLine(InputStream inputStream, int length) throws IOException
	{
		if (length == 0)
			return null;

		char[] buffer = null;
		int offset = 0;
		int available = inputStream.available();

		while (true)
		{
			if((available > 0) && (offset > available))
				break;
			
			int data = inputStream.read();
			if ((length == 0) || (data == -1))
				break;

			if (buffer == null)
			{
				buffer = new char[128];
			}
			else
			{
				char[] oldBuffer = buffer;
				buffer = new char[offset + 128];
				System.arraycopy(oldBuffer, 0, buffer, 0, offset);
			}
			buffer[offset++] = (char) data;

			if (data == '\n')
				break;

			length--;
		}

		if (buffer == null)
			return null;

		String ret = String.copyValueOf(buffer, 0, offset);
		return ret;
	}
	
	public static StringBuffer xmlAttribute(String name, String value)
	{
		StringBuffer attribute = new StringBuffer();
		if(value == null)
			return attribute;
		else
			value = ProxyUtil.useValidXMLCharacters(value);
			
		return attribute.append(" ").append(name).append("=\"").append(value).append("\"");
	}

	public static String useValidXMLCharacters(String input)
	{
		if(input == null)
			return null;
			
		return new Escape().convert(input);
	}

	public static class Escape
	{
		protected char[] value;

		protected final char[] AMP = { '&', 'a', 'm', 'p', ';' };
		protected final char[] LESS = { '&', 'l', 't', ';' };
		protected final char[] QUOTE = { '&', 'q', 'u', 'o', 't', ';' };
		protected final char[] LF = { '&', '#', 'x', 'A', ';' };
		protected final char[] CR = { '&', '#', 'x', 'D', ';' };
		protected final char[] TAB = { '&', '#', 'x', '9', ';' };

		Escape()
		{
			value = new char[100];
		}

		/*
		 *  Convert:
		 *  & to &amp;
		 *  < to &lt;
		 *  " to &quot;
		 *  \t to &#x9;
		 *  \n to &#xA;
		 *  \r to &#xD;
		 */
		public String convert(String input)
		{
			boolean changed = false;
			int inputLength = input.length();
			grow(inputLength);
			input.getChars(0, inputLength, value, 0);
			int pos = 0;
			while (inputLength-- > 0)
			{
				switch (value[pos])
				{
					case '&' :
						pos = replace(pos, AMP, inputLength);
						changed = true;
						break;
					case '<' :
						pos = replace(pos, LESS, inputLength);
						changed = true;
						break;
					case '"' :
						pos = replace(pos, QUOTE, inputLength);
						changed = true;
						break;
					case '\n' :
						{
							pos = replace(pos, LF, inputLength);
							changed = true;
							break;
						}
					case '\r' :
						{
							pos = replace(pos, CR, inputLength);
							changed = true;
							break;
						}
					case '\t' :
						{
							pos = replace(pos, TAB, inputLength);
							changed = true;
							break;
						}
					default :
						pos++;
						break;
				}
			}

			return changed ? new String(value, 0, pos) : input;
		}

		protected int replace(int pos, char[] replacement, int inputLength)
		{
			int rlen = replacement.length;
			int newPos = pos + rlen;
			grow(newPos + inputLength);
			System.arraycopy(value, pos + 1, value, newPos, inputLength);
			System.arraycopy(replacement, 0, value, pos, rlen);
			return newPos;
		}

		protected void grow(int newSize)
		{
			int vlen = value.length;
			if (vlen < newSize)
			{
				char[] newValue = new char[newSize + newSize / 2];
				System.arraycopy(value, 0, newValue, 0, vlen);
				value = newValue;
			}
		}
	}
	
	public static byte[] trim(byte[] byteArray)
	{
		int size = byteArray.length;
		while(--size>=0)
		{
			if(byteArray[size] != 0)
				break;
		}
		
		if(size == (byteArray.length-1))
			return byteArray;
			
		if(size < 0)
			return new byte[0];
		
		size++;
		byte[] newArray = new byte[size];
		System.arraycopy(byteArray, 0, newArray, 0, size);
		return newArray;
	}
}
