static int compare(nsIFile* aElement1, nsIFile* aElement2, void* aData) { if (!NS_IsNativeUTF8()) { // don't check for errors, because we can't report them anyway nsAutoString name1, name2; aElement1->GetLeafName(name1); aElement2->GetLeafName(name2); // Note - we should do the collation to do sorting. Why don't we? // Because that is _slow_. Using TestProtocols to list file:///dev/ // goes from 3 seconds to 22. (This may be why nsXULSortService is // so slow as well). // Does this have bad effects? Probably, but since nsXULTree appears // to use the raw RDF literal value as the sort key (which ammounts to an // strcmp), it won't be any worse, I think. // This could be made faster, by creating the keys once, // but CompareString could still be smarter - see bug 99383 - bbaetz // NB - 99393 has been WONTFIXed. So if the I18N code is ever made // threadsafe so that this matters, we'd have to pass through a // struct { nsIFile*, PRUint8* } with the pre-calculated key. return Compare(name1, name2); } nsCAutoString name1, name2; aElement1->GetNativeLeafName(name1); aElement2->GetNativeLeafName(name2); return Compare(name1, name2); }
// XXX : aTryLocaleCharset is not yet effective. nsresult nsMIMEHeaderParamImpl::DoGetParameter(const nsACString& aHeaderVal, const char *aParamName, ParamDecoding aDecoding, const nsACString& aFallbackCharset, bool aTryLocaleCharset, char **aLang, nsAString& aResult) { aResult.Truncate(); nsresult rv; // get parameter (decode RFC 2231/5987 when applicable, as specified by // aDecoding (5987 being a subset of 2231) and return charset.) nsXPIDLCString med; nsXPIDLCString charset; rv = DoParameterInternal(PromiseFlatCString(aHeaderVal).get(), aParamName, aDecoding, getter_Copies(charset), aLang, getter_Copies(med)); if (NS_FAILED(rv)) return rv; // convert to UTF-8 after charset conversion and RFC 2047 decoding // if necessary. nsCAutoString str1; rv = DecodeParameter(med, charset.get(), nullptr, false, str1); NS_ENSURE_SUCCESS(rv, rv); if (!aFallbackCharset.IsEmpty()) { nsCAutoString str2; nsCOMPtr<nsIUTF8ConverterService> cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID)); if (cvtUTF8 && NS_SUCCEEDED(cvtUTF8->ConvertStringToUTF8(str1, PromiseFlatCString(aFallbackCharset).get(), false, true, 1, str2))) { CopyUTF8toUTF16(str2, aResult); return NS_OK; } } if (IsUTF8(str1)) { CopyUTF8toUTF16(str1, aResult); return NS_OK; } if (aTryLocaleCharset && !NS_IsNativeUTF8()) return NS_CopyNativeToUnicode(str1, aResult); CopyASCIItoUTF16(str1, aResult); return NS_OK; }
nsresult net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { // NOTE: See also the implementation in nsURLHelperOSX.cpp, // which is based on this. nsresult rv; nsCOMPtr<nsILocalFile> localFile; rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localFile)); if (NS_FAILED(rv)) return rv; nsCAutoString directory, fileBaseName, fileExtension, path; rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; if (!directory.IsEmpty()) NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path); if (!fileBaseName.IsEmpty()) NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path); if (!fileExtension.IsEmpty()) { path += '.'; NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path); } NS_UnescapeURL(path); if (path.Length() != strlen(path.get())) return NS_ERROR_FILE_INVALID_PATH; if (IsUTF8(path)) { // speed up the start-up where UTF-8 is the native charset // (e.g. on recent Linux distributions) if (NS_IsNativeUTF8()) rv = localFile->InitWithNativePath(path); else rv = localFile->InitWithPath(NS_ConvertUTF8toUTF16(path)); // XXX In rare cases, a valid UTF-8 string can be valid as a native // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x). // However, the chance is very low that a meaningful word in a legacy // encoding is valid as UTF-8. } else // if path is not in UTF-8, assume it is encoded in the native charset rv = localFile->InitWithNativePath(path); if (NS_FAILED(rv)) return rv; NS_ADDREF(*result = localFile); return NS_OK; }
// XXX : aTryLocaleCharset is not yet effective. NS_IMETHODIMP nsMIMEHeaderParamImpl::GetParameter(const nsACString& aHeaderVal, const char *aParamName, const nsACString& aFallbackCharset, PRBool aTryLocaleCharset, char **aLang, nsAString& aResult) { aResult.Truncate(); nsresult rv; // get parameter (decode RFC 2231 if it's RFC 2231-encoded and // return charset.) nsXPIDLCString med; nsXPIDLCString charset; rv = GetParameterInternal(PromiseFlatCString(aHeaderVal).get(), aParamName, getter_Copies(charset), aLang, getter_Copies(med)); if (NS_FAILED(rv)) return rv; // convert to UTF-8 after charset conversion and RFC 2047 decoding // if necessary. nsCAutoString str1; rv = DecodeParameter(med, charset.get(), nsnull, PR_FALSE, str1); NS_ENSURE_SUCCESS(rv, rv); if (!aFallbackCharset.IsEmpty()) { nsCAutoString str2; nsCOMPtr<nsIUTF8ConverterService> cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID)); if (cvtUTF8 && NS_SUCCEEDED(cvtUTF8->ConvertStringToUTF8(str1, PromiseFlatCString(aFallbackCharset).get(), PR_FALSE, str2))) { CopyUTF8toUTF16(str2, aResult); return NS_OK; } } if (IsUTF8(str1)) { CopyUTF8toUTF16(str1, aResult); return NS_OK; } if (aTryLocaleCharset && !NS_IsNativeUTF8()) return NS_CopyNativeToUnicode(str1, aResult); CopyASCIItoUTF16(str1, aResult); return NS_OK; }
NS_IMETHODIMP nsDirectoryIndexStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aReadCount) { if (mStatus == NS_BASE_STREAM_CLOSED) { *aReadCount = 0; return NS_OK; } if (NS_FAILED(mStatus)) return mStatus; PRUint32 nread = 0; // If anything is enqueued (or left-over) in mBuf, then feed it to // the reader first. while (mOffset < (PRInt32)mBuf.Length() && aCount != 0) { *(aBuf++) = char(mBuf.CharAt(mOffset++)); --aCount; ++nread; } // Room left? if (aCount > 0) { mOffset = 0; mBuf.Truncate(); // Okay, now we'll suck stuff off of our iterator into the mBuf... while (PRUint32(mBuf.Length()) < aCount) { bool more = mPos < mArray.Count(); if (!more) break; // don't addref, for speed - an addref happened when it // was placed in the array, so it's not going to go stale nsIFile* current = mArray.ObjectAt(mPos); ++mPos; #ifdef PR_LOGGING if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) { nsCAutoString path; current->GetNativePath(path); PR_LOG(gLog, PR_LOG_DEBUG, ("nsDirectoryIndexStream[%p]: iterated %s", this, path.get())); } #endif // rjc: don't return hidden files/directories! // bbaetz: why not? nsresult rv; #ifndef XP_UNIX bool hidden = false; current->IsHidden(&hidden); if (hidden) { PR_LOG(gLog, PR_LOG_DEBUG, ("nsDirectoryIndexStream[%p]: skipping hidden file/directory", this)); continue; } #endif PRInt64 fileSize = 0; current->GetFileSize( &fileSize ); PRInt64 fileInfoModifyTime = 0; current->GetLastModifiedTime( &fileInfoModifyTime ); fileInfoModifyTime *= PR_USEC_PER_MSEC; mBuf.AppendLiteral("201: "); // The "filename" field char* escaped = nsnull; if (!NS_IsNativeUTF8()) { nsAutoString leafname; rv = current->GetLeafName(leafname); if (NS_FAILED(rv)) return rv; if (!leafname.IsEmpty()) escaped = nsEscape(NS_ConvertUTF16toUTF8(leafname).get(), url_Path); } else { nsCAutoString leafname; rv = current->GetNativeLeafName(leafname); if (NS_FAILED(rv)) return rv; if (!leafname.IsEmpty()) escaped = nsEscape(leafname.get(), url_Path); } if (escaped) { mBuf += escaped; mBuf.Append(' '); nsMemory::Free(escaped); } // The "content-length" field mBuf.AppendInt(fileSize, 10); mBuf.Append(' '); // The "last-modified" field PRExplodedTime tm; PR_ExplodeTime(fileInfoModifyTime, PR_GMTParameters, &tm); { char buf[64]; PR_FormatTimeUSEnglish(buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm); mBuf.Append(buf); } // The "file-type" field bool isFile = true; current->IsFile(&isFile); if (isFile) { mBuf.AppendLiteral("FILE "); } else { bool isDir; rv = current->IsDirectory(&isDir); if (NS_FAILED(rv)) return rv; if (isDir) { mBuf.AppendLiteral("DIRECTORY "); } else { bool isLink; rv = current->IsSymlink(&isLink); if (NS_FAILED(rv)) return rv; if (isLink) { mBuf.AppendLiteral("SYMBOLIC-LINK "); } } } mBuf.Append('\n'); } // ...and once we've either run out of directory entries, or // filled up the buffer, then we'll push it to the reader. while (mOffset < (PRInt32)mBuf.Length() && aCount != 0) { *(aBuf++) = char(mBuf.CharAt(mOffset++)); --aCount; ++nread; } } *aReadCount = nread; return NS_OK; }
NS_IMETHODIMP nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes) { nsresult rv; bool longName; #ifdef XP_WIN nsAutoString pathName, leafName, rootName, suffix; rv = GetPath(pathName); #else nsAutoCString pathName, leafName, rootName, suffix; rv = GetNativePath(pathName); #endif if (NS_FAILED(rv)) { return rv; } longName = (pathName.Length() + kMaxSequenceNumberLength > kMaxFilenameLength); if (!longName) { rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } #ifdef XP_WIN rv = GetLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar(char16_t('.')); #else rv = GetNativeLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar('.'); #endif if (lastDot == kNotFound) { rootName = leafName; } else { suffix = Substring(leafName, lastDot); // include '.' rootName = Substring(leafName, 0, lastDot); // strip suffix and dot } if (longName) { int32_t maxRootLength = (kMaxFilenameLength - (pathName.Length() - leafName.Length()) - suffix.Length() - kMaxSequenceNumberLength); // We cannot create an item inside a directory whose name is too long. // Also, ensure that at least one character remains after we truncate // the root name, as we don't want to end up with an empty leaf name. if (maxRootLength < 2) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } #ifdef XP_WIN // ensure that we don't cut the name in mid-UTF16-character rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ? maxRootLength - 1 : maxRootLength); SetLeafName(rootName + suffix); #else if (NS_IsNativeUTF8()) { // ensure that we don't cut the name in mid-UTF8-character // (assume the name is valid UTF8 to begin with) while (UTF8traits::isInSeq(rootName[maxRootLength])) { --maxRootLength; } // Another check to avoid ending up with an empty leaf name. if (maxRootLength == 0 && suffix.IsEmpty()) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } } rootName.SetLength(maxRootLength); SetNativeLeafName(rootName + suffix); #endif nsresult rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } for (int indx = 1; indx < 10000; ++indx) { // start with "Picture-1.jpg" after "Picture.jpg" exists #ifdef XP_WIN SetLeafName(rootName + NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) + suffix); #else SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix); #endif rv = Create(aType, aAttributes); if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } // The disk is full, sort of return NS_ERROR_FILE_TOO_BIG; }