diff options
author | Ranjit Mathew <rmathew@hotmail.com> | 2003-03-02 00:36:03 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2003-03-02 00:36:03 +0000 |
commit | 3ccd3d704112889a79a0ccdcfc51bfcc55019827 (patch) | |
tree | 01d9125b79e1f1a6ddae6430cffd78841636a6e2 /libjava/java/io | |
parent | d457094cc1695409b74aa40a7d095d39dfcf943e (diff) | |
download | gcc-3ccd3d704112889a79a0ccdcfc51bfcc55019827.zip gcc-3ccd3d704112889a79a0ccdcfc51bfcc55019827.tar.gz gcc-3ccd3d704112889a79a0ccdcfc51bfcc55019827.tar.bz2 |
File.java (normalizePath): Remove trailing separator on Windows only if path is not of the form "x:\".
2003-03-01 Ranjit Mathew <rmathew@hotmail.com>
* java/io/File.java (normalizePath): Remove trailing separator
on Windows only if path is not of the form "x:\".
* java/io/natFileWin32.cc (WIN32_EPOCH_MILLIS): New constant.
(java::io::File::attr): Change formatting a bit and use
WIN32_EPOCH_MILLIS instead of magic numbers.
(java::io::File::isAbsolute): Path must have at least 3
characters for a UNC network path.
(java::io::File::init_native): Define.
(java::io::File::performCreate): Likewise.
(java::io::File::performSetReadOnly): Likewise.
(java::io::File::performSetLastModified): Likewise.
(java::io::File::performListRoots): Likewise.
From-SVN: r63646
Diffstat (limited to 'libjava/java/io')
-rw-r--r-- | libjava/java/io/File.java | 22 | ||||
-rw-r--r-- | libjava/java/io/natFileWin32.cc | 152 |
2 files changed, 154 insertions, 20 deletions
diff --git a/libjava/java/io/File.java b/libjava/java/io/File.java index 367fd44..0f11bce 100644 --- a/libjava/java/io/File.java +++ b/libjava/java/io/File.java @@ -96,9 +96,13 @@ public class File implements Serializable, Comparable if (dupIndex == -1) { - // Ignore trailing separator. - if (plen > 1 && p.charAt(plen - 1) == separatorChar) - return p.substring(0, plen - 1); + // Ignore trailing separator (though on Windows "a:\", for + // example, is a valid and minimal path). + if (plen > 1 && p.charAt (plen - 1) == separatorChar) + { + if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')) + return p.substring (0, plen - 1); + } else return p; } @@ -120,10 +124,16 @@ public class File implements Serializable, Comparable dupIndex = p.indexOf(dupSeparator, last); } - // Again, ignore possible trailing separator. + // Again, ignore possible trailing separator (except special cases + // like "a:\" on Windows). int end; - if (plen > 1 && p.charAt(plen - 1) == separatorChar) - end = plen - 1; + if (plen > 1 && p.charAt (plen - 1) == separatorChar) + { + if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':') + end = plen; + else + end = plen - 1; + } else end = plen; newpath.append(p.substring(last, end)); diff --git a/libjava/java/io/natFileWin32.cc b/libjava/java/io/natFileWin32.cc index 9029881..af12f5b 100644 --- a/libjava/java/io/natFileWin32.cc +++ b/libjava/java/io/natFileWin32.cc @@ -26,6 +26,19 @@ details. */ #include <java/io/FileFilter.h> #include <java/lang/System.h> +// Java timestamps are milliseconds since the UNIX epoch (00:00:00 UTC on +// January 1, 1970) while Win32 file-times are 100-nanosecond intervals +// since the Win32 epoch (00:00:00 UTC on January 1, 1601). The following +// constant represents the number of milliseconds to be added to a +// Java timestamp to base it on the Win32 epoch. +// +// There were 369 years between 1601 and 1970, including 89 leap years +// (since 1700, 1800 and 1900 were not leap years): +// +// (89*366 + 280*365) days * 86400 seconds/day = 11644473600 seconds +// +#define WIN32_EPOCH_MILLIS 11644473600000LL + jboolean java::io::File::_access (jint query) { @@ -91,12 +104,16 @@ java::io::File::attr (jint query) FindClose( sHandle); if (query == LENGTH) - return ((long long)info.nFileSizeHigh) << 32 | (unsigned long long)info.nFileSizeLow; - else { - // FIXME? This is somewhat compiler dependant (the LL constant suffix) - // The file time as return by windows is the number of 100-nanosecond intervals since January 1, 1601 - return (((((long long)info.ftLastWriteTime.dwHighDateTime) << 32) | ((unsigned long long)info.ftLastWriteTime.dwLowDateTime)) - 116444736000000000LL) / 10000LL; - } + return ((long long)info.nFileSizeHigh) << 32 + | (unsigned long long)info.nFileSizeLow; + else + { + // The file time as returned by Windows is in terms of the number + // of 100-nanosecond intervals since 00:00:00 UTC, January 1, 1601. + return (((((long long)info.ftLastWriteTime.dwHighDateTime) << 32) + | ((unsigned long long)info.ftLastWriteTime.dwLowDateTime)) + - WIN32_EPOCH_MILLIS*10000LL) / 10000LL; + } } jstring @@ -120,7 +137,7 @@ jboolean java::io::File::isAbsolute (void) { // See if the path represents a Windows UNC network path. - if (path->length () > 1 + if (path->length () > 2 && (path->charAt (0) == '\\') && (path->charAt (1) == '\\')) return true; @@ -138,8 +155,11 @@ java::io::File::isAbsolute (void) && (path->charAt(2) == '/' || path->charAt(2) == '\\')); } -void java::io::File::init_native() { } - +void java::io::File::init_native () +{ + maxPathLen = MAX_PATH; + caseSensitive = false; +} jobjectArray java::io::File::performList (java::io::FilenameFilter *filter, @@ -194,7 +214,6 @@ java::io::File::performList (java::io::FilenameFilter *filter, return ret; } - jboolean java::io::File::performMkdir (void) { @@ -237,7 +256,112 @@ java::io::File::performDelete () return (DeleteFile (buf)) ? true : false; } -jboolean java::io::File::performCreate (void) { JvFail("unimplemented\n"); } -jboolean java::io::File::performSetReadOnly() { JvFail("unimplemented"); } -jboolean java::io::File::performSetLastModified(jlong time) { JvFail("unimplemented"); } -JArray<java::io::File*>* java::io::File::performListRoots() { JvFail("unimplemented"); } +jboolean java::io::File::performCreate (void) +{ + jstring canon = getCanonicalPath (); + char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); + jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); + buf[total] = '\0'; + + HANDLE h = CreateFile (buf, 0, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL); + if (h != INVALID_HANDLE_VALUE) + { + CloseHandle (h); + return true; + } + else + { + if (GetLastError () == ERROR_ALREADY_EXISTS) + return false; + else + throw new IOException (JvNewStringLatin1 ("CreateFile failed")); + } +} + +jboolean java::io::File::performSetReadOnly () +{ + jstring canon = getCanonicalPath (); + char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); + jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); + buf[total] = '\0'; + + DWORD attrs = GetFileAttributes (buf); + if (attrs != INVALID_FILE_ATTRIBUTES) + { + if (SetFileAttributes (buf, attrs | FILE_ATTRIBUTE_READONLY) != 0) + return true; + else + return false; + } + else + return false; +} + +jboolean java::io::File::performSetLastModified (jlong time) +{ + jstring canon = getCanonicalPath (); + char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); + jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); + buf[total] = '\0'; + + FILETIME modTime; + long long mTime100ns = ((long long) time /* Ha! */ + + WIN32_EPOCH_MILLIS) * 10000LL; + + modTime.dwLowDateTime = (DWORD) mTime100ns; + modTime.dwHighDateTime = (DWORD) (mTime100ns >> 32); + + jboolean retVal = false; + HANDLE h = CreateFile (buf, FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + + if (h != INVALID_HANDLE_VALUE) + { + if (SetFileTime (h, NULL, &modTime, &modTime) != 0) + retVal = true; + + CloseHandle (h); + } + + return retVal; +} + +JArray<java::io::File*>* java::io::File::performListRoots () +{ + DWORD drivesBitmap = GetLogicalDrives (); + DWORD mask; + + // Possible drive letters are from ASCII 'A'-'Z'. + int numDrives = 0; + mask = 1; + for (int i = 0; i < 26; i++) + { + if ((drivesBitmap & mask) != 0) + numDrives++; + mask <<= 1; + } + + JArray<java::io::File *> *roots + = reinterpret_cast <JArray<java::io::File *>*> + (JvNewObjectArray (numDrives, &java::io::File::class$, NULL)); + + ::java::io::File **rootsArray = elements (roots); + + char aDriveRoot[] = {'A', ':', '\\', '\0'}; + mask = 1; + for (int i = 0, j = 0; i < 26; i++) + { + if ((drivesBitmap & mask) != 0) + { + rootsArray[j] + = new ::java::io::File (JvNewStringLatin1 (aDriveRoot)); + j++; + } + mask <<= 1; + aDriveRoot[0]++; + } + + return roots; +} |