diff -r afc583cfa176 -r da2ae96f639b contentmgmt/referencedrmagent/contentiterator/contentiterator.cpp --- /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 (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; + } +