core/src/file_reader.cpp
changeset 0 7f656887cf89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/file_reader.cpp	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,146 @@
+// file_reader.cpp
+// 
+// Copyright (c) 2005 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "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:
+// Accenture - Initial contribution
+//
+
+#include "file_reader.h"
+
+
+CFileReader* CFileReader::NewL(TInt aBlockSize, RFs& aFs, TBool aDirect)
+	{
+	CFileReader* self = new(ELeave) CFileReader(aFs, aDirect, aBlockSize);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFileReader::~CFileReader()
+	{
+	Cancel();
+	iFile.Close();
+	delete iBuf;
+	}
+
+void CFileReader::Read(const TDesC& aFileName, MFileReaderObserver& aObserver)
+	{
+	Read(aFileName, 0, aObserver);
+	}
+
+void CFileReader::Read(const TDesC& aFileName, TInt aOffset, MFileReaderObserver& aObserver)
+	{
+	ASSERT(!IsActive());
+	iObserver = &aObserver;
+	iFirstRead = ETrue;
+	if (iDirect)
+		{
+		iDirectOffset = aOffset;
+		iFileName = aFileName;
+		ReadNextDirectChunk();
+		}
+	else
+		{
+		iFile.Close();
+		TInt err = iFile.Open(iFs, aFileName, EFileRead);
+		if (err)
+			{
+			iObserver->HandleFileReadError(err);
+			}
+		else
+			{
+			err = iFile.Seek(ESeekStart, aOffset);
+			if (err)
+				{
+				iObserver->HandleFileReadError(err);
+				}
+			ReadNextChunk();
+			}
+		}
+	}
+
+CFileReader::CFileReader(RFs& aFs, TBool aDirect, TInt aBlockSize)
+	: CActive(CActive::EPriorityStandard), iFs(aFs), iBlockSize(aBlockSize), iPtr(NULL, 0), iDirect(aDirect)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CFileReader::ConstructL()
+	{
+	iBuf = HBufC8::NewL(iBlockSize);
+	iPtr.Set(iBuf->Des());
+	}
+
+void CFileReader::ReadNextChunk()
+	{
+	ASSERT(!IsActive());
+	iPtr.Zero();
+	iFile.Read(iPtr, iBlockSize, iStatus);
+	SetActive();
+	}
+
+void CFileReader::ReadNextDirectChunk()
+	{
+	ASSERT(!IsActive());
+	iPtr.Zero();
+	SetActive();
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+void CFileReader::DoCancel()
+	{
+	// Can't cancel reads, to do nothing.
+	}
+
+void CFileReader::RunL()
+	{
+	TInt err;
+	if (iDirect)
+		{
+		err = iFs.ReadFileSection(iFileName, iDirectOffset, iPtr, iBlockSize);
+		if (err == KErrNone)
+			{
+			iDirectOffset += iPtr.Length();
+			}
+		}
+	else
+		{
+		err = iStatus.Int();
+		}
+
+	if (err)
+		{
+		iObserver->HandleFileReadError(err);
+		return;
+		}
+
+	TBool keepGoing(EFalse);
+	if (iFirstRead)
+		{
+		iFirstRead = EFalse;
+		iObserver->HandleFileData(iPtr, MFileReaderObserver::EFirst, keepGoing);
+		}
+	else if (iPtr.Length() < iBlockSize)
+		{
+		iFile.Close();
+		TBool dummy;
+		iObserver->HandleFileData(iPtr, MFileReaderObserver::ELast, dummy);
+		}
+	else
+		{
+		iObserver->HandleFileData(iPtr, MFileReaderObserver::EMiddle, keepGoing);
+		}
+
+	if (keepGoing)
+		{
+		iDirect ? ReadNextDirectChunk() : ReadNextChunk();
+		}
+	}
+