--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contentmgmt/referencedrmagent/contentiterator/contentiterator.cpp Mon Oct 12 10:17:04 2009 +0300
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+#include "cafpanic.h"
+#include "contentIterator.h"
+#include "FileContentIterator.h"
+#include "contentiteratordata.h"
+
+using ContentAccess::CContentIterator;
+using ContentAccess::TVirtualPathPtr;
+
+_LIT(KIteratorThread,"ContentIterator");
+EXPORT_C CContentIterator* CContentIterator::NewL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType)
+ {
+ CContentIterator* self = new (ELeave) CContentIterator();
+ CleanupStack::PushL(self);
+ self->ConstructL(aPath, aRecursive, aMimeType);
+ CleanupStack::Pop();
+ return self;
+ }
+
+CContentIterator::CContentIterator() : CActive(EPriorityStandard)
+ {
+ }
+
+CContentIterator::~CContentIterator()
+ {
+ // tell thread to cancel and shutdown
+ Cancel();
+
+ // close thread handle
+ iWorkerThread.Close();
+ delete info;
+ }
+
+void CContentIterator::ConstructL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType)
+ {
+ // This data buffer will be shared between the client and the worker thread
+ info = CContentIteratorData::NewL(aPath,aRecursive,aMimeType);
+
+ // create the thread, need a big heap and stack for recursively searching through directories
+ User::LeaveIfError(iWorkerThread.Create(KIteratorThread(),CContentIterator::ThreadEntry,32768, KMinHeapSize, 131072, (void *) info , EOwnerProcess));
+
+ // add ourselves to active scheduler
+ CActiveScheduler::Add(this);
+
+ // Set up notification in case the thread panics etc
+ iStatus = KRequestPending;
+ iWorkerThread.Logon(iStatus);
+ SetActive();
+
+ // start the thread
+ iWorkerThread.Resume();
+ }
+
+
+void CContentIterator::DoCancel()
+ {
+ // Wait until thread finishes whatever it's doing
+ info->Lock();
+
+ // Signal for the thread to close
+ info->RunThreadFunction(EIteratorShutdownThread);
+ }
+
+void CContentIterator::RunL()
+ {
+ // Thread must have completed
+ if(iWorkerThread.ExitType() == EExitPanic)
+ {
+ // Thread panicd, better panic our thread
+ User::Panic(KCafPanicString, ECafPanicContentIteratorThreadPanic);
+ }
+ }
+
+EXPORT_C TVirtualPathPtr CContentIterator::VirtualPath()
+ {
+ // Wait until thread finishes whatever it's doing
+ info->Lock();
+ iFileName.Copy(info->Path());
+ iUniqueId.Copy(info->UniqueId());
+ info->Unlock();
+ return TVirtualPathPtr(iFileName, iUniqueId);
+ }
+
+EXPORT_C const TDesC& CContentIterator::Name()
+ {
+ // Wait until thread finishes whatever it's doing
+ info->Lock();
+ iName.Copy(info->Name());
+ info->Unlock();
+ return iName;
+ }
+
+EXPORT_C const TDesC8& CContentIterator::MimeType()
+ {
+ // Wait until thread finishes whatever it's doing
+ info->Lock();
+ iMimeType.Copy(info->MimeType());
+ info->Unlock();
+ return iMimeType;
+ }
+
+EXPORT_C void CContentIterator::Next(TRequestStatus &aStatus)
+ {
+ // Wait until thread finishes whatever it's doing
+ info->Lock();
+
+ // Remember which thread and TRequestStatus to notify
+ TThreadId id = RThread().Id();
+ info->SetClientRequest(id, aStatus);
+
+ // Tell it to find the next iteration
+ info->RunThreadFunction(EIteratorFindNextContentObject);
+ }
+
+
+TInt CContentIterator::ThreadEntry(TAny* aAny)
+ {
+ TBool exitNow = EFalse;
+ TInt err;
+ CFileContentIterator* iterator = NULL;
+ RThread clientThread;
+ CContentIteratorData* info = reinterpret_cast <CContentIteratorData *> (aAny);
+
+ // create a trap handler
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+
+ while(!exitNow)
+ {
+ // Thread will wait here until signaled by other CContentIterator functions
+ switch(info->ThreadWait())
+ {
+ // Client thread has asked us to shutdown, exit loop
+ case EIteratorShutdownThread:
+ exitNow = ETrue;
+ break;
+ // Client thread is asking us to find the next object
+ case EIteratorFindNextContentObject:
+ if(!iterator)
+ {
+ TRAP(err, iterator = CFileContentIterator::NewL(info->Path(), info->IsRecursive(), info->MimeType()));
+ info->SetData(KNullDesC(), KNullDesC(), KNullDesC(), KNullDesC8());
+ }
+ else
+ {
+ err = iterator->Next();
+ }
+
+ if(err == KErrNone)
+ {
+ // If a content object was found, write the value back
+ // into the other thread while the info is still locked
+ info->SetData(iterator->FileName(),iterator->UniqueId(), iterator->Name(), iterator->MimeType());
+ }
+
+ // Complete the clients asynchronous request
+ info->CompleteClientRequest(err);
+ break;
+ default:
+ User::Panic(KCafPanicString, ECafPanicContentIteratorUnknownRequest);
+ break;
+ };
+
+ // Allow the client to post a new request
+ info->Unlock();
+ }
+ delete iterator;
+ delete cleanup;
+ return KErrNone;
+ }
+