57 #include <nsAutoLock.h>
58 #include <nsAutoPtr.h>
59 #include <nsComponentManagerUtils.h>
61 #include <nsILocalFile.h>
101 NS_DECL_NSISIMPLEENUMERATOR
107 nsresult
Init(nsIFile * aDirectory);
109 nsCOMPtr<nsIFile> mDirectory;
112 typedef HANDLE Directory;
114 typedef PRDir * Directory;
122 nsresult OpenDir(
const nsAString &
aPath);
135 nsresult ReadDir(nsAString & aPath);
142 mDir(INVALID_HANDLE_VALUE)
155 NS_ENSURE_ARG_POINTER(aDirectory);
159 mDirectory = aDirectory;
162 rv = aDirectory->GetPath(path);
163 NS_ENSURE_SUCCESS(rv, rv);
166 NS_ENSURE_SUCCESS(rv, rv);
172 sbDirectoryEnumeratorHelper::HasMoreElements(PRBool *_retval NS_OUTPARAM)
174 NS_ENSURE_ARG_POINTER(_retval);
176 *_retval = mNextPath.IsEmpty() ? PR_FALSE: PR_TRUE;
181 sbDirectoryEnumeratorHelper::GetNext(
nsISupports ** aEntry NS_OUTPARAM)
183 NS_ENSURE_ARG_POINTER(aEntry);
185 if (mNextPath.IsEmpty()) {
186 return NS_ERROR_NOT_AVAILABLE;
191 nsCOMPtr<nsILocalFile>
file =
192 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
195 rv = mDirectory->GetPath(path);
196 NS_ENSURE_SUCCESS(rv, rv);
198 rv = file->InitWithPath(path);
199 NS_ENSURE_SUCCESS(rv, rv);
201 rv = file->Append(mNextPath);
202 NS_ENSURE_SUCCESS(rv, rv);
204 *aEntry = file.get();
208 rv = ReadDir(mNextPath);
209 NS_ENSURE_SUCCESS(rv, rv);
219 return aPath[0] == (T)
'.' &&
220 ((aPath[1] == (T)
'.' && aPath[2] == 0) || aPath[1] == 0);
223 nsresult sbDirectoryEnumeratorHelper::OpenDir(
const nsAString &
aPath)
229 nsString
path(aPath);
232 if (!path.EqualsLiteral(
".") &&
233 !path.EqualsLiteral(
"..")) {
235 if (path.EqualsLiteral(
"\\\\")) {
236 path = NS_LITERAL_STRING(
"\\\\?\\UNC\\");
237 path.Append(aPath.BeginReading() + 2, aPath.Length() - 2);
241 path = NS_LITERAL_STRING(
"\\\\?\\");
250 if (path.IsEmpty() ||
251 path[path.Length() - 1] == L
'/' ||
252 path[path.Length() -1] == L
'\\')
253 path.AppendLiteral(
"*");
255 path.AppendLiteral(
"\\*");
257 PRUnichar *begin, *end;
259 for (path.BeginWriting(&begin, &end); begin < end; ++begin) {
260 if (*begin == L
'/') {
265 WIN32_FIND_DATAW findData;
266 mDir = ::FindFirstFileW(path.BeginReading(), &findData);
267 NS_ENSURE_TRUE(mDir != INVALID_HANDLE_VALUE, NS_ERROR_FILE_NOT_FOUND);
269 rv = ReadDir(mNextPath);
270 NS_ENSURE_SUCCESS(rv, rv);
273 mNextPath.Assign(findData.cFileName);
276 mDir = PR_OpenDir(NS_ConvertUTF16toUTF8(aPath).BeginReading());
277 NS_ENSURE_TRUE(mDir, NS_ERROR_FILE_NOT_FOUND);
279 rv = ReadDir(mNextPath);
280 NS_ENSURE_SUCCESS(rv, rv);
285 void sbDirectoryEnumeratorHelper::CloseDir()
288 if (mDir != INVALID_HANDLE_VALUE) {
290 mDir = INVALID_HANDLE_VALUE;
300 nsresult sbDirectoryEnumeratorHelper::ReadDir(nsAString & aPath)
303 WIN32_FIND_DATAW findData;
304 BOOL
succeeded = ::FindNextFileW(mDir, &findData);
305 while (succeeded &&
IsDotDir(findData.cFileName)) {
306 succeeded = ::FindNextFileW(mDir, &findData);
309 aPath.Assign(nsString(findData.cFileName));
316 PRDirEntry *
entry = PR_ReadDir(mDir, PR_SKIP_BOTH);
318 aPath.Assign(NS_ConvertUTF8toUTF16(entry->name));
322 NS_ENSURE_TRUE(PR_GetError() == PR_NO_MORE_FILES_ERROR,
323 NS_ERROR_UNEXPECTED);
336 sbDirectoryEnumerator::Enumerate(nsIFile* aDirectory)
339 NS_ENSURE_ARG_POINTER(aDirectory);
340 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
347 nsAutoLock autoLock(mEnumeratorLock);
352 rv = aDirectory->Exists(&exists);
353 NS_ENSURE_SUCCESS(rv, rv);
354 NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
355 rv = aDirectory->IsDirectory(&isDirectory);
356 NS_ENSURE_SUCCESS(rv, rv);
357 NS_ENSURE_TRUE(isDirectory, NS_ERROR_FILE_NOT_DIRECTORY);
361 nsRefPtr<sbDirectoryEnumeratorHelper> dirEnumerator =
363 NS_ENSURE_TRUE(dirEnumerator, NS_ERROR_OUT_OF_MEMORY);
364 rv = dirEnumerator->Init(aDirectory);
367 mEntriesEnumStack.Clear();
369 if (rv != NS_ERROR_FILE_NOT_FOUND) {
370 NS_ENSURE_SUCCESS(rv, rv);
371 success = mEntriesEnumStack.AppendObject(dirEnumerator);
372 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
376 rv = ScanForNextFile();
377 NS_ENSURE_SUCCESS(rv, rv);
390 sbDirectoryEnumerator::HasMoreElements(PRBool* aHasMoreElements)
393 NS_ENSURE_ARG_POINTER(aHasMoreElements);
394 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
397 nsAutoLock autoLock(mEnumeratorLock);
400 *aHasMoreElements = (mEntriesEnumStack.Count() > 0);
413 sbDirectoryEnumerator::GetNext(nsIFile** aFile)
416 NS_ENSURE_ARG_POINTER(aFile);
417 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
423 nsAutoLock autoLock(mEnumeratorLock);
427 mNextFile.forget(aFile);
429 return NS_ERROR_NOT_AVAILABLE;
432 rv = ScanForNextFile();
433 NS_ENSURE_SUCCESS(rv, rv);
450 sbDirectoryEnumerator::GetMaxDepth(PRUint32* aMaxDepth)
452 NS_ENSURE_ARG_POINTER(aMaxDepth);
453 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
454 nsAutoLock autoLock(mEnumeratorLock);
455 *aMaxDepth = mMaxDepth;
460 sbDirectoryEnumerator::SetMaxDepth(PRUint32 aMaxDepth)
462 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
463 nsAutoLock autoLock(mEnumeratorLock);
464 mMaxDepth = aMaxDepth;
474 sbDirectoryEnumerator::GetDirectoriesOnly(PRBool* aDirectoriesOnly)
476 NS_ENSURE_ARG_POINTER(aDirectoriesOnly);
477 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
478 nsAutoLock autoLock(mEnumeratorLock);
479 *aDirectoriesOnly = mDirectoriesOnly;
484 sbDirectoryEnumerator::SetDirectoriesOnly(PRBool aDirectoriesOnly)
486 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
487 nsAutoLock autoLock(mEnumeratorLock);
488 mDirectoriesOnly = aDirectoriesOnly;
498 sbDirectoryEnumerator::GetFilesOnly(PRBool* aFilesOnly)
500 NS_ENSURE_ARG_POINTER(aFilesOnly);
501 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
502 nsAutoLock autoLock(mEnumeratorLock);
503 *aFilesOnly = mFilesOnly;
508 sbDirectoryEnumerator::SetFilesOnly(PRBool aFilesOnly)
510 NS_PRECONDITION(mIsInitialized,
"Directory enumerator not initialized");
511 nsAutoLock autoLock(mEnumeratorLock);
512 mFilesOnly = aFilesOnly;
528 mIsInitialized(PR_FALSE),
529 mEnumeratorLock(nsnull),
531 mDirectoriesOnly(PR_FALSE),
560 nsAutoLock::NewLock(
"sbDirectoryEnumerator.mEnumeratorLock");
561 NS_ENSURE_TRUE(mEnumeratorLock, NS_ERROR_OUT_OF_MEMORY);
564 mIsInitialized = PR_TRUE;
578 mIsInitialized = PR_FALSE;
582 nsAutoLock::DestroyLock(mEnumeratorLock);
583 mEnumeratorLock = nsnull;
586 mEntriesEnumStack.Clear();
607 sbDirectoryEnumerator::ScanForNextFile()
613 while (!mNextFile && (mEntriesEnumStack.Count() > 0)) {
615 nsCOMPtr<nsISimpleEnumerator>
616 entriesEnum = mEntriesEnumStack.ObjectAt(mEntriesEnumStack.Count() - 1);
620 rv = entriesEnum->HasMoreElements(&hasMoreElements);
621 NS_ENSURE_SUCCESS(rv, rv);
622 if (!hasMoreElements) {
623 mEntriesEnumStack.RemoveObjectAt(mEntriesEnumStack.Count() - 1);
628 nsCOMPtr<nsISupports> fileEntry;
629 rv = entriesEnum->GetNext(getter_AddRefs(fileEntry));
630 NS_ENSURE_SUCCESS(rv, rv);
631 nsCOMPtr<nsIFile> file = do_QueryInterface(fileEntry, &rv);
632 NS_ENSURE_SUCCESS(rv, rv);
635 PRBool skipFile = PR_FALSE;
637 rv = file->IsDirectory(&isDirectory);
639 NS_WARNING(
"IsDirectory failed, assuming not a directory");
640 isDirectory = PR_FALSE;
642 if (mDirectoriesOnly) {
648 rv = file->IsFile(&isFile);
650 NS_WARNING(
"IsFile failed, assuming not a file");
661 PRUint32 depth = mEntriesEnumStack.Count();
662 if (isDirectory && !((mMaxDepth > 0) && (depth >= mMaxDepth))) {
665 nsRefPtr<sbDirectoryEnumeratorHelper> dirEnumeratorAdapter =
667 NS_ENSURE_TRUE(dirEnumeratorAdapter, NS_ERROR_OUT_OF_MEMORY);
668 rv = dirEnumeratorAdapter->Init(file);
669 nsCOMPtr<nsISimpleEnumerator> dirEntryEnumerator;
670 if (rv != NS_ERROR_FILE_NOT_FOUND) {
671 NS_ENSURE_SUCCESS(rv, rv);
672 dirEntryEnumerator = do_QueryInterface(dirEnumeratorAdapter, &rv);
673 NS_ENSURE_SUCCESS(rv, rv);
675 if (dirEntryEnumerator) {
676 success = mEntriesEnumStack.AppendObject(dirEntryEnumerator);
677 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
bool IsDotDir(T const *aPath)
function succeeded(ch, cx, status, data)
virtual ~sbDirectoryEnumerator()
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceCapsCompatibility, sbIDeviceCapsCompatibility) sbDeviceCapsCompatibility
boolean hasMoreElements()
Return true if more elements are available to enumerate.
Songbird Directory Enumerator Definitions.
virtual ~sbDirectoryEnumeratorHelper()
NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR nsresult Init(nsIFile *aDirectory)
NS_DECL_ISUPPORTS NS_DECL_SBIDIRECTORYENUMERATOR sbDirectoryEnumerator()