Author: imario
Date: Fri Nov  4 12:11:27 2005
New Revision: 330878

URL: http://svn.apache.org/viewcvs?rev=330878&view=rev
Log:
enh: Some speedup in filename parsing (Thanks to Filip, [EMAIL PROTECTED])

Added:
    jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/
    
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
   (with props)
Modified:
    jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/HostFileNameParser.java
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/LayeredFileNameParser.java
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/URLFileNameParser.java
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/UriParser.java
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/local/LocalFileNameParser.java
    
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/temp/TemporaryFileProvider.java

Modified: jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt Fri Nov  4 12:11:27 2005
@@ -1,5 +1,12 @@
 2005-11 comons-vfs 1.0 RC6
 
+uri praser:
+We have had lots of duplicate calls to fixSeparator, so normalizePath now no 
longer calls it.
+Now normalizePath assumes this has been called.
+This only bothers you if you use normalizePath which should never be the case 
and is not
+needed to work with VFS.
+(Thanks to Filip - filipdef -at - cirquedigital.com)
+
 sftp:
 new configuration parameter SftpFileSystemConfigBuilder.timeout
 upgrade to jsch-0.1.23

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/HostFileNameParser.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/HostFileNameParser.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/HostFileNameParser.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/HostFileNameParser.java
 Fri Nov  4 12:11:27 2005
@@ -57,6 +57,7 @@
 
         // Decode and normalise the file name
         UriParser.canonicalizePath(name, 0, name.length(), this);
+        UriParser.fixSeparators(name);
         FileType fileType = UriParser.normalisePath(name);
         final String path = name.toString();
 

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/LayeredFileNameParser.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/LayeredFileNameParser.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/LayeredFileNameParser.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/LayeredFileNameParser.java
 Fri Nov  4 12:11:27 2005
@@ -55,6 +55,7 @@
 
         // Decode and normalise the path
         UriParser.canonicalizePath(name, 0, name.length(), this);
+        UriParser.fixSeparators(name);
         FileType fileType = UriParser.normalisePath(name);
         final String path = name.toString();
 

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/URLFileNameParser.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/URLFileNameParser.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/URLFileNameParser.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/URLFileNameParser.java
 Fri Nov  4 12:11:27 2005
@@ -51,6 +51,7 @@
 
         // Decode and normalise the file name
         UriParser.canonicalizePath(name, 0, name.length(), this);
+        UriParser.fixSeparators(name);
         FileType fileType = UriParser.normalisePath(name);
         final String path = name.toString();
 

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/UriParser.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/UriParser.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/UriParser.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/UriParser.java
 Fri Nov  4 12:11:27 2005
@@ -21,465 +21,466 @@
 import org.apache.commons.vfs.VFS;
 
 /**
- * Utilities for dealing with URIs.  See RFC 2396 for details.
- *
+ * Utilities for dealing with URIs. See RFC 2396 for details.
+ * 
  * @author <a href="mailto:[EMAIL PROTECTED]">Adam Murdoch</a>
- * @version $Revision$ $Date$
+ * @version $Revision$ $Date: 2005-10-13 21:11:33 +0200 (Do, 13 Okt
+ *          2005) $
  */
 public final class UriParser
 {
-    /**
-     * The normalised separator to use.
-     */
-    private static final char SEPARATOR_CHAR = FileName.SEPARATOR_CHAR;
-
-    /**
-     * The set of valid separators.  These are all converted to the normalised 
one.
-     * Does <i>not</i> contain the normalised separator
-     */
-    public static final char[] separators = {'\\'};
-
-    private UriParser()
-    {
-    }
-
-    /**
-     * Extracts the first element of a path.
-     */
-    public static String extractFirstElement(final StringBuffer name)
-    {
-        final int len = name.length();
-        if (len < 1)
-        {
-            return null;
-        }
-        int startPos = 0;
-        if (name.charAt(0) == SEPARATOR_CHAR)
-        {
-            startPos = 1;
-        }
-        for (int pos = startPos; pos < len; pos++)
-        {
-            if (name.charAt(pos) == SEPARATOR_CHAR)
-            {
-                // Found a separator
-                final String elem = name.substring(startPos, pos);
-                name.delete(startPos, pos + 1);
-                return elem;
-            }
-        }
-
-        // No separator
-        final String elem = name.substring(startPos);
-        name.setLength(0);
-        return elem;
-    }
-
-    /**
-     * Normalises a path.  Does the following:
-     * <ul>
-     * <li>Normalises separators, where more than one can be used.
-     * <li>Removes empty path elements.
-     * <li>Handles '.' and '..' elements.
-     * <li>Removes trailing separator.
-     * </ul>
-     */
-    public static FileType normalisePath(final StringBuffer path)
-        throws FileSystemException
-    {
-        FileType fileType = FileType.FOLDER;
-        if (path.length() == 0)
-        {
-            return fileType;
-        }
-
-        if (path.charAt(path.length() - 1) != '/')
-        {
-            fileType = FileType.FILE;
-        }
-
-        // Adjust separators
-        fixSeparators(path);
-
-        // Determine the start of the first element
-        int startFirstElem = 0;
-        if (path.charAt(0) == SEPARATOR_CHAR)
-        {
-            if (path.length() == 1)
-            {
-                return fileType;
-            }
-            startFirstElem = 1;
-        }
-
-        // Iterate over each element
-        int startElem = startFirstElem;
-        int maxlen = path.length();
-        while (startElem < maxlen)
-        {
-            // Find the end of the element
-            int endElem = startElem;
-            for (; endElem < maxlen && path.charAt(endElem) != SEPARATOR_CHAR; 
endElem++)
-            {
-            }
-
-            final int elemLen = endElem - startElem;
-            if (elemLen == 0)
-            {
-                // An empty element - axe it
-                path.delete(endElem, endElem + 1);
-                maxlen = path.length();
-                continue;
-            }
-            if (elemLen == 1 && path.charAt(startElem) == '.')
-            {
-                // A '.' element - axe it
-                path.delete(startElem, endElem + 1);
-                maxlen = path.length();
-                continue;
-            }
-            if (elemLen == 2
-                && path.charAt(startElem) == '.'
-                && path.charAt(startElem + 1) == '.')
-            {
-                // A '..' element - remove the previous element
-                if (startElem == startFirstElem)
-                {
-                    // Previous element is missing
-                    throw new 
FileSystemException("vfs.provider/invalid-relative-path.error");
-                }
-
-                // Find start of previous element
-                int pos = startElem - 2;
-                for (; pos >= 0 && path.charAt(pos) != SEPARATOR_CHAR; pos--)
-                {
-                }
-                startElem = pos + 1;
-
-                path.delete(startElem, endElem + 1);
-                maxlen = path.length();
-                continue;
-            }
-
-            // A regular element
-            startElem = endElem + 1;
-        }
-
-        // Remove trailing separator
-        if (!VFS.isUriStyle())
-        {
-            if (maxlen > 0 && path.charAt(maxlen - 1) == SEPARATOR_CHAR && 
maxlen > 1)
-            {
-                path.delete(maxlen - 1, maxlen);
-            }
-        }
-
-        return fileType;
-    }
-
-    /**
-     * Normalises the separators in a name.
-     */
-    public static boolean fixSeparators(final StringBuffer name)
-    {
-        if (separators.length == 0)
-        {
-            // Only one valid separator, so don't need to do anything
-            return false;
-        }
-
-        boolean changed = false;
-        final int maxlen = name.length();
-        for (int i = 0; i < maxlen; i++)
-        {
-            final char ch = name.charAt(i);
-            for (int j = 0; j < separators.length; j++)
-            {
-                char separator = separators[j];
-                if (ch == separator)
-                {
-                    name.setCharAt(i, SEPARATOR_CHAR);
-                    changed = true;
-                    break;
-                }
-            }
-        }
-        return changed;
-    }
-
-    /**
-     * Extracts the scheme from a URI.
-     *
-     * @param uri The URI.
-     * @return The scheme name.  Returns null if there is no scheme.
-     */
-    public static String extractScheme(final String uri)
-    {
-        return extractScheme(uri, null);
-    }
-
-    /**
-     * Extracts the scheme from a URI.  Removes the scheme and ':' delimiter
-     * from the front of the URI.
-     *
-     * @param uri    The URI.
-     * @param buffer Returns the remainder of the URI.
-     * @return The scheme name.  Returns null if there is no scheme.
-     */
-    public static String extractScheme(final String uri,
-                                       final StringBuffer buffer)
-    {
-        if (buffer != null)
-        {
-            buffer.setLength(0);
-            buffer.append(uri);
-        }
-
-        final int maxPos = uri.length();
-        for (int pos = 0; pos < maxPos; pos++)
-        {
-            final char ch = uri.charAt(pos);
-
-            if (ch == ':')
-            {
-                // Found the end of the scheme
-                final String scheme = uri.substring(0, pos);
-                if (buffer != null)
-                {
-                    buffer.delete(0, pos + 1);
-                }
-                return scheme;
-            }
-
-            if ((ch >= 'a' && ch <= 'z')
-                || (ch >= 'A' && ch <= 'Z'))
-            {
-                // A scheme character
-                continue;
-            }
-            if (pos > 0
-                && ((ch >= '0' && ch <= '9')
-                || ch == '+' || ch == '-' || ch == '.'))
-            {
-                // A scheme character (these are not allowed as the first
-                // character of the scheme, but can be used as subsequent
-                // characters.
-                continue;
-            }
-
-            // Not a scheme character
-            break;
-        }
-
-        // No scheme in URI
-        return null;
-    }
-
-    /**
-     * Removes %nn encodings from a string.
-     */
-    public static String decode(final String encodedStr)
-        throws FileSystemException
-    {
-        if (encodedStr == null)
-        {
-            return null;
-        }
-        final StringBuffer buffer = new StringBuffer(encodedStr);
-        decode(buffer, 0, buffer.length());
-        return buffer.toString();
-    }
-
-    /**
-     * Removes %nn encodings from a string.
-     */
-    public static void decode(final StringBuffer buffer,
-                              final int offset,
-                              final int length)
-        throws FileSystemException
-    {
-        int index = offset;
-        int count = length;
-        for (; count > 0; count--, index++)
-        {
-            final char ch = buffer.charAt(index);
-            if (ch != '%')
-            {
-                continue;
-            }
-            if (count < 3)
-            {
-                throw new 
FileSystemException("vfs.provider/invalid-escape-sequence.error", 
buffer.substring(index, index + count));
-            }
-
-            // Decode
-            int dig1 = Character.digit(buffer.charAt(index + 1), 16);
-            int dig2 = Character.digit(buffer.charAt(index + 2), 16);
-            if (dig1 == -1 || dig2 == -1)
-            {
-                throw new 
FileSystemException("vfs.provider/invalid-escape-sequence.error", 
buffer.substring(index, index + 3));
-            }
-            char value = (char) (dig1 << 4 | dig2);
-
-            // Replace
-            buffer.setCharAt(index, value);
-            buffer.delete(index + 1, index + 3);
-            count -= 2;
-        }
-    }
-
-    /**
-     * Encodes and appends a string to a StringBuffer.
-     */
-    public static void appendEncoded(final StringBuffer buffer,
-                                     final String unencodedValue,
-                                     final char[] reserved)
-    {
-        final int offset = buffer.length();
-        buffer.append(unencodedValue);
-        encode(buffer, offset, unencodedValue.length(), reserved);
-    }
-
-    /**
-     * Encodes a set of reserved characters in a StringBuffer, using the URI
-     * %nn encoding.  Always encodes % characters.
-     */
-    public static void encode(final StringBuffer buffer,
-                              final int offset,
-                              final int length,
-                              final char[] reserved)
-    {
-        int index = offset;
-        int count = length;
-        for (; count > 0; index++, count--)
-        {
-            final char ch = buffer.charAt(index);
-            boolean match = (ch == '%');
-            if (reserved != null)
-            {
-                for (int i = 0; !match && i < reserved.length; i++)
-                {
-                    if (ch == reserved[i])
-                    {
-                        match = true;
-                    }
-                }
-            }
-            if (match)
-            {
-                // Encode
-                char[] digits = {
-                    Character.forDigit(((ch >> 4) & 0xF), 16),
-                    Character.forDigit((ch & 0xF), 16)
-                };
-                buffer.setCharAt(index, '%');
-                buffer.insert(index + 1, digits);
-                index += 2;
-            }
-        }
-    }
-
-    /**
-     * Removes %nn encodings from a string.
-     */
-    public static String encode(final String decodedStr)
-    {
-        return encode(decodedStr, null);
-    }
-
-    public static String encode(final String decodedStr, final char[] reserved)
-    {
-        if (decodedStr == null)
-        {
-            return null;
-        }
-        final StringBuffer buffer = new StringBuffer(decodedStr);
-        encode(buffer, 0, buffer.length(), reserved);
-        return buffer.toString();
-    }
-
-    public static String[] encode(String[] strings)
-    {
-        if (strings == null)
-        {
-            return null;
-        }
-        for (int i = 0; i < strings.length; i++)
-        {
-            strings[i] = encode(strings[i]);
-        }
-        return strings;
-    }
-
-    public static void checkUriEncoding(String uri) throws FileSystemException
-    {
-        decode(uri);
-    }
-
-    public static void canonicalizePath(StringBuffer buffer, int offset, int 
length, FileNameParser fileNameParser) throws FileSystemException
-    {
-        int index = offset;
-        int count = length;
-        for (; count > 0; count--, index++)
-        {
-            final char ch = buffer.charAt(index);
-            if (ch == '%')
-            {
-                if (count < 3)
-                {
-                    throw new 
FileSystemException("vfs.provider/invalid-escape-sequence.error", 
buffer.substring(index, index + count));
-                }
-
-                // Decode
-                int dig1 = Character.digit(buffer.charAt(index + 1), 16);
-                int dig2 = Character.digit(buffer.charAt(index + 2), 16);
-                if (dig1 == -1 || dig2 == -1)
-                {
-                    throw new 
FileSystemException("vfs.provider/invalid-escape-sequence.error", 
buffer.substring(index, index + 3));
-                }
-                char value = (char) (dig1 << 4 | dig2);
-
-                boolean match = (value == '%') || (fileNameParser != null && 
fileNameParser.encodeCharacter(value));
-
-                if (match)
-                {
-                    // this is a reserved character, not allowed to decode
-                    index += 2;
-                    count -= 2;
-                    continue;
-                }
-
-                // Replace
-                buffer.setCharAt(index, value);
-                buffer.delete(index + 1, index + 3);
-                count -= 2;
-            }
-            else if (fileNameParser.encodeCharacter(ch))
-            {
-                // Encode
-                char[] digits = {
-                    Character.forDigit(((ch >> 4) & 0xF), 16),
-                    Character.forDigit((ch & 0xF), 16)
-                };
-                buffer.setCharAt(index, '%');
-                buffer.insert(index + 1, digits);
-                index += 2;
-            }
-        }
-    }
-
-    public static String extractQueryString(StringBuffer name)
-    {
-        for (int pos = 0; pos < name.length(); pos++)
-        {
-            if (name.charAt(pos) == '?')
-            {
-                String queryString = name.substring(pos + 1);
-                name.delete(pos, name.length());
-                return queryString;
-            }
-        }
+       /**
+        * The normalised separator to use.
+        */
+       private static final char SEPARATOR_CHAR = FileName.SEPARATOR_CHAR;
+
+       /**
+        * The set of valid separators. These are all converted to the 
normalised
+        * one. Does <i>not</i> contain the normalised separator
+        */
+       // public static final char[] separators = {'\\'};
+       public static final char TRANS_SEPARATOR = '\\';
+
+       private UriParser()
+       {
+       }
+
+       /**
+        * Extracts the first element of a path.
+        */
+       public static String extractFirstElement(final StringBuffer name)
+       {
+               final int len = name.length();
+               if (len < 1)
+               {
+                       return null;
+               }
+               int startPos = 0;
+               if (name.charAt(0) == SEPARATOR_CHAR)
+               {
+                       startPos = 1;
+               }
+               for (int pos = startPos; pos < len; pos++)
+               {
+                       if (name.charAt(pos) == SEPARATOR_CHAR)
+                       {
+                               // Found a separator
+                               final String elem = name.substring(startPos, 
pos);
+                               name.delete(startPos, pos + 1);
+                               return elem;
+                       }
+               }
+
+               // No separator
+               final String elem = name.substring(startPos);
+               name.setLength(0);
+               return elem;
+       }
+
+       /**
+        * Normalises a path. Does the following:
+        * <ul>
+        * <li>Removes empty path elements.
+        * <li>Handles '.' and '..' elements.
+        * <li>Removes trailing separator.
+        * </ul>
+        * 
+        * Its assumed that the separators are already fixed.
+        * 
+        *  @see #fixSeparators
+        */
+       public static FileType normalisePath(final StringBuffer path)
+                       throws FileSystemException
+       {
+               FileType fileType = FileType.FOLDER;
+               if (path.length() == 0)
+               {
+                       return fileType;
+               }
+
+               if (path.charAt(path.length() - 1) != '/')
+               {
+                       fileType = FileType.FILE;
+               }
+
+               // Adjust separators
+               // fixSeparators(path);
+
+               // Determine the start of the first element
+               int startFirstElem = 0;
+               if (path.charAt(0) == SEPARATOR_CHAR)
+               {
+                       if (path.length() == 1)
+                       {
+                               return fileType;
+                       }
+                       startFirstElem = 1;
+               }
+
+               // Iterate over each element
+               int startElem = startFirstElem;
+               int maxlen = path.length();
+               while (startElem < maxlen)
+               {
+                       // Find the end of the element
+                       int endElem = startElem;
+                       for (; endElem < maxlen && path.charAt(endElem) != 
SEPARATOR_CHAR; endElem++)
+                       {
+                       }
+
+                       final int elemLen = endElem - startElem;
+                       if (elemLen == 0)
+                       {
+                               // An empty element - axe it
+                               path.delete(endElem, endElem + 1);
+                               maxlen = path.length();
+                               continue;
+                       }
+                       if (elemLen == 1 && path.charAt(startElem) == '.')
+                       {
+                               // A '.' element - axe it
+                               path.delete(startElem, endElem + 1);
+                               maxlen = path.length();
+                               continue;
+                       }
+                       if (elemLen == 2 && path.charAt(startElem) == '.'
+                                       && path.charAt(startElem + 1) == '.')
+                       {
+                               // A '..' element - remove the previous element
+                               if (startElem == startFirstElem)
+                               {
+                                       // Previous element is missing
+                                       throw new FileSystemException(
+                                                       
"vfs.provider/invalid-relative-path.error");
+                               }
+
+                               // Find start of previous element
+                               int pos = startElem - 2;
+                               for (; pos >= 0 && path.charAt(pos) != 
SEPARATOR_CHAR; pos--)
+                               {
+                               }
+                               startElem = pos + 1;
+
+                               path.delete(startElem, endElem + 1);
+                               maxlen = path.length();
+                               continue;
+                       }
+
+                       // A regular element
+                       startElem = endElem + 1;
+               }
+
+               // Remove trailing separator
+               if (!VFS.isUriStyle())
+               {
+                       if (maxlen > 0 && path.charAt(maxlen - 1) == 
SEPARATOR_CHAR
+                                       && maxlen > 1)
+                       {
+                               path.delete(maxlen - 1, maxlen);
+                       }
+               }
+
+               return fileType;
+       }
+
+       /**
+        * Normalises the separators in a name.
+        */
+       public static boolean fixSeparators(final StringBuffer name)
+       {
+               boolean changed = false;
+               final int maxlen = name.length();
+               for (int i = 0; i < maxlen; i++)
+               {
+                       final char ch = name.charAt(i);
+                       if (ch == TRANS_SEPARATOR)
+                       {
+                               name.setCharAt(i, SEPARATOR_CHAR);
+                               changed = true;
+                       }
+               }
+               return changed;
+       }
+
+       /**
+        * Extracts the scheme from a URI.
+        * 
+        * @param uri
+        *            The URI.
+        * @return The scheme name. Returns null if there is no scheme.
+        */
+       public static String extractScheme(final String uri)
+       {
+               return extractScheme(uri, null);
+       }
+
+       /**
+        * Extracts the scheme from a URI. Removes the scheme and ':' delimiter 
from
+        * the front of the URI.
+        * 
+        * @param uri
+        *            The URI.
+        * @param buffer
+        *            Returns the remainder of the URI.
+        * @return The scheme name. Returns null if there is no scheme.
+        */
+       public static String extractScheme(final String uri,
+                       final StringBuffer buffer)
+       {
+               if (buffer != null)
+               {
+                       buffer.setLength(0);
+                       buffer.append(uri);
+               }
+
+               final int maxPos = uri.length();
+               for (int pos = 0; pos < maxPos; pos++)
+               {
+                       final char ch = uri.charAt(pos);
+
+                       if (ch == ':')
+                       {
+                               // Found the end of the scheme
+                               final String scheme = uri.substring(0, pos);
+                               if (buffer != null)
+                               {
+                                       buffer.delete(0, pos + 1);
+                               }
+                               return scheme;
+                       }
+
+                       if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 
'Z'))
+                       {
+                               // A scheme character
+                               continue;
+                       }
+                       if (pos > 0
+                                       && ((ch >= '0' && ch <= '9') || ch == 
'+' || ch == '-' || ch == '.'))
+                       {
+                               // A scheme character (these are not allowed as 
the first
+                               // character of the scheme, but can be used as 
subsequent
+                               // characters.
+                               continue;
+                       }
+
+                       // Not a scheme character
+                       break;
+               }
+
+               // No scheme in URI
+               return null;
+       }
+
+       /**
+        * Removes %nn encodings from a string.
+        */
+       public static String decode(final String encodedStr)
+                       throws FileSystemException
+       {
+               if (encodedStr == null)
+               {
+                       return null;
+               }
+               final StringBuffer buffer = new StringBuffer(encodedStr);
+               decode(buffer, 0, buffer.length());
+               return buffer.toString();
+       }
+
+       /**
+        * Removes %nn encodings from a string.
+        */
+       public static void decode(final StringBuffer buffer, final int offset,
+                       final int length) throws FileSystemException
+       {
+               int index = offset;
+               int count = length;
+               for (; count > 0; count--, index++)
+               {
+                       final char ch = buffer.charAt(index);
+                       if (ch != '%')
+                       {
+                               continue;
+                       }
+                       if (count < 3)
+                       {
+                               throw new FileSystemException(
+                                               
"vfs.provider/invalid-escape-sequence.error", buffer
+                                                               
.substring(index, index + count));
+                       }
+
+                       // Decode
+                       int dig1 = Character.digit(buffer.charAt(index + 1), 
16);
+                       int dig2 = Character.digit(buffer.charAt(index + 2), 
16);
+                       if (dig1 == -1 || dig2 == -1)
+                       {
+                               throw new FileSystemException(
+                                               
"vfs.provider/invalid-escape-sequence.error", buffer
+                                                               
.substring(index, index + 3));
+                       }
+                       char value = (char) (dig1 << 4 | dig2);
+
+                       // Replace
+                       buffer.setCharAt(index, value);
+                       buffer.delete(index + 1, index + 3);
+                       count -= 2;
+               }
+       }
+
+       /**
+        * Encodes and appends a string to a StringBuffer.
+        */
+       public static void appendEncoded(final StringBuffer buffer,
+                       final String unencodedValue, final char[] reserved)
+       {
+               final int offset = buffer.length();
+               buffer.append(unencodedValue);
+               encode(buffer, offset, unencodedValue.length(), reserved);
+       }
+
+       /**
+        * Encodes a set of reserved characters in a StringBuffer, using the 
URI %nn
+        * encoding. Always encodes % characters.
+        */
+       public static void encode(final StringBuffer buffer, final int offset,
+                       final int length, final char[] reserved)
+       {
+               int index = offset;
+               int count = length;
+               for (; count > 0; index++, count--)
+               {
+                       final char ch = buffer.charAt(index);
+                       boolean match = (ch == '%');
+                       if (reserved != null)
+                       {
+                               for (int i = 0; !match && i < reserved.length; 
i++)
+                               {
+                                       if (ch == reserved[i])
+                                       {
+                                               match = true;
+                                       }
+                               }
+                       }
+                       if (match)
+                       {
+                               // Encode
+                               char[] digits =
+                               { Character.forDigit(((ch >> 4) & 0xF), 16),
+                                               Character.forDigit((ch & 0xF), 
16) };
+                               buffer.setCharAt(index, '%');
+                               buffer.insert(index + 1, digits);
+                               index += 2;
+                       }
+               }
+       }
+
+       /**
+        * Removes %nn encodings from a string.
+        */
+       public static String encode(final String decodedStr)
+       {
+               return encode(decodedStr, null);
+       }
+
+       public static String encode(final String decodedStr, final char[] 
reserved)
+       {
+               if (decodedStr == null)
+               {
+                       return null;
+               }
+               final StringBuffer buffer = new StringBuffer(decodedStr);
+               encode(buffer, 0, buffer.length(), reserved);
+               return buffer.toString();
+       }
+
+       public static String[] encode(String[] strings)
+       {
+               if (strings == null)
+               {
+                       return null;
+               }
+               for (int i = 0; i < strings.length; i++)
+               {
+                       strings[i] = encode(strings[i]);
+               }
+               return strings;
+       }
+
+       public static void checkUriEncoding(String uri) throws 
FileSystemException
+       {
+               decode(uri);
+       }
+
+       public static void canonicalizePath(StringBuffer buffer, int offset,
+                       int length, FileNameParser fileNameParser)
+                       throws FileSystemException
+       {
+               int index = offset;
+               int count = length;
+               for (; count > 0; count--, index++)
+               {
+                       final char ch = buffer.charAt(index);
+                       if (ch == '%')
+                       {
+                               if (count < 3)
+                               {
+                                       throw new FileSystemException(
+                                                       
"vfs.provider/invalid-escape-sequence.error",
+                                                       buffer.substring(index, 
index + count));
+                               }
+
+                               // Decode
+                               int dig1 = Character.digit(buffer.charAt(index 
+ 1), 16);
+                               int dig2 = Character.digit(buffer.charAt(index 
+ 2), 16);
+                               if (dig1 == -1 || dig2 == -1)
+                               {
+                                       throw new FileSystemException(
+                                                       
"vfs.provider/invalid-escape-sequence.error",
+                                                       buffer.substring(index, 
index + 3));
+                               }
+                               char value = (char) (dig1 << 4 | dig2);
+
+                               boolean match = (value == '%')
+                                               || (fileNameParser != null && 
fileNameParser
+                                                               
.encodeCharacter(value));
+
+                               if (match)
+                               {
+                                       // this is a reserved character, not 
allowed to decode
+                                       index += 2;
+                                       count -= 2;
+                                       continue;
+                               }
+
+                               // Replace
+                               buffer.setCharAt(index, value);
+                               buffer.delete(index + 1, index + 3);
+                               count -= 2;
+                       }
+                       else if (fileNameParser.encodeCharacter(ch))
+                       {
+                               // Encode
+                               char[] digits =
+                               { Character.forDigit(((ch >> 4) & 0xF), 16),
+                                               Character.forDigit((ch & 0xF), 
16) };
+                               buffer.setCharAt(index, '%');
+                               buffer.insert(index + 1, digits);
+                               index += 2;
+                       }
+               }
+       }
+
+       public static String extractQueryString(StringBuffer name)
+       {
+               for (int pos = 0; pos < name.length(); pos++)
+               {
+                       if (name.charAt(pos) == '?')
+                       {
+                               String queryString = name.substring(pos + 1);
+                               name.delete(pos, name.length());
+                               return queryString;
+                       }
+               }
 
-        return null;
-    }
+               return null;
+       }
 }

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/local/LocalFileNameParser.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/local/LocalFileNameParser.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/local/LocalFileNameParser.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/local/LocalFileNameParser.java
 Fri Nov  4 12:11:27 2005
@@ -70,13 +70,15 @@
 
         // Remove encoding, and adjust the separators
         UriParser.canonicalizePath(name, 0, name.length(), this);
-        UriParser.fixSeparators(name);
 
+        UriParser.fixSeparators(name);
+        
         // Extract the root prefix
         final String rootFile = extractRootPrefix(filename, name);
 
         // Normalise the path
         FileType fileType = UriParser.normalisePath(name);
+
         final String path = name.toString();
 
         return createFileName(

Modified: 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/temp/TemporaryFileProvider.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/temp/TemporaryFileProvider.java?rev=330878&r1=330877&r2=330878&view=diff
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/temp/TemporaryFileProvider.java
 (original)
+++ 
jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/temp/TemporaryFileProvider.java
 Fri Nov  4 12:11:27 2005
@@ -93,6 +93,9 @@
         // Parse the name
         final StringBuffer buffer = new StringBuffer(uri);
         final String scheme = UriParser.extractScheme(uri, buffer);
+
+        UriParser.fixSeparators(buffer);
+        
         FileType fileType = UriParser.normalisePath(buffer);
         final String path = buffer.toString();
 

Added: 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java?rev=330878&view=auto
==============================================================================
--- 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
 (added)
+++ 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
 Fri Nov  4 12:11:27 2005
@@ -0,0 +1,86 @@
+package org.apache.commons.vfs.perf;
+
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemManager;
+import org.apache.commons.vfs.VFS;
+
+public class FileNamePerformance
+{
+       private final static int NUOF_RESOLVES = 100000;
+
+       public static void main(String[] args) throws FileSystemException
+       {
+               FileSystemManager mgr = VFS.getManager();
+
+               FileObject root = mgr
+                               
.resolveFile("smb://HOME\\vfsusr:vfs%2f%25\\te:[EMAIL PROTECTED]/vfsusr");
+               FileName rootName = root.getName();
+       
+               testNames(mgr, rootName);
+
+               testChildren(root);
+
+               testFiles(mgr);
+       }
+
+       private static void testFiles(FileSystemManager mgr) throws 
FileSystemException
+       {
+               for (int i = 0; i < 10; i++)
+               {
+                       // warmup jvm
+                       
mgr.resolveFile("smb://HOME\\vfsusr:vfs%2f%25\\te:[EMAIL 
PROTECTED]/vfsusr/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+
+               long start = System.currentTimeMillis();
+               for (int i = 0; i < NUOF_RESOLVES; i++)
+               {
+                       
mgr.resolveFile("smb://HOME\\vfsusr:vfs%2f%25\\te:[EMAIL 
PROTECTED]/vfsusr/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+               long end = System.currentTimeMillis();
+
+               System.err.println("time to resolve " + NUOF_RESOLVES + " 
files: "
+                               + (end - start) + "ms");
+       }
+
+       private static void testChildren(FileObject root) throws 
FileSystemException
+       {
+               for (int i = 0; i < 10; i++)
+               {
+                       // warmup jvm
+                       
root.resolveFile("/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+
+               long start = System.currentTimeMillis();
+               for (int i = 0; i < NUOF_RESOLVES; i++)
+               {
+                       
root.resolveFile("/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+               long end = System.currentTimeMillis();
+
+               System.err.println("time to resolve " + NUOF_RESOLVES + " 
childs: "
+                               + (end - start) + "ms");
+       }
+
+       private static void testNames(FileSystemManager mgr, FileName rootName) 
throws FileSystemException
+       {
+               for (int i = 0; i < 10; i++)
+               {
+                       // warmup jvm
+                       mgr.resolveName(rootName,
+                                       
"/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+
+               long start = System.currentTimeMillis();
+               for (int i = 0; i < NUOF_RESOLVES; i++)
+               {
+                       mgr.resolveName(rootName,
+                                       
"/many/path/elements/with%25esc/any%25where/to/file.txt");
+               }
+               long end = System.currentTimeMillis();
+
+               System.err.println("time to resolve " + NUOF_RESOLVES + " 
names: "
+                               + (end - start) + "ms");
+       }
+}

Propchange: 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: 
jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/perf/FileNamePerformance.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to