James, I sent a patch a while ago that does more or less what is done here: http://marc.theaimsgroup.com/?l=turbine-dev&m=101660712315179&w=2
I think you should look into it... ----- Original Message ----- From: "James Taylor" <[EMAIL PROTECTED]> To: "Turbine Developers List" <[EMAIL PROTECTED]> Sent: Tuesday, April 16, 2002 7:10 PM Subject: Re: cvs commit: jakarta-turbine-3/src/java/org/apache/turbineDynamicURI.java > Sorry for the reformatting folks -- it is unintentional -- all the meat > is down at the end. > > On Tue, 2002-04-16 at 12:49, [EMAIL PROTECTED] wrote: > > jtaylor 02/04/16 09:49:38 > > > > Modified: src/java/org/apache/turbine DynamicURI.java > > Log: > > No longer uses java.net.URLEncoder, use StringBuffer more effectively. A couple > > of times faster and fewer object creations. There is probably room for more > > optimization, any improvement is probably worthwhile since this is a real > > hotspot. > > > > Revision Changes Path > > 1.6 +285 -194 jakarta-turbine-3/src/java/org/apache/turbine/DynamicURI.java > > > > Index: DynamicURI.java > > =================================================================== > > RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/DynamicURI.java,v > > retrieving revision 1.5 > > retrieving revision 1.6 > > diff -u -r1.5 -r1.6 > > --- DynamicURI.java 5 Mar 2002 01:32:34 -0000 1.5 > > +++ DynamicURI.java 16 Apr 2002 16:49:38 -0000 1.6 > > @@ -54,14 +54,11 @@ > > * <http://www.apache.org/>. > > */ > > > > -import org.apache.turbine.RunData; > > -import java.net.URLEncoder; > > +import java.util.BitSet; > > import java.util.Enumeration; > > import java.util.Vector; > > import javax.servlet.http.HttpServletRequest; > > import javax.servlet.http.HttpServletResponse; > > -import org.apache.turbine.Turbine; > > -import org.apache.turbine.ParameterParser; > > > > /** > > * This creates a Dynamic URI for use within the Turbine system > > @@ -84,7 +81,8 @@ > > * @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a> > > * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> > > * @author <a href="mailto:[EMAIL PROTECTED]">John McNally</a> > > - * @version $Id: DynamicURI.java,v 1.5 2002/03/05 01:32:34 jon Exp $ > > + * @author <a href="mailto:[EMAIL PROTECTED]">James Taylor</a> > > + * @version $Id: DynamicURI.java,v 1.6 2002/04/16 16:49:38 jtaylor Exp $ > > */ > > public class DynamicURI > > { > > @@ -141,7 +139,7 @@ > > * > > * @param data A Turbine RunData object. > > */ > > - public DynamicURI( RunData data ) > > + public DynamicURI(RunData data) > > { > > init(data); > > } > > @@ -160,8 +158,8 @@ > > * @param data A Turbine RunData object. > > * @param screen A String with the name of a screen. > > */ > > - public DynamicURI( RunData data, > > - String screen ) > > + public DynamicURI(RunData data, > > + String screen) > > { > > this(data); > > setScreen(screen); > > @@ -174,11 +172,11 @@ > > * @param screen A String with the name of a screen. > > * @param action A String with the name of an action. > > */ > > - public DynamicURI( RunData data, > > - String screen, > > - String action ) > > + public DynamicURI(RunData data, > > + String screen, > > + String action) > > { > > - this( data, screen ); > > + this(data, screen); > > setAction(action); > > } > > > > @@ -190,12 +188,12 @@ > > * @param action A String with the name of an action. > > * @param redirect True if it should redirect. > > */ > > - public DynamicURI( RunData data, > > - String screen, > > - String action, > > - boolean redirect ) > > + public DynamicURI(RunData data, > > + String screen, > > + String action, > > + boolean redirect) > > { > > - this( data, screen, action ); > > + this(data, screen, action); > > this.redirect = redirect; > > } > > > > @@ -206,11 +204,11 @@ > > * @param screen A String with the name of a screen. > > * @param redirect True if it should redirect. > > */ > > - public DynamicURI( RunData data, > > - String screen, > > - boolean redirect ) > > + public DynamicURI(RunData data, > > + String screen, > > + boolean redirect) > > { > > - this( data, screen ); > > + this(data, screen); > > this.redirect = redirect; > > } > > > > @@ -220,19 +218,19 @@ > > * @param data A Turbine RunData object. > > * @param redirect True if it should redirect. > > */ > > - public DynamicURI( RunData data, > > - boolean redirect ) > > + public DynamicURI(RunData data, > > + boolean redirect) > > { > > - this( data ); > > + this(data); > > this.redirect = redirect; > > } > > > > /** > > * Initialize with a RunData object > > * > > - * @param RunData > > + * @param data > > */ > > - public void init( RunData data ) > > + public void init(RunData data) > > { > > this.data = data; > > this.res = data.getResponse(); > > @@ -250,23 +248,23 @@ > > * @param name A String with the name to add. > > * @param value A String with the value to add. > > */ > > - protected void add ( int type, > > + protected void add(int type, > > String name, > > - String value ) > > + String value) > > { > > Object[] tmp = new Object[2]; > > tmp[0] = (Object) data.getParameters().convertAndTrim(name); > > tmp[1] = (Object) value; > > switch (type) > > { > > - case PATH_INFO: > > - this.pathInfo.addElement ( tmp ); > > - this.hasPathInfo = true; > > - break; > > - case QUERY_DATA: > > - this.queryData.addElement ( tmp ); > > - this.hasQueryData = true; > > - break; > > + case PATH_INFO: > > + this.pathInfo.addElement(tmp); > > + this.hasPathInfo = true; > > + break; > > + case QUERY_DATA: > > + this.queryData.addElement(tmp); > > + this.hasQueryData = true; > > + break; > > } > > } > > > > @@ -283,21 +281,21 @@ > > * @param type Type (P or Q) of insertion. > > * @param pp A ParameterParser. > > */ > > - protected void add( int type, > > - ParameterParser pp ) > > + protected void add(int type, > > + ParameterParser pp) > > { > > Enumeration e = pp.keys(); > > - while ( e.hasMoreElements() ) > > + while (e.hasMoreElements()) > > { > > - String key = (String)e.nextElement(); > > - if ( !key.equalsIgnoreCase(Turbine.ACTION) && > > - !key.equalsIgnoreCase(Turbine.SCREEN) && > > - !key.equalsIgnoreCase(Turbine.TEMPLATE) ) > > + String key = (String) e.nextElement(); > > + if (!key.equalsIgnoreCase(Turbine.ACTION) && > > + !key.equalsIgnoreCase(Turbine.SCREEN) && > > + !key.equalsIgnoreCase(Turbine.TEMPLATE)) > > { > > String[] values = pp.getStrings(key); > > - for ( int i=0; i<values.length; i++ ) > > + for (int i = 0; i < values.length; i++) > > { > > - add( type, key, values[i] ); > > + add(type, key, values[i]); > > } > > } > > } > > @@ -309,9 +307,9 @@ > > * @param name A String with the name to add. > > * @param value An Object with the value to add. > > */ > > - public DynamicURI addPathInfo ( String name, Object value ) > > + public DynamicURI addPathInfo(String name, Object value) > > { > > - add ( PATH_INFO, name, value.toString() ); > > + add(PATH_INFO, name, value.toString()); > > return this; > > } > > > > @@ -321,9 +319,9 @@ > > * @param name A String with the name to add. > > * @param value A String with the value to add. > > */ > > - public DynamicURI addPathInfo ( String name, String value ) > > + public DynamicURI addPathInfo(String name, String value) > > { > > - add ( PATH_INFO, name, value ); > > + add(PATH_INFO, name, value); > > return this; > > } > > > > @@ -333,9 +331,9 @@ > > * @param name A String with the name to add. > > * @param value A double with the value to add. > > */ > > - public DynamicURI addPathInfo ( String name, double value ) > > + public DynamicURI addPathInfo(String name, double value) > > { > > - add ( PATH_INFO, name, Double.toString(value) ); > > + add(PATH_INFO, name, Double.toString(value)); > > return this; > > } > > > > @@ -345,9 +343,9 @@ > > * @param name A String with the name to add. > > * @param value An int with the value to add. > > */ > > - public DynamicURI addPathInfo ( String name, int value ) > > + public DynamicURI addPathInfo(String name, int value) > > { > > - add ( PATH_INFO, name, new Integer(value).toString() ); > > + add(PATH_INFO, name, new Integer(value).toString()); > > return this; > > } > > > > @@ -357,9 +355,9 @@ > > * @param name A String with the name to add. > > * @param value A long with the value to add. > > */ > > - public DynamicURI addPathInfo ( String name, long value ) > > + public DynamicURI addPathInfo(String name, long value) > > { > > - add ( PATH_INFO, name, new Long(value).toString() ); > > + add(PATH_INFO, name, new Long(value).toString()); > > return this; > > } > > > > @@ -369,9 +367,9 @@ > > * > > * @param pp A ParameterParser. > > */ > > - public DynamicURI addPathInfo ( ParameterParser pp ) > > + public DynamicURI addPathInfo(ParameterParser pp) > > { > > - add ( PATH_INFO, pp ); > > + add(PATH_INFO, pp); > > return this; > > } > > > > @@ -381,9 +379,9 @@ > > * @param name A String with the name to add. > > * @param value An Object with the value to add. > > */ > > - public DynamicURI addQueryData ( String name, Object value ) > > + public DynamicURI addQueryData(String name, Object value) > > { > > - add ( QUERY_DATA, name, value.toString() ); > > + add(QUERY_DATA, name, value.toString()); > > return this; > > } > > > > @@ -393,9 +391,9 @@ > > * @param name A String with the name to add. > > * @param value A String with the value to add. > > */ > > - public DynamicURI addQueryData ( String name, String value ) > > + public DynamicURI addQueryData(String name, String value) > > { > > - add ( QUERY_DATA, name, value ); > > + add(QUERY_DATA, name, value); > > return this; > > } > > > > @@ -405,9 +403,9 @@ > > * @param name A String with the name to add. > > * @param value A double with the value to add. > > */ > > - public DynamicURI addQueryData ( String name, double value ) > > + public DynamicURI addQueryData(String name, double value) > > { > > - add ( QUERY_DATA, name, Double.toString(value) ); > > + add(QUERY_DATA, name, Double.toString(value)); > > return this; > > } > > > > @@ -417,9 +415,9 @@ > > * @param name A String with the name to add. > > * @param value An int with the value to add. > > */ > > - public DynamicURI addQueryData ( String name, int value ) > > + public DynamicURI addQueryData(String name, int value) > > { > > - add ( QUERY_DATA, name, new Integer(value).toString() ); > > + add(QUERY_DATA, name, new Integer(value).toString()); > > return this; > > } > > > > @@ -429,9 +427,9 @@ > > * @param name A String with the name to add. > > * @param value A long with the value to add. > > */ > > - public DynamicURI addQueryData ( String name, long value ) > > + public DynamicURI addQueryData(String name, long value) > > { > > - add ( QUERY_DATA, name, new Long(value).toString() ); > > + add(QUERY_DATA, name, new Long(value).toString()); > > return this; > > } > > > > @@ -441,9 +439,9 @@ > > * > > * @param pp A ParameterParser. > > */ > > - public DynamicURI addQueryData ( ParameterParser pp ) > > + public DynamicURI addQueryData(ParameterParser pp) > > { > > - add ( QUERY_DATA, pp ); > > + add(QUERY_DATA, pp); > > return this; > > } > > > > @@ -463,7 +461,7 @@ > > * @param name A String with the name for the anchor. > > * @return The anchor as a <A HREF="">name</A>. > > */ > > - public String getA( String name ) > > + public String getA(String name) > > { > > return new StringBuffer("<a href=\"") > > .append(this.toString()) > > @@ -479,7 +477,7 @@ > > * > > * @return A String with the script name. > > */ > > - public String getScriptName () > > + public String getScriptName() > > { > > return data.getScriptName(); > > } > > @@ -489,7 +487,7 @@ > > * > > * @return A String with the server name. > > */ > > - public String getServerName () > > + public String getServerName() > > { > > return data.getServerName(); > > } > > @@ -499,7 +497,7 @@ > > * > > * @return A String with the server port. > > */ > > - public int getServerPort () > > + public int getServerPort() > > { > > return data.getServerPort(); > > } > > @@ -533,48 +531,48 @@ > > * @param type Type (P or Q) of removal. > > * @param name A String with the name to be removed. > > */ > > - protected void remove ( int type, > > - String name ) > > + protected void remove(int type, > > + String name) > > { > > try > > { > > switch (type) > > { > > - case PATH_INFO: > > - for (Enumeration e = this.pathInfo.elements() ; > > - e.hasMoreElements() ;) > > - { > > - Object[] tmp = (Object[]) e.nextElement(); > > - if ( data.getParameters().convertAndTrim(name) > > - .equals ( (String)tmp[0] ) ) > > + case PATH_INFO: > > + for (Enumeration e = this.pathInfo.elements(); > > + e.hasMoreElements();) > > { > > - this.pathInfo.removeElement ( tmp ); > > + Object[] tmp = (Object[]) e.nextElement(); > > + if (data.getParameters().convertAndTrim(name) > > + .equals((String) tmp[0])) > > + { > > + this.pathInfo.removeElement(tmp); > > + } > > } > > - } > > - if ( hasPathInfo && this.pathInfo.size() == 0 ) > > - { > > - this.hasPathInfo = false; > > - } > > - break; > > - case QUERY_DATA: > > - for (Enumeration e = this.queryData.elements() ; > > - e.hasMoreElements() ;) > > - { > > - Object[] tmp = (Object[]) e.nextElement(); > > - if ( data.getParameters().convertAndTrim(name) > > - .equals ( (String)tmp[0] ) ) > > + if (hasPathInfo && this.pathInfo.size() == 0) > > { > > - this.queryData.removeElement ( tmp ); > > + this.hasPathInfo = false; > > } > > - } > > - if ( hasQueryData && this.queryData.size() == 0 ) > > - { > > - this.hasQueryData = false; > > - } > > - break; > > + break; > > + case QUERY_DATA: > > + for (Enumeration e = this.queryData.elements(); > > + e.hasMoreElements();) > > + { > > + Object[] tmp = (Object[]) e.nextElement(); > > + if (data.getParameters().convertAndTrim(name) > > + .equals((String) tmp[0])) > > + { > > + this.queryData.removeElement(tmp); > > + } > > + } > > + if (hasQueryData && this.queryData.size() == 0) > > + { > > + this.hasQueryData = false; > > + } > > + break; > > } > > } > > - catch ( Exception e ) > > + catch (Exception e) > > { > > } > > } > > @@ -582,7 +580,7 @@ > > /** > > * Removes all the path info elements. > > */ > > - public void removePathInfo () > > + public void removePathInfo() > > { > > this.pathInfo.removeAllElements(); > > this.hasPathInfo = false; > > @@ -593,15 +591,15 @@ > > * > > * @param name A String with the name to be removed. > > */ > > - public void removePathInfo ( String name ) > > + public void removePathInfo(String name) > > { > > - remove ( PATH_INFO, name ); > > + remove(PATH_INFO, name); > > } > > > > /** > > * Removes all the query string elements. > > */ > > - public void removeQueryData () > > + public void removeQueryData() > > { > > this.queryData.removeAllElements(); > > this.hasQueryData = false; > > @@ -612,9 +610,9 @@ > > * > > * @param name A String with the name to be removed. > > */ > > - public void removeQueryData ( String name ) > > + public void removeQueryData(String name) > > { > > - remove ( QUERY_DATA, name ); > > + remove(QUERY_DATA, name); > > } > > > > /** > > @@ -624,36 +622,39 @@ > > * @param data A Vector of key/value arrays. > > * @return A String with the URL encoded data. > > */ > > - protected String renderPathInfo ( Vector data ) > > + protected String renderPathInfo(Vector data) > > { > > - String key = null; > > - String value = null; > > - String tmp = null; > > StringBuffer out = new StringBuffer(); > > + > > + renderPathInfo(data, out); > > + > > + return out.toString(); > > + } > > + > > + /** > > + * This method takes a Vector of key/value arrays and writes it to the > > + * supplied StringBuffer as encoded path info. > > + * > > + * @param data A Vector of key/value arrays. > > + * @param out Buffer to which encoded path info is written > > + */ > > + protected void renderPathInfo(Vector data, StringBuffer out) > > + { > > Enumeration keys = data.elements(); > > - while(keys.hasMoreElements()) > > + > > + while (keys.hasMoreElements()) > > { > > Object[] stuff = (Object[]) keys.nextElement(); > > - key = URLEncoder.encode((String)stuff[0]); > > - tmp = (String) stuff[1]; > > - if (tmp == null || tmp.length() == 0) > > - { > > - value = "null"; > > - } > > - else > > - { > > - value = URLEncoder.encode(tmp); > > - } > > > > if (out.length() > 0) > > { > > - out.append ( "/" ); > > + out.append("/"); > > } > > - out.append ( key ); > > - out.append ( "/" ); > > - out.append ( value ); > > + > > + writeEncoded((String) stuff[0], out); > > + out.append("/"); > > + writeEncoded((String) stuff[1], out); > > } > > - return out.toString(); > > } > > > > /** > > @@ -663,36 +664,39 @@ > > * @param data A Vector of key/value arrays. > > * @return A String with the URL encoded data. > > */ > > - protected String renderQueryString ( Vector data ) > > + protected String renderQueryString(Vector data) > > { > > - String key = null; > > - String value = null; > > - String tmp = null; > > StringBuffer out = new StringBuffer(); > > + > > + renderQueryString(data, out); > > + > > + return out.toString(); > > + } > > + > > + /** > > + * This method takes a Vector of key/value arrays and writes it to the > > + * provided StringBuffer in encoded query string format. > > + * > > + * @param data A Vector of key/value arrays. > > + * @param out Buffer to which encoded query string is written. > > + */ > > + protected void renderQueryString(Vector data, StringBuffer out) > > + { > > Enumeration keys = data.elements(); > > - while(keys.hasMoreElements()) > > + > > + while (keys.hasMoreElements()) > > { > > Object[] stuff = (Object[]) keys.nextElement(); > > - key = URLEncoder.encode((String) stuff[0]); > > - tmp = (String) stuff[1]; > > - if (tmp == null || tmp.length() == 0) > > - { > > - value = "null"; > > - } > > - else > > - { > > - value = URLEncoder.encode(tmp); > > - } > > > > - if ( out.length() > 0) > > + if (out.length() > 0) > > { > > - out.append ( "&" ); > > + out.append("&"); > > } > > - out.append ( key ); > > - out.append ( "=" ); > > - out.append ( value ); > > + > > + writeEncoded((String) stuff[0], out); > > + out.append("="); > > + writeEncoded((String) stuff[1], out); > > } > > - return out.toString(); > > } > > > > /** > > @@ -704,9 +708,9 @@ > > * @param action A String with the action value. > > * @return A DynamicURI (self). > > */ > > - public DynamicURI setAction ( String action ) > > + public DynamicURI setAction(String action) > > { > > - add ( PATH_INFO, Turbine.ACTION, action ); > > + add(PATH_INFO, Turbine.ACTION, action); > > return this; > > } > > > > @@ -716,12 +720,12 @@ > > * <p>By default it adds the information to the path_info instead > > * of the query data. > > * > > - * @param action A String with the screen value. > > + * @param screen A String with the screen value. > > * @return A DynamicURI (self). > > */ > > - public DynamicURI setScreen ( String screen ) > > + public DynamicURI setScreen(String screen) > > { > > - add ( PATH_INFO, Turbine.SCREEN, screen ); > > + add(PATH_INFO, Turbine.SCREEN, screen); > > return this; > > } > > > > @@ -760,7 +764,7 @@ > > * if true, the scheme, domain, and port will not be included in the > > * String representation of this uri.. > > * > > - * @param b a <code>boolean</code> > > + * @param b a <code>boolean</code> > > * @return a <code>DynamicURI</code> (self) > > */ > > public DynamicURI setRelative(boolean b) > > @@ -783,7 +787,7 @@ > > /** > > * Can be used to disable url rewriting. > > * > > - * @param b a <code>boolean</code> > > + * @param b a <code>boolean</code> > > * @return a <code>DynamicURI</code> (self) > > */ > > public DynamicURI setEncodeUrl(boolean b) > > @@ -825,44 +829,44 @@ > > public String toString() > > { > > StringBuffer output = new StringBuffer(); > > - if (!isRelative) > > + if (!isRelative()) > > { > > - output.append ( getServerScheme() ); > > - output.append ( "://" ); > > - output.append ( getServerName() ); > > - if ( (getServerScheme().equals(HTTP) && getServerPort() != 80) > > - || (getServerScheme().equals(HTTPS) && getServerPort() != 443) > > - ) > > + output.append(getServerScheme()); > > + output.append("://"); > > + output.append(getServerName()); > > + if ((getServerScheme().equals(HTTP) && getServerPort() != 80) > > + || (getServerScheme().equals(HTTPS) && getServerPort() != 443)) > > { > > - output.append (':'); > > - output.append ( getServerPort() ); > > + output.append(':'); > > + output.append(getServerPort()); > > } > > } > > > > - output.append ( getScriptName() ); > > - if ( this.hasPathInfo ) > > + output.append(getScriptName()); > > + > > + if (this.hasPathInfo) > > { > > - output.append ('/'); > > - output.append ( renderPathInfo(this.pathInfo) ); > > + output.append('/'); > > + renderPathInfo(this.pathInfo, output); > > } > > - if ( this.hasQueryData ) > > + if (this.hasQueryData) > > { > > - output.append ('?'); > > - output.append ( renderQueryString(this.queryData) ); > > + output.append('?'); > > + renderQueryString(this.queryData, output); > > } > > > > // There seems to be a bug in Apache JServ 1.0 where the > > // session id is not appended to the end of the url when a > > // cookie has not been set. > > - if ( this.res != null && encodeUrl ) > > + if (this.res != null && isEncodeUrl()) > > { > > - if ( this.redirect ) > > + if (this.redirect) > > { > > - return res.encodeRedirectURL (output.toString()); > > + return res.encodeRedirectURL(output.toString()); > > } > > else > > { > > - return res.encodeURL (output.toString()); > > + return res.encodeURL(output.toString()); > > } > > } > > else > > @@ -894,7 +898,7 @@ > > * would not. > > * > > * @param data A Turbine RunData object. > > - * @param boolean to determine absolute vs. relative links. > > + * @param isAbsolute to determine absolute vs. relative links. > > * @return A String with the URL representing the RunData. > > */ > > public static String toString(RunData data, boolean isAbsolute) > > @@ -904,32 +908,119 @@ > > > > if (isAbsolute) > > { > > - output.append (data.getServerScheme()); > > - output.append ( "://" ); > > - output.append (data.getServerName()); > > - > > - if ( (data.getServerScheme().equals(HTTP) && > > - data.getServerPort() != 80) || > > - (data.getServerScheme().equals(HTTPS) && > > - data.getServerPort() != 443) ) > > + output.append(data.getServerScheme()); > > + output.append("://"); > > + output.append(data.getServerName()); > > + > > + if ((data.getServerScheme().equals(HTTP) && > > + data.getServerPort() != 80) || > > + (data.getServerScheme().equals(HTTPS) && > > + data.getServerPort() != 443)) > > { > > - output.append (':'); > > - output.append (data.getServerPort()); > > + output.append(':'); > > + output.append(data.getServerPort()); > > } > > } > > > > - output.append (data.getScriptName()); > > + output.append(data.getScriptName()); > > > > - if ( request.getPathInfo() != null ) > > + if (request.getPathInfo() != null) > > { > > output.append(request.getPathInfo()); > > } > > > > - if ( request.getQueryString() != null ) > > + if (request.getQueryString() != null) > > { > > - output.append ('?'); > > - output.append (request.getQueryString()); > > + output.append('?'); > > + output.append(request.getQueryString()); > > } > > return output.toString(); > > + } > > + > > + /** > > + * URL encodes <code>in</code> and writes it to <code>out</code>. If the > > + * string is null, 'null' will be written. > > + * > > + * @param in String to write. > > + * @param out Buffer to write to. > > + */ > > + protected static final void writeEncoded(String in, StringBuffer out) > > + { > > + if (in == null || in.length() == 0) > > + { > > + out.append("null"); > > + return; > > + } > > + > > + // This is the most expensive operation: > > + > > + byte[] bytes = in.getBytes(); > > + > > + for (int i = 0; i < bytes.length; i++) > > + { > > + char c = (char) bytes[i]; > > + > > + if ( safe[ c ] ) > > + { > > + out.append(c); > > + } > > + else if (c == ' ') > > + { > > + out.append('+'); > > + } > > + else > > + { > > + byte toEscape = bytes[i]; > > + out.append('%'); > > + int low = (int) (toEscape & 0x0f); > > + int high = (int) ((toEscape & 0xf0) >> 4); > > + out.append(hexadecimal[high]); > > + out.append(hexadecimal[low]); > > + } > > + } > > + } > > + > > + // ------------------------------------- private constants for url encoding > > + > > + /** > > + * Array mapping hexadecimal values to the corresponding ASCII characters. > > + */ > > + private static final char[] hexadecimal = > > + { > > + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', > > + 'A', 'B', 'C', 'D', 'E', 'F' > > + }; > > + > > + /** > > + * Characters that need not be encoded. This is much faster than using a > > + * BitSet, and for such a small array the space cost seems justified. > > + */ > > + private static boolean[] safe = new boolean[ 255 ]; > > + > > + /** Static initializer for {@link #safe} */ > > + static > > + { > > + for (int i = 'a'; i <= 'z'; i++) > > + { > > + safe[ i ] = true; > > + } > > + for (int i = 'A'; i <= 'Z'; i++) > > + { > > + safe[ i ] = true; > > + } > > + for (int i = '0'; i <= '9'; i++) > > + { > > + safe[ i ] = true; > > + } > > + > > + safe['-'] = true; > > + safe['_'] = true; > > + safe['.'] = true; > > + safe['!'] = true; > > + safe['~'] = true; > > + safe['*'] = true; > > + safe['\''] = true; > > + safe['('] = true; > > + safe[')'] = true; > > } > > } > > > > > > > > > > -- > > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > > > > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
