diff -r 000000000000 -r 1fb32624e06b charconvfw/Charconvplugin/src/iscii.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/charconvfw/Charconvplugin/src/iscii.cpp Tue Feb 02 02:02:46 2010 +0200 @@ -0,0 +1,1689 @@ +/* +* 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 +#include +#include +#include + +//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 +#include + + +/** +* 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& 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; i0) + { + 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 (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 searchBuffer; + RArray 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& anArrayOfSearches,RArray& anArrayOfReplaces) +{ + TPtr8 buffer(const_cast(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length()); + TUint count = anArrayOfSearches.Count(); + FOREVER + { + TBool flag = EFalse; + for(TUint i=0;i searchBuffer; + RArray 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 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 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; + 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 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 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 + +#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& 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; i0) + { + 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 (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 searchBuffer; + RArray 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& anArrayOfSearches,RArray& anArrayOfReplaces) +{ + TPtr8 buffer(const_cast(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length()); + TUint count = anArrayOfSearches.Count(); + FOREVER + { + TBool flag = EFalse; + for(TUint i=0;i searchBuffer; + RArray 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 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 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; + 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 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 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