contentmgmt/referencedrmagent/contentiterator/contentiterator.cpp
changeset 15 da2ae96f639b
equal deleted inserted replaced
10:afc583cfa176 15:da2ae96f639b
       
     1 /*
       
     2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "cafpanic.h"
       
    21 #include "contentIterator.h"
       
    22 #include "FileContentIterator.h"
       
    23 #include "contentiteratordata.h"
       
    24 
       
    25 using ContentAccess::CContentIterator;
       
    26 using ContentAccess::TVirtualPathPtr;
       
    27 
       
    28 _LIT(KIteratorThread,"ContentIterator");
       
    29 EXPORT_C CContentIterator* CContentIterator::NewL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType) 
       
    30 	{  
       
    31 	CContentIterator* self = new (ELeave) CContentIterator();
       
    32 	CleanupStack::PushL(self);
       
    33 	self->ConstructL(aPath, aRecursive, aMimeType);
       
    34 	CleanupStack::Pop();
       
    35 	return self;
       
    36 	}
       
    37 
       
    38 CContentIterator::CContentIterator() : CActive(EPriorityStandard)
       
    39 	{
       
    40 	}
       
    41 
       
    42 CContentIterator::~CContentIterator()
       
    43 	{
       
    44 	// tell thread to cancel and shutdown
       
    45 	Cancel();
       
    46 	
       
    47 	// close thread handle
       
    48 	iWorkerThread.Close();
       
    49 	delete info; 
       
    50 	}
       
    51 
       
    52 void CContentIterator::ConstructL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType)
       
    53 	{	
       
    54 	// This data buffer will be shared between the client and the worker thread
       
    55 	info = CContentIteratorData::NewL(aPath,aRecursive,aMimeType);
       
    56 	
       
    57 	// create the thread, need a big heap and stack for recursively searching through directories
       
    58 	User::LeaveIfError(iWorkerThread.Create(KIteratorThread(),CContentIterator::ThreadEntry,32768, KMinHeapSize, 131072, (void *) info , EOwnerProcess));
       
    59 
       
    60 	// add ourselves to active scheduler
       
    61 	CActiveScheduler::Add(this);
       
    62 
       
    63 	// Set up notification in case the thread panics etc
       
    64 	iStatus = KRequestPending;
       
    65 	iWorkerThread.Logon(iStatus);
       
    66 	SetActive();
       
    67 	
       
    68 	// start the thread
       
    69 	iWorkerThread.Resume();
       
    70 	}
       
    71 
       
    72 
       
    73 void CContentIterator::DoCancel()
       
    74 	{
       
    75 	// Wait until thread finishes whatever it's doing
       
    76 	info->Lock();
       
    77 	 
       
    78 	// Signal for the thread to close
       
    79 	info->RunThreadFunction(EIteratorShutdownThread);
       
    80 	}
       
    81 
       
    82 void CContentIterator::RunL()
       
    83 	{
       
    84 	// Thread must have completed
       
    85 	if(iWorkerThread.ExitType() == EExitPanic)
       
    86 		{
       
    87 		// Thread panicd, better panic our thread
       
    88 		User::Panic(KCafPanicString, ECafPanicContentIteratorThreadPanic);
       
    89 		}
       
    90 	}
       
    91 
       
    92 EXPORT_C TVirtualPathPtr CContentIterator::VirtualPath()
       
    93 	{
       
    94 	// Wait until thread finishes whatever it's doing
       
    95 	info->Lock(); 
       
    96 	iFileName.Copy(info->Path());	
       
    97 	iUniqueId.Copy(info->UniqueId());	
       
    98 	info->Unlock(); 
       
    99 	return TVirtualPathPtr(iFileName, iUniqueId);
       
   100 	}
       
   101 
       
   102 EXPORT_C const TDesC&  CContentIterator::Name()
       
   103 	{
       
   104 	// Wait until thread finishes whatever it's doing
       
   105 	info->Lock(); 
       
   106 	iName.Copy(info->Name());	
       
   107 	info->Unlock(); 
       
   108 	return iName;
       
   109 	}
       
   110 
       
   111 EXPORT_C const TDesC8& CContentIterator::MimeType()
       
   112 	{
       
   113 	// Wait until thread finishes whatever it's doing
       
   114 	info->Lock(); 
       
   115 	iMimeType.Copy(info->MimeType());
       
   116 	info->Unlock(); 
       
   117 	return iMimeType;
       
   118 	}
       
   119 
       
   120 EXPORT_C void CContentIterator::Next(TRequestStatus &aStatus)
       
   121 	{
       
   122 	// Wait until thread finishes whatever it's doing
       
   123 	info->Lock(); 
       
   124 
       
   125 	// Remember which thread and TRequestStatus to notify
       
   126 	TThreadId id = RThread().Id();
       
   127 	info->SetClientRequest(id, aStatus);
       
   128 	
       
   129 	// Tell it to find the next iteration
       
   130 	info->RunThreadFunction(EIteratorFindNextContentObject); 
       
   131 	}
       
   132 	
       
   133 
       
   134 TInt CContentIterator::ThreadEntry(TAny* aAny) 
       
   135 	{
       
   136 	TBool exitNow = EFalse;
       
   137 	TInt err;
       
   138 	CFileContentIterator* iterator = NULL;
       
   139 	RThread clientThread;
       
   140 	CContentIteratorData* info = reinterpret_cast <CContentIteratorData *> (aAny);
       
   141 	
       
   142 	// create a trap handler
       
   143 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   144 	
       
   145 	while(!exitNow)
       
   146 		{
       
   147 		// Thread will wait here until signaled by other CContentIterator functions
       
   148 		switch(info->ThreadWait())
       
   149 			{
       
   150 		// Client thread has asked us to shutdown, exit loop
       
   151 		case EIteratorShutdownThread:
       
   152 			exitNow = ETrue;
       
   153 			break;
       
   154 		// Client thread is asking us to find the next object	
       
   155 		case EIteratorFindNextContentObject:
       
   156 			if(!iterator)
       
   157 				{
       
   158 				TRAP(err, iterator = CFileContentIterator::NewL(info->Path(), info->IsRecursive(), info->MimeType()));
       
   159 				info->SetData(KNullDesC(), KNullDesC(), KNullDesC(), KNullDesC8());
       
   160 				}
       
   161 			else
       
   162 				{
       
   163 				err = iterator->Next();
       
   164 				}
       
   165 	
       
   166 			if(err == KErrNone)
       
   167 				{
       
   168 				// If a content object was found, write the value back 
       
   169 				// into the other thread while the info is still locked
       
   170 				info->SetData(iterator->FileName(),iterator->UniqueId(), iterator->Name(), iterator->MimeType());
       
   171 				}
       
   172 
       
   173 			// Complete the clients asynchronous request
       
   174 			info->CompleteClientRequest(err);
       
   175 			break;
       
   176 		default:
       
   177 			User::Panic(KCafPanicString, ECafPanicContentIteratorUnknownRequest);
       
   178 			break;
       
   179 			};
       
   180 
       
   181 		// Allow the client to post a new request
       
   182 		info->Unlock(); 
       
   183 		}
       
   184 	delete iterator;
       
   185 	delete cleanup;
       
   186 	return KErrNone;
       
   187 	}
       
   188