/*
* 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 <f32file.h>
#include <apmstd.h>
#include "contentIterator.h"
#include "virtualpath.h"
#include "content.h"
#include "manager.h"
#include "embeddedobject.h"
#include "FileContentIteratorBase.h"
#include "EmbeddedcontentIterator.h"
using namespace ContentAccess;
_LIT(KCAFBackSlashCharacter, "\\");
CFileContentIteratorBase* CFileContentIteratorBase::NewL(CManager &aManager, const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType)
{
CFileContentIteratorBase* self = new (ELeave) CFileContentIteratorBase(aManager, aPath, aRecursive, aMimeType);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CFileContentIteratorBase::CFileContentIteratorBase(CManager& aManager, const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType) :
iManager(aManager), iPath(aPath), iRecursive(aRecursive), iMimeType(aMimeType)
{
iDirIndex = 0;
iFileIndex = 0;
}
void CFileContentIteratorBase::ConstructL()
{
// Get our list of files and directories
User::LeaveIfError(iManager.GetDir(iPath, ESortByName, KEntryAttNormal, iCurrentFileList, iCurrentDirectoryList));
if(!iRecursive)
{
// Won't be needing the list of directories
delete iCurrentDirectoryList;
iCurrentDirectoryList = NULL;
}
// Find the Next, (ie. first content object) inside this directory
// This will leave if nothing was found
User::LeaveIfError(Next());
}
CFileContentIteratorBase::~CFileContentIteratorBase()
{
delete iSubIterator;
delete iCurrentDirectoryList;
delete iCurrentFileList;
delete iNewPath;
}
const TDesC& CFileContentIteratorBase::FileName() const
{
return iSubIterator->FileName();
}
const TDesC& CFileContentIteratorBase::UniqueId() const
{
return iSubIterator->UniqueId();
}
const TDesC& CFileContentIteratorBase::Name() const
{
return iSubIterator->Name();
}
const TDesC8& CFileContentIteratorBase::MimeType() const
{
return iSubIterator->MimeType();
}
TInt CFileContentIteratorBase::Next()
{
_LIT(KSysDirEntry, "sys");
TInt ret = KErrNotFound;
// If we are already looking into some sub container, try finding the next in there
if(iSubIterator)
{
ret = iSubIterator->Next();
if(ret == KErrNone)
{
return ret;
}
else
{
// Delete sub-iterator
delete iSubIterator;
iSubIterator = NULL;
delete iNewPath;
iNewPath = NULL;
}
}
// Search files in our directory first
// this allows us to free memory used by iCurrentFileList
// before recursing into sub-directories
if(iCurrentFileList)
{
for ( ; iFileIndex < iCurrentFileList->Count(); iFileIndex++)
{
// Get a reference to the file we are interested in
const TEntry &entry = (*iCurrentFileList)[iFileIndex];
// create a new path string for the sub directory
TRAP(ret, iNewPath = HBufC::NewL(iPath.Length() + entry.iName.Length()));
if(ret != KErrNone)
{
return ret;
}
iNewPath->Des().Append(iPath);
iNewPath->Des().Append(entry.iName);
// Look inside the file
TRAP(ret, iSubIterator = CEmbeddedContentIterator::NewL(TVirtualPathPtr(*iNewPath, KNullDesC()), iRecursive, iMimeType));
if(ret == KErrNone)
{
// must have found something in the file
// make sure next time we look at the next item in our list
iFileIndex++;
return KErrNone;
}
// next iteration
delete iNewPath;
iNewPath = NULL;
}
delete iCurrentFileList;
iCurrentFileList = NULL;
}
if(iRecursive)
{
// Search sub directories
for ( ; iDirIndex < iCurrentDirectoryList->Count(); iDirIndex++)
{
// Get a reference to the directory we are interested in
const TEntry &entry = (*iCurrentDirectoryList)[iDirIndex];
// make sure it's not the sys directory
if(KSysDirEntry().CompareF(entry.iName) == 0 && iPath.Length() == 3)
{
// go to the next iteration, skip the sys directory
continue;
}
// create a new path string for the sub directory
TRAP(ret, iNewPath = HBufC::NewL(iPath.Length() + 1 + entry.iName.Length()));
if(ret != KErrNone)
{
return ret;
}
iNewPath->Des().Append(iPath);
iNewPath->Des().Append(entry.iName);
iNewPath->Des().Append(KCAFBackSlashCharacter);
// lets look inside the directory
TRAP(ret, iSubIterator = CFileContentIteratorBase::NewL(iManager, *iNewPath, iRecursive, iMimeType));
if(ret == KErrNone)
{
// must have found something in the sub-iterator
// make sure next time we look at the next item in our list
iDirIndex++;
return KErrNone;
}
// next iteration
delete iNewPath;
iNewPath = NULL;
}
}
// reached the end of our list of directories and list of files
return KErrNotFound;
}