From e4e974dc5ab1272bff08599855dd47732f4a9068 Mon Sep 17 00:00:00 2001 From: "sayrer%gmail.com" Date: Tue, 30 Jan 2007 21:50:45 +0000 Subject: [PATCH] Bug 367608. implement nsIFile::normalize() on OS X. r=mano, sr=bsmedberg --- xpcom/io/nsLocalFileOSX.cpp | 44 ++++++++++++++++++++- xpcom/tests/nsIFileTest.cpp | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/xpcom/io/nsLocalFileOSX.cpp b/xpcom/io/nsLocalFileOSX.cpp index 68bb2bb6528f..096f66429030 100644 --- a/xpcom/io/nsLocalFileOSX.cpp +++ b/xpcom/io/nsLocalFileOSX.cpp @@ -65,6 +65,7 @@ // Unix Includes #include #include +#include #if !defined(MAC_OS_X_VERSION_10_4) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 #define GetAliasSizeFromRecord(aliasRecord) aliasRecord.aliasSize @@ -412,7 +413,48 @@ NS_IMETHODIMP nsLocalFile::AppendNative(const nsACString& aNode) /* void normalize (); */ NS_IMETHODIMP nsLocalFile::Normalize() { - return NS_OK; + // Check we are correctly initialized. + CHECK_mBaseRef(); + + // CFURL doesn't doesn't seem to resolve paths containing relative + // components, so we'll nick the stdlib code from nsLocalFileUnix + UInt8 path[PATH_MAX] = ""; + Boolean success; + success = ::CFURLGetFileSystemRepresentation(mBaseRef, true, path, PATH_MAX); + if (!success) + return NS_ERROR_FAILURE; + + char resolved_path[PATH_MAX] = ""; + char *resolved_path_ptr = nsnull; + resolved_path_ptr = realpath((char*)path, resolved_path); + + // if there is an error, the return is null. + if (!resolved_path_ptr) + return NSRESULT_FOR_ERRNO(); + + // Need to know whether we're a directory to create a new CFURLRef + PRBool isDirectory; + nsresult rv = IsDirectory(&isDirectory); + NS_ENSURE_SUCCESS(rv, rv); + + rv = NS_ERROR_FAILURE; + CFStringRef pathStrRef = + ::CFStringCreateWithCString(kCFAllocatorDefault, + resolved_path, + kCFStringEncodingUTF8); + if (pathStrRef) { + CFURLRef newURLRef = + ::CFURLCreateWithFileSystemPath(kCFAllocatorDefault, pathStrRef, + kCFURLPOSIXPathStyle, isDirectory); + if (newURLRef) { + SetBaseRef(newURLRef); + ::CFRelease(newURLRef); + rv = NS_OK; + } + ::CFRelease(pathStrRef); + } + + return rv; } /* void create (in unsigned long type, in unsigned long permissions); */ diff --git a/xpcom/tests/nsIFileTest.cpp b/xpcom/tests/nsIFileTest.cpp index c593a53ff167..12ff162e0301 100644 --- a/xpcom/tests/nsIFileTest.cpp +++ b/xpcom/tests/nsIFileTest.cpp @@ -337,7 +337,80 @@ MoveTest(const char *testFile, const char *targetDir) printf("end move test\n"); } +// move up the number of directories in moveUpCount, then append "foo/bar" +void +NormalizeTest(const char *testPath, int moveUpCount, + const char *expected) +{ + Banner("Normalize Test"); + nsresult rv; + nsCOMPtr file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + + if (!file) + { + printf("create nsILocalFile failed\n"); + return; + } + + rv = file->InitWithNativePath(nsDependentCString(testPath)); + VerifyResult(rv); + + nsCOMPtr parent; + nsAutoString path; + for (int i=0; i < moveUpCount; i++) + { + rv = file->GetParent(getter_AddRefs(parent)); + VerifyResult(rv); + rv = parent->GetPath(path); + VerifyResult(rv); + rv = file->InitWithPath(path); + VerifyResult(rv); + } + + if (!parent) { + printf("Getting parent failed!\n"); + return; + } + + rv = parent->Append(NS_LITERAL_STRING("foo")); + VerifyResult(rv); + rv = parent->Append(NS_LITERAL_STRING("bar")); + VerifyResult(rv); + + rv = parent->Normalize(); + VerifyResult(rv); + + nsCAutoString newPath; + rv = parent->GetNativePath(newPath); + VerifyResult(rv); + + nsCOMPtr + expectedFile(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + + if (!expectedFile) + { + printf("create nsILocalFile failed\n"); + return; + } + rv = expectedFile->InitWithNativePath(nsDependentCString(expected)); + VerifyResult(rv); + + rv = expectedFile->Normalize(); + VerifyResult(rv); + + nsCAutoString expectedPath; + rv = expectedFile->GetNativePath(expectedPath); + VerifyResult(rv); + + if (!newPath.Equals(expectedPath)) { + printf("ERROR: Normalize() test Failed!\n"); + printf(" Got: %s\n", newPath.get()); + printf("Expected: %s\n", expectedPath); + } + + printf("end normalize test.\n"); +} int main(void) { @@ -383,6 +456,12 @@ int main(void) MoveTest("/tmp/file", "/tmp/newDir/anotherNewDir"); DeletionTest("/tmp", "newDir", PR_TRUE); + CreationTest("/tmp", "qux/quux", nsIFile::NORMAL_FILE_TYPE, 0644); + CreationTest("/tmp", "foo/bar", nsIFile::NORMAL_FILE_TYPE, 0644); + NormalizeTest("/tmp/qux/quux/..", 1, "/tmp/foo/bar"); + DeletionTest("/tmp", "qux", PR_TRUE); + DeletionTest("/tmp", "foo", PR_TRUE); + #endif /* XP_UNIX */ #endif /* XP_WIN || XP_OS2 */ return 0;