diff --git a/mozilla/xpcom/io/nsDirectoryService.cpp b/mozilla/xpcom/io/nsDirectoryService.cpp index 82fe35eb91b..fca58f44863 100644 --- a/mozilla/xpcom/io/nsDirectoryService.cpp +++ b/mozilla/xpcom/io/nsDirectoryService.cpp @@ -538,7 +538,21 @@ NS_IMETHODIMP nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result) { nsStringKey key(prop); - if (!mHashtable->Exists(&key)) + + nsCOMPtr value = dont_AddRef(mHashtable->Get(&key)); + + if (value) + { + nsCOMPtr cloneFile; + nsCOMPtr cachedFile = do_QueryInterface(value); + + if (!cachedFile) + return NS_ERROR_NULL_POINTER; + + cachedFile->Clone(getter_AddRefs(cloneFile)); + return cloneFile->QueryInterface(uuid, result); + } + else { // it is not one of our defaults, lets check any providers FileData fileData; @@ -550,32 +564,16 @@ nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result) if (fileData.file) { - if (!fileData.persistant) + if (fileData.persistant) { - nsresult rv = (fileData.file)->QueryInterface(uuid, result); - NS_RELEASE(fileData.file); - return rv; + Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file)); } - Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file)); - NS_RELEASE(fileData.file); + nsresult rv = (fileData.file)->QueryInterface(uuid, result); + NS_RELEASE(fileData.file); // addref occurs in FindProviderFile() + return rv; } } - - // now check again to see if it was added above. - if (mHashtable->Exists(&key)) - { - nsCOMPtr ourFile; - nsCOMPtr value = getter_AddRefs (mHashtable->Get(&key)); - - if (value && NS_SUCCEEDED(value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile)))) - { - nsCOMPtr cloneFile; - ourFile->Clone(getter_AddRefs(cloneFile)); - return cloneFile->QueryInterface(uuid, result); - } - } - return NS_ERROR_FAILURE; } @@ -593,7 +591,7 @@ nsDirectoryService::Set(const char* prop, nsISupports* value) nsCOMPtr cloneFile; ourFile->Clone (getter_AddRefs (cloneFile)); mHashtable->Put(&key, cloneFile); - return NS_OK; + return NS_OK; } return NS_ERROR_FAILURE; } diff --git a/mozilla/xpcom/io/nsIFile.idl b/mozilla/xpcom/io/nsIFile.idl index 3c20073f52d..2c85098ef30 100644 --- a/mozilla/xpcom/io/nsIFile.idl +++ b/mozilla/xpcom/io/nsIFile.idl @@ -230,6 +230,12 @@ interface nsIFile : nsISupports */ boolean isSpecial(); + /** + * . + */ + void makeUnique(in string suggestedName); + + /** * clone() * @@ -258,7 +264,7 @@ interface nsIFile : nsISupports * Parent will be nsnull when this is at the top of the volume. */ readonly attribute nsIFile parent; - + /** * Returns an enumeration of the elements in a directory. Each * element in the enumeration is an nsIFile. diff --git a/mozilla/xpcom/io/nsLocalFileCommon.cpp b/mozilla/xpcom/io/nsLocalFileCommon.cpp index 24ab363ccd7..752c128c1a0 100644 --- a/mozilla/xpcom/io/nsLocalFileCommon.cpp +++ b/mozilla/xpcom/io/nsLocalFileCommon.cpp @@ -367,3 +367,49 @@ nsresult nsFileSpec::Execute(const nsString& args) const SET_UCS( Execute , args.GetUnicode()); } +// should work on Macintosh, Unix, and Win32. +#define kMaxFilenameLength 31 + + +NS_IMETHODIMP +nsLocalFile::MakeUnique(const char* suggestedName) +{ + PRBool exists; + nsresult rv = Exists(&exists); + + if (NS_FAILED(rv)) return rv; + if (!exists) return NS_OK; + + char* leafName; + rv = GetLeafName(&leafName); + + if (NS_FAILED(rv)) return rv; + + char* lastDot = strrchr(leafName, '.'); + char* suffix = ""; + if (lastDot) + { + suffix = nsCRT::strdup(lastDot); // include '.' + *lastDot = '\0'; // strip suffix and dot. + } + + // 27 should work on Macintosh, Unix, and Win32. + const int maxRootLength = 27 - nsCRT::strlen(suffix) - 1; + + if ((int)nsCRT::strlen(leafName) > (int)maxRootLength) + leafName[maxRootLength] = '\0'; + + for (short indx = 1; indx < 10000 && exists; indx++) + { + // start with "Picture-1.jpg" after "Picture.jpg" exists + char newName[kMaxFilenameLength + 1]; + sprintf(newName, "%s-%d%s", leafName, indx, suffix); + SetLeafName(newName); + + rv = Exists(&exists); + if (NS_FAILED(rv)) return rv; + } + return NS_OK; +} + +