charconvfw/charconvplugins/src/plugins/iscii.cpp
changeset 0 1fb32624e06b
child 16 748ec5531811
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/charconvfw/charconvplugins/src/plugins/iscii.cpp	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,1690 @@
+/*
+* Copyright (c) 2002 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:     Implements the characterconversion plug-in
+*                for ISCII characterset.
+*
+*/
+
+
+
+
+
+#include <e32std.h>
+#include <charconv.h>
+#include <convgeneratedcpp.h>
+#include <convutils.h>
+
+//The maximum length of any intermediate buffer allocated for conversion.
+const TInt KMaximumLengthOfIntermediateBuffer=5;
+//The ISCII ATR code point, used for ISCII script switching mechanism.
+const TUint KControlCharacterEscape=0xef;
+//The number of Indic scripts supported by the plug-in.
+//ISCII in general addresses all the Indic character sets.
+const TUint KNumberOfIndicCharactersetsSupported = 1;
+//The common reason for panic for all panics raised by the iscii plug-in
+_LIT16(KPanicReason,"ISCII Plug-in Panic"); 
+//The escape sequence for ISCII (ATR) is 0xEF and immidiate byte following 
+//that is the script selection code for Devanagari.
+_LIT8(KEscapeSequenceDevanagari,"\xef\x42");
+//The sequence for Explicit Halant, in unicode it gets converted to VIRAMA+ZWNJ
+_LIT8(KExplicitHalant,"\xe8\xe8");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForExplicitHalant,"\xe8\xfc");
+//The sequence for Soft Halant, in unicode it gets converted to VIRAMA+ZWJ
+_LIT8(KSoftHalant,"\xe8\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForSoftHalant,"\xe8\xfd");
+//Devanagari character Om
+_LIT8(KOm,"\xa1\xe9");
+////For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForOm,"\xfe");
+//Devanagari character Avagraha
+_LIT8(KAvagraha,"\xea\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForAvagraha,"\xff");
+
+//Devanagari character VOCALIC RR
+_LIT8(KVocalicRr,"\xaa\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicRr,"\x80");
+//Devanagari character VOCALIC LL
+_LIT8(KVocalicLl,"\xa7\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicLl,"\x81");
+//Devanagari character VOCALIC L SIGN
+_LIT8(KVocalicLSign,"\xdb\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicLSign,"\x82");
+//Devanagari character VOCALIC LL SIGN
+_LIT8(KVocalicLlSign,"\xdc\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicLlSign,"\x83");
+//Devanagari character VOCALIC L
+_LIT8(KVocalicL,"\xa6\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicL,"\x84");
+//Devanagari character VOCALIC RR SIGN
+_LIT8(KVocalicRrSign,"\xdf\xe9");
+//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
+//sequence is converted to intermediate unused iscii code point.
+_LIT8(KReplacementForVocalicRrSign,"\x85");
+
+//Unconvertible ISCII character
+_LIT8(KIsciiUnconvertibleCharacter,"\xeb");
+
+enum TPanic
+{
+	//The panic raised by ConvertToUnicodeFromModalForeign_Internal() if the input
+	//conversion flag is CCnvCharacterSetConverter::EInputConversionFlagStopAtFirstUnconvertibleCharacter
+	EPanicBadInputConversionFlags=1,
+	//Panic raised if the buffer does not start with the escape sequence 0xEF
+	EPanicBadRemainderOfForeign,
+	//Panic is raised if the length of the search buffer is greater than the length of the 
+	//replacement buffer
+	EPanicBadReplacementBuffer,
+	//If the offset of start of the escape sequence is not an unsigned number.
+	EPanicBadStartOfNextEscapeSequence
+};
+
+//The dummy datastructure for the dummy conversion data i.e. used for conversion if the 
+//script selection code is not supported.
+#define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
+
+LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_foreignToUnicode_1[]=
+	{
+		{
+		0xa0,
+		0xfffd
+		}
+	};
+
+LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_unicodeToForeign_1[]=
+	{
+		{
+		0xfffd,
+		0xa0
+		}
+	};
+
+LOCAL_D const SCnvConversionData::SVariableByteData::SRange foreignVariableByteDataRanges[]=
+	{
+		{
+		0x00,
+		0xff,
+		0,
+		0
+		}
+	};
+
+LOCAL_D const SCnvConversionData::SOneDirectionData::SRange foreignToUnicodeDataRanges[]=
+	{
+		{
+		0x00,
+		0x7f,
+		SCnvConversionData::SOneDirectionData::SRange::EDirect,
+		0,
+		0,
+			{
+			0
+			}
+		},
+		{
+		0xa0,
+		0xff,
+		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
+		0,
+		0,
+			{
+			UData_SKeyedTable1616(keyedTable1616_foreignToUnicode_1)
+			}
+		}
+	};
+
+LOCAL_D const SCnvConversionData::SOneDirectionData::SRange unicodeToForeignDataRanges[]=
+	{
+		{
+		0x0000,
+		0x007f,
+		SCnvConversionData::SOneDirectionData::SRange::EDirect,
+		1,
+		0,
+			{
+			0
+			}
+		},
+		{
+		0x00a0,
+		0xffff,
+		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
+		1,
+		0,
+			{
+			UData_SKeyedTable1616(keyedTable1616_unicodeToForeign_1)
+			}
+		}
+	};
+
+//The dummy conversion data to be used for conversion if the iscii code sequence is not
+//Devanagari (i.e. the script selection code is not 0x42 and something else.
+//In this case the ISCII characters are converted to unconvertible characters.
+
+LOCAL_D const SCnvConversionData conversionDataDummy=
+	{
+	SCnvConversionData::EFixedBigEndian,
+		{
+		ARRAY_LENGTH(foreignVariableByteDataRanges),
+		foreignVariableByteDataRanges
+		},
+		{
+		ARRAY_LENGTH(foreignToUnicodeDataRanges),
+		foreignToUnicodeDataRanges
+		},
+		{
+		ARRAY_LENGTH(unicodeToForeignDataRanges),
+		unicodeToForeignDataRanges
+		},
+	NULL,
+	NULL
+	};
+
+
+
+#ifdef EKA2
+
+///////////////////////////////////////////////////////////////
+// 3.1 Code
+
+// INCLUDES
+#include <ecom/implementationproxy.h>
+#include <charactersetconverter.h>
+
+
+/**
+* The character conversion plug-in implementation for Iscii.
+*
+*  @lib ecom.lib
+*  @since Series 60 3.1
+*/
+
+class CIsciiImplementation : public CCharacterSetConverterPluginInterface
+{
+    public:
+    	//From CCharacterSetConverterPluginInterface
+        virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
+
+	//From CCharacterSetConverterPluginInterface
+        virtual TInt ConvertFromUnicode(
+            CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+            const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
+            TDes8& aForeign, 
+            const TDesC16& aUnicode, 
+            CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters );
+
+	//From CCharacterSetConverterPluginInterface
+        virtual TInt ConvertToUnicode(
+            CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+            TDes16& aUnicode, 
+            const TDesC8& aForeign, 
+            TInt&, 
+            TInt& aNumberOfUnconvertibleCharacters, 
+            TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter );
+
+	//From CCharacterSetConverterPluginInterface
+        virtual TBool IsInThisCharacterSetL(
+            TBool& aSetToTrue, 
+            TInt& aConfidenceLevel, 
+            const TDesC8& );
+
+        static CIsciiImplementation* NewL();
+
+        virtual ~CIsciiImplementation();
+    private:
+        CIsciiImplementation();
+};
+
+//Checks if a descriptor starts with another descriptor at the begining.
+LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer)
+{
+	const TInt lengthOfStart=aEscapeSequence.Length();
+	return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence);
+}
+// -----------------------------------------------------------------------------
+// MatchesEscapeSequence()
+//If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text
+//and  sets the homogeneous run buffer that uses the same conversion data.
+//The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code
+// neither it contains the script switching code.
+//The aRemainderOfForeign buffer 
+
+// Returns: ETrue: If the sequence contains the escape sequence
+//              EFalse: If the sequence does not contain the escape sequence
+//
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun,
+		TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence)
+{
+	const TInt lengthOfEscapeSequence=aEscapeSequence.Length();
+	if (IsStartOf(aEscapeSequence, aRemainderOfForeign))
+		{
+		aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence));
+		const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape);
+		if (startOfNextEscapeSequence==KErrNotFound)
+			{
+			aHomogeneousRun.Set(aRemainderOfForeign);
+			aRemainderOfForeign.Set(NULL, 0);
+			}
+		else
+			{
+			aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence));
+			aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence));
+			}
+		aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence;
+		return ETrue;
+		}
+	return EFalse;
+}
+
+// -----------------------------------------------------------------------------
+// NextHomogeneousForeignRun()
+//Matches the escape sequence of each of the elements of the SState array with the remainder of
+//foreign text and if the escape sequence matches with the start of remainder of the foreign text, 
+//then the conversion data is set to the conversion data corresponding to the escape sequence
+//Also the homogeneous foreign text for conversion with the same escape sequence is set.
+
+// Returns: ETrue: If length of the remainder of foreign buffer is nonzero.
+//              EFalse: If length of the remainder of foreign buffer is zero.
+//
+// -----------------------------------------------------------------------------
+//
+
+
+LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags)
+{
+	TBool returnValue = EFalse;
+	TBool foundState = EFalse;
+	__ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign));
+	if (aRemainderOfForeign.Length()==0)
+		{
+		return returnValue;
+		}
+	const TInt numberOfStates=aArrayOfStates.Count();
+	TInt i;
+	for (i=0; i<numberOfStates; ++i)
+		{
+		const CnvUtilities::SState& state=aArrayOfStates[i];
+		if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence))
+			{
+			aConversionData=state.iConversionData;
+			foundState = ETrue;
+			}
+		}
+	if(!foundState)
+		{
+		for (i=0; i<numberOfStates; ++i)
+			{
+			if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence))
+				{
+				// aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more
+				aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated;
+				break;
+				}
+			}
+
+		MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2));
+		aConversionData = &conversionDataDummy;	
+		returnValue = ETrue;
+		}
+		if (aHomogeneousRun.Length()>0)
+			{
+			returnValue = ETrue;
+			}
+		return returnValue;		
+}
+// -----------------------------------------------------------------------------
+// ConvertFromUnicodeIntermediateBufferInPlace()
+//Default implementation for conversion to the intermediate buffer
+//It modifies the unicode buffer before it is converted back to iscii.
+//The current implementation of iscii plug-in doesn't require any
+//modification to the default implementation
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+
+LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
+{
+	CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1);
+}
+
+// -----------------------------------------------------------------------------
+// DoFindAndModifyBuffer()
+//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
+//Introduced for handling multibyte iscii sequence.
+//Takes the search buffer array and the replacement buffer arrays as input to it and replaces all
+//the occurances of the search buffer with the corresponding replace buffer.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer)
+{
+	FOREVER
+	{
+		TInt offset;
+		__ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer));
+		if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound)
+		{
+			TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr());
+			Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length());
+			Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset);
+			aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length());
+		}
+		else
+			break;
+	}
+	
+}
+
+// -----------------------------------------------------------------------------
+// FindAndModifyBuffer()
+//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
+//Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer.
+//Introduced for handling multibyte iscii sequence.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	RArray<TPtrC8> replaceBuffer;
+	
+	//If the passed buffer contains the replacement buffer,
+	//Then it should not get converted to respective Unicode
+	//buffer rather it should get converted to replacement for
+	//unconvertible character.
+	
+	searchBuffer.Append(KReplacementForExplicitHalant().Right(1));
+	searchBuffer.Append(KReplacementForSoftHalant().Right(1));
+	searchBuffer.Append(KReplacementForOm().Right(1));
+	searchBuffer.Append(KReplacementForAvagraha().Right(1));
+	
+	searchBuffer.Append(KReplacementForVocalicRr().Right(1));
+	searchBuffer.Append(KReplacementForVocalicLl().Right(1));
+	searchBuffer.Append(KReplacementForVocalicLSign().Right(1));
+	searchBuffer.Append(KReplacementForVocalicLlSign().Right(1));
+	searchBuffer.Append(KReplacementForVocalicL().Right(1));
+	searchBuffer.Append(KReplacementForVocalicRrSign().Right(1));
+	
+	//All normal search buffers
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	
+	searchBuffer.Append(KVocalicRr().Mid(0));
+	searchBuffer.Append(KVocalicLl().Mid(0));
+	searchBuffer.Append(KVocalicLSign().Mid(0));
+	searchBuffer.Append(KVocalicLlSign().Mid(0));
+	searchBuffer.Append(KVocalicL().Mid(0));
+	searchBuffer.Append(KVocalicRrSign().Mid(0));
+	
+	//The replacement buffer for the odd cases to restrict the 
+	//replacement buffers not to get converted to the corresponding 
+	//unicode buffer
+	
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
+	
+	//All normal replace buffers		
+	replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForOm().Mid(0));
+	replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
+	
+	
+	replaceBuffer.Append(KReplacementForVocalicRr().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLl().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicL().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0));
+	
+			
+	for(TInt counter=0;counter<searchBuffer.Count();counter++)
+	{
+		DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]);
+	}
+	searchBuffer.Reset();
+	replaceBuffer.Reset();
+	
+}
+
+// -----------------------------------------------------------------------------
+// DoNormalizeReturnValue()
+//Modifies the return value(Number of bytes did not get converted) according to the modified
+//intermediate buffer. Takes the modified intermediate buffer, return value, search and replace
+//buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for
+//the actual buffer corresponding to the replace buffer and adds the difference of the lengths
+//of the actual to replace buffer to the return value.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces)
+{
+	TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length());
+	TUint count = anArrayOfSearches.Count();
+	FOREVER
+	{
+		TBool flag = EFalse;
+		for(TUint i=0;i<count;i++)
+		{
+			TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length()));
+			TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]);
+			if(returnCompare == 0)
+			{
+				flag =ETrue;
+				aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length());
+				buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length());
+				break;
+			}
+		}
+		
+		if(buffer.Length() == 0)
+		{
+			break;
+		}
+		
+		if(!flag)
+		{
+			buffer=buffer.MidTPtr(0,buffer.Length()-1);
+		}
+	}
+
+}
+
+// -----------------------------------------------------------------------------
+// NormalizeReturnValue()
+//Modifies the return value(Number of bytes did not get converted) according to the 
+//replacements done to the iscii buffer before conversion.
+//Internally calls DoNormalizeReturnValue() by suppling the search and replacement 
+//buffers.
+
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	RArray<TPtrC8> replaceBuffer;
+	
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	
+	searchBuffer.Append(KVocalicRr().Mid(0));
+	searchBuffer.Append(KVocalicLl().Mid(0));
+	searchBuffer.Append(KVocalicLSign().Mid(0));
+	searchBuffer.Append(KVocalicLlSign().Mid(0));
+	searchBuffer.Append(KVocalicL().Mid(0));
+	searchBuffer.Append(KVocalicRrSign().Mid(0));
+	
+	replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForOm().Mid(0));
+	replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
+	
+	replaceBuffer.Append(KReplacementForVocalicRr().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLl().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicL().Mid(0));
+	replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0));
+	
+	DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer);
+	searchBuffer.Reset();
+	replaceBuffer.Reset();
+}
+
+// -----------------------------------------------------------------------------
+// HandleHomogeneousRun()
+//Handles a homogeneous foreign buffer and converts the foreign buffer to unicode
+//On return the aUnicode argument contains the converted unicode data.
+//Also it sets the return value, returned from the conversion. The return value also
+//takes into account if there is any buffer modification done before passing it to
+//CCnvCharacterSetConverter::DoConvertToUnicode()
+//buffers.
+
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, 
+							CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
+							TDes16& aUnicode,
+							const TDesC8& aHomogeneousForeign,
+							TInt& aNumberOfUnconvertibleCharacters,
+							TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter,
+							TUint& aOutputConversionFlags,
+							TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed,
+							TInt& aReturnValue)
+{
+	TInt numberOfUnconvertibleCharacters;
+	TInt indexOfFirstByteOfFirstUnconvertibleCharacter;
+	TUint noOfConsumedBytes = 0;
+	if(aConversionData == NULL)
+		{
+		aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput;
+		return;
+		}
+	aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters,
+															  aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters,
+															  indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,
+
+	//The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with
+	//respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and 
+	//aNumberOfUnconvertibleCharacters need to be adjusted accordingly.
+	
+	aInputConversionFlags);
+	if(numberOfUnconvertibleCharacters>0)
+		{
+		if(aNumberOfUnconvertibleCharacters == 0)
+			{
+			aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter;
+			}
+		aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters;
+		}
+	noOfConsumedBytes = aHomogeneousForeign.Length();
+	//To Check whether it is really required.
+	NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign);
+	aNumberOfForeignBytesConsumed+=noOfConsumedBytes;
+	if(aReturnValue>0)
+		{
+		TUint normalizedReturnValue = aReturnValue;
+		
+		//There original iscii buffer copied to an intermediate iscii buffer and then modified 
+		//and is then passed for conversion. Now, after conversion, the return value needs to
+		//be adjusted according to the original buffer. NormalizeReturnValue() does the 
+		//same thing.
+		
+		NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign);
+		aNumberOfForeignBytesConsumed-=normalizedReturnValue;
+		aReturnValue=normalizedReturnValue;
+		}
+	
+	//The HandleHomogeneousRun() method is called in a loop and once there is some
+	//iscii codes converted to unicode, the ConvertToUnicode() should not return
+	//CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion
+	//method does not convert any of the iscii codes ppassed. To ensure that once the
+	//first non-zero number of iscii codes are converted, the internal input conversion
+	//flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable.
+	
+	if(aNumberOfForeignBytesConsumed>0)
+		{
+		aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable;
+		}
+	return;
+}
+
+// -----------------------------------------------------------------------------
+// IsTruncatedDoubleByteIsciiSequence()
+//Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle.
+//If it is a truncated sequence, then returns ETrue else returns EFalse.
+//
+// Returns: ETrue: If the intermediate input iscii buffer is truncated
+//              EFalse: If the intermediate input iscii buffer is not truncated
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	if(anIsciiBuffer.Length () == 0)
+		return EFalse;
+	if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF)
+	return ETrue;
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	TBool ret = EFalse;
+	TBool isNotTruncated =EFalse;
+	
+	//First check if the intermediate iscii buffer is ending with a complete multi byte sequence.
+	//If it ends with a complete multi byte sequence, no need to check if the last character of 
+	//intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse.
+	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
+		{
+		if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0)
+			{
+			isNotTruncated = ETrue;
+			break;
+			}
+		}
+	//If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the 
+	//last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a 
+	//truncated sequence and in that case return ETrue.
+	
+	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
+		{
+		if(isNotTruncated)
+			break;
+		else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0]))
+			{
+			ret =ETrue;
+			break;
+			}
+		}
+	searchBuffer.Reset();
+	return ret;
+}
+
+// -----------------------------------------------------------------------------
+// ReplacementForUnconvertibleUnicodeCharacters()
+//Returns the replacement character for unconvertible unicode character.
+//In the current implementation it is 0x1a (ASCII Substitute character)
+//The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal()
+//in turn which is generated by cnvtool.
+//
+// Returns: Replacemt for unconvertible unicode characters (0x1a)
+//
+// -----------------------------------------------------------------------------
+//
+
+const TDesC8& CIsciiImplementation::ReplacementForUnconvertibleUnicodeCharacters()
+	{
+    return ReplacementForUnconvertibleUnicodeCharacters_internal();
+	}
+
+// -----------------------------------------------------------------------------
+// ConvertFromUnicode()
+//The main conversion function for converting from unicode to iscii
+//Loaded and called by the character conversion framework.
+//In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide
+//utility method for converting unicode to modal character codes.
+//
+// Returns: The numbet of unicode codes it could not convert.
+//
+// -----------------------------------------------------------------------------
+//
+
+TInt CIsciiImplementation::ConvertFromUnicode(
+         CCnvCharacterSetConverter::TEndianness 
+         aDefaultEndiannessOfForeignCharacters, 
+         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
+         TDes8& aForeign, 
+         const TDesC16& aUnicode, 
+         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters )
+	{
+	TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets;
+	aArrayOfCharacterSets[0].iConversionData = &conversionData;
+	aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace;
+	aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari();
+
+		return CnvUtilities::ConvertFromUnicode(
+				aDefaultEndiannessOfForeignCharacters, 
+				aReplacementForUnconvertibleUnicodeCharacters, 
+				aForeign, 
+				aUnicode, 
+				aIndicesOfUnconvertibleCharacters, 
+				aArrayOfCharacterSets.Array());
+	}
+
+// -----------------------------------------------------------------------------
+// ConvertToUnicode()
+//The main conversion function for converting from iscii to unicode
+//Loaded and called by the character conversion framework.
+//To support some of the iscii characters, the input forign buffer is
+//copied to an intermediate buffer and then is then modified and 
+//CCnvCharactersetConverter::DoConvertToUnicode() is called with
+//the modified buffer. For extensibility of iscii to other Indic languages
+//it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a
+//Symbian defined class for modal charactersets. The escape sequence 
+//is specified to ATR followed by the script selection code and the conversion
+//data is specified to be the conversion for the particular script. For the time
+//being only Devanagari with script selection code 0x42 is supported. If 
+//any of the other script codes are used the conversion leads to unconvertible
+//character i.e. 0xFFFD.
+// Returns: The numbet of iscii codes it could not convert.
+//
+// -----------------------------------------------------------------------------
+//
+
+TInt CIsciiImplementation::ConvertToUnicode(
+         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+         TDes16& aUnicode, 
+         const TDesC8& aForeign, 
+         TInt& aState, 
+         TInt& aNumberOfUnconvertibleCharacters, 
+         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter )
+	{
+	aNumberOfUnconvertibleCharacters = 0;
+	TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault;
+	aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1;
+	TUint internalInputConversionFlags = 0;
+	TInt numberOfForeignBytesConsumed=0;
+	TPtrC8 remainderOfForeign(aForeign);
+	TInt returnValue;
+	TBool flag = EFalse;
+	TBool isSkipMatchSequence = EFalse;
+	const SCnvConversionData* convData;
+	//Set the iscii conversion data and escape sequence for Devanagari.
+	TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals;
+	modals[0].iConversionData = &conversionData;
+	modals[0].iEscapeSequence = &KEscapeSequenceDevanagari();
+
+	aUnicode.SetLength(0);
+	
+	//The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend
+	//so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer.
+	internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend;
+	if (aForeign.Length()==0)
+	{
+		return 0;
+	}
+	//Get the conversion data from the previous call else the conversion data is set to the default 
+	//conversion data, i.e. Devanagari.
+	convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData;
+	FOREVER
+	{
+		TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer;
+		TUint numberOfForeignBytesConsumedThisTime = 0;
+		if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer))
+		{
+			numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer;
+			intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+			//If the intermediate buffer is a part of truncated buffer sequence but the
+			//actual input buffer is not truncated then truncated sequence is not converted.
+			//The intermediate buffer is modified so as not to contain the truncated sequence.
+			
+			flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer);
+			if(flag)
+				{
+					numberOfForeignBytesConsumedThisTime --;
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);					
+				}
+			
+		}
+		else
+		{
+			flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length()));
+			if(!flag)
+				{
+				numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
+				intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+				}
+			else
+				{
+				if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length()))
+					{
+					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1;
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+					break;
+					}
+				else
+					{
+					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+					}
+				}
+		}			
+		
+		//The input intermediate iscii buffer is modified with the search and replace
+		//buffers. It is required for supporting multibyte iscii sequences.		
+		FindAndModifyBuffer(intermediateBuffer);
+		TPtrC8 remainderOfForeignInternal(intermediateBuffer);
+		TPtrC8 homogeneousRun;
+		const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape);
+		if (startOfNextEscapeSequence!=0) 
+			{
+			if (startOfNextEscapeSequence==KErrNotFound)
+				{
+				homogeneousRun.Set(remainderOfForeignInternal);
+				remainderOfForeignInternal.Set(NULL, 0);
+				}
+			else
+				{
+				__ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence));
+				homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence));
+				remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence));
+				}
+			isSkipMatchSequence = ETrue;
+			}
+		FOREVER
+			{
+			if(!isSkipMatchSequence)
+				{
+				if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, 
+											remainderOfForeignInternal, modals.Array(), aOutputConversionFlags))
+					{
+					break;
+					}
+				}
+			HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, 
+								aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags,
+								numberOfForeignBytesConsumed,returnValue);
+			if(returnValue<0)
+				{
+				return returnValue;
+				}
+			isSkipMatchSequence = EFalse;
+			}
+		if(returnValue > 0)
+			break;
+		if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) )))
+			break;
+		remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed));				
+	}
+	//If the number of iscii bytes consumed by the conversion is zero also the output conversion
+	//flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput.
+	if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated))
+		{
+		return CCnvCharacterSetConverter::EErrorIllFormedInput;
+		}
+	//Set the conversion data sothat next time when ConvertToUnicode() is called,
+	//will use the previous conversion data.
+	aState=REINTERPRET_CAST(TInt, convData);
+	return aForeign.Length()-numberOfForeignBytesConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// IsInThisCharacterSetL()
+//The method tells how probable it is that a sample piece of text is encoded in this character set.
+//On return aConfidenceLevel, indicates how confident the function is about its return value. For
+//iscii it is the default implementation and it does not implement the autodetect functionality.
+//Loaded and called by the character conversion framework.
+//
+// Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL()  that the plug-in DLL
+//                          is not implementing a function of this signature and is therefore empty.
+//
+// -----------------------------------------------------------------------------
+//
+
+
+//Default implementation for IsInThisCharacterSetL()
+
+TBool CIsciiImplementation::IsInThisCharacterSetL(
+         TBool& aSetToTrue, 
+         TInt& aConfidenceLevel, 
+         const TDesC8& )
+	{
+    	aSetToTrue = EFalse;
+	aConfidenceLevel = 0;
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// NewL()
+//Factory function for CIsciiImplementation(). Instantiates a CIsciiImplementation object on heap
+//and returns the pointer to it.
+//
+// Returns: CIsciiImplementation*
+//
+// -----------------------------------------------------------------------------
+//
+	
+CIsciiImplementation* CIsciiImplementation::NewL()
+    {
+    CIsciiImplementation* self = new(ELeave) CIsciiImplementation;
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CIsciiImplementation()
+//default constructor, does nothing
+//
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+CIsciiImplementation::CIsciiImplementation()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// ~CIsciiImplementation()
+//default desstructor, does nothing
+//
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+CIsciiImplementation::~CIsciiImplementation()
+    {
+    }
+
+// ECOM CREATION FUNCTION
+const TImplementationProxy ImplementationTable[] = 
+    {
+    // Used also in 0x1027508E.rss ( implementation_uid )
+    IMPLEMENTATION_PROXY_ENTRY( 0x1027508E, CIsciiImplementation::NewL )
+    };
+
+// -----------------------------------------------------------------------------
+// ImplementationGroupProxy()
+//Returns a pointer to TImplementationProxy object which contains the implementation uid vs factory
+//function table. Also on return sets the aTableCount to the number of entries in the table.
+//
+// Returns: TImplementationProxy*
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
+    {
+    aTableCount = sizeof( ImplementationTable ) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+    }
+#else
+
+#include <convplug.h>
+
+#ifndef EKA2
+// -----------------------------------------------------------------------------
+// E32Dll()
+//For EKA1 this is the entry point for the DLL.
+//
+// Returns: KErrNone
+//
+// -----------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Dll(TDllReason)
+{
+	return KErrNone;
+}
+#endif
+
+//Checks if a descriptor starts with another descriptor at the begining.
+LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer)
+{
+	const TInt lengthOfStart=aEscapeSequence.Length();
+	return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence);
+}
+// -----------------------------------------------------------------------------
+// MatchesEscapeSequence()
+//If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text
+//and  sets the homogeneous run buffer that uses the same conversion data.
+//The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code
+// neither it contains the script switching code.
+//The aRemainderOfForeign buffer 
+
+// Returns: ETrue: If the sequence contains the escape sequence
+//              EFalse: If the sequence does not contain the escape sequence
+//
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun,
+		TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence)
+{
+	const TInt lengthOfEscapeSequence=aEscapeSequence.Length();
+	if (IsStartOf(aEscapeSequence, aRemainderOfForeign))
+		{
+		aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence));
+		const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape);
+		if (startOfNextEscapeSequence==KErrNotFound)
+			{
+			aHomogeneousRun.Set(aRemainderOfForeign);
+			aRemainderOfForeign.Set(NULL, 0);
+			}
+		else
+			{
+			aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence));
+			aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence));
+			}
+		aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence;
+		return ETrue;
+		}
+	return EFalse;
+}
+
+// -----------------------------------------------------------------------------
+// NextHomogeneousForeignRun()
+//Matches the escape sequence of each of the elements of the SState array with the remainder of
+//foreign text and if the escape sequence matches with the start of remainder of the foreign text, 
+//then the conversion data is set to the conversion data corresponding to the escape sequence
+//Also the homogeneous foreign text for conversion with the same escape sequence is set.
+
+// Returns: ETrue: If length of the remainder of foreign buffer is nonzero.
+//              EFalse: If length of the remainder of foreign buffer is zero.
+//
+// -----------------------------------------------------------------------------
+//
+
+
+LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags)
+{
+	TBool returnValue = EFalse;
+	TBool foundState = EFalse;
+	__ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign));
+	if (aRemainderOfForeign.Length()==0)
+		{
+		return returnValue;
+		}
+	const TInt numberOfStates=aArrayOfStates.Count();
+	TInt i;
+	for (i=0; i<numberOfStates; ++i)
+		{
+		const CnvUtilities::SState& state=aArrayOfStates[i];
+		if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence))
+			{
+			aConversionData=state.iConversionData;
+			foundState = ETrue;
+			}
+		}
+	if(!foundState)
+		{
+		for (i=0; i<numberOfStates; ++i)
+			{
+			if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence))
+				{
+				// aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more
+				aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated;
+				break;
+				}
+			}
+
+		MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2));
+		aConversionData = &conversionDataDummy;	
+		returnValue = ETrue;
+		}
+		if (aHomogeneousRun.Length()>0)
+			{
+			returnValue = ETrue;
+			}
+		return returnValue;		
+}
+// -----------------------------------------------------------------------------
+// ConvertFromUnicodeIntermediateBufferInPlace()
+//Default implementation for conversion to the intermediate buffer
+//It modifies the unicode buffer before it is converted back to iscii.
+//The current implementation of iscii plug-in doesn't require any
+//modification to the default implementation
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+
+LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
+{
+	CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1);
+}
+
+// -----------------------------------------------------------------------------
+// DoFindAndModifyBuffer()
+//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
+//Introduced for handling multibyte iscii sequence.
+//Takes the search buffer array and the replacement buffer arrays as input to it and replaces all
+//the occurances of the search buffer with the corresponding replace buffer.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer)
+{
+	FOREVER
+	{
+		TInt offset;
+		__ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer));
+		if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound)
+		{
+			TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr());
+			Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length());
+			Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset);
+			aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length());
+		}
+		else
+			break;
+	}
+	
+}
+
+// -----------------------------------------------------------------------------
+// FindAndModifyBuffer()
+//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
+//Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer.
+//Introduced for handling multibyte iscii sequence.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	RArray<TPtrC8> replaceBuffer;
+	
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	
+	replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForOm().Mid(0));
+	replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
+	
+	for(TInt counter=0;counter<searchBuffer.Count();counter++)
+	{
+		DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]);
+	}
+	searchBuffer.Reset();
+	replaceBuffer.Reset();
+	
+}
+
+// -----------------------------------------------------------------------------
+// DoNormalizeReturnValue()
+//Modifies the return value(Number of bytes did not get converted) according to the modified
+//intermediate buffer. Takes the modified intermediate buffer, return value, search and replace
+//buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for
+//the actual buffer corresponding to the replace buffer and adds the difference of the lengths
+//of the actual to replace buffer to the return value.
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces)
+{
+	TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length());
+	TUint count = anArrayOfSearches.Count();
+	FOREVER
+	{
+		TBool flag = EFalse;
+		for(TUint i=0;i<count;i++)
+		{
+			TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length()));
+			TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]);
+			if(returnCompare == 0)
+			{
+				flag =ETrue;
+				aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length());
+				buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length());
+				break;
+			}
+		}
+		
+		if(buffer.Length() == 0)
+		{
+			break;
+		}
+		
+		if(!flag)
+		{
+			buffer=buffer.MidTPtr(0,buffer.Length()-1);
+		}
+	}
+
+}
+
+// -----------------------------------------------------------------------------
+// NormalizeReturnValue()
+//Modifies the return value(Number of bytes did not get converted) according to the 
+//replacements done to the iscii buffer before conversion.
+//Internally calls DoNormalizeReturnValue() by suppling the search and replacement 
+//buffers.
+
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	RArray<TPtrC8> replaceBuffer;
+	
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	
+	replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
+	replaceBuffer.Append(KReplacementForOm().Mid(0));
+	replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
+	DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer);
+	searchBuffer.Reset();
+	replaceBuffer.Reset();
+}
+
+// -----------------------------------------------------------------------------
+// HandleHomogeneousRun()
+//Handles a homogeneous foreign buffer and converts the foreign buffer to unicode
+//On return the aUnicode argument contains the converted unicode data.
+//Also it sets the return value, returned from the conversion. The return value also
+//takes into account if there is any buffer modification done before passing it to
+//CCnvCharacterSetConverter::DoConvertToUnicode()
+//buffers.
+
+// Returns: Nothing
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, 
+							CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
+							TDes16& aUnicode,
+							const TDesC8& aHomogeneousForeign,
+							TInt& aNumberOfUnconvertibleCharacters,
+							TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter,
+							TUint& aOutputConversionFlags,
+							TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed,
+							TInt& aReturnValue)
+{
+	TInt numberOfUnconvertibleCharacters;
+	TInt indexOfFirstByteOfFirstUnconvertibleCharacter;
+	TUint noOfConsumedBytes = 0;
+	if(aConversionData == NULL)
+		{
+		aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput;
+		return;
+		}
+	aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters,
+															  aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters,
+															  indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,
+
+	//The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with
+	//respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and 
+	//aNumberOfUnconvertibleCharacters need to be adjusted accordingly.
+	
+	aInputConversionFlags);
+	if(numberOfUnconvertibleCharacters>0)
+		{
+		if(aNumberOfUnconvertibleCharacters == 0)
+			{
+			aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter;
+			}
+		aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters;
+		}
+	noOfConsumedBytes = aHomogeneousForeign.Length();
+	//To Check whether it is really required.
+	NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign);
+	aNumberOfForeignBytesConsumed+=noOfConsumedBytes;
+	if(aReturnValue>0)
+		{
+		TUint normalizedReturnValue = aReturnValue;
+		
+		//There original iscii buffer copied to an intermediate iscii buffer and then modified 
+		//and is then passed for conversion. Now, after conversion, the return value needs to
+		//be adjusted according to the original buffer. NormalizeReturnValue() does the 
+		//same thing.
+		
+		NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign);
+		aNumberOfForeignBytesConsumed-=normalizedReturnValue;
+		aReturnValue=normalizedReturnValue;
+		}
+	
+	//The HandleHomogeneousRun() method is called in a loop and once there is some
+	//iscii codes converted to unicode, the ConvertToUnicode() should not return
+	//CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion
+	//method does not convert any of the iscii codes ppassed. To ensure that once the
+	//first non-zero number of iscii codes are converted, the internal input conversion
+	//flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable.
+	
+	if(aNumberOfForeignBytesConsumed>0)
+		{
+		aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable;
+		}
+	return;
+}
+
+// -----------------------------------------------------------------------------
+// IsTruncatedDoubleByteIsciiSequence()
+//Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle.
+//If it is a truncated sequence, then returns ETrue else returns EFalse.
+//
+// Returns: ETrue: If the intermediate input iscii buffer is truncated
+//              EFalse: If the intermediate input iscii buffer is not truncated
+//
+// -----------------------------------------------------------------------------
+//
+
+LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer)
+{
+	RArray<TPtrC8> searchBuffer;
+	if(anIsciiBuffer.Length () == 0)
+		return EFalse;
+	if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF)
+	return ETrue;
+	searchBuffer.Append(KSoftHalant().Mid(0));
+	searchBuffer.Append(KOm().Mid(0));
+	searchBuffer.Append(KAvagraha().Mid(0));
+	searchBuffer.Append(KExplicitHalant().Mid(0));
+	TBool ret = EFalse;
+	TBool isNotTruncated =EFalse;
+	
+	//First check if the intermediate iscii buffer is ending with a complete multi byte sequence.
+	//If it ends with a complete multi byte sequence, no need to check if the last character of 
+	//intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse.
+	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
+		{
+		if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0)
+			{
+			isNotTruncated = ETrue;
+			break;
+			}
+		}
+	//If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the 
+	//last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a 
+	//truncated sequence and in that case return ETrue.
+	
+	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
+		{
+		if(isNotTruncated)
+			break;
+		else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0]))
+			{
+			ret =ETrue;
+			break;
+			}
+		}
+	searchBuffer.Reset();
+	return ret;
+}
+
+// -----------------------------------------------------------------------------
+// ReplacementForUnconvertibleUnicodeCharacters()
+//Returns the replacement character for unconvertible unicode character.
+//In the current implementation it is 0x1a (ASCII Substitute character)
+//The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal()
+//in turn which is generated by cnvtool.
+//
+// Returns: Replacemt for unconvertible unicode characters (0x1a)
+//
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C const TDesC8& ReplacementForUnconvertibleUnicodeCharacters()
+	{
+    return ReplacementForUnconvertibleUnicodeCharacters_internal();
+	}
+
+// -----------------------------------------------------------------------------
+// ConvertFromUnicode()
+//The main conversion function for converting from unicode to iscii
+//Loaded and called by the character conversion framework.
+//In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide
+//utility method for converting unicode to modal character codes.
+//
+// Returns: The numbet of unicode codes it could not convert.
+//
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C TInt ConvertFromUnicode(
+         CCnvCharacterSetConverter::TEndianness 
+         aDefaultEndiannessOfForeignCharacters, 
+         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
+         TDes8& aForeign, 
+         const TDesC16& aUnicode, 
+         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters )
+	{
+	TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets;
+	aArrayOfCharacterSets[0].iConversionData = &conversionData;
+	aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace;
+	aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari();
+
+		return CnvUtilities::ConvertFromUnicode(
+				aDefaultEndiannessOfForeignCharacters, 
+				aReplacementForUnconvertibleUnicodeCharacters, 
+				aForeign, 
+				aUnicode, 
+				aIndicesOfUnconvertibleCharacters, 
+				aArrayOfCharacterSets.Array());
+	}
+
+// -----------------------------------------------------------------------------
+// ConvertToUnicode()
+//The main conversion function for converting from iscii to unicode
+//Loaded and called by the character conversion framework.
+//To support some of the iscii characters, the input forign buffer is
+//copied to an intermediate buffer and then is then modified and 
+//CCnvCharactersetConverter::DoConvertToUnicode() is called with
+//the modified buffer. For extensibility of iscii to other Indic languages
+//it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a
+//Symbian defined class for modal charactersets. The escape sequence 
+//is specified to ATR followed by the script selection code and the conversion
+//data is specified to be the conversion for the particular script. For the time
+//being only Devanagari with script selection code 0x42 is supported. If 
+//any of the other script codes are used the conversion leads to unconvertible
+//character i.e. 0xFFFD.
+// Returns: The numbet of iscii codes it could not convert.
+//
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C TInt ConvertToUnicode(
+         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+         TDes16& aUnicode, 
+         const TDesC8& aForeign, 
+         TInt& aState, 
+         TInt& aNumberOfUnconvertibleCharacters, 
+         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter )
+	{
+	aNumberOfUnconvertibleCharacters = 0;
+	TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault;
+	aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1;
+	TUint internalInputConversionFlags = 0;
+	TInt numberOfForeignBytesConsumed=0;
+	TPtrC8 remainderOfForeign(aForeign);
+	TInt returnValue;
+	TBool flag = EFalse;
+	TBool isSkipMatchSequence = EFalse;
+	const SCnvConversionData* convData;
+	//Set the iscii conversion data and escape sequence for Devanagari.
+	TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals;
+	modals[0].iConversionData = &conversionData;
+	modals[0].iEscapeSequence = &KEscapeSequenceDevanagari();
+
+	aUnicode.SetLength(0);
+	
+	//The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend
+	//so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer.
+	internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend;
+	if (aForeign.Length()==0)
+	{
+		return 0;
+	}
+	//Get the conversion data from the previous call else the conversion data is set to the default 
+	//conversion data, i.e. Devanagari.
+	convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData;
+	FOREVER
+	{
+		TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer;
+		TUint numberOfForeignBytesConsumedThisTime = 0;
+		if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer))
+		{
+			numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer;
+			intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+			//If the intermediate buffer is a part of truncated buffer sequence but the
+			//actual input buffer is not truncated then truncated sequence is not converted.
+			//The intermediate buffer is modified so as not to contain the truncated sequence.
+			
+			flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer);
+			if(flag)
+				{
+					numberOfForeignBytesConsumedThisTime --;
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);					
+				}
+			
+		}
+		else
+		{
+			flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length()));
+			if(!flag)
+				{
+				numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
+				intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+				}
+			else
+				{
+				if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length()))
+					{
+					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1;
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+					break;
+					}
+				else
+					{
+					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
+					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
+					}
+				}
+		}			
+		
+		//The input intermediate iscii buffer is modified with the search and replace
+		//buffers. It is required for supporting multibyte iscii sequences.		
+		FindAndModifyBuffer(intermediateBuffer);
+		TPtrC8 remainderOfForeignInternal(intermediateBuffer);
+		TPtrC8 homogeneousRun;
+		const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape);
+		if (startOfNextEscapeSequence!=0) 
+			{
+			if (startOfNextEscapeSequence==KErrNotFound)
+				{
+				homogeneousRun.Set(remainderOfForeignInternal);
+				remainderOfForeignInternal.Set(NULL, 0);
+				}
+			else
+				{
+				__ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence));
+				homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence));
+				remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence));
+				}
+			isSkipMatchSequence = ETrue;
+			}
+		FOREVER
+			{
+			if(!isSkipMatchSequence)
+				{
+				if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, 
+											remainderOfForeignInternal, modals.Array(), aOutputConversionFlags))
+					{
+					break;
+					}
+				}
+			HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, 
+								aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags,
+								numberOfForeignBytesConsumed,returnValue);
+			if(returnValue<0)
+				{
+				return returnValue;
+				}
+			isSkipMatchSequence = EFalse;
+			}
+		if(returnValue > 0)
+			break;
+		if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) )))
+			break;
+		remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed));				
+	}
+	//If the number of iscii bytes consumed by the conversion is zero also the output conversion
+	//flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput.
+	if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated))
+		{
+		return CCnvCharacterSetConverter::EErrorIllFormedInput;
+		}
+	//Set the conversion data sothat next time when ConvertToUnicode() is called,
+	//will use the previous conversion data.
+	aState=REINTERPRET_CAST(TInt, convData);
+	return aForeign.Length()-numberOfForeignBytesConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// IsInThisCharacterSetL()
+//The method tells how probable it is that a sample piece of text is encoded in this character set.
+//On return aConfidenceLevel, indicates how confident the function is about its return value. For
+//iscii it is the default implementation and it does not implement the autodetect functionality.
+//Loaded and called by the character conversion framework.
+//
+// Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL()  that the plug-in DLL
+//                          is not implementing a function of this signature and is therefore empty.
+//
+// -----------------------------------------------------------------------------
+//
+
+
+//Default implementation for IsInThisCharacterSetL()
+
+EXPORT_C TBool IsInThisCharacterSetL(
+         TBool& aSetToTrue, 
+         TInt& aConfidenceLevel, 
+         const TDesC8& )
+	{
+    	aSetToTrue = EFalse;
+	aConfidenceLevel = 0;
+	return EFalse;
+	}
+
+EXPORT_C void Reserved_2()
+	{
+	}
+
+EXPORT_C void Reserved_3()
+	{
+	}
+
+EXPORT_C void Reserved_4()
+	{
+	}
+
+EXPORT_C void Reserved_5()
+	{
+	}
+
+EXPORT_C void Reserved_6()
+	{
+	}
+
+EXPORT_C void Reserved_7()
+	{
+	}
+
+EXPORT_C void Reserved_8()
+	{
+	}
+
+#endif //EKA2