First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 CFileReader::CFileReader(RFile* aFile)
22 : CBufferReader(iFileBuffer, CReader::EFile),
31 CFileReader::~CFileReader()
39 CFileReader* CFileReader::NewLC(RFile* aFile)
41 CFileReader* self = new(ELeave) CFileReader(aFile);
42 CleanupStack::PushL(self);
51 void CFileReader::ConstructL()
54 User::LeaveIfError(iFile->Seek(ESeekStart, pos));
55 User::LeaveIfError(iFile->Read(iFileBuffer));
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.
64 TBool CFileReader::CheckEnoughData(TInt aAmount)
66 if (CBufferReader::CheckEnoughData(aAmount))
71 // Try to read more data.
72 TInt bufPos = CBufferReader::Position();
73 TInt err = PhysicallySeekAndRead(bufPos - iFileBuffer.Length());
76 // The read may have succeeded but that
77 // still doesn't mean we have enough data.
78 return (aAmount <= iFileBuffer.Length());
88 void CFileReader::Reset()
90 CBufferReader::Reset(); // This will reset iBufPos.
94 // We need to seek to the start and fill the buffer.
97 TInt err = iFile->Seek(ESeekStart, filepos);
100 err = iFile->Read(iFileBuffer);
110 // There's no need to seek and read.
119 void CFileReader::SeekL(TInt aOffset)
121 TInt err = CReader::Seek(aOffset);
122 if (err == KErrUnderflow)
124 TInt bufPos = CBufferReader::Position();
125 aOffset += bufPos - iFileBuffer.Length();
126 User::LeaveIfError(PhysicallySeekAndRead(aOffset));
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.
137 void CFileReader::SeekL(TInt64 aOffset)
139 if (aOffset < KMinTInt64)
141 User::Leave(KErrNotSupported);
144 if (aOffset > KMaxTInt64)
146 User::Leave(KErrNotSupported);
149 if (aOffset < (TInt64)KMaxTInt)
151 TInt low = (TInt)I64LOW(aOffset);
156 TInt err = CReader::Seek(aOffset);
157 if (err == KErrUnderflow)
159 TInt64 bufPos = CBufferReader::Position();
160 aOffset += bufPos - iFileBuffer.Length();
161 User::LeaveIfError(PhysicallySeekAndRead(aOffset));
167 // This function seeks forward/backward aOffset bytes
168 // and fills the buffer from that point.
170 TInt CFileReader::PhysicallySeekAndRead(TInt aOffset)
174 // New buffer contents so read from the start of it.
175 CBufferReader::Reset();
178 err = iFile->Seek(ESeekCurrent, aOffset);
185 err = iFile->Read(iFileBuffer);
190 return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);
192 TInt CFileReader::PhysicallySeekAndRead(TInt64 aOffset)
195 // New buffer contents so read from the start of it.
196 CBufferReader::Reset();
200 tempfile = static_cast<RFile64*> (iFile);
202 err = tempfile->Seek(ESeekCurrent, iFilePos);
208 err = iFile->Read(iFileBuffer);
214 return (iFileBuffer.Length() == 0 ? KErrEof : KErrNone);