1 7 8 package java.io; 9 10 import java.security.AccessController ; 11 import sun.security.action.GetPropertyAction; 12 13 14 class Win32FileSystem extends FileSystem { 15 16 private final char slash; 17 private final char altSlash; 18 private final char semicolon; 19 20 public Win32FileSystem() { 21 slash = ((String ) AccessController.doPrivileged( 22 new GetPropertyAction("file.separator"))).charAt(0); 23 semicolon = ((String ) AccessController.doPrivileged( 24 new GetPropertyAction("path.separator"))).charAt(0); 25 altSlash = (this.slash == '\\') ? '/' : '\\'; 26 } 27 28 private boolean isSlash(char c) { 29 return (c == '\\') || (c == '/'); 30 } 31 32 private boolean isLetter(char c) { 33 return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); 34 } 35 36 private String slashify(String p) { 37 if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p; 38 else return p; 39 } 40 41 42 43 44 public char getSeparator() { 45 return slash; 46 } 47 48 public char getPathSeparator() { 49 return semicolon; 50 } 51 52 64 65 private int normalizePrefix(String path, int len, StringBuffer sb) { 66 int src = 0; 67 while ((src < len) && isSlash(path.charAt(src))) src++; 68 char c; 69 if ((len - src >= 2) 70 && isLetter(c = path.charAt(src)) 71 && path.charAt(src + 1) == ':') { 72 76 sb.append(c); 77 sb.append(':'); 78 src += 2; 79 } else { 80 src = 0; 81 if ((len >= 2) 82 && isSlash(path.charAt(0)) 83 && isSlash(path.charAt(1))) { 84 89 src = 1; 90 sb.append(slash); 91 } 92 } 93 return src; 94 } 95 96 98 private String normalize(String path, int len, int off) { 99 if (len == 0) return path; 100 if (off < 3) off = 0; 101 int src; 102 char slash = this.slash; 103 StringBuffer sb = new StringBuffer (len); 104 105 if (off == 0) { 106 107 src = normalizePrefix(path, len, sb); 108 } else { 109 110 src = off; 111 sb.append(path.substring(0, off)); 112 } 113 114 116 while (src < len) { 117 char c = path.charAt(src++); 118 if (isSlash(c)) { 119 while ((src < len) && isSlash(path.charAt(src))) src++; 120 if (src == len) { 121 122 int sn = sb.length(); 123 if ((sn == 2) && (sb.charAt(1) == ':')) { 124 125 sb.append(slash); 126 break; 127 } 128 if (sn == 0) { 129 130 sb.append(slash); 131 break; 132 } 133 if ((sn == 1) && (isSlash(sb.charAt(0)))) { 134 141 sb.append(slash); 142 break; 143 } 144 146 break; 147 } else { 148 sb.append(slash); 149 } 150 } else { 151 sb.append(c); 152 } 153 } 154 155 String rv = sb.toString(); 156 return rv; 157 } 158 159 162 public String normalize(String path) { 163 int n = path.length(); 164 char slash = this.slash; 165 char altSlash = this.altSlash; 166 char prev = 0; 167 for (int i = 0; i < n; i++) { 168 char c = path.charAt(i); 169 if (c == altSlash) 170 return normalize(path, n, (prev == slash) ? i - 1 : i); 171 if ((c == slash) && (prev == slash) && (i > 1)) 172 return normalize(path, n, i - 1); 173 if ((c == ':') && (i > 1)) 174 return normalize(path, n, 0); 175 prev = c; 176 } 177 if (prev == slash) return normalize(path, n, n - 1); 178 return path; 179 } 180 181 public int prefixLength(String path) { 182 char slash = this.slash; 183 int n = path.length(); 184 if (n == 0) return 0; 185 char c0 = path.charAt(0); 186 char c1 = (n > 1) ? path.charAt(1) : 0; 187 if (c0 == slash) { 188 if (c1 == slash) return 2; 189 return 1; 190 } 191 if (isLetter(c0) && (c1 == ':')) { 192 if ((n > 2) && (path.charAt(2) == slash)) 193 return 3; 194 return 2; 195 } 196 return 0; 197 } 198 199 public String resolve(String parent, String child) { 200 int pn = parent.length(); 201 if (pn == 0) return child; 202 int cn = child.length(); 203 if (cn == 0) return parent; 204 205 String c = child; 206 int childStart = 0; 207 int parentEnd = pn; 208 209 if ((cn > 1) && (c.charAt(0) == slash)) { 210 if (c.charAt(1) == slash) { 211 212 childStart = 2; 213 } else { 214 215 childStart = 1; 216 217 } 218 if (cn == childStart) { if (parent.charAt(pn - 1) == slash) 220 return parent.substring(0, pn - 1); 221 return parent; 222 } 223 } 224 225 if (parent.charAt(pn - 1) == slash) 226 parentEnd--; 227 228 int strlen = parentEnd + cn - childStart; 229 char[] theChars = null; 230 if (child.charAt(childStart) == slash) { 231 theChars = new char[strlen]; 232 parent.getChars(0, parentEnd, theChars, 0); 233 child.getChars(childStart, cn, theChars, parentEnd); 234 } else { 235 theChars = new char[strlen + 1]; 236 parent.getChars(0, parentEnd, theChars, 0); 237 theChars[parentEnd] = slash; 238 child.getChars(childStart, cn, theChars, parentEnd + 1); 239 } 240 return new String (theChars); 241 } 242 243 public String getDefaultParent() { 244 return ("" + slash); 245 } 246 247 public String fromURIPath(String path) { 248 String p = path; 249 if ((p.length() > 2) && (p.charAt(2) == ':')) { 250 p = p.substring(1); 252 if ((p.length() > 3) && p.endsWith("/")) 254 p = p.substring(0, p.length() - 1); 255 } else if ((p.length() > 1) && p.endsWith("/")) { 256 p = p.substring(0, p.length() - 1); 258 } 259 return p; 260 } 261 262 263 264 265 266 public boolean isAbsolute(File f) { 267 int pl = f.getPrefixLength(); 268 return (((pl == 2) && (f.getPath().charAt(0) == slash)) 269 || (pl == 3)); 270 } 271 272 protected native String getDriveDirectory(int drive); 273 274 private static String [] driveDirCache = new String [26]; 275 276 private static int driveIndex(char d) { 277 if ((d >= 'a') && (d <= 'z')) return d - 'a'; 278 if ((d >= 'A') && (d <= 'Z')) return d - 'A'; 279 return -1; 280 } 281 282 private String getDriveDirectory(char drive) { 283 int i = driveIndex(drive); 284 if (i < 0) return null; 285 String s = driveDirCache[i]; 286 if (s != null) return s; 287 s = getDriveDirectory(i + 1); 288 driveDirCache[i] = s; 289 return s; 290 } 291 292 private String getUserPath() { 293 295 return normalize(System.getProperty("user.dir")); 296 } 297 298 private String getDrive(String path) { 299 int pl = prefixLength(path); 300 return (pl == 3) ? path.substring(0, 2) : null; 301 } 302 303 public String resolve(File f) { 304 String path = f.getPath(); 305 int pl = f.getPrefixLength(); 306 if ((pl == 2) && (path.charAt(0) == slash)) 307 return path; 308 if (pl == 3) 309 return path; 310 if (pl == 0) 311 return getUserPath() + slashify(path); 312 if (pl == 1) { 313 String up = getUserPath(); 314 String ud = getDrive(up); 315 if (ud != null) return ud + path; 316 return up + path; 317 } 318 if (pl == 2) { 319 String up = getUserPath(); 320 String ud = getDrive(up); 321 if ((ud != null) && path.startsWith(ud)) 322 return up + slashify(path.substring(2)); 323 char drive = path.charAt(0); 324 String dir = getDriveDirectory(drive); 325 String np; 326 if (dir != null) { 327 330 String p = drive + (':' + dir + slashify(path.substring(2))); 331 SecurityManager security = System.getSecurityManager(); 332 try { 333 if (security != null) security.checkRead(p); 334 } catch (SecurityException x) { 335 336 throw new SecurityException ("Cannot resolve path " + path); 337 } 338 return p; 339 } 340 return drive + ":" + slashify(path.substring(2)); 341 } 342 throw new InternalError ("Unresolvable path: " + path); 343 } 344 345 private ExpiringCache cache = new ExpiringCache (); 352 private ExpiringCache prefixCache = new ExpiringCache (); 353 354 public String canonicalize(String path) throws IOException { 355 int len = path.length(); 357 if ((len == 2) && 358 (isLetter(path.charAt(0))) && 359 (path.charAt(1) == ':')) { 360 char c = path.charAt(0); 361 if ((c >= 'A') && (c <= 'Z')) 362 return path; 363 return "" + ((char) (c-32)) + ':'; 364 } else if ((len == 3) && 365 (isLetter(path.charAt(0))) && 366 (path.charAt(1) == ':') && 367 (path.charAt(2) == '\\')) { 368 char c = path.charAt(0); 369 if ((c >= 'A') && (c <= 'Z')) 370 return path; 371 return "" + ((char) (c-32)) + ':' + '\\'; 372 } 373 if (!useCanonCaches) { 374 return canonicalize0(path); 375 } else { 376 String res = cache.get(path); 377 if (res == null) { 378 String dir = null; 379 String resDir = null; 380 if (useCanonPrefixCache) { 381 dir = parentOrNull(path); 382 if (dir != null) { 383 resDir = prefixCache.get(dir); 384 if (resDir != null) { 385 String filename = path.substring(1 + dir.length()); 389 res = canonicalizeWithPrefix(resDir, filename); 390 cache.put(dir + File.separatorChar + filename, res); 391 } 392 } 393 } 394 if (res == null) { 395 res = canonicalize0(path); 396 cache.put(path, res); 397 if (useCanonPrefixCache && dir != null) { 398 resDir = parentOrNull(res); 399 if (resDir != null) { 400 File f = new File (res); 401 if (f.exists() && !f.isDirectory()) { 402 prefixCache.put(dir, resDir); 403 } 404 } 405 } 406 } 407 } 408 assert canonicalize0(path).equalsIgnoreCase(res); 409 return res; 410 } 411 } 412 413 protected native String canonicalize0(String path) 414 throws IOException ; 415 protected String canonicalizeWithPrefix(String canonicalPrefix, 416 String filename) throws IOException  417 { 418 return canonicalizeWithPrefix0(canonicalPrefix, 419 canonicalPrefix + File.separatorChar + filename); 420 } 421 protected native String canonicalizeWithPrefix0(String canonicalPrefix, 425 String pathWithCanonicalPrefix) 426 throws IOException ; 427 static String parentOrNull(String path) { 435 if (path == null) return null; 436 char sep = File.separatorChar; 437 char altSep = '/'; 438 int last = path.length() - 1; 439 int idx = last; 440 int adjacentDots = 0; 441 int nonDotCount = 0; 442 while (idx > 0) { 443 char c = path.charAt(idx); 444 if (c == '.') { 445 if (++adjacentDots >= 2) { 446 return null; 448 } 449 if (nonDotCount == 0) { 450 return null; 452 } 453 } else if (c == sep) { 454 if (adjacentDots == 1 && nonDotCount == 0) { 455 return null; 457 } 458 if (idx == 0 || 459 idx >= last - 1 || 460 path.charAt(idx - 1) == sep || 461 path.charAt(idx - 1) == altSep) { 462 return null; 465 } 466 return path.substring(0, idx); 467 } else if (c == altSep) { 468 return null; 471 } else if (c == '*' || c == '?') { 472 return null; 474 } else { 475 ++nonDotCount; 476 adjacentDots = 0; 477 } 478 --idx; 479 } 480 return null; 481 } 482 483 484 485 486 public native int getBooleanAttributes(File f); 487 public native boolean checkAccess(File f, boolean write); 488 public native long getLastModifiedTime(File f); 489 public native long getLength(File f); 490 491 492 493 494 public native boolean createFileExclusively(String path) 495 throws IOException ; 496 public boolean delete(File f) { 497 cache.clear(); 503 prefixCache.clear(); 504 return delete0(f); 505 } 506 protected native boolean delete0(File f); 507 public synchronized native boolean deleteOnExit(File f); 508 public native String [] list(File f); 509 public native boolean createDirectory(File f); 510 public boolean rename(File f1, File f2) { 511 cache.clear(); 517 prefixCache.clear(); 518 return rename0(f1, f2); 519 } 520 protected native boolean rename0(File f1, File f2); 521 public native boolean setLastModifiedTime(File f, long time); 522 public native boolean setReadOnly(File f); 523 524 525 526 527 private boolean access(String path) { 528 try { 529 SecurityManager security = System.getSecurityManager(); 530 if (security != null) security.checkRead(path); 531 return true; 532 } catch (SecurityException x) { 533 return false; 534 } 535 } 536 537 private static native int listRoots0(); 538 539 public File [] listRoots() { 540 int ds = listRoots0(); 541 int n = 0; 542 for (int i = 0; i < 26; i++) { 543 if (((ds >> i) & 1) != 0) { 544 if (!access((char)('A' + i) + ":" + slash)) 545 ds &= ~(1 << i); 546 else 547 n++; 548 } 549 } 550 File [] fs = new File [n]; 551 int j = 0; 552 char slash = this.slash; 553 for (int i = 0; i < 26; i++) { 554 if (((ds >> i) & 1) != 0) 555 fs[j++] = new File ((char)('A' + i) + ":" + slash); 556 } 557 return fs; 558 } 559 560 561 562 563 public int compare(File f1, File f2) { 564 return f1.getPath().compareToIgnoreCase(f2.getPath()); 565 } 566 567 public int hashCode(File f) { 568 569 return f.getPath().toLowerCase().hashCode() ^ 1234321; 570 } 571 572 573 private static native void initIDs(); 574 575 static { 576 initIDs(); 577 } 578 579 } 580
| Popular Tags
|