📄 urldecoder.java
字号:
// URLDecoder.java// $Id: URLDecoder.java,v 1.10 2000/08/16 21:37:38 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.forms ;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.util.Hashtable ;import java.util.Enumeration ;/** * Form data decoder. * This class takes an InputStream and decodes it in compliance to the * <b>application/x-www-form-urlencoded</b> MIME type. */public class URLDecoder { public final static String EMPTY_VALUE = "" ; int ch = -1 ; Hashtable values = null ; byte buffer[] = new byte[1024] ; int bsize = 0 ; Reader in = null ; boolean overide = true ; private void append (int c) { if ( bsize+1 >= buffer.length ) { byte nb[] = new byte[buffer.length*2] ; System.arraycopy (buffer, 0, nb, 0, buffer.length) ; buffer = nb ; } buffer[bsize++] = (byte) c ; } /** * Get an enumeration of the variable names. * @return An enumeration continaing one element per key. */ public Enumeration keys() { return values.keys() ; } /** * Define a new variable in this data set. * @param name The name of the variable. * @param value Its value. */ protected void addVariable (String var, String val) { if ( overide ) { values.put (var, val) ; } else { Object value = values.get (var) ; if ( value == null ) { values.put (var, val) ; } else if ( value instanceof String[] ) { String olds[] = (String[]) value ; String vals[] = new String[olds.length+1] ; System.arraycopy (olds, 0, vals, 0, olds.length) ; vals[olds.length] = val ; values.put (var, vals) ; } else if ( value instanceof String ) { String vals[] = new String[2] ; vals[0] = (String) value ; vals[1] = val ; values.put (var, vals) ; } } } /** * Get the values of the variable, as an array. * Use this method when you have turned off the <em>overide</em> flag * in the constructor of this object. This will always return either an * array of Strings or <strong>null</strong>. * <p>I use this in the PICS label bureau, and I pretty sure this is not a * good reason to have it here. * @param name The name of the variable to look for. * @return An String[] having one entry per variable's value, or <strong> * null</strong> if none was found. */ public String[] getMultipleValues (String name) { if ( overide ) throw new RuntimeException (this.getClass().getName() + "[getMultipleValues]: " + " overide not set !") ; Object value = values.get (name) ; if ( value instanceof String[] ) { return (String[]) value ; } else { String vals[] = new String[1] ; vals[0] = (String) value ; values.put (name, vals) ; return vals ; } } /** * Get the value of a variable. * If you have allowed the decoder to accumulate multiple values for the * same variable, this method casts of the value to a String may fail * <em>at runtime</em>. * @param name The name of the variable whose value is to be fetched. * @return Its values, which is always provided as a String, or null. */ public String getValue (String name) { Object value = values.get(name) ; if ( (value != null) && ! (value instanceof String) ) throw new RuntimeException (this.getClass().getName() + "[getValue]:" + " use getMultipleValues in:\n\t" + name + " " + value) ; return (String) value ; } /** * Parse our input stream following the * <b>application/x-www-form-urlencoded</b> specification. * @return The raw bindings obtained from parsing the stream, as a * Hashtable instance. * @exception IOException When IO error occurs while reading the stream. * @exception URLDecoderException If the format is invalid. */ public Hashtable parse () throws IOException, URLDecoderException { String key = null ; read_loop: ch = in.read() ; while ( true ) { switch (ch) { case '+': append (' ') ; break ; case '%': int hi, lo ; if ((hi = ch = in.read()) == -1) throw new URLDecoderException ("Invalid escape seq.") ; if ((lo = ch = in.read()) == -1) throw new URLDecoderException ("Invalid escape seq.") ; hi = (Character.isDigit((char) hi) ? (hi - '0') : 10 + (Character.toUpperCase((char) hi) - 'A')) ; lo = (Character.isDigit((char) lo) ? (lo - '0') : 10 + (Character.toUpperCase((char) lo) - 'A')) ; append ((char)(((byte) lo) | (((byte) hi) << 4))) ; break ; case '&': if ( key == null ) { // We only get a simple key (with no value) addVariable(new String(buffer,0,bsize), EMPTY_VALUE); bsize = 0 ; } else { addVariable (key, new String (buffer, 0, bsize)) ; key = null ; bsize = 0 ; } break ; case ';': // HTML4.0: appendix b2.2: use of ";" in place of "&" if ( key == null ) { // We only get a simple key (with no value) addVariable(new String(buffer,0,bsize), EMPTY_VALUE); bsize = 0 ; } else { addVariable (key, new String (buffer, 0, bsize)) ; key = null ; bsize = 0 ; } break ; case '=': if ( key != null ) { append(ch); } else { key = new String (buffer, 0, bsize) ; bsize = 0 ; } break ; case -1: // Same as '&', except that we return if ( key == null ) { // We only get a simple key (with no value) addVariable(new String(buffer,0,bsize), EMPTY_VALUE); bsize = 0 ; } else { addVariable (key, new String (buffer, 0, bsize)) ; key = null ; bsize = 0 ; } return values ; default: append (ch) ; break ; } ch = in.read() ; } } /** * Create an URLDecoder for the given stream. * @param in The input stream to be parsed. * @param list Tells how to handle multiple settings of the same variable. * When <strong>false</strong>, mutiple settings to the same variable * will accumulate the value into an array, returned by getValue(). * Otherwise, the last assignment will overide any previous assignment. */ public URLDecoder (Reader in, boolean overide) { this.values = new Hashtable (23) ; this.in = in ; this.ch = -1 ; this.overide = overide ; } /** * Create an URLDecoder for the given stream. * @param in The input stream to be parsed. * @param list Tells how to handle multiple settings of the same variable. * When <strong>false</strong>, mutiple settings to the same variable * will accumulate the value into an array, returned by getValue(). * Otherwise, the last assignment will overide any previous assignment. */ public URLDecoder (Reader in) { this(in, true); } /** * Create an URLDecoder for the given stream. * @param in The input stream to be parsed. * @param list Tells how to handle multiple settings of the same variable. * When <strong>false</strong>, mutiple settings to the same variable * will accumulate the value into an array, returned by getValue(). * Otherwise, the last assignment will overide any previous assignment. */ public URLDecoder (InputStream in, boolean overide) { this.values = new Hashtable (23) ; this.in = new InputStreamReader(in) ; this.ch = -1 ; this.overide = overide ; } /** * Create an URLDecoder for the given stream. * Default constructor, which will keep track only of the last setting * of the same variable (if ever it gets assigned multiply). * @param in The input stream to be parsed. */ public URLDecoder (InputStream in) { this (in, true) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -