jdk/src/java.base/share/classes/sun/net/www/ParseUtil.java
changeset 42992 c692f1d73e14
parent 32649 2ee9017c7597
child 47024 5bfe7700a8f7
equal deleted inserted replaced
42991:174ff3aebaf7 42992:c692f1d73e14
    24  */
    24  */
    25 
    25 
    26 package sun.net.www;
    26 package sun.net.www;
    27 
    27 
    28 import java.util.BitSet;
    28 import java.util.BitSet;
    29 import java.io.UnsupportedEncodingException;
       
    30 import java.io.File;
    29 import java.io.File;
    31 import java.net.URL;
    30 import java.net.URL;
    32 import java.net.MalformedURLException;
    31 import java.net.MalformedURLException;
    33 import java.net.URI;
    32 import java.net.URI;
    34 import java.net.URISyntaxException;
    33 import java.net.URISyntaxException;
    47 
    46 
    48 public class ParseUtil {
    47 public class ParseUtil {
    49     static BitSet encodedInPath;
    48     static BitSet encodedInPath;
    50 
    49 
    51     static {
    50     static {
    52         encodedInPath = new BitSet(256);
    51         encodedInPath = new BitSet(128);
    53 
    52 
    54         // Set the bits corresponding to characters that are encoded in the
    53         // Set the bits corresponding to characters that are encoded in the
    55         // path component of a URI.
    54         // path component of a URI.
    56 
    55 
    57         // These characters are reserved in the path segment as described in
    56         // These characters are reserved in the path segment as described in
   100      * flag indicates whether path uses platform dependent
    99      * flag indicates whether path uses platform dependent
   101      * File.separatorChar or not. True indicates path uses platform
   100      * File.separatorChar or not. True indicates path uses platform
   102      * dependent File.separatorChar.
   101      * dependent File.separatorChar.
   103      */
   102      */
   104     public static String encodePath(String path, boolean flag) {
   103     public static String encodePath(String path, boolean flag) {
   105         char[] retCC = new char[path.length() * 2 + 16];
   104         if (flag && File.separatorChar != '/') {
   106         int    retLen = 0;
   105             return encodePath(path, 0, File.separatorChar);
       
   106         } else {
       
   107             int index = firstEncodeIndex(path);
       
   108             if (index > -1) {
       
   109                 return encodePath(path, index, '/');
       
   110             } else {
       
   111                 return path;
       
   112             }
       
   113         }
       
   114     }
       
   115 
       
   116     private static int firstEncodeIndex(String path) {
       
   117         int len = path.length();
       
   118         for (int i = 0; i < len; i++) {
       
   119             char c = path.charAt(i);
       
   120             if (c == '/' || c == '.' ||
       
   121                     c >= 'a' && c <= 'z' ||
       
   122                     c >= 'A' && c <= 'Z' ||
       
   123                     c >= '0' && c <= '9') {
       
   124                 continue;
       
   125             } else if (c > 0x007F || encodedInPath.get(c)) {
       
   126                 return i;
       
   127             }
       
   128         }
       
   129         return -1;
       
   130     }
       
   131 
       
   132     private static String encodePath(String path, int index, char sep) {
   107         char[] pathCC = path.toCharArray();
   133         char[] pathCC = path.toCharArray();
   108 
   134         char[] retCC = new char[pathCC.length * 2 + 16 - index];
   109         int n = path.length();
   135         if (index > 0) {
   110         for (int i=0; i<n; i++) {
   136             System.arraycopy(pathCC, 0, retCC, 0, index);
       
   137         }
       
   138         int retLen = index;
       
   139 
       
   140         for (int i = index; i < pathCC.length; i++) {
   111             char c = pathCC[i];
   141             char c = pathCC[i];
   112             if ((!flag && c == '/') || (flag && c == File.separatorChar))
   142             if (c == sep)
   113                 retCC[retLen++] = '/';
   143                 retCC[retLen++] = '/';
   114             else {
   144             else {
   115                 if (c <= 0x007F) {
   145                 if (c <= 0x007F) {
   116                     if (c >= 'a' && c <= 'z' ||
   146                     if (c >= 'a' && c <= 'z' ||
   117                         c >= 'A' && c <= 'Z' ||
   147                         c >= 'A' && c <= 'Z' ||
   118                         c >= '0' && c <= '9') {
   148                         c >= '0' && c <= '9') {
   119                         retCC[retLen++] = c;
   149                         retCC[retLen++] = c;
   120                     } else
   150                     } else if (encodedInPath.get(c)) {
   121                     if (encodedInPath.get(c))
       
   122                         retLen = escape(retCC, c, retLen);
   151                         retLen = escape(retCC, c, retLen);
   123                     else
   152                     } else {
   124                         retCC[retLen++] = c;
   153                         retCC[retLen++] = c;
       
   154                     }
   125                 } else if (c > 0x07FF) {
   155                 } else if (c > 0x07FF) {
   126                     retLen = escape(retCC, (char)(0xE0 | ((c >> 12) & 0x0F)), retLen);
   156                     retLen = escape(retCC, (char)(0xE0 | ((c >> 12) & 0x0F)), retLen);
   127                     retLen = escape(retCC, (char)(0x80 | ((c >>  6) & 0x3F)), retLen);
   157                     retLen = escape(retCC, (char)(0x80 | ((c >>  6) & 0x3F)), retLen);
   128                     retLen = escape(retCC, (char)(0x80 | ((c >>  0) & 0x3F)), retLen);
   158                     retLen = escape(retCC, (char)(0x80 | ((c >>  0) & 0x3F)), retLen);
   129                 } else {
   159                 } else {