40 #include <nsAutoLock.h>
41 #include <nsIIOService.h>
43 #include <nsUnicharUtils.h>
44 #include <nsISupportsPrimitives.h>
45 #include <nsArrayUtils.h>
46 #include <nsThreadUtils.h>
47 #include <nsStringGlue.h>
48 #include <nsIMutableArray.h>
49 #include <nsIThreadPool.h>
50 #include <nsNetUtil.h>
51 #include <sbILibraryUtils.h>
52 #include <sbIDirectoryEnumerator.h>
71 : m_pDirectoryLock(PR_NewLock())
72 , m_pCurrentPathLock(PR_NewLock())
73 , m_bSearchHidden(PR_FALSE)
74 , m_bRecurse(PR_FALSE)
75 , m_bWantLibraryContentURIs(PR_TRUE)
76 , m_pScanningLock(PR_NewLock())
77 , m_bIsScanning(PR_FALSE)
78 , m_pCallbackLock(PR_NewLock())
79 , m_pExtensionsLock(PR_NewLock())
80 , m_pFlaggedFileExtensionsLock(PR_NewLock())
81 , m_pCancelLock(PR_NewLock())
84 NS_ASSERTION(m_pDirectoryLock,
"FileScanQuery.m_pDirectoryLock failed");
85 NS_ASSERTION(m_pCurrentPathLock,
"FileScanQuery.m_pCurrentPathLock failed");
86 NS_ASSERTION(m_pCallbackLock,
"FileScanQuery.m_pCallbackLock failed");
87 NS_ASSERTION(m_pExtensionsLock,
"FileScanQuery.m_pExtensionsLock failed");
88 NS_ASSERTION(m_pFlaggedFileExtensionsLock,
89 "FileScanQuery.m_pFlaggedFileExtensionsLock failed!");
90 NS_ASSERTION(m_pScanningLock,
"FileScanQuery.m_pScanningLock failed");
91 NS_ASSERTION(m_pCancelLock,
"FileScanQuery.m_pCancelLock failed");
98 const PRBool & bRecurse,
100 : m_pDirectoryLock(PR_NewLock())
101 , m_strDirectory(strDirectory)
102 , m_pCurrentPathLock(PR_NewLock())
103 , m_bSearchHidden(PR_FALSE)
104 , m_bRecurse(bRecurse)
105 , m_bWantLibraryContentURIs(PR_TRUE)
106 , m_pScanningLock(PR_NewLock())
107 , m_bIsScanning(PR_FALSE)
108 , m_pCallbackLock(PR_NewLock())
109 , m_pCallback(pCallback)
110 , m_pExtensionsLock(PR_NewLock())
111 , m_pFlaggedFileExtensionsLock(PR_NewLock())
112 , m_pCancelLock(PR_NewLock())
113 , m_bCancel(PR_FALSE)
120 "FileScanQuery.m_pFlaggedFileExtensionsLock failed!");
122 NS_ASSERTION(
m_pCancelLock,
"FileScanQuery.m_pCancelLock failed");
136 NS_ASSERTION(success,
"FileScanQuery.m_Extensions failed to be initialized");
143 NS_ASSERTION(success,
144 "FileScanQuery.m_FlaggedExtensions failed to be initialized!");
172 NS_IMETHODIMP sbFileScanQuery::GetSearchHidden(PRBool *aSearchHidden)
174 NS_ENSURE_ARG_POINTER(aSearchHidden);
180 NS_IMETHODIMP sbFileScanQuery::SetSearchHidden(PRBool aSearchHidden)
188 NS_IMETHODIMP sbFileScanQuery::SetDirectory(
const nsAString &strDirectory)
195 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
196 NS_ENSURE_SUCCESS(rv, rv);
200 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
201 NS_ENSURE_SUCCESS(rv, rv);
210 NS_IMETHODIMP sbFileScanQuery::GetDirectory(nsAString &_retval)
220 NS_IMETHODIMP sbFileScanQuery::SetRecurse(PRBool bRecurse)
228 NS_IMETHODIMP sbFileScanQuery::GetRecurse(PRBool *_retval)
230 NS_ENSURE_ARG_POINTER(_retval);
236 NS_IMETHODIMP sbFileScanQuery::AddFileExtension(
const nsAString &strExtension)
240 nsAutoString extStr(strExtension);
243 nsStringHashKey* hashKey =
m_Extensions.PutEntry(extStr);
244 NS_ENSURE_TRUE(hashKey, NS_ERROR_OUT_OF_MEMORY);
252 sbFileScanQuery::AddFlaggedFileExtension(
const nsAString & strExtension)
256 nsAutoString extStr(strExtension);
260 NS_ENSURE_TRUE(hashKey, NS_ERROR_OUT_OF_MEMORY);
268 sbFileScanQuery::GetFlaggedExtensionsFound(PRBool *aOutIsFound)
270 NS_ENSURE_ARG_POINTER(aOutIsFound);
272 *aOutIsFound = PR_FALSE;
277 NS_ENSURE_SUCCESS(rv, rv);
279 *aOutIsFound = length > 0;
289 NS_ENSURE_ARG_POINTER(pCallback);
304 NS_ENSURE_ARG_POINTER(_retval);
313 NS_IMETHODIMP sbFileScanQuery::GetFileCount(PRUint32 *_retval)
315 NS_ENSURE_ARG_POINTER(_retval);
322 LOG(
"sbFileScanQuery: reporting %d files\n", *_retval);
328 NS_IMETHODIMP sbFileScanQuery::GetFlaggedFileCount(PRUint32 *_retval)
330 NS_ENSURE_ARG_POINTER(_retval);
339 LOG(
"sbFileScanQuery: reporting %d flagged files\n", *_retval);
345 NS_IMETHODIMP sbFileScanQuery::AddFilePath(
const nsAString &strFilePath)
347 PRBool isFlagged = PR_FALSE;
354 if (isValidExtension) {
356 }
else if (!isValidExtension && !isFlagged) {
357 LOG(
"sbFileScanQuery::AddFilePath, unrecognized extension: (%s) is seen\n",
358 NS_LossyConvertUTF16toASCII(strExtension).
get());
364 nsCOMPtr<nsISupportsString>
string =
365 do_CreateInstance(
"@mozilla.org/supports-string;1", &rv);
366 NS_ENSURE_SUCCESS(rv, rv);
368 rv =
string->SetData(strFilePath);
369 NS_ENSURE_SUCCESS(rv, rv);
373 NS_ENSURE_SUCCESS(rv, rv);
377 NS_ENSURE_SUCCESS(rv, rv);
380 LOG(
"sbFileScanQuery::AddFilePath(%s)\n",
381 NS_LossyConvertUTF16toASCII(strFilePath).
get());
387 NS_IMETHODIMP sbFileScanQuery::GetFilePath(PRUint32 nIndex, nsAString &_retval)
389 _retval = EmptyString();
390 NS_ENSURE_ARG_MIN(nIndex, 0);
394 if (nIndex < length) {
396 nsCOMPtr<nsISupportsString>
path = do_QueryElementAt(
m_pFileStack, nIndex, &rv);
397 NS_ENSURE_SUCCESS(rv, rv);
398 path->GetData(_retval);
407 sbFileScanQuery::GetFlaggedFilePath(PRUint32 nIndex, nsAString &retVal)
409 retVal = EmptyString();
410 NS_ENSURE_ARG_MIN(nIndex, 0);
414 if (nIndex < length) {
416 nsCOMPtr<nsISupportsString>
path =
418 NS_ENSURE_SUCCESS(rv, rv);
420 path->GetData(retVal);
428 NS_IMETHODIMP sbFileScanQuery::IsScanning(PRBool *_retval)
430 NS_ENSURE_ARG_POINTER(_retval);
439 NS_IMETHODIMP sbFileScanQuery::SetIsScanning(PRBool bIsScanning)
449 NS_IMETHODIMP sbFileScanQuery::GetLastFileFound(nsAString &_retval)
455 nsCOMPtr<nsISupportsString>
path =
457 NS_ENSURE_SUCCESS(rv, rv);
458 path->GetData(_retval);
468 NS_IMETHODIMP sbFileScanQuery::GetCurrentScanPath(nsAString &_retval)
478 NS_IMETHODIMP sbFileScanQuery::SetCurrentScanPath(
const nsAString &strScanPath)
488 NS_IMETHODIMP sbFileScanQuery::Cancel()
497 NS_IMETHODIMP sbFileScanQuery::GetResultRangeAsURIStrings(PRUint32 aStartIndex,
503 NS_ENSURE_TRUE(aStartIndex < length, NS_ERROR_INVALID_ARG);
504 NS_ENSURE_TRUE(aEndIndex < length, NS_ERROR_INVALID_ARG);
506 if (aStartIndex == 0 && aEndIndex == length - 1) {
510 nsCOMPtr<nsIMutableArray>
array =
511 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
513 for (PRUint32
i = aStartIndex;
i <= aEndIndex;
i++) {
514 nsCOMPtr<nsISupportsString> uriSpec = do_QueryElementAt(
m_pFileStack,
i);
518 rv = array->AppendElement(uriSpec, PR_FALSE);
519 NS_ENSURE_SUCCESS(rv, rv);
522 if (NS_SUCCEEDED(uriSpec->GetData(s)) && !s.IsEmpty()) {
523 LOG(
"sbFileScanQuery:: fetched URI %s\n", NS_LossyConvertUTF16toASCII(s).
get());
527 NS_ADDREF(*_retval = array);
529 LOG(
"sbFileScanQuery:: fetched URIs %d through %d\n", aStartIndex, aEndIndex);
536 NS_IMETHODIMP sbFileScanQuery::IsCancelled(PRBool *_retval)
538 NS_ENSURE_ARG_POINTER(_retval);
548 nsAutoString
str(strFilename);
550 PRInt32 index = str.RFindChar(NS_L(
'.'));
552 return nsString(Substring(str, index + 1, str.Length() - index));
554 return EmptyString();
559 PRBool *aOutIsFlaggedExtension)
561 NS_ENSURE_ARG_POINTER(aOutIsFlaggedExtension);
563 *aOutIsFlaggedExtension = PR_FALSE;
564 PRBool isValid = PR_FALSE;
565 nsAutoString extString;
570 extString = PromiseFlatString(strExtension);
571 ToLowerCase(extString);
581 *aOutIsFlaggedExtension =
591 NS_IMETHODIMP sbFileScanQuery::
592 GetWantLibraryContentURIs(PRBool *aWantLibraryContentURIs)
594 NS_ENSURE_ARG_POINTER(aWantLibraryContentURIs);
600 NS_IMETHODIMP sbFileScanQuery::
601 SetWantLibraryContentURIs(PRBool aWantLibraryContentURIs)
615 : m_ScanQueryQueueLock(nsAutoLock::NewLock("
sbFileScan.m_ScanQueriesLock"))
616 , m_ScanQueryProcessorIsRunning(0)
617 , m_ThreadShouldShutdown(PR_FALSE)
618 , m_Finalized(PR_FALSE)
620 NS_ASSERTION(m_ScanQueryQueueLock,
"sbFileScan.m_ScanQueriesLock failed");
631 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"sbFileScan::Finalize failed");
633 NS_ASSERTION(NS_SUCCEEDED(rv),
634 "Unable to shut down the query processor thread");
649 NS_ENSURE_TRUE(currentThread, NS_ERROR_FAILURE);
654 NS_ProcessPendingEvents(currentThread);
656 PR_Sleep(PR_MillisecondsToInterval(100));
668 NS_ENSURE_ARG_POINTER(pQuery);
674 pQuery->SetIsScanning(PR_TRUE);
681 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
682 "ERROR: Could not start the query processor thread!");
690 NS_IMETHODIMP sbFileScan::Finalize()
694 NS_WARNING(
"sbFileScan::Finalize called more than once");
699 NS_ENSURE_SUCCESS(rv, rv);
711 nsCOMPtr<nsIThreadPool> threadPoolService =
712 do_GetService(
"@songbirdnest.com/Songbird/ThreadPoolService;1", &rv);
713 NS_ENSURE_SUCCESS(rv, rv);
715 nsCOMPtr<nsIRunnable> runnable =
717 NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE);
719 rv = threadPoolService->Dispatch(runnable, NS_DISPATCH_NORMAL);
720 NS_ENSURE_SUCCESS(rv, rv);
735 nsCOMPtr<sbIFileScanQuery> curScanQuery;
760 rv = curScanQuery->SetIsScanning(PR_TRUE);
761 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
762 "WARNING: Could not inform the scan query to isScanning=true!");
765 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
766 "WARNING: Could not scan the current directory!");
768 rv = curScanQuery->SetIsScanning(PR_FALSE);
769 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
770 "WARNING: Could not inform the scan query to isScanning=false!");
785 PRInt32 nFoundCount = 0;
787 nsCOMPtr<nsILocalFile> pFile = do_CreateInstance(
"@mozilla.org/file/local;1");
788 nsCOMPtr<sbILibraryUtils> pLibraryUtils =
789 do_GetService(
"@songbirdnest.com/Songbird/library/Manager;1", &rv);
790 NS_ENSURE_SUCCESS(rv, rv);
793 pQuery->GetCallback(&pCallback);
795 PRBool bSearchHidden = PR_FALSE;
796 pQuery->GetSearchHidden(&bSearchHidden);
798 PRBool bRecurse = PR_FALSE;
799 pQuery->GetRecurse(&bRecurse);
801 nsString strTheDirectory;
802 pQuery->GetDirectory(strTheDirectory);
804 PRBool bWantLibraryContentURIs = PR_TRUE;
805 pQuery->GetWantLibraryContentURIs(&bWantLibraryContentURIs);
807 rv = pFile->InitWithPath(strTheDirectory);
808 if(NS_FAILED(rv))
return rv;
810 PRBool bFlag = PR_FALSE;
811 pFile->IsDirectory(&bFlag);
815 pCallback->OnFileScanStart();
822 NS_ENSURE_SUCCESS(rv, rv);
829 PRBool cancel = PR_FALSE;
830 pQuery->IsCancelled(&cancel);
836 PRBool bHasMore = PR_FALSE;
837 rv = pDirEntries->HasMoreElements(&bHasMore);
838 nsCOMPtr<nsIFile> pEntry;
839 if(NS_SUCCEEDED(rv) && bHasMore) {
840 rv = pDirEntries->GetNext(getter_AddRefs(pEntry));
843 if(NS_SUCCEEDED(rv) && pEntry)
845 PRBool bIsFile = PR_FALSE, bIsDirectory = PR_FALSE, bIsHidden = PR_FALSE;
846 pEntry->IsFile(&bIsFile);
847 pEntry->IsDirectory(&bIsDirectory);
848 pEntry->IsHidden(&bIsHidden);
854 PRBool isSpecial = PR_FALSE;
855 pEntry->IsSpecial(&isSpecial);
862 rv = pEntry->GetLeafName(fileName);
863 NS_ENSURE_SUCCESS(rv, rv);
864 isSpecial |= (fileName.Length() >= 2 &&
865 fileName[0] == PRUnichar(
'.') &&
866 fileName[1] == PRUnichar(
'_'));
868 if(!isSpecial && (!bIsHidden || bSearchHidden))
873 nsCOMPtr<nsIURI> pURI;
874 if (bWantLibraryContentURIs) {
875 rv = pLibraryUtils->GetFileContentURI(pEntry,
876 getter_AddRefs(pURI));
878 rv = NS_NewFileURI(getter_AddRefs(pURI), pEntry);
883 if (NS_SUCCEEDED(rv)) {
884 rv = pURI->GetSpec(spec);
885 LOG(
"sbFileScan::ScanDirectory (C++) found spec: %s\n",
890 if (NS_SUCCEEDED(rv)) {
891 nsString strPath = NS_ConvertUTF8toUTF16(spec);
892 pQuery->AddFilePath(strPath);
897 pCallback->OnFileScanFile(strPath, nFoundCount);
901 else if(bIsDirectory && bRecurse)
906 NS_ENSURE_SUCCESS(rv, rv);
908 rv = pMoreEntries->SetFilesOnly(PR_FALSE);
909 NS_ENSURE_SUCCESS(rv, rv);
910 rv = pMoreEntries->SetMaxDepth(1);
911 NS_ENSURE_SUCCESS(rv, rv);
912 rv = pMoreEntries->Enumerate(pEntry);
913 NS_ENSURE_SUCCESS(rv, rv);
917 dirStack.push_back(pDirEntries);
918 fileEntryStack.push_back(pEntry);
919 entryStack.push_back(pEntry);
921 pDirEntries = pMoreEntries;
930 NS_IF_RELEASE(pDirEntries);
932 pDirEntries = dirStack.back();
935 fileEntryStack.pop_back();
936 entryStack.pop_back();
942 pCallback->OnFileScanEnd();
945 NS_IF_RELEASE(pCallback);
946 NS_IF_RELEASE(pDirEntries);
953 PR_Sleep(PR_MillisecondsToInterval(0));
959 NS_IF_RELEASE(pDirEntries);
962 else if(NS_SUCCEEDED(pFile->IsFile(&bFlag)) && bFlag)
964 pQuery->AddFilePath(strTheDirectory);
969 pCallback->OnFileScanEnd();
972 NS_IF_RELEASE(pCallback);
974 dirstack_t::iterator it = dirStack.begin();
975 for(; it != dirStack.end(); ++it) {
980 fileEntryStack.clear();
std::deque< nsCOMPtr< nsIFile > > entrystack_t
GeneratorThread currentThread
PRBool VerifyFileExtension(const nsAString &strExtension, PRBool *aOutIsFlaggedExtension)
#define SB_PRLOG_SETUP(x)
nsresult ScanDirectory(sbIFileScanQuery *pQuery)
PRLock * m_ScanQueryQueueLock
PRBool m_bWantLibraryContentURIs
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
std::deque< nsCOMPtr< nsIFile > > fileentrystack_t
PRLock * m_pExtensionsLock
nsresult sbGetDirectoryEntries(nsIFile *aFile, sbIDirectoryEnumerator **aDirEntryEnumerator)
PRLock * m_pFlaggedFileExtensionsLock
queryqueue_t m_ScanQueryQueue
nsresult StartProcessScanQueriesProcessor()
std::deque< sbIDirectoryEnumerator * > dirstack_t
The callback to the sbIFileScanQuery interface.
virtual ~sbFileScanQuery()
PRLock * m_pCurrentPathLock
void RunProcessScanQueries()
#define SB_DIRECTORYENUMERATOR_CONTRACTID
nsTHashtable< nsStringHashKey > m_FlaggedExtensions
nsString m_strCurrentPath
nsCOMPtr< sbIFileScanCallback > m_pCallback
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceCapsCompatibility, sbIDeviceCapsCompatibility) sbDeviceCapsCompatibility
PRBool m_ThreadShouldShutdown
nsString GetExtensionFromFilename(const nsAString &strFilename)
nsCOMPtr< nsIMutableArray > m_pFileStack
nsString m_lastSeenExtension
The engine in which to execute sbIFileScanQuery objects.
PRLock * m_pDirectoryLock
nsCOMPtr< nsIMutableArray > m_pFlaggedFileStack
PRInt32 m_ScanQueryProcessorIsRunning
An object to scan through the files of a folder (and optionally subfolders)
_getSelectedPageStyle s i
#define SB_UNUSED_IN_RELEASE(decl)
nsTHashtable< nsStringHashKey > m_Extensions