/* URLDecoder.java -- Class to decode URL's from encoded form.
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.net;

import java.io.UnsupportedEncodingException;


/**
 * This utility class contains static methods that converts a
 * string encoded in the x-www-form-urlencoded format to the original
 * text.  The x-www-form-urlencoded format replaces certain disallowed
 * characters with encoded equivalents.  All upper case and lower case
 * letters in the US alphabet remain as is, the space character (' ')
 * is replaced with '+' sign, and all other characters are converted to a
 * "%XX" format where XX is the hexadecimal representation of that character
 * in a given character encoding (default is "UTF-8").
 * <p>
 * This method is very useful for decoding strings sent to CGI scripts
 *
 * Written using on-line Java Platform 1.2/1.4 API Specification.
 * Status:  Believed complete and correct.
 *
 * @since 1.2
 *
 * @author Warren Levy (warrenl@cygnus.com)
 * @author Aaron M. Renn (arenn@urbanophile.com) (documentation comments)
 * @author Mark Wielaard (mark@klomp.org)
 */
public class URLDecoder
{
  /**
   * Public contructor. Note that this class has only static methods.
   */
  public URLDecoder()
  {
  }

  /**
   * This method translates the passed in string from x-www-form-urlencoded
   * format using the default encoding "UTF-8" to decode the hex encoded
   * unsafe characters.
   *
   * @param s the String to convert
   *
   * @return the converted String
   *
   * @deprecated
   */
  public static String decode(String s)
  {
    try
      {
	return decode(s, "UTF-8");
      }
    catch (UnsupportedEncodingException uee)
      {
	// Should never happen since UTF-8 encoding should always be supported
	return s;
      }
  }

  /**
   * This method translates the passed in string from x-www-form-urlencoded
   * format using the given character encoding to decode the hex encoded
   * unsafe characters.
   *
   * This implementation will decode the string even if it contains
   * unsafe characters (characters that should have been encoded) or if the
   * two characters following a % do not represent a hex encoded byte.
   * In those cases the unsafe character or the % character will be added
   * verbatim to the decoded result.
   *
   * @param s the String to convert
   * @param encoding the character encoding to use the decode the hex encoded
   *        unsafe characters
   *
   * @return the converted String
   *
   * @exception UnsupportedEncodingException If the named encoding is not
   * supported
   *
   * @since 1.4
   */
  public static String decode(String s, String encoding)
    throws UnsupportedEncodingException
  {
    // First convert all '+' characters to spaces.
    String str = s.replace('+', ' ');

    // Then go through the whole string looking for byte encoded characters
    int i;
    int start = 0;
    byte[] bytes = null;
    int length = str.length();
    StringBuffer result = new StringBuffer(length);
    while ((i = str.indexOf('%', start)) >= 0)
      {
	// Add all non-encoded characters to the result buffer
	result.append(str.substring(start, i));
	start = i;

	// Get all consecutive encoded bytes
	while ((i + 2 < length) && (str.charAt(i) == '%'))
	  i += 3;

	// Decode all these bytes
	if ((bytes == null) || (bytes.length < ((i - start) / 3)))
	  bytes = new byte[((i - start) / 3)];

	int index = 0;
	try
	  {
	    while (start < i)
	      {
		String sub = str.substring(start + 1, start + 3);
		bytes[index] = (byte) Integer.parseInt(sub, 16);
		index++;
		start += 3;
	      }
	  }
	catch (NumberFormatException nfe)
	  {
	    // One of the hex encoded strings was bad
	  }

	// Add the bytes as characters according to the given encoding
	result.append(new String(bytes, 0, index, encoding));

	// Make sure we skip to just after a % sign
	// There might not have been enough encoded characters after the %
	// or the hex chars were not actually hex chars (NumberFormatException)
	if (start < length && s.charAt(start) == '%')
	  {
	    result.append('%');
	    start++;
	  }
      }

    // Add any characters left
    if (start < str.length())
      result.append(str.substring(start));

    return result.toString();
  }
} // class URLDecoder
