mmlibs/mmfw/Recogniser/src/filereader.cpp
changeset 0 b8ed18f6c07b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/Recogniser/src/filereader.cpp	Thu Oct 07 22:34:12 2010 +0100
@@ -0,0 +1,216 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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 "readers.h"
+
+//
+//
+//
+CFileReader::CFileReader(RFile* aFile)
+ :	CBufferReader(iFileBuffer, CReader::EFile),
+ 	iFile(aFile)
+	{
+	}
+
+
+//
+//
+//
+CFileReader::~CFileReader()
+	{
+	}
+
+
+//
+//
+//
+CFileReader* CFileReader::NewLC(RFile* aFile)
+	{
+	CFileReader* self = new(ELeave) CFileReader(aFile);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+
+//
+//
+//
+void CFileReader::ConstructL()
+	{
+	TInt pos = 0;
+	User::LeaveIfError(iFile->Seek(ESeekStart, pos));
+	User::LeaveIfError(iFile->Read(iFileBuffer));
+	}
+
+
+//
+// Checks if there is aAmount of data left in the buffer.
+// It is important to call the base-class implementation first
+// to ensure correct operation.
+//
+TBool CFileReader::CheckEnoughData(TInt aAmount)
+	{
+	if (CBufferReader::CheckEnoughData(aAmount))
+		{
+		return ETrue;
+		}
+		
+	// Try to read more data.
+	TInt bufPos = CBufferReader::Position();
+	TInt err = PhysicallySeekAndRead(bufPos - iFileBuffer.Length());
+	if (err == KErrNone)
+		{
+		// The read may have succeeded but that 
+		// still doesn't mean we have enough data.
+		return (aAmount <= iFileBuffer.Length());
+		}
+	
+	return EFalse;
+	}
+
+
+//
+//
+//
+void CFileReader::Reset()
+	{
+	CBufferReader::Reset(); // This will reset iBufPos.
+	
+	if (iFilePos != 0)
+		{
+		// We need to seek to the start and fill the buffer.
+		iFilePos = 0;
+		TInt filepos = 0;
+		TInt err = iFile->Seek(ESeekStart, filepos);
+		if (err == KErrNone)
+			{
+			err = iFile->Read(iFileBuffer);
+			}
+			
+		if (err != KErrNone)
+			{
+			iFileBuffer.Zero();
+			}
+		}
+	else
+		{
+		// There's no need to seek and read.
+		iFilePos = 0;
+		}
+	}
+
+
+//
+//
+//
+void CFileReader::SeekL(TInt aOffset)
+	{
+	TInt err = CReader::Seek(aOffset);
+	if (err == KErrUnderflow)
+		{
+		TInt bufPos = CBufferReader::Position();
+		aOffset += bufPos - iFileBuffer.Length();
+		User::LeaveIfError(PhysicallySeekAndRead(aOffset));
+		}
+	}
+
+
+//
+// It could be possible for a 64-bit field in formats such as MPEG4
+// to have values that would fit in a 32-bit variable. In this case
+// we can use it for seeking. This function checks if a 64-bit value
+// is compatible with RFile's 32-bit operations.
+//
+void CFileReader::SeekL(TInt64 aOffset)
+	{
+	if (aOffset < KMinTInt64)
+		{
+		User::Leave(KErrNotSupported);
+		}
+		
+	if (aOffset > KMaxTInt64)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	
+	if (aOffset < (TInt64)KMaxTInt)
+	    {
+        TInt low = (TInt)I64LOW(aOffset);
+        SeekL(low);
+	    }
+	else
+	    {
+        TInt err = CReader::Seek(aOffset);
+        if (err == KErrUnderflow)
+            {
+            TInt64 bufPos = CBufferReader::Position();
+            aOffset += bufPos - iFileBuffer.Length();
+            User::LeaveIfError(PhysicallySeekAndRead(aOffset));
+            }
+	    }
+	}
+	
+//
+// This function seeks forward/backward aOffset bytes
+// and fills the buffer from that point.
+//
+TInt CFileReader::PhysicallySeekAndRead(TInt aOffset)
+	{
+	TInt err;
+	
+	// New buffer contents so read from the start of it.
+	CBufferReader::Reset();
+	
+	iFilePos = aOffset;
+	err = iFile->Seek(ESeekCurrent, aOffset);
+	
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	err = iFile->Read(iFileBuffer);
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);
+	}
+TInt CFileReader::PhysicallySeekAndRead(TInt64 aOffset)
+    {
+    TInt err;
+    // New buffer contents so read from the start of it.
+    CBufferReader::Reset();
+    
+    iFilePos = aOffset;
+    RFile64* tempfile;
+    tempfile = static_cast<RFile64*> (iFile);
+ 
+    err = tempfile->Seek(ESeekCurrent, iFilePos);
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	err = iFile->Read(iFileBuffer);
+	if (err != KErrNone)
+		{
+		return err;
+		}
+		
+	return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);
+	}
+