os/mm/mmlibs/mmfw/Recogniser/src/filereader.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "readers.h"
    17 
    18 //
    19 //
    20 //
    21 CFileReader::CFileReader(RFile* aFile)
    22  :	CBufferReader(iFileBuffer, CReader::EFile),
    23  	iFile(aFile)
    24 	{
    25 	}
    26 
    27 
    28 //
    29 //
    30 //
    31 CFileReader::~CFileReader()
    32 	{
    33 	}
    34 
    35 
    36 //
    37 //
    38 //
    39 CFileReader* CFileReader::NewLC(RFile* aFile)
    40 	{
    41 	CFileReader* self = new(ELeave) CFileReader(aFile);
    42 	CleanupStack::PushL(self);
    43 	self->ConstructL();
    44 	return self;
    45 	}
    46 
    47 
    48 //
    49 //
    50 //
    51 void CFileReader::ConstructL()
    52 	{
    53 	TInt pos = 0;
    54 	User::LeaveIfError(iFile->Seek(ESeekStart, pos));
    55 	User::LeaveIfError(iFile->Read(iFileBuffer));
    56 	}
    57 
    58 
    59 //
    60 // Checks if there is aAmount of data left in the buffer.
    61 // It is important to call the base-class implementation first
    62 // to ensure correct operation.
    63 //
    64 TBool CFileReader::CheckEnoughData(TInt aAmount)
    65 	{
    66 	if (CBufferReader::CheckEnoughData(aAmount))
    67 		{
    68 		return ETrue;
    69 		}
    70 		
    71 	// Try to read more data.
    72 	TInt bufPos = CBufferReader::Position();
    73 	TInt err = PhysicallySeekAndRead(bufPos - iFileBuffer.Length());
    74 	if (err == KErrNone)
    75 		{
    76 		// The read may have succeeded but that 
    77 		// still doesn't mean we have enough data.
    78 		return (aAmount <= iFileBuffer.Length());
    79 		}
    80 	
    81 	return EFalse;
    82 	}
    83 
    84 
    85 //
    86 //
    87 //
    88 void CFileReader::Reset()
    89 	{
    90 	CBufferReader::Reset(); // This will reset iBufPos.
    91 	
    92 	if (iFilePos != 0)
    93 		{
    94 		// We need to seek to the start and fill the buffer.
    95 		iFilePos = 0;
    96 		TInt filepos = 0;
    97 		TInt err = iFile->Seek(ESeekStart, filepos);
    98 		if (err == KErrNone)
    99 			{
   100 			err = iFile->Read(iFileBuffer);
   101 			}
   102 			
   103 		if (err != KErrNone)
   104 			{
   105 			iFileBuffer.Zero();
   106 			}
   107 		}
   108 	else
   109 		{
   110 		// There's no need to seek and read.
   111 		iFilePos = 0;
   112 		}
   113 	}
   114 
   115 
   116 //
   117 //
   118 //
   119 void CFileReader::SeekL(TInt aOffset)
   120 	{
   121 	TInt err = CReader::Seek(aOffset);
   122 	if (err == KErrUnderflow)
   123 		{
   124 		TInt bufPos = CBufferReader::Position();
   125 		aOffset += bufPos - iFileBuffer.Length();
   126 		User::LeaveIfError(PhysicallySeekAndRead(aOffset));
   127 		}
   128 	}
   129 
   130 
   131 //
   132 // It could be possible for a 64-bit field in formats such as MPEG4
   133 // to have values that would fit in a 32-bit variable. In this case
   134 // we can use it for seeking. This function checks if a 64-bit value
   135 // is compatible with RFile's 32-bit operations.
   136 //
   137 void CFileReader::SeekL(TInt64 aOffset)
   138 	{
   139 	if (aOffset < KMinTInt64)
   140 		{
   141 		User::Leave(KErrNotSupported);
   142 		}
   143 		
   144 	if (aOffset > KMaxTInt64)
   145 		{
   146 		User::Leave(KErrNotSupported);
   147 		}
   148 	
   149 	if (aOffset < (TInt64)KMaxTInt)
   150 	    {
   151         TInt low = (TInt)I64LOW(aOffset);
   152         SeekL(low);
   153 	    }
   154 	else
   155 	    {
   156         TInt err = CReader::Seek(aOffset);
   157         if (err == KErrUnderflow)
   158             {
   159             TInt64 bufPos = CBufferReader::Position();
   160             aOffset += bufPos - iFileBuffer.Length();
   161             User::LeaveIfError(PhysicallySeekAndRead(aOffset));
   162             }
   163 	    }
   164 	}
   165 	
   166 //
   167 // This function seeks forward/backward aOffset bytes
   168 // and fills the buffer from that point.
   169 //
   170 TInt CFileReader::PhysicallySeekAndRead(TInt aOffset)
   171 	{
   172 	TInt err;
   173 	
   174 	// New buffer contents so read from the start of it.
   175 	CBufferReader::Reset();
   176 	
   177 	iFilePos = aOffset;
   178 	err = iFile->Seek(ESeekCurrent, aOffset);
   179 	
   180 	if (err != KErrNone)
   181 		{
   182 		return err;
   183 		}
   184 
   185 	err = iFile->Read(iFileBuffer);
   186 	if (err != KErrNone)
   187 		{
   188 		return err;
   189 		}
   190 	return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);
   191 	}
   192 TInt CFileReader::PhysicallySeekAndRead(TInt64 aOffset)
   193     {
   194     TInt err;
   195     // New buffer contents so read from the start of it.
   196     CBufferReader::Reset();
   197     
   198     iFilePos = aOffset;
   199     RFile64* tempfile;
   200     tempfile = static_cast<RFile64*> (iFile);
   201  
   202     err = tempfile->Seek(ESeekCurrent, iFilePos);
   203 	if (err != KErrNone)
   204 		{
   205 		return err;
   206 		}
   207 
   208 	err = iFile->Read(iFileBuffer);
   209 	if (err != KErrNone)
   210 		{
   211 		return err;
   212 		}
   213 		
   214 	return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);
   215 	}
   216