package at.gv.egovernment.moa.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

/**
 * Decodes an URL encoded String using a specified character encoding.
 * Provides a function missing in JDK 1.3. 
 * @author Paul Ivancsics
 * @version $Id$
 */
public class URLDecoder {

  /**
   * Decodes an <code>application/x-www-form-urlencoded</code> string using a specific encoding scheme.
   * @param s the string to decode
   * @param encoding name of character encoding
   * @return the newly decoded string
   * @throws UnsupportedEncodingException if the encoding is not supported
   */
  public static String decode(String s, String encoding) throws UnsupportedEncodingException {
    StringReader in = new StringReader(s);
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    for (int b = read(in); b >= 0; b = read(in))
      bout.write(b);
    return bout.toString(encoding);
  }
  /**
   * Decodes the next byte from the string reader.
   * @param in string reader
   * @return the next byte decoded; 
   *          -1 upon end of string, on erroneous data, and on any exception caught
   * @todo syntax check on string
   */
  private static int read(StringReader in) {
    try { 
      int b = in.read();
      if (b == '+')
        return ' ';
      if (b == '%') {
        char[] hex = new char[2];
        if (in.read(hex, 0, 2) >= 0) {
          String hexString = new String(hex);
          return Integer.valueOf(hexString, 16).intValue();
        }
        else
          return -1;
      }
      return b;
    } 
    catch (IOException ex) { 
      return -1; 
    }
    catch (NumberFormatException ex) { 
      return -1; 
    }
  }
}