filehandling/htmltorichtextconverter/src/CHtmlToCrtConvBuffer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 10:12:00 +0200
changeset 0 2e3d3ce01487
permissions -rw-r--r--
Revision: 201002 Kit: 201005

// Copyright (c) 2001-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 "CHtmlToCrtConvBuffer.h"
#include "CHtmlToCrtConvAssertDefines.h"

const TInt KReadBufferSize = 256;

CHtmlToCrtConvBuffer::CHtmlToCrtConvBuffer(CCnvCharacterSetConverter& aCnvCharacterSetConverter)
:iCnvCharacterSetConverter(aCnvCharacterSetConverter)
	{
	}

CHtmlToCrtConvBuffer* CHtmlToCrtConvBuffer::NewL(const TDesC& aFile, RFs& aFsSession, CCnvCharacterSetConverter& aCnvCharacterSetConverter)
	{
	CHtmlToCrtConvBuffer* self=new(ELeave) CHtmlToCrtConvBuffer(aCnvCharacterSetConverter);
	CleanupStack::PushL(self);
	self->ConstructL(aFile, aFsSession);
	CleanupStack::Pop(self);
	return self;
	}

void CHtmlToCrtConvBuffer::ConstructL(const TDesC& aFile, RFs& aFsSession)
	{
	User::LeaveIfError(iFile.Open(aFsSession, aFile, EFileShareReadersOnly));
	iSourceBuffer=HBufC8::NewL(KReadBufferSize);
	iUnicodeBuffer=HBufC16::NewL(KReadBufferSize);
	}

CHtmlToCrtConvBuffer::~CHtmlToCrtConvBuffer()
	{
	iFile.Close();
	delete iSourceBuffer;
	delete iUnicodeBuffer;
	}

//===================================================================================================
//ReadCharacterL - returns EFalse if no character read, ie when end of file and end of buffer reached
//===================================================================================================
TBool CHtmlToCrtConvBuffer::ReadCharacterL(TChar& aCharacter, TInt& aBufferPosition, TBool& aEndOfBuffer)
	{
	ASSERT((iBufferPosition>=0 && iBufferPosition<=KReadBufferSize));

	aEndOfBuffer=EFalse;
	if (iBufferPosition < iUnicodeBuffer->Length())
		//character in buffer
		{
		aBufferPosition=iBufferPosition;
		aCharacter=(*iUnicodeBuffer)[iBufferPosition++];
		if (iBufferPosition==iUnicodeBuffer->Length())
			{
			aEndOfBuffer=ETrue;
			}
		return ETrue;
		}
	else
		//no characters remaining in buffer
		{
		aBufferPosition=0;
		if (FillBufferL())
			//file was not empty
			{
			aCharacter=(*iUnicodeBuffer)[iBufferPosition++];
			if (iBufferPosition==iUnicodeBuffer->Length())
				{
				aEndOfBuffer=ETrue;
				}
			return ETrue;
			}
		else
			//file was empty
			{
			aEndOfBuffer=ETrue;
			return EFalse;
			}
		}
	}

void CHtmlToCrtConvBuffer::GetPartOfBufferL(TPtrC16& aPartOfBuffer, TInt aStartPosition, TInt aEndPosition) const
	{
	TPtrC16 partOfBuffer(iUnicodeBuffer->Mid(aStartPosition,(aEndPosition - aStartPosition + 1)));
	aPartOfBuffer.Set(partOfBuffer);
	}

void CHtmlToCrtConvBuffer::GetToEndOfBufferL(TPtrC16& aPartOfBuffer, TInt aStartPosition) const
	{
	TPtrC16 partOfBuffer(iUnicodeBuffer->Mid(aStartPosition));
	aPartOfBuffer.Set(partOfBuffer);
	}

void CHtmlToCrtConvBuffer::GetSampleOfTextFromFileL(TDes8& aSample, TInt aLength, TInt aOffset)
	{
	TInt fileSize=0;
	User::LeaveIfError(iFile.Size(fileSize));

	//adjust aOffset - used to get sample of text from file, so should read aLength chars
	if(fileSize<aLength)
		aOffset=0;
	else if(fileSize<aOffset+aLength)
		aOffset=fileSize-aLength;

	User::LeaveIfError(iFile.Read(aOffset, aSample, aLength));
	ResetL();
	}

void CHtmlToCrtConvBuffer::ResetL()
	{
	//set read file position to start of file
	TInt pos=0;
	User::LeaveIfError(iFile.Seek(ESeekStart, pos));
	}

TBool CHtmlToCrtConvBuffer::FillBufferL()
	{
	iBufferPosition = 0;
	//iSourceBuffer contains any remaining unconverted characters from last call to ConvertToUnicode.
	TPtr8 sourcePtr(iSourceBuffer->Des());
	TInt sourceLength=iSourceBuffer->Length();
	TBool endOfFileReached=EFalse;

	//newBuffer gets characters from the file to fill the remaining space in iSourceBuffer
	HBufC8* newBuffer=HBufC8::NewLC(KReadBufferSize-sourceLength);
	TPtr8 newBufferPtr(newBuffer->Des());
	User::LeaveIfError(iFile.Read(newBufferPtr, KReadBufferSize-sourceLength));
	sourcePtr.Append(newBufferPtr);
	CleanupStack::PopAndDestroy(newBuffer);

	sourceLength=sourcePtr.Length();
	if(sourceLength < KReadBufferSize)
		{
		endOfFileReached=ETrue;
		if(sourcePtr.Length()==0)
			{
			return EFalse;
			}
		}

	TPtr16 unicodePtr(iUnicodeBuffer->Des());
	unicodePtr.Zero();

	DoConvertBufferL(sourcePtr, unicodePtr, sourceLength, endOfFileReached);

	return ETrue;
	}

//=============================================================================
//DoConvertBufferL - sets iUnicodeBuffer to contain the converted characters,
//and iSourceBuffer to contain only the unconverted characters.
//=============================================================================
void CHtmlToCrtConvBuffer::DoConvertBufferL(TPtr8& aSourcePtr, TPtr16& aUnicodePtr, TInt& aSourceLength, TBool& aEndOfFile)
	{
	HBufC16* tempUnicode=HBufC16::NewLC(aSourceLength);
	TPtr16 tempUnicodePtr(tempUnicode->Des());

	//returnValue = number of unconverted characters at end of buffer
	TInt returnValue=iCnvCharacterSetConverter.ConvertToUnicode(tempUnicodePtr, aSourcePtr, iState);

	if(!aEndOfFile)
		{
		if(returnValue==CCnvCharacterSetConverter::EErrorIllFormedInput)
			User::Leave(KErrCorrupt);
		}
	if(returnValue<0)//future-proof against 'TError' expanding
		User::Leave(KErrGeneral);

	aUnicodePtr.Append(tempUnicodePtr);
	CleanupStack::PopAndDestroy(tempUnicode);
	
	//set iSourceBuffer to contain only the unconverted characters
	aSourcePtr.Copy(aSourcePtr.Right(returnValue));
	aSourceLength=aSourcePtr.Length();
	}