You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by py...@apache.org on 2007/04/26 11:43:50 UTC

svn commit: r532683 - in /harmony/enhanced/classlib/trunk/modules: luni/src/main/java/java/io/ luni/src/main/java/org/apache/harmony/luni/util/ luni/src/test/java/tests/api/java/io/ portlib/src/main/native/port/windows/

Author: pyang
Date: Thu Apr 26 02:43:49 2007
New Revision: 532683

URL: http://svn.apache.org/viewvc?view=rev&rev=532683
Log:
Apply patch for HARMONY-3656([classlib][luni] File.mkdir does not support unicode)

Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/io/FileTest.java
    harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java?view=diff&rev=532683&r1=532682&r2=532683
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java Thu Apr 26 02:43:49 2007
@@ -394,7 +394,7 @@
             security.checkDelete(path);
         }
 
-        DeleteOnExit.addFile(Util.toString(properPath(true)));
+        DeleteOnExit.addFile(Util.toUTF8String(properPath(true)));
     }
 
     /**
@@ -450,7 +450,7 @@
      */
     public String getAbsolutePath() {
         byte[] absolute = properPath(false);
-        return Util.toString(absolute);
+        return Util.toUTF8String(absolute);
     }
 
     /**
@@ -575,7 +575,7 @@
         newResult[newLength] = 0;
         newResult = getCanonImpl(newResult);
         newLength = newResult.length;
-        return Util.toString(newResult, 0, newLength);
+        return Util.toUTF8String(newResult, 0, newLength);
     }
 
     /**
@@ -1175,7 +1175,7 @@
         if (properPath != null) {
             return properPath;
         }
-        byte[] pathBytes = Util.getBytes(path);
+        byte[] pathBytes = Util.getUTF8Bytes(path);
         if (isAbsoluteImpl(pathBytes)) {
             return properPath = pathBytes;
         }
@@ -1191,23 +1191,32 @@
             return properPath;
         }
         if (path.length() == 0) {
-            return properPath = Util.getBytes(userdir);
+            return properPath = Util.getUTF8Bytes(userdir);
         }
         int length = userdir.length();
+        
+        // Handle windows-like path
         if (path.charAt(0) == '\\') {
             if (length > 1 && userdir.charAt(1) == ':') {
-                return properPath = Util.getBytes(userdir.substring(0, 2)
+                return properPath = Util.getUTF8Bytes(userdir.substring(0, 2)
                         + path);
+            } else {
+                path = path.substring(1);
             }
-            if (length > 0 && userdir.charAt(length - 1) == separatorChar) {
-                return properPath = Util.getBytes(userdir + path.substring(1));
-            }
-            return properPath = Util.getBytes(userdir + path);
         }
-        if (length > 0 && userdir.charAt(length - 1) == separatorChar) {
-            return properPath = Util.getBytes(userdir + path);
+        
+        // Handle separator
+        String result  = userdir;
+        if (userdir.charAt(length - 1) != separatorChar) {
+            if (path.charAt(0) != separatorChar) {
+                result += separator;
+            }
+        } else if (path.charAt(0) == separatorChar) {
+            result = result.substring(0, length - 2);
+
         }
-        return properPath = Util.getBytes(userdir + separator + path);
+        result += path;
+        return properPath = Util.getUTF8Bytes(result);        
     }
 
     private static native byte[] properPathImpl(byte[] path);

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java?view=diff&rev=532683&r1=532682&r2=532683
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Util.java Thu Apr 26 02:43:49 2007
@@ -55,6 +55,22 @@
 		}
 		return name.getBytes();
 	}
+    
+    /**
+     * Get bytes from String with specific encoding
+     * @param name
+     *          input String
+     * @param encoding
+     *          specific encoding
+     * @return byte array
+     */
+    public static byte[] getUTF8Bytes(String name) {
+        try {
+            return name.getBytes("UTF-8");
+        } catch (java.io.UnsupportedEncodingException e) {
+            return getBytes(name);
+        }
+    }
 
 	public static String toString(byte[] bytes) {
 		if (defaultEncoding != null) {
@@ -66,6 +82,10 @@
 		return new String(bytes, 0, bytes.length);
 	}
 
+    public static String toUTF8String(byte[] bytes) {
+        return toUTF8String(bytes, 0, bytes.length);
+    }    
+    
 	public static String toString(byte[] bytes, int offset, int length) {
 		if (defaultEncoding != null) {
 			try {
@@ -76,6 +96,14 @@
 		return new String(bytes, offset, length);
 	}
 
+    public static String toUTF8String(byte[] bytes, int offset, int length) {
+        try {
+            return new String(bytes, offset, length, "UTF-8");
+        } catch (java.io.UnsupportedEncodingException e) {
+            return toString(bytes, offset, length);
+        }
+    }
+    
 	/**
 	 * Answers the millisecond value of the date and time parsed from the
 	 * specified String. Many date/time formats are recognized

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/io/FileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/io/FileTest.java?view=diff&rev=532683&r1=532682&r2=532683
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/io/FileTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/io/FileTest.java Thu Apr 26 02:43:49 2007
@@ -1812,6 +1812,7 @@
         dir.deleteOnExit();
 
         String longDirName = "abcdefghijklmnopqrstuvwx";// 24 chars
+        String newbase = new String(dir + File.separator);
         StringBuilder sb = new StringBuilder(dir + File.separator);
         StringBuilder sb2 = new StringBuilder(dir + File.separator);
         
@@ -1830,7 +1831,7 @@
                     dir.mkdir() && dir.exists());
             dir.deleteOnExit();
         }
-        
+        dir = new File(sb2.toString());
         // Test make many paths
         while (dir.getCanonicalPath().length() < 256) {
             sb2.append(0);
@@ -1839,6 +1840,25 @@
                     dir.mkdir() && dir.exists());
             dir.deleteOnExit();
         }     
+        
+        // Regression test for HARMONY-3656
+        String []ss = {
+                "dir\u3400",
+                "abc",
+                "abc@123",
+                "!@#$%^&",
+                "~\u4E00!\u4E8C@\u4E09$",
+                "\u56DB\u4E94\u516D",
+                "\u4E03\u516B\u4E5D"
+        };
+        for (int i=0; i<ss.length; i++)
+        {
+            dir = new File(newbase, ss[i]);
+            assertTrue("mkdir " + dir.getCanonicalPath() + " failed",
+                    dir.mkdir() && dir.exists() 
+                    && dir.getCanonicalPath().equals(newbase + ss[i]));
+            dir.deleteOnExit();
+        }
     }
 
 	/**

Modified: harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c?view=diff&rev=532683&r1=532682&r2=532683
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c (original)
+++ harmony/enhanced/classlib/trunk/modules/portlib/src/main/native/port/windows/hyfile.c Thu Apr 26 02:43:49 2007
@@ -35,6 +35,8 @@
 #define CDEV_CURRENT_FUNCTION _prototypes_private
 
 static I_32 findError (I_32 errorCode);
+void convert_path_to_unicode(struct HyPortLibrary * portLibrary, const char *path,
+	     wchar_t **pathW);
 
 #undef CDEV_CURRENT_FUNCTION
 
@@ -87,7 +89,10 @@
 hyfile_attr (struct HyPortLibrary * portLibrary, const char *path)
 {
   DWORD result;
-  result = GetFileAttributes ((LPCTSTR) path);
+  wchar_t *pathW;
+  convert_path_to_unicode(portLibrary, path, &pathW);
+  result = GetFileAttributesW ((LPCWSTR) pathW);
+  portLibrary->mem_free_memory(portLibrary, pathW);
   if (result == 0xFFFFFFFF)
     {
       result = GetLastError ();
@@ -327,32 +332,21 @@
 
 #undef CDEV_CURRENT_FUNCTION
 
-#define CDEV_CURRENT_FUNCTION hyfile_mkdir
-/**
- * Create a directory.
- *
- * @param[in] portLibrary The port library
- * @param[in] path Directory to be created.
- *
- * @return 0 on success, -1 on failure.
- * @note Assumes all components of path up to the last directory already exist. 
- * @internal @todo return negative portable return code on failure.
- */
-I_32 VMCALL
-hyfile_mkdir (struct HyPortLibrary * portLibrary, const char *path)
+#define CDEV_CURRENT_FUNCTION convert_path_to_unicode
+
+void
+convert_path_to_unicode(struct HyPortLibrary * portLibrary, const char *path,
+	     wchar_t **pathW)
 {
-	int returnVar=0;
 	int len = strlen(path);
-    //If the length is longer than 248, unicode format should be used to CreateDirectroy.
-    //"." and ".." need be processed in the unicode format.
-    if(len >= 248){
+	int wlen;
     	char *canonicalpath;
     	int srcArrayCount=0;
     	int destArrayCount=0;
     	int slashCount=0; //record how many slashes it met.
     	int dotsCount=0; //record how many dots following a separator.
     	int *slashStack; //record position of every separator.
-        slashStack = portLibrary->mem_allocate_memory(portLibrary, len);
+        slashStack = portLibrary->mem_allocate_memory(portLibrary, len*sizeof(int));
         canonicalpath = portLibrary->mem_allocate_memory(portLibrary, len+5);
 
         strcpy(canonicalpath,"\\\\?\\");
@@ -388,13 +382,34 @@
         }
         
         canonicalpath[destArrayCount]='\0';
-        returnVar = CreateDirectory (canonicalpath, 0);
-        
+        wlen = MultiByteToWideChar(CP_UTF8, 0, canonicalpath, -1, *pathW, 0);
+        *pathW = portLibrary->mem_allocate_memory(portLibrary, wlen*sizeof(wchar_t));
+        MultiByteToWideChar(CP_UTF8, 0, canonicalpath, -1, *pathW, wlen);
         portLibrary->mem_free_memory(portLibrary, canonicalpath);
         portLibrary->mem_free_memory(portLibrary, slashStack);
-    }else{
-        returnVar = CreateDirectory (path, 0);
-    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyfile_mkdir
+/**
+ * Create a directory.
+ *
+ * @param[in] portLibrary The port library
+ * @param[in] path Directory to be created.
+ *
+ * @return 0 on success, -1 on failure.
+ * @note Assumes all components of path up to the last directory already exist. 
+ * @internal @todo return negative portable return code on failure.
+ */
+I_32 VMCALL
+hyfile_mkdir (struct HyPortLibrary * portLibrary, const char *path)
+{
+	int returnVar=0;
+	wchar_t *pathW;
+	convert_path_to_unicode(portLibrary, path, &pathW);
+	returnVar = CreateDirectoryW (pathW, 0);
+	portLibrary->mem_free_memory(portLibrary, pathW);
 
 	if (returnVar)
 	{
@@ -759,20 +774,25 @@
 I_32 VMCALL
 hyfile_unlinkdir (struct HyPortLibrary * portLibrary, const char *path)
 {
+  wchar_t *pathW;
+  convert_path_to_unicode(portLibrary, path, &pathW);
+
   /* should be able to delete read-only dirs, so we set the file attribute back to normal */
-  if (0 == SetFileAttributes (path, FILE_ATTRIBUTE_NORMAL))
+  if (0 == SetFileAttributesW (pathW, FILE_ATTRIBUTE_NORMAL))
     {
       I_32 error = GetLastError ();
       portLibrary->error_set_last_error (portLibrary, error, findError (error));	/* continue */
     }
 
-  if (RemoveDirectory (path))
+  if (RemoveDirectoryW (pathW))
     {
+      portLibrary->mem_free_memory(portLibrary, pathW);
       return 0;
     }
   else
     {
       I_32 error = GetLastError ();
+      portLibrary->mem_free_memory(portLibrary, pathW);
       portLibrary->error_set_last_error (portLibrary, error,
 					 findError (error));
       return -1;