src/solaris/classes/sun/nio/fs/UnixPath.java

Print this page




  51 
  52     // internal representation
  53     private final byte[] path;
  54 
  55     // String representation (created lazily)
  56     private volatile String stringValue;
  57 
  58     // cached hashcode (created lazily, no need to be volatile)
  59     private int hash;
  60 
  61     // array of offsets of elements in path (created lazily)
  62     private volatile int[] offsets;
  63 
  64     UnixPath(UnixFileSystem fs, byte[] path) {
  65         this.fs = fs;
  66         this.path = path;
  67     }
  68 
  69     UnixPath(UnixFileSystem fs, String input) {
  70         // removes redundant slashes and checks for invalid characters
  71         this(fs, encode(normalizeAndCheck(input)));
  72     }
  73 
  74     // package-private
  75     // removes redundant slashes and check input for invalid characters
  76     static String normalizeAndCheck(String input) {
  77         int n = input.length();
  78         char prevChar = 0;
  79         for (int i=0; i < n; i++) {
  80             char c = input.charAt(i);
  81             if ((c == '/') && (prevChar == '/'))
  82                 return normalize(input, n, i - 1);
  83             checkNotNul(input, c);
  84             prevChar = c;
  85         }
  86         if (prevChar == '/')
  87             return normalize(input, n, n - 1);
  88         return input;
  89     }
  90 
  91     private static void checkNotNul(String input, char c) {


  99         int n = len;
 100         while ((n > 0) && (input.charAt(n - 1) == '/')) n--;
 101         if (n == 0)
 102             return "/";
 103         StringBuilder sb = new StringBuilder(input.length());
 104         if (off > 0)
 105             sb.append(input.substring(0, off));
 106         char prevChar = 0;
 107         for (int i=off; i < n; i++) {
 108             char c = input.charAt(i);
 109             if ((c == '/') && (prevChar == '/'))
 110                 continue;
 111             checkNotNul(input, c);
 112             sb.append(c);
 113             prevChar = c;
 114         }
 115         return sb.toString();
 116     }
 117 
 118     // encodes the given path-string into a sequence of bytes
 119     private static byte[] encode(String input) {
 120         SoftReference<CharsetEncoder> ref = encoder.get();
 121         CharsetEncoder ce = (ref != null) ? ref.get() : null;
 122         if (ce == null) {
 123             ce = Charset.defaultCharset().newEncoder()
 124                 .onMalformedInput(CodingErrorAction.REPORT)
 125                 .onUnmappableCharacter(CodingErrorAction.REPORT);
 126             encoder.set(new SoftReference<CharsetEncoder>(ce));
 127         }
 128 
 129         char[] ca = input.toCharArray();
 130 
 131         // size output buffer for worse-case size
 132         byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
 133 
 134         // encode
 135         ByteBuffer bb = ByteBuffer.wrap(ba);
 136         CharBuffer cb = CharBuffer.wrap(ca);
 137         ce.reset();
 138         CoderResult cr = ce.encode(cb, bb, true);
 139         boolean error;
 140         if (!cr.isUnderflow()) {
 141             error = true;
 142         } else {
 143             cr = ce.flush(bb);
 144             error = !cr.isUnderflow();
 145         }
 146         if (error) {
 147             throw new InvalidPathException(input,
 148                 "Malformed input or input contains unmappable chacraters");
 149         }


 740         }
 741         return false;
 742     }
 743 
 744     @Override
 745     public int hashCode() {
 746         // OK if two or more threads compute hash
 747         int h = hash;
 748         if (h == 0) {
 749             for (int i = 0; i< path.length; i++) {
 750                 h = 31*h + (path[i] & 0xff);
 751             }
 752             hash = h;
 753         }
 754         return h;
 755     }
 756 
 757     @Override
 758     public String toString() {
 759         // OK if two or more threads create a String
 760         if (stringValue == null)
 761             stringValue = new String(path);     // platform encoding

 762         return stringValue;
 763     }
 764 
 765     // -- file operations --
 766 
 767     // package-private
 768     int openForAttributeAccess(boolean followLinks) throws IOException {
 769         int flags = O_RDONLY;
 770         if (!followLinks) {
 771             if (!supportsNoFollowLinks())
 772                 throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
 773             flags |= O_NOFOLLOW;
 774         }
 775         try {
 776             return open(this, flags, 0);
 777         } catch (UnixException x) {
 778             // HACK: EINVAL instead of ELOOP on Solaris 10 prior to u4 (see 6460380)
 779             if (getFileSystem().isSolaris() && x.errno() == EINVAL)
 780                 x.setError(ELOOP);
 781 




  51 
  52     // internal representation
  53     private final byte[] path;
  54 
  55     // String representation (created lazily)
  56     private volatile String stringValue;
  57 
  58     // cached hashcode (created lazily, no need to be volatile)
  59     private int hash;
  60 
  61     // array of offsets of elements in path (created lazily)
  62     private volatile int[] offsets;
  63 
  64     UnixPath(UnixFileSystem fs, byte[] path) {
  65         this.fs = fs;
  66         this.path = path;
  67     }
  68 
  69     UnixPath(UnixFileSystem fs, String input) {
  70         // removes redundant slashes and checks for invalid characters
  71         this(fs, encode(fs, normalizeAndCheck(input)));
  72     }
  73 
  74     // package-private
  75     // removes redundant slashes and check input for invalid characters
  76     static String normalizeAndCheck(String input) {
  77         int n = input.length();
  78         char prevChar = 0;
  79         for (int i=0; i < n; i++) {
  80             char c = input.charAt(i);
  81             if ((c == '/') && (prevChar == '/'))
  82                 return normalize(input, n, i - 1);
  83             checkNotNul(input, c);
  84             prevChar = c;
  85         }
  86         if (prevChar == '/')
  87             return normalize(input, n, n - 1);
  88         return input;
  89     }
  90 
  91     private static void checkNotNul(String input, char c) {


  99         int n = len;
 100         while ((n > 0) && (input.charAt(n - 1) == '/')) n--;
 101         if (n == 0)
 102             return "/";
 103         StringBuilder sb = new StringBuilder(input.length());
 104         if (off > 0)
 105             sb.append(input.substring(0, off));
 106         char prevChar = 0;
 107         for (int i=off; i < n; i++) {
 108             char c = input.charAt(i);
 109             if ((c == '/') && (prevChar == '/'))
 110                 continue;
 111             checkNotNul(input, c);
 112             sb.append(c);
 113             prevChar = c;
 114         }
 115         return sb.toString();
 116     }
 117 
 118     // encodes the given path-string into a sequence of bytes
 119     private static byte[] encode(UnixFileSystem fs, String input) {
 120         SoftReference<CharsetEncoder> ref = encoder.get();
 121         CharsetEncoder ce = (ref != null) ? ref.get() : null;
 122         if (ce == null) {
 123             ce = Charset.defaultCharset().newEncoder()
 124                 .onMalformedInput(CodingErrorAction.REPORT)
 125                 .onUnmappableCharacter(CodingErrorAction.REPORT);
 126             encoder.set(new SoftReference<CharsetEncoder>(ce));
 127         }
 128 
 129         char[] ca = fs.normalizeNativePath(input.toCharArray());
 130 
 131         // size output buffer for worse-case size
 132         byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
 133 
 134         // encode
 135         ByteBuffer bb = ByteBuffer.wrap(ba);
 136         CharBuffer cb = CharBuffer.wrap(ca);
 137         ce.reset();
 138         CoderResult cr = ce.encode(cb, bb, true);
 139         boolean error;
 140         if (!cr.isUnderflow()) {
 141             error = true;
 142         } else {
 143             cr = ce.flush(bb);
 144             error = !cr.isUnderflow();
 145         }
 146         if (error) {
 147             throw new InvalidPathException(input,
 148                 "Malformed input or input contains unmappable chacraters");
 149         }


 740         }
 741         return false;
 742     }
 743 
 744     @Override
 745     public int hashCode() {
 746         // OK if two or more threads compute hash
 747         int h = hash;
 748         if (h == 0) {
 749             for (int i = 0; i< path.length; i++) {
 750                 h = 31*h + (path[i] & 0xff);
 751             }
 752             hash = h;
 753         }
 754         return h;
 755     }
 756 
 757     @Override
 758     public String toString() {
 759         // OK if two or more threads create a String
 760         if (stringValue == null) {
 761             stringValue = fs.normalizeJavaPath(new String(path));     // platform encoding
 762         }
 763         return stringValue;
 764     }
 765 
 766     // -- file operations --
 767 
 768     // package-private
 769     int openForAttributeAccess(boolean followLinks) throws IOException {
 770         int flags = O_RDONLY;
 771         if (!followLinks) {
 772             if (!supportsNoFollowLinks())
 773                 throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
 774             flags |= O_NOFOLLOW;
 775         }
 776         try {
 777             return open(this, flags, 0);
 778         } catch (UnixException x) {
 779             // HACK: EINVAL instead of ELOOP on Solaris 10 prior to u4 (see 6460380)
 780             if (getFileSystem().isSolaris() && x.errno() == EINVAL)
 781                 x.setError(ELOOP);
 782