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 &lt;A HREF=""&gt;name&lt;/A&gt;.
        */
  -    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]>

Reply via email to