aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorRanjit Mathew <rmathew@hotmail.com>2003-03-02 00:36:03 +0000
committerTom Tromey <tromey@gcc.gnu.org>2003-03-02 00:36:03 +0000
commit3ccd3d704112889a79a0ccdcfc51bfcc55019827 (patch)
tree01d9125b79e1f1a6ddae6430cffd78841636a6e2 /libjava
parentd457094cc1695409b74aa40a7d095d39dfcf943e (diff)
downloadgcc-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')
-rw-r--r--libjava/ChangeLog16
-rw-r--r--libjava/java/io/File.java22
-rw-r--r--libjava/java/io/natFileWin32.cc152
3 files changed, 170 insertions, 20 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 5af34bf..25ee6f4 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,19 @@
+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.
+
2003-03-01 Tom Tromey <tromey@redhat.com>
* java/lang/natObject.cc: Don't include assert.h.
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;
+}