contentmgmt/referencedrmagent/contentiterator/contentiterator.cpp
changeset 15 da2ae96f639b
--- /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;
+	}
+