OSDN Git Service

2003-03-01 Ranjit Mathew <rmathew@hotmail.com>
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Mar 2003 00:36:03 +0000 (00:36 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Mar 2003 00:36:03 +0000 (00:36 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63646 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/java/io/File.java
libjava/java/io/natFileWin32.cc

index 5af34bf..25ee6f4 100644 (file)
@@ -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.
index 367fd44..0f11bce 100644 (file)
@@ -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));
index 9029881..af12f5b 100644 (file)
@@ -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;
+}