OSDN Git Service

1999-06-02 Warren Levy <warrenl@cygnus.com>
authorwarrenl <warrenl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Jun 1999 22:29:12 +0000 (22:29 +0000)
committerwarrenl <warrenl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Jun 1999 22:29:12 +0000 (22:29 +0000)
* java/net/URL.java (URL(URL,String)): Initialize port to -1.
Ignore context if spec is an absolute URL.  Fix braindead
string comparison.
(hashCode): Use JDK 1.2 style algorithm.
* java/net/URLStreamHandler.java (parseURL): Reimplement to handle
context URL properly.
1999-05-30  Anthony Green  <green@cygnus.com>
* java/net/URLStreamHandler.java (parseURL): Parse relative URLs
correctly.  Clean up "/../" and "/./" path fragments.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27334 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/java/net/URL.java
libjava/java/net/URLStreamHandler.java

index d611139..bd9afc2 100644 (file)
@@ -1,3 +1,17 @@
+1999-06-02  Warren Levy  <warrenl@cygnus.com>
+
+       * java/net/URL.java (URL(URL,String)): Initialize port to -1.
+       Ignore context if spec is an absolute URL.  Fix braindead
+       string comparison.
+       (hashCode): Use JDK 1.2 style algorithm.
+       * java/net/URLStreamHandler.java (parseURL): Reimplement to handle
+       context URL properly.
+
+1999-05-30  Anthony Green  <green@cygnus.com>
+
+       * java/net/URLStreamHandler.java (parseURL): Parse relative URLs
+       correctly.  Clean up "/../" and "/./" path fragments.
+
 1999-05-28  Warren Levy  <warrenl@cygnus.com>
 
        * java/net/DatagramSocket.java (laddr): Removed.
