W3C home > Mailing lists > Public > uri@w3.org > May 2005

Update on file->URI code (fixed)

From: Graham Klyne <gk@ninebynine.org>
Date: Wed, 18 May 2005 12:38:07 +0100
Message-Id: <5.1.0.14.2.20050518123531.01e4ace0@127.0.0.1>
To: uri@w3.org

[My last attempt was embarassingly bug-ridden -- I thought I had tested it, 
but obviously I had not...]

Noting some of the comments received, I've updated my file->URI mapping 
function:

[[
     /**
      * Convert filename string to a URI.
      * Map system-dependent path separator characters to '/'.
      * %-escape non-URI characters
      * %-escape characters which get special URI interpretation
      * For unix-like systems, the absolute filename begins with a '/'
      * and is preceded by "file://".
      * For other systems an extra '/' must be supplied.
      */
     public static String uriFromFilename(
         String filename)
         {
         StringBuffer mapfilename = new StringBuffer( filename ) ;
         String uriChars =           // See: 
http://www.ietf.org/rfc/rfc3986.txt
                   // ":/?#[]@" +    // gen-delims
                   ":@" +            // selected gen-delims not %-encoded
                   "!$&'()*+,;=" +   // sub-delims
                   "-._~" ;          // unreserved
         char pathsep = System.getProperty("path.separator").charAt(0);
         for ( int i = 0 ; i < mapfilename.length() ; i++ )
             {
             char c = mapfilename.charAt(i) ;
             if ( c == pathsep )
                 { // Replace filename path separator with '/'
                 mapfilename.replace( i, i+1, "/" ) ;
                 }
             else
             if ( !Character.isLetterOrDigit(c) && uriChars.indexOf(c) < 0  )
                 { // %-encode non-URI and other special characters
                 String hv = ("0"+Integer.toHexString(c)) ;
                 mapfilename.replace( i, i+1, 
"%"+hv.substring(hv.length()-2) ) ;
                 i += 2 ;
                 }
             }
         if (mapfilename.charAt(0) == '/')
             {
             return "file://"+mapfilename.toString() ;
             }
         else
             {
             return "file:///"+mapfilename.toString() ;
             }
         }
]]

(I can't help feeling there's a better way to construct the escape sequence 
digits.)

I'm trying to navigate a path to a useful and workable function that will 
work for most practical situations, rather than cover every corner case.

#g


------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact
Received on Wednesday, 18 May 2005 13:42:41 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:25:09 UTC