index da56f49..b6dc13d 100644 (file)
@@ -29,7 +29,7 @@ public final class URL implements Serializable
 {
   private String protocol;
   private String host;
-  private int port;
+  private int port = -1;       // Initialize for constructor using context.
   private String file;
   private String ref;
   private URLStreamHandler handler;
@@ -117,14 +117,22 @@ public final class URL implements Serializable
      * to the context's file.  The optional anchor is not inherited. 
      */
 
+    // If this is an absolute URL, then ignore context completely.
+    // An absolute URL must have chars prior to "://" but cannot have a colon
+    // right after the "://".  The second colon is for an optional port value
+    // and implies that the host from the context is used if available.
     int colon;
+    if ((colon = spec.indexOf("://", 1)) > 0 &&
+       ! spec.regionMatches(colon, "://:", 0, 4))
+      context = null;
+
     int slash;
     if ((colon = spec.indexOf(':')) > 0 &&
        (colon < (slash = spec.indexOf('/')) || slash < 0))
       {
        // Protocol specified in spec string.
        protocol = spec.substring(0, colon);
-       if (context != null && context.protocol == protocol)
+       if (context != null && context.protocol.equals(protocol))
          {
            // The 1.2 doc specifically says these are copied to the new URL.
            host = context.host;
@@ -222,8 +230,20 @@ public final class URL implements Serializable
   {
     // JCL book says this is computed using (only) the hashcodes of the 
     // protocol, host and file fields.  Empirical evidence indicates this
-    // is probably XOR.
-    return (protocol.hashCode() ^ host.hashCode() ^ file.hashCode());
+    // is probably XOR in JDK 1.1.  In JDK 1.2 it seems to be a sum including
+    // the port.
+    //
+    // JDK 1.2 online doc infers that host could be null because it
+    // explicitly states that file cannot be null but is silent on host.
+    // A simple example with protocol "http" (hashcode 3213448), host null,
+    // file "/" (hashcode 47) produced a hashcode (3213494) which appeared
+    // to be the sum of the two hashcodes plus the port.  Another example
+    // using "/index.html" for file bore this out; as well as "#" for file
+    // (which was reduced to "" with a hashcode of zero).  A "" host also
+    // causes the port number and the two hashcodes to be summed.
+
+    return (protocol.hashCode() + ((host == null) ? 0 : host.hashCode()) +
+       port + file.hashCode());
   }
 
   public URLConnection openConnection() throws IOException
index ae364e4..ba2114c 100644 (file)
@@ -28,29 +28,35 @@ public abstract class URLStreamHandler
 
   protected void parseURL(URL u, String spec, int start, int limit)
   {
-    String tmpStr;
-    String host = "";  // Initialize to null string.
-    String file;
-    int port = -1;
-    int colon;
-
+    String host = u.getHost();
+    int port = u.getPort();
+    String file = u.getFile();
+    
     /* TBD: The JDK 1.2 doc specifically says that limit is the position
      * to stop parsing at and that it will be either the end of the string
      * or the position of '#'; thus the doc infers that this method does
      * not set the ref.
      */
-    tmpStr = spec.substring(start, limit);
-    int hostEnd = 0;
-    if (tmpStr.startsWith("//"))
+    if (spec.regionMatches (start, "//", 0, 2))
       {
-       int slash = tmpStr.indexOf('/', 2);
-       hostEnd = tmpStr.length();
-       if (slash >= 0)
-         hostEnd = slash;
+       int hostEnd;
+       int colon;
 
-       host = tmpStr.substring(2, hostEnd);
-
-       // Look for optional port number.
+       start += 2;
+       int slash = spec.indexOf('/', start);
+       if (slash >= 0) 
+         hostEnd = slash;
+        else
+         hostEnd = limit;
+
+       host = spec.substring (start, hostEnd);
+       
+       // Look for optional port number.  It is valid for the non-port
+       // part of the host name to be null (e.g. a URL "http://:80").
+       // TBD: JDK 1.2 in this case sets host to null rather than "";
+       // this is undocumented and likely an unintended side effect in 1.2
+       // so we'll be simple here and stick with "". Note that
+       // "http://" or "http:///" produce a "" host in JDK 1.2.
        if ((colon = host.indexOf(':')) >= 0)
          {
            try
@@ -59,17 +65,55 @@ public abstract class URLStreamHandler
              }
            catch (NumberFormatException e)
              {
-               ; // Ignore invalid port values; port is already set to -1.
+               ; // Ignore invalid port values; port is already set to u's
+                 // port.
              }
            host = host.substring(0, colon);
          }
+       file = null;
+       start = hostEnd;
+      } 
+    else if (host == null) 
+      host = "";
+
+    if (start < limit && spec.charAt(start) == '/') 
+      {
+       // This is an absolute path name; ignore any file context.
+       file = spec.substring(start, limit);
+      } 
+    else if (file == null || file.length() <= 0)
+      {
+       // No file context available; just spec for file.
+       file = "/" + spec.substring(start, limit);
+      }
+    else if (start < limit)
+      {
+       // Context is available, but only override it if there is a new file.
+        // FIXME: unsure to what extent `/` and File.separatorChar
+       //        can mix in URLs.  Ignore File.separatorChar for now.
+       file = file.substring(0, file.lastIndexOf('/'))
+               + "/" + spec.substring(start, limit);
       }
 
-    if (hostEnd < tmpStr.length())
-      file = ((tmpStr.startsWith("/")) ? "" : "/") + tmpStr.substring(hostEnd);
-    else
-      file = "/";
+    int index;
 
+    // Replace "/./" with "/".  This probably isn't very efficient in
+    // the general case, but it's probably not bad most of the time.
+    while ((index = file.indexOf("/./")) >= 0)
+      file = file.substring(0, index) + file.substring(index + 2);
+
+    // Process "/../" correctly.  This probably isn't very efficient in
+    // the general case, but it's probably not bad most of the time.
+    while ((index = file.indexOf("/../")) >= 0)
+      {
+       // Strip of the previous directory - if it exists.
+       int previous = file.lastIndexOf('/', index - 1);
+       if (previous >= 0)
+         file = file.substring(0, previous) + file.substring(index + 3);
+       else
+         file = file.substring(index + 3);
+      }
+    
     u.set(u.getProtocol(), host, port, file, u.getRef());
   }
   
@@ -90,12 +134,17 @@ public abstract class URLStreamHandler
     file = u.getFile();
     ref = u.getRef();
 
-    if (! host.equals(""))
-      {
-        resStr = resStr + "//" + host;
-       if (port >= 0)
-         resStr = resStr + ":" + port;
-      }
+    // JDK 1.2 online doc infers that host could be null because it
+    // explicitly states that file cannot be null, but is silent on host.
+    //
+    // Note that this produces different results from JDK 1.2 as JDK 1.2
+    // ignores a non-default port if host is null or "".  That is inconsistent
+    // with the spec since the result of this method is spec'ed so it can be
+    // used to construct a new URL that is equivalent to the original.
+    if (host == null)
+      host = "";
+    if (port >= 0 || ! (host.length() == 0))
+      resStr = resStr + "//" + host + (port < 0 ? "" : ":" + port);
 
     resStr = resStr + file;