os/textandloc/charconvfw/charconvplugins/src/plugins/iscii.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description:     Implements the characterconversion plug-in
sl@0
    15
*                for ISCII characterset.
sl@0
    16
*
sl@0
    17
*/
sl@0
    18
sl@0
    19
sl@0
    20
sl@0
    21
sl@0
    22
sl@0
    23
#include <e32std.h>
sl@0
    24
#include <charconv.h>
sl@0
    25
#include <convgeneratedcpp.h>
sl@0
    26
#include <convutils.h>
sl@0
    27
sl@0
    28
//The maximum length of any intermediate buffer allocated for conversion.
sl@0
    29
const TInt KMaximumLengthOfIntermediateBuffer=5;
sl@0
    30
//The ISCII ATR code point, used for ISCII script switching mechanism.
sl@0
    31
const TUint KControlCharacterEscape=0xef;
sl@0
    32
//The number of Indic scripts supported by the plug-in.
sl@0
    33
//ISCII in general addresses all the Indic character sets.
sl@0
    34
const TUint KNumberOfIndicCharactersetsSupported = 1;
sl@0
    35
//The common reason for panic for all panics raised by the iscii plug-in
sl@0
    36
_LIT16(KPanicReason,"ISCII Plug-in Panic"); 
sl@0
    37
//The escape sequence for ISCII (ATR) is 0xEF and immidiate byte following 
sl@0
    38
//that is the script selection code for Devanagari.
sl@0
    39
_LIT8(KEscapeSequenceDevanagari,"\xef\x42");
sl@0
    40
//The sequence for Explicit Halant, in unicode it gets converted to VIRAMA+ZWNJ
sl@0
    41
_LIT8(KExplicitHalant,"\xe8\xe8");
sl@0
    42
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    43
//sequence is converted to intermediate unused iscii code point.
sl@0
    44
_LIT8(KReplacementForExplicitHalant,"\xe8\xfc");
sl@0
    45
//The sequence for Soft Halant, in unicode it gets converted to VIRAMA+ZWJ
sl@0
    46
_LIT8(KSoftHalant,"\xe8\xe9");
sl@0
    47
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    48
//sequence is converted to intermediate unused iscii code point.
sl@0
    49
_LIT8(KReplacementForSoftHalant,"\xe8\xfd");
sl@0
    50
//Devanagari character Om
sl@0
    51
_LIT8(KOm,"\xa1\xe9");
sl@0
    52
////For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    53
//sequence is converted to intermediate unused iscii code point.
sl@0
    54
_LIT8(KReplacementForOm,"\xfe");
sl@0
    55
//Devanagari character Avagraha
sl@0
    56
_LIT8(KAvagraha,"\xea\xe9");
sl@0
    57
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    58
//sequence is converted to intermediate unused iscii code point.
sl@0
    59
_LIT8(KReplacementForAvagraha,"\xff");
sl@0
    60
sl@0
    61
//Devanagari character VOCALIC RR
sl@0
    62
_LIT8(KVocalicRr,"\xaa\xe9");
sl@0
    63
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    64
//sequence is converted to intermediate unused iscii code point.
sl@0
    65
_LIT8(KReplacementForVocalicRr,"\x80");
sl@0
    66
//Devanagari character VOCALIC LL
sl@0
    67
_LIT8(KVocalicLl,"\xa7\xe9");
sl@0
    68
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    69
//sequence is converted to intermediate unused iscii code point.
sl@0
    70
_LIT8(KReplacementForVocalicLl,"\x81");
sl@0
    71
//Devanagari character VOCALIC L SIGN
sl@0
    72
_LIT8(KVocalicLSign,"\xdb\xe9");
sl@0
    73
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    74
//sequence is converted to intermediate unused iscii code point.
sl@0
    75
_LIT8(KReplacementForVocalicLSign,"\x82");
sl@0
    76
//Devanagari character VOCALIC LL SIGN
sl@0
    77
_LIT8(KVocalicLlSign,"\xdc\xe9");
sl@0
    78
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    79
//sequence is converted to intermediate unused iscii code point.
sl@0
    80
_LIT8(KReplacementForVocalicLlSign,"\x83");
sl@0
    81
//Devanagari character VOCALIC L
sl@0
    82
_LIT8(KVocalicL,"\xa6\xe9");
sl@0
    83
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    84
//sequence is converted to intermediate unused iscii code point.
sl@0
    85
_LIT8(KReplacementForVocalicL,"\x84");
sl@0
    86
//Devanagari character VOCALIC RR SIGN
sl@0
    87
_LIT8(KVocalicRrSign,"\xdf\xe9");
sl@0
    88
//For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the
sl@0
    89
//sequence is converted to intermediate unused iscii code point.
sl@0
    90
_LIT8(KReplacementForVocalicRrSign,"\x85");
sl@0
    91
sl@0
    92
//Unconvertible ISCII character
sl@0
    93
_LIT8(KIsciiUnconvertibleCharacter,"\xeb");
sl@0
    94
sl@0
    95
enum TPanic
sl@0
    96
{
sl@0
    97
	//The panic raised by ConvertToUnicodeFromModalForeign_Internal() if the input
sl@0
    98
	//conversion flag is CCnvCharacterSetConverter::EInputConversionFlagStopAtFirstUnconvertibleCharacter
sl@0
    99
	EPanicBadInputConversionFlags=1,
sl@0
   100
	//Panic raised if the buffer does not start with the escape sequence 0xEF
sl@0
   101
	EPanicBadRemainderOfForeign,
sl@0
   102
	//Panic is raised if the length of the search buffer is greater than the length of the 
sl@0
   103
	//replacement buffer
sl@0
   104
	EPanicBadReplacementBuffer,
sl@0
   105
	//If the offset of start of the escape sequence is not an unsigned number.
sl@0
   106
	EPanicBadStartOfNextEscapeSequence
sl@0
   107
};
sl@0
   108
sl@0
   109
//The dummy datastructure for the dummy conversion data i.e. used for conversion if the 
sl@0
   110
//script selection code is not supported.
sl@0
   111
#define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
sl@0
   112
sl@0
   113
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_foreignToUnicode_1[]=
sl@0
   114
	{
sl@0
   115
		{
sl@0
   116
		0xa0,
sl@0
   117
		0xfffd
sl@0
   118
		}
sl@0
   119
	};
sl@0
   120
sl@0
   121
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_unicodeToForeign_1[]=
sl@0
   122
	{
sl@0
   123
		{
sl@0
   124
		0xfffd,
sl@0
   125
		0xa0
sl@0
   126
		}
sl@0
   127
	};
sl@0
   128
sl@0
   129
LOCAL_D const SCnvConversionData::SVariableByteData::SRange foreignVariableByteDataRanges[]=
sl@0
   130
	{
sl@0
   131
		{
sl@0
   132
		0x00,
sl@0
   133
		0xff,
sl@0
   134
		0,
sl@0
   135
		0
sl@0
   136
		}
sl@0
   137
	};
sl@0
   138
sl@0
   139
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange foreignToUnicodeDataRanges[]=
sl@0
   140
	{
sl@0
   141
		{
sl@0
   142
		0x00,
sl@0
   143
		0x7f,
sl@0
   144
		SCnvConversionData::SOneDirectionData::SRange::EDirect,
sl@0
   145
		0,
sl@0
   146
		0,
sl@0
   147
			{
sl@0
   148
			0
sl@0
   149
			}
sl@0
   150
		},
sl@0
   151
		{
sl@0
   152
		0xa0,
sl@0
   153
		0xff,
sl@0
   154
		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
sl@0
   155
		0,
sl@0
   156
		0,
sl@0
   157
			{
sl@0
   158
			UData_SKeyedTable1616(keyedTable1616_foreignToUnicode_1)
sl@0
   159
			}
sl@0
   160
		}
sl@0
   161
	};
sl@0
   162
sl@0
   163
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange unicodeToForeignDataRanges[]=
sl@0
   164
	{
sl@0
   165
		{
sl@0
   166
		0x0000,
sl@0
   167
		0x007f,
sl@0
   168
		SCnvConversionData::SOneDirectionData::SRange::EDirect,
sl@0
   169
		1,
sl@0
   170
		0,
sl@0
   171
			{
sl@0
   172
			0
sl@0
   173
			}
sl@0
   174
		},
sl@0
   175
		{
sl@0
   176
		0x00a0,
sl@0
   177
		0xffff,
sl@0
   178
		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
sl@0
   179
		1,
sl@0
   180
		0,
sl@0
   181
			{
sl@0
   182
			UData_SKeyedTable1616(keyedTable1616_unicodeToForeign_1)
sl@0
   183
			}
sl@0
   184
		}
sl@0
   185
	};
sl@0
   186
sl@0
   187
//The dummy conversion data to be used for conversion if the iscii code sequence is not
sl@0
   188
//Devanagari (i.e. the script selection code is not 0x42 and something else.
sl@0
   189
//In this case the ISCII characters are converted to unconvertible characters.
sl@0
   190
sl@0
   191
LOCAL_D const SCnvConversionData conversionDataDummy=
sl@0
   192
	{
sl@0
   193
	SCnvConversionData::EFixedBigEndian,
sl@0
   194
		{
sl@0
   195
		ARRAY_LENGTH(foreignVariableByteDataRanges),
sl@0
   196
		foreignVariableByteDataRanges
sl@0
   197
		},
sl@0
   198
		{
sl@0
   199
		ARRAY_LENGTH(foreignToUnicodeDataRanges),
sl@0
   200
		foreignToUnicodeDataRanges
sl@0
   201
		},
sl@0
   202
		{
sl@0
   203
		ARRAY_LENGTH(unicodeToForeignDataRanges),
sl@0
   204
		unicodeToForeignDataRanges
sl@0
   205
		},
sl@0
   206
	NULL,
sl@0
   207
	NULL
sl@0
   208
	};
sl@0
   209
sl@0
   210
sl@0
   211
sl@0
   212
#ifdef EKA2
sl@0
   213
sl@0
   214
///////////////////////////////////////////////////////////////
sl@0
   215
// 3.1 Code
sl@0
   216
sl@0
   217
// INCLUDES
sl@0
   218
#include <ecom/implementationproxy.h>
sl@0
   219
#include <charactersetconverter.h>
sl@0
   220
sl@0
   221
sl@0
   222
/**
sl@0
   223
* The character conversion plug-in implementation for Iscii.
sl@0
   224
*
sl@0
   225
*  @lib ecom.lib
sl@0
   226
*  @since Series 60 3.1
sl@0
   227
*/
sl@0
   228
sl@0
   229
class CIsciiImplementation : public CCharacterSetConverterPluginInterface
sl@0
   230
{
sl@0
   231
    public:
sl@0
   232
    	//From CCharacterSetConverterPluginInterface
sl@0
   233
        virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
sl@0
   234
sl@0
   235
	//From CCharacterSetConverterPluginInterface
sl@0
   236
        virtual TInt ConvertFromUnicode(
sl@0
   237
            CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
   238
            const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
   239
            TDes8& aForeign, 
sl@0
   240
            const TDesC16& aUnicode, 
sl@0
   241
            CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters );
sl@0
   242
sl@0
   243
	//From CCharacterSetConverterPluginInterface
sl@0
   244
        virtual TInt ConvertToUnicode(
sl@0
   245
            CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
   246
            TDes16& aUnicode, 
sl@0
   247
            const TDesC8& aForeign, 
sl@0
   248
            TInt&, 
sl@0
   249
            TInt& aNumberOfUnconvertibleCharacters, 
sl@0
   250
            TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter );
sl@0
   251
sl@0
   252
	//From CCharacterSetConverterPluginInterface
sl@0
   253
        virtual TBool IsInThisCharacterSetL(
sl@0
   254
            TBool& aSetToTrue, 
sl@0
   255
            TInt& aConfidenceLevel, 
sl@0
   256
            const TDesC8& );
sl@0
   257
sl@0
   258
        static CIsciiImplementation* NewL();
sl@0
   259
sl@0
   260
        virtual ~CIsciiImplementation();
sl@0
   261
    private:
sl@0
   262
        CIsciiImplementation();
sl@0
   263
};
sl@0
   264
sl@0
   265
//Checks if a descriptor starts with another descriptor at the begining.
sl@0
   266
LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer)
sl@0
   267
{
sl@0
   268
	const TInt lengthOfStart=aEscapeSequence.Length();
sl@0
   269
	return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence);
sl@0
   270
}
sl@0
   271
// -----------------------------------------------------------------------------
sl@0
   272
// MatchesEscapeSequence()
sl@0
   273
//If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text
sl@0
   274
//and  sets the homogeneous run buffer that uses the same conversion data.
sl@0
   275
//The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code
sl@0
   276
// neither it contains the script switching code.
sl@0
   277
//The aRemainderOfForeign buffer 
sl@0
   278
sl@0
   279
// Returns: ETrue: If the sequence contains the escape sequence
sl@0
   280
//              EFalse: If the sequence does not contain the escape sequence
sl@0
   281
//
sl@0
   282
// -----------------------------------------------------------------------------
sl@0
   283
//
sl@0
   284
LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun,
sl@0
   285
		TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence)
sl@0
   286
{
sl@0
   287
	const TInt lengthOfEscapeSequence=aEscapeSequence.Length();
sl@0
   288
	if (IsStartOf(aEscapeSequence, aRemainderOfForeign))
sl@0
   289
		{
sl@0
   290
		aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence));
sl@0
   291
		const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape);
sl@0
   292
		if (startOfNextEscapeSequence==KErrNotFound)
sl@0
   293
			{
sl@0
   294
			aHomogeneousRun.Set(aRemainderOfForeign);
sl@0
   295
			aRemainderOfForeign.Set(NULL, 0);
sl@0
   296
			}
sl@0
   297
		else
sl@0
   298
			{
sl@0
   299
			aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence));
sl@0
   300
			aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence));
sl@0
   301
			}
sl@0
   302
		aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence;
sl@0
   303
		return ETrue;
sl@0
   304
		}
sl@0
   305
	return EFalse;
sl@0
   306
}
sl@0
   307
sl@0
   308
// -----------------------------------------------------------------------------
sl@0
   309
// NextHomogeneousForeignRun()
sl@0
   310
//Matches the escape sequence of each of the elements of the SState array with the remainder of
sl@0
   311
//foreign text and if the escape sequence matches with the start of remainder of the foreign text, 
sl@0
   312
//then the conversion data is set to the conversion data corresponding to the escape sequence
sl@0
   313
//Also the homogeneous foreign text for conversion with the same escape sequence is set.
sl@0
   314
sl@0
   315
// Returns: ETrue: If length of the remainder of foreign buffer is nonzero.
sl@0
   316
//              EFalse: If length of the remainder of foreign buffer is zero.
sl@0
   317
//
sl@0
   318
// -----------------------------------------------------------------------------
sl@0
   319
//
sl@0
   320
sl@0
   321
sl@0
   322
LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags)
sl@0
   323
{
sl@0
   324
	TBool returnValue = EFalse;
sl@0
   325
	TBool foundState = EFalse;
sl@0
   326
	__ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign));
sl@0
   327
	if (aRemainderOfForeign.Length()==0)
sl@0
   328
		{
sl@0
   329
		return returnValue;
sl@0
   330
		}
sl@0
   331
	const TInt numberOfStates=aArrayOfStates.Count();
sl@0
   332
	TInt i;
sl@0
   333
	for (i=0; i<numberOfStates; ++i)
sl@0
   334
		{
sl@0
   335
		const CnvUtilities::SState& state=aArrayOfStates[i];
sl@0
   336
		if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence))
sl@0
   337
			{
sl@0
   338
			aConversionData=state.iConversionData;
sl@0
   339
			foundState = ETrue;
sl@0
   340
			}
sl@0
   341
		}
sl@0
   342
	if(!foundState)
sl@0
   343
		{
sl@0
   344
		for (i=0; i<numberOfStates; ++i)
sl@0
   345
			{
sl@0
   346
			if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence))
sl@0
   347
				{
sl@0
   348
				// aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more
sl@0
   349
				aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated;
sl@0
   350
				break;
sl@0
   351
				}
sl@0
   352
			}
sl@0
   353
sl@0
   354
		MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2));
sl@0
   355
		aConversionData = &conversionDataDummy;	
sl@0
   356
		returnValue = ETrue;
sl@0
   357
		}
sl@0
   358
		if (aHomogeneousRun.Length()>0)
sl@0
   359
			{
sl@0
   360
			returnValue = ETrue;
sl@0
   361
			}
sl@0
   362
		return returnValue;		
sl@0
   363
}
sl@0
   364
// -----------------------------------------------------------------------------
sl@0
   365
// ConvertFromUnicodeIntermediateBufferInPlace()
sl@0
   366
//Default implementation for conversion to the intermediate buffer
sl@0
   367
//It modifies the unicode buffer before it is converted back to iscii.
sl@0
   368
//The current implementation of iscii plug-in doesn't require any
sl@0
   369
//modification to the default implementation
sl@0
   370
// Returns: Nothing
sl@0
   371
//
sl@0
   372
// -----------------------------------------------------------------------------
sl@0
   373
//
sl@0
   374
sl@0
   375
sl@0
   376
LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
sl@0
   377
{
sl@0
   378
	CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1);
sl@0
   379
}
sl@0
   380
sl@0
   381
// -----------------------------------------------------------------------------
sl@0
   382
// DoFindAndModifyBuffer()
sl@0
   383
//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
sl@0
   384
//Introduced for handling multibyte iscii sequence.
sl@0
   385
//Takes the search buffer array and the replacement buffer arrays as input to it and replaces all
sl@0
   386
//the occurances of the search buffer with the corresponding replace buffer.
sl@0
   387
// Returns: Nothing
sl@0
   388
//
sl@0
   389
// -----------------------------------------------------------------------------
sl@0
   390
//
sl@0
   391
sl@0
   392
LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer)
sl@0
   393
{
sl@0
   394
	FOREVER
sl@0
   395
	{
sl@0
   396
		TInt offset;
sl@0
   397
		__ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer));
sl@0
   398
		if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound)
sl@0
   399
		{
sl@0
   400
			TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr());
sl@0
   401
			Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length());
sl@0
   402
			Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset);
sl@0
   403
			aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length());
sl@0
   404
		}
sl@0
   405
		else
sl@0
   406
			break;
sl@0
   407
	}
sl@0
   408
	
sl@0
   409
}
sl@0
   410
sl@0
   411
// -----------------------------------------------------------------------------
sl@0
   412
// FindAndModifyBuffer()
sl@0
   413
//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
sl@0
   414
//Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer.
sl@0
   415
//Introduced for handling multibyte iscii sequence.
sl@0
   416
// Returns: Nothing
sl@0
   417
//
sl@0
   418
// -----------------------------------------------------------------------------
sl@0
   419
//
sl@0
   420
sl@0
   421
LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer)
sl@0
   422
{
sl@0
   423
	TInt ret = KErrNone;
sl@0
   424
    RArray<TPtrC8> searchBuffer;
sl@0
   425
	RArray<TPtrC8> replaceBuffer;
sl@0
   426
	
sl@0
   427
	//If the passed buffer contains the replacement buffer,
sl@0
   428
	//Then it should not get converted to respective Unicode
sl@0
   429
	//buffer rather it should get converted to replacement for
sl@0
   430
	//unconvertible character.
sl@0
   431
	
sl@0
   432
	ret |= searchBuffer.Append(KReplacementForExplicitHalant().Right(1));
sl@0
   433
	ret |= searchBuffer.Append(KReplacementForSoftHalant().Right(1));
sl@0
   434
	ret |= searchBuffer.Append(KReplacementForOm().Right(1));
sl@0
   435
	ret |= searchBuffer.Append(KReplacementForAvagraha().Right(1));
sl@0
   436
	
sl@0
   437
	ret |= searchBuffer.Append(KReplacementForVocalicRr().Right(1));
sl@0
   438
	ret |= searchBuffer.Append(KReplacementForVocalicLl().Right(1));
sl@0
   439
	ret |= searchBuffer.Append(KReplacementForVocalicLSign().Right(1));
sl@0
   440
	ret |= searchBuffer.Append(KReplacementForVocalicLlSign().Right(1));
sl@0
   441
	ret |= searchBuffer.Append(KReplacementForVocalicL().Right(1));
sl@0
   442
	ret |= searchBuffer.Append(KReplacementForVocalicRrSign().Right(1));
sl@0
   443
	
sl@0
   444
	//All normal search buffers
sl@0
   445
	ret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
   446
	ret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
   447
	ret |= searchBuffer.Append(KOm().Mid(0));
sl@0
   448
	ret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
   449
	
sl@0
   450
	ret |= searchBuffer.Append(KVocalicRr().Mid(0));
sl@0
   451
	ret |= searchBuffer.Append(KVocalicLl().Mid(0));
sl@0
   452
	ret |= searchBuffer.Append(KVocalicLSign().Mid(0));
sl@0
   453
	ret |= searchBuffer.Append(KVocalicLlSign().Mid(0));
sl@0
   454
	ret |= searchBuffer.Append(KVocalicL().Mid(0));
sl@0
   455
	ret |= searchBuffer.Append(KVocalicRrSign().Mid(0));
sl@0
   456
	
sl@0
   457
	//The replacement buffer for the odd cases to restrict the 
sl@0
   458
	//replacement buffers not to get converted to the corresponding 
sl@0
   459
	//unicode buffer
sl@0
   460
	
sl@0
   461
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   462
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   463
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   464
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   465
	
sl@0
   466
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   467
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   468
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   469
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   470
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   471
	ret |= replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0));
sl@0
   472
	
sl@0
   473
	//All normal replace buffers		
sl@0
   474
	ret |= replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
sl@0
   475
	ret |= replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
sl@0
   476
	ret |= replaceBuffer.Append(KReplacementForOm().Mid(0));
sl@0
   477
	ret |= replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
sl@0
   478
	
sl@0
   479
	
sl@0
   480
	ret |= replaceBuffer.Append(KReplacementForVocalicRr().Mid(0));
sl@0
   481
	ret |= replaceBuffer.Append(KReplacementForVocalicLl().Mid(0));
sl@0
   482
	ret |= replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0));
sl@0
   483
	ret |= replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0));
sl@0
   484
	ret |= replaceBuffer.Append(KReplacementForVocalicL().Mid(0));
sl@0
   485
	ret |= replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0));
sl@0
   486
	
sl@0
   487
	__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
sl@0
   488
			
sl@0
   489
	for(TInt counter=0;counter<searchBuffer.Count();counter++)
sl@0
   490
	{
sl@0
   491
		DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]);
sl@0
   492
	}
sl@0
   493
	searchBuffer.Reset();
sl@0
   494
	replaceBuffer.Reset();
sl@0
   495
	
sl@0
   496
}
sl@0
   497
sl@0
   498
// -----------------------------------------------------------------------------
sl@0
   499
// DoNormalizeReturnValue()
sl@0
   500
//Modifies the return value(Number of bytes did not get converted) according to the modified
sl@0
   501
//intermediate buffer. Takes the modified intermediate buffer, return value, search and replace
sl@0
   502
//buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for
sl@0
   503
//the actual buffer corresponding to the replace buffer and adds the difference of the lengths
sl@0
   504
//of the actual to replace buffer to the return value.
sl@0
   505
// Returns: Nothing
sl@0
   506
//
sl@0
   507
// -----------------------------------------------------------------------------
sl@0
   508
//
sl@0
   509
sl@0
   510
LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces)
sl@0
   511
{
sl@0
   512
	TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length());
sl@0
   513
	TUint count = anArrayOfSearches.Count();
sl@0
   514
	FOREVER
sl@0
   515
	{
sl@0
   516
		TBool flag = EFalse;
sl@0
   517
		for(TUint i=0;i<count;i++)
sl@0
   518
		{
sl@0
   519
			TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length()));
sl@0
   520
			TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]);
sl@0
   521
			if(returnCompare == 0)
sl@0
   522
			{
sl@0
   523
				flag =ETrue;
sl@0
   524
				aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length());
sl@0
   525
				buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length());
sl@0
   526
				break;
sl@0
   527
			}
sl@0
   528
		}
sl@0
   529
		
sl@0
   530
		if(buffer.Length() == 0)
sl@0
   531
		{
sl@0
   532
			break;
sl@0
   533
		}
sl@0
   534
		
sl@0
   535
		if(!flag)
sl@0
   536
		{
sl@0
   537
			buffer=buffer.MidTPtr(0,buffer.Length()-1);
sl@0
   538
		}
sl@0
   539
	}
sl@0
   540
sl@0
   541
}
sl@0
   542
sl@0
   543
// -----------------------------------------------------------------------------
sl@0
   544
// NormalizeReturnValue()
sl@0
   545
//Modifies the return value(Number of bytes did not get converted) according to the 
sl@0
   546
//replacements done to the iscii buffer before conversion.
sl@0
   547
//Internally calls DoNormalizeReturnValue() by suppling the search and replacement 
sl@0
   548
//buffers.
sl@0
   549
sl@0
   550
// Returns: Nothing
sl@0
   551
//
sl@0
   552
// -----------------------------------------------------------------------------
sl@0
   553
//
sl@0
   554
sl@0
   555
LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer)
sl@0
   556
{
sl@0
   557
	TInt ret = KErrNone;
sl@0
   558
    RArray<TPtrC8> searchBuffer;
sl@0
   559
	RArray<TPtrC8> replaceBuffer;
sl@0
   560
	
sl@0
   561
	ret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
   562
	ret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
   563
	ret |= searchBuffer.Append(KOm().Mid(0));
sl@0
   564
	ret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
   565
	
sl@0
   566
	ret |= searchBuffer.Append(KVocalicRr().Mid(0));
sl@0
   567
	ret |= searchBuffer.Append(KVocalicLl().Mid(0));
sl@0
   568
	ret |= searchBuffer.Append(KVocalicLSign().Mid(0));
sl@0
   569
	ret |= searchBuffer.Append(KVocalicLlSign().Mid(0));
sl@0
   570
	ret |= searchBuffer.Append(KVocalicL().Mid(0));
sl@0
   571
	ret |= searchBuffer.Append(KVocalicRrSign().Mid(0));
sl@0
   572
	
sl@0
   573
	ret |= replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
sl@0
   574
	ret |= replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
sl@0
   575
	ret |= replaceBuffer.Append(KReplacementForOm().Mid(0));
sl@0
   576
	ret |= replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
sl@0
   577
	
sl@0
   578
	ret |= replaceBuffer.Append(KReplacementForVocalicRr().Mid(0));
sl@0
   579
	ret |= replaceBuffer.Append(KReplacementForVocalicLl().Mid(0));
sl@0
   580
	ret |= replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0));
sl@0
   581
	ret |= replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0));
sl@0
   582
	ret |= replaceBuffer.Append(KReplacementForVocalicL().Mid(0));
sl@0
   583
	ret |= replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0));
sl@0
   584
	
sl@0
   585
	__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
sl@0
   586
	
sl@0
   587
	DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer);
sl@0
   588
	searchBuffer.Reset();
sl@0
   589
	replaceBuffer.Reset();
sl@0
   590
}
sl@0
   591
sl@0
   592
// -----------------------------------------------------------------------------
sl@0
   593
// HandleHomogeneousRun()
sl@0
   594
//Handles a homogeneous foreign buffer and converts the foreign buffer to unicode
sl@0
   595
//On return the aUnicode argument contains the converted unicode data.
sl@0
   596
//Also it sets the return value, returned from the conversion. The return value also
sl@0
   597
//takes into account if there is any buffer modification done before passing it to
sl@0
   598
//CCnvCharacterSetConverter::DoConvertToUnicode()
sl@0
   599
//buffers.
sl@0
   600
sl@0
   601
// Returns: Nothing
sl@0
   602
//
sl@0
   603
// -----------------------------------------------------------------------------
sl@0
   604
//
sl@0
   605
sl@0
   606
LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, 
sl@0
   607
							CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
sl@0
   608
							TDes16& aUnicode,
sl@0
   609
							const TDesC8& aHomogeneousForeign,
sl@0
   610
							TInt& aNumberOfUnconvertibleCharacters,
sl@0
   611
							TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter,
sl@0
   612
							TUint& aOutputConversionFlags,
sl@0
   613
							TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed,
sl@0
   614
							TInt& aReturnValue)
sl@0
   615
{
sl@0
   616
	TInt numberOfUnconvertibleCharacters;
sl@0
   617
	TInt indexOfFirstByteOfFirstUnconvertibleCharacter;
sl@0
   618
	TUint noOfConsumedBytes = 0;
sl@0
   619
	if(aConversionData == NULL)
sl@0
   620
		{
sl@0
   621
		aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   622
		return;
sl@0
   623
		}
sl@0
   624
	aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters,
sl@0
   625
															  aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters,
sl@0
   626
															  indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,
sl@0
   627
sl@0
   628
	//The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with
sl@0
   629
	//respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and 
sl@0
   630
	//aNumberOfUnconvertibleCharacters need to be adjusted accordingly.
sl@0
   631
	
sl@0
   632
	aInputConversionFlags);
sl@0
   633
	if(numberOfUnconvertibleCharacters>0)
sl@0
   634
		{
sl@0
   635
		if(aNumberOfUnconvertibleCharacters == 0)
sl@0
   636
			{
sl@0
   637
			aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter;
sl@0
   638
			}
sl@0
   639
		aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters;
sl@0
   640
		}
sl@0
   641
	noOfConsumedBytes = aHomogeneousForeign.Length();
sl@0
   642
	//To Check whether it is really required.
sl@0
   643
	NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign);
sl@0
   644
	aNumberOfForeignBytesConsumed+=noOfConsumedBytes;
sl@0
   645
	if(aReturnValue>0)
sl@0
   646
		{
sl@0
   647
		TUint normalizedReturnValue = aReturnValue;
sl@0
   648
		
sl@0
   649
		//There original iscii buffer copied to an intermediate iscii buffer and then modified 
sl@0
   650
		//and is then passed for conversion. Now, after conversion, the return value needs to
sl@0
   651
		//be adjusted according to the original buffer. NormalizeReturnValue() does the 
sl@0
   652
		//same thing.
sl@0
   653
		
sl@0
   654
		NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign);
sl@0
   655
		aNumberOfForeignBytesConsumed-=normalizedReturnValue;
sl@0
   656
		aReturnValue=normalizedReturnValue;
sl@0
   657
		}
sl@0
   658
	
sl@0
   659
	//The HandleHomogeneousRun() method is called in a loop and once there is some
sl@0
   660
	//iscii codes converted to unicode, the ConvertToUnicode() should not return
sl@0
   661
	//CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion
sl@0
   662
	//method does not convert any of the iscii codes ppassed. To ensure that once the
sl@0
   663
	//first non-zero number of iscii codes are converted, the internal input conversion
sl@0
   664
	//flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable.
sl@0
   665
	
sl@0
   666
	if(aNumberOfForeignBytesConsumed>0)
sl@0
   667
		{
sl@0
   668
		aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable;
sl@0
   669
		}
sl@0
   670
	return;
sl@0
   671
}
sl@0
   672
sl@0
   673
// -----------------------------------------------------------------------------
sl@0
   674
// IsTruncatedDoubleByteIsciiSequence()
sl@0
   675
//Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle.
sl@0
   676
//If it is a truncated sequence, then returns ETrue else returns EFalse.
sl@0
   677
//
sl@0
   678
// Returns: ETrue: If the intermediate input iscii buffer is truncated
sl@0
   679
//              EFalse: If the intermediate input iscii buffer is not truncated
sl@0
   680
//
sl@0
   681
// -----------------------------------------------------------------------------
sl@0
   682
//
sl@0
   683
sl@0
   684
LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer)
sl@0
   685
{
sl@0
   686
	RArray<TPtrC8> searchBuffer;
sl@0
   687
	if(anIsciiBuffer.Length () == 0)
sl@0
   688
		return EFalse;
sl@0
   689
	if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF)
sl@0
   690
	return ETrue;
sl@0
   691
	
sl@0
   692
	TInt appendret = KErrNone;
sl@0
   693
	appendret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
   694
	appendret |= searchBuffer.Append(KOm().Mid(0));
sl@0
   695
	appendret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
   696
	appendret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
   697
	__ASSERT_DEBUG(!appendret, User::Panic(_L("RArray append failure"), appendret));
sl@0
   698
	
sl@0
   699
	TBool ret = EFalse;
sl@0
   700
	TBool isNotTruncated =EFalse;
sl@0
   701
	
sl@0
   702
	//First check if the intermediate iscii buffer is ending with a complete multi byte sequence.
sl@0
   703
	//If it ends with a complete multi byte sequence, no need to check if the last character of 
sl@0
   704
	//intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse.
sl@0
   705
	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
sl@0
   706
		{
sl@0
   707
		if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0)
sl@0
   708
			{
sl@0
   709
			isNotTruncated = ETrue;
sl@0
   710
			break;
sl@0
   711
			}
sl@0
   712
		}
sl@0
   713
	//If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the 
sl@0
   714
	//last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a 
sl@0
   715
	//truncated sequence and in that case return ETrue.
sl@0
   716
	
sl@0
   717
	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
sl@0
   718
		{
sl@0
   719
		if(isNotTruncated)
sl@0
   720
			break;
sl@0
   721
		else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0]))
sl@0
   722
			{
sl@0
   723
			ret =ETrue;
sl@0
   724
			break;
sl@0
   725
			}
sl@0
   726
		}
sl@0
   727
	searchBuffer.Reset();
sl@0
   728
	return ret;
sl@0
   729
}
sl@0
   730
sl@0
   731
// -----------------------------------------------------------------------------
sl@0
   732
// ReplacementForUnconvertibleUnicodeCharacters()
sl@0
   733
//Returns the replacement character for unconvertible unicode character.
sl@0
   734
//In the current implementation it is 0x1a (ASCII Substitute character)
sl@0
   735
//The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal()
sl@0
   736
//in turn which is generated by cnvtool.
sl@0
   737
//
sl@0
   738
// Returns: Replacemt for unconvertible unicode characters (0x1a)
sl@0
   739
//
sl@0
   740
// -----------------------------------------------------------------------------
sl@0
   741
//
sl@0
   742
sl@0
   743
const TDesC8& CIsciiImplementation::ReplacementForUnconvertibleUnicodeCharacters()
sl@0
   744
	{
sl@0
   745
    return ReplacementForUnconvertibleUnicodeCharacters_internal();
sl@0
   746
	}
sl@0
   747
sl@0
   748
// -----------------------------------------------------------------------------
sl@0
   749
// ConvertFromUnicode()
sl@0
   750
//The main conversion function for converting from unicode to iscii
sl@0
   751
//Loaded and called by the character conversion framework.
sl@0
   752
//In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide
sl@0
   753
//utility method for converting unicode to modal character codes.
sl@0
   754
//
sl@0
   755
// Returns: The numbet of unicode codes it could not convert.
sl@0
   756
//
sl@0
   757
// -----------------------------------------------------------------------------
sl@0
   758
//
sl@0
   759
sl@0
   760
TInt CIsciiImplementation::ConvertFromUnicode(
sl@0
   761
         CCnvCharacterSetConverter::TEndianness 
sl@0
   762
         aDefaultEndiannessOfForeignCharacters, 
sl@0
   763
         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
   764
         TDes8& aForeign, 
sl@0
   765
         const TDesC16& aUnicode, 
sl@0
   766
         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters )
sl@0
   767
	{
sl@0
   768
	TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets;
sl@0
   769
	aArrayOfCharacterSets[0].iConversionData = &conversionData;
sl@0
   770
	aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace;
sl@0
   771
	aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari();
sl@0
   772
sl@0
   773
		return CnvUtilities::ConvertFromUnicode(
sl@0
   774
				aDefaultEndiannessOfForeignCharacters, 
sl@0
   775
				aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
   776
				aForeign, 
sl@0
   777
				aUnicode, 
sl@0
   778
				aIndicesOfUnconvertibleCharacters, 
sl@0
   779
				aArrayOfCharacterSets.Array());
sl@0
   780
	}
sl@0
   781
sl@0
   782
// -----------------------------------------------------------------------------
sl@0
   783
// ConvertToUnicode()
sl@0
   784
//The main conversion function for converting from iscii to unicode
sl@0
   785
//Loaded and called by the character conversion framework.
sl@0
   786
//To support some of the iscii characters, the input forign buffer is
sl@0
   787
//copied to an intermediate buffer and then is then modified and 
sl@0
   788
//CCnvCharactersetConverter::DoConvertToUnicode() is called with
sl@0
   789
//the modified buffer. For extensibility of iscii to other Indic languages
sl@0
   790
//it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a
sl@0
   791
//Symbian defined class for modal charactersets. The escape sequence 
sl@0
   792
//is specified to ATR followed by the script selection code and the conversion
sl@0
   793
//data is specified to be the conversion for the particular script. For the time
sl@0
   794
//being only Devanagari with script selection code 0x42 is supported. If 
sl@0
   795
//any of the other script codes are used the conversion leads to unconvertible
sl@0
   796
//character i.e. 0xFFFD.
sl@0
   797
// Returns: The numbet of iscii codes it could not convert.
sl@0
   798
//
sl@0
   799
// -----------------------------------------------------------------------------
sl@0
   800
//
sl@0
   801
sl@0
   802
TInt CIsciiImplementation::ConvertToUnicode(
sl@0
   803
         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
   804
         TDes16& aUnicode, 
sl@0
   805
         const TDesC8& aForeign, 
sl@0
   806
         TInt& aState, 
sl@0
   807
         TInt& aNumberOfUnconvertibleCharacters, 
sl@0
   808
         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter )
sl@0
   809
	{
sl@0
   810
	aNumberOfUnconvertibleCharacters = 0;
sl@0
   811
	TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault;
sl@0
   812
	aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1;
sl@0
   813
	TUint internalInputConversionFlags = 0;
sl@0
   814
	TInt numberOfForeignBytesConsumed=0;
sl@0
   815
	TPtrC8 remainderOfForeign(aForeign);
sl@0
   816
	TInt returnValue;
sl@0
   817
	TBool flag = EFalse;
sl@0
   818
	TBool isSkipMatchSequence = EFalse;
sl@0
   819
	const SCnvConversionData* convData;
sl@0
   820
	//Set the iscii conversion data and escape sequence for Devanagari.
sl@0
   821
	TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals;
sl@0
   822
	modals[0].iConversionData = &conversionData;
sl@0
   823
	modals[0].iEscapeSequence = &KEscapeSequenceDevanagari();
sl@0
   824
sl@0
   825
	aUnicode.SetLength(0);
sl@0
   826
	
sl@0
   827
	//The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend
sl@0
   828
	//so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer.
sl@0
   829
	internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend;
sl@0
   830
	if (aForeign.Length()==0)
sl@0
   831
	{
sl@0
   832
		return 0;
sl@0
   833
	}
sl@0
   834
	//Get the conversion data from the previous call else the conversion data is set to the default 
sl@0
   835
	//conversion data, i.e. Devanagari.
sl@0
   836
	convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData;
sl@0
   837
	FOREVER
sl@0
   838
	{
sl@0
   839
		TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer;
sl@0
   840
		TUint numberOfForeignBytesConsumedThisTime = 0;
sl@0
   841
		if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer))
sl@0
   842
		{
sl@0
   843
			numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer;
sl@0
   844
			intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
   845
			//If the intermediate buffer is a part of truncated buffer sequence but the
sl@0
   846
			//actual input buffer is not truncated then truncated sequence is not converted.
sl@0
   847
			//The intermediate buffer is modified so as not to contain the truncated sequence.
sl@0
   848
			
sl@0
   849
			flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer);
sl@0
   850
			if(flag)
sl@0
   851
				{
sl@0
   852
					numberOfForeignBytesConsumedThisTime --;
sl@0
   853
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);					
sl@0
   854
				}
sl@0
   855
			
sl@0
   856
		}
sl@0
   857
		else
sl@0
   858
		{
sl@0
   859
			flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length()));
sl@0
   860
			if(!flag)
sl@0
   861
				{
sl@0
   862
				numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
sl@0
   863
				intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
   864
				}
sl@0
   865
			else
sl@0
   866
				{
sl@0
   867
				if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length()))
sl@0
   868
					{
sl@0
   869
					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1;
sl@0
   870
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
   871
					break;
sl@0
   872
					}
sl@0
   873
				else
sl@0
   874
					{
sl@0
   875
					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
sl@0
   876
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
   877
					}
sl@0
   878
				}
sl@0
   879
		}			
sl@0
   880
		
sl@0
   881
		//The input intermediate iscii buffer is modified with the search and replace
sl@0
   882
		//buffers. It is required for supporting multibyte iscii sequences.		
sl@0
   883
		FindAndModifyBuffer(intermediateBuffer);
sl@0
   884
		TPtrC8 remainderOfForeignInternal(intermediateBuffer);
sl@0
   885
		TPtrC8 homogeneousRun;
sl@0
   886
		const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape);
sl@0
   887
		if (startOfNextEscapeSequence!=0) 
sl@0
   888
			{
sl@0
   889
			if (startOfNextEscapeSequence==KErrNotFound)
sl@0
   890
				{
sl@0
   891
				homogeneousRun.Set(remainderOfForeignInternal);
sl@0
   892
				remainderOfForeignInternal.Set(NULL, 0);
sl@0
   893
				}
sl@0
   894
			else
sl@0
   895
				{
sl@0
   896
				__ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence));
sl@0
   897
				homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence));
sl@0
   898
				remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence));
sl@0
   899
				}
sl@0
   900
			isSkipMatchSequence = ETrue;
sl@0
   901
			}
sl@0
   902
		FOREVER
sl@0
   903
			{
sl@0
   904
			if(!isSkipMatchSequence)
sl@0
   905
				{
sl@0
   906
				if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, 
sl@0
   907
											remainderOfForeignInternal, modals.Array(), aOutputConversionFlags))
sl@0
   908
					{
sl@0
   909
					break;
sl@0
   910
					}
sl@0
   911
				}
sl@0
   912
			HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, 
sl@0
   913
								aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags,
sl@0
   914
								numberOfForeignBytesConsumed,returnValue);
sl@0
   915
			if(returnValue<0)
sl@0
   916
				{
sl@0
   917
				return returnValue;
sl@0
   918
				}
sl@0
   919
			isSkipMatchSequence = EFalse;
sl@0
   920
			}
sl@0
   921
		if(returnValue > 0)
sl@0
   922
			break;
sl@0
   923
		if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) )))
sl@0
   924
			break;
sl@0
   925
		remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed));				
sl@0
   926
	}
sl@0
   927
	//If the number of iscii bytes consumed by the conversion is zero also the output conversion
sl@0
   928
	//flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput.
sl@0
   929
	if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated))
sl@0
   930
		{
sl@0
   931
		return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   932
		}
sl@0
   933
	//Set the conversion data sothat next time when ConvertToUnicode() is called,
sl@0
   934
	//will use the previous conversion data.
sl@0
   935
	aState=REINTERPRET_CAST(TInt, convData);
sl@0
   936
	return aForeign.Length()-numberOfForeignBytesConsumed;
sl@0
   937
    }
sl@0
   938
sl@0
   939
// -----------------------------------------------------------------------------
sl@0
   940
// IsInThisCharacterSetL()
sl@0
   941
//The method tells how probable it is that a sample piece of text is encoded in this character set.
sl@0
   942
//On return aConfidenceLevel, indicates how confident the function is about its return value. For
sl@0
   943
//iscii it is the default implementation and it does not implement the autodetect functionality.
sl@0
   944
//Loaded and called by the character conversion framework.
sl@0
   945
//
sl@0
   946
// Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL()  that the plug-in DLL
sl@0
   947
//                          is not implementing a function of this signature and is therefore empty.
sl@0
   948
//
sl@0
   949
// -----------------------------------------------------------------------------
sl@0
   950
//
sl@0
   951
sl@0
   952
sl@0
   953
//Default implementation for IsInThisCharacterSetL()
sl@0
   954
sl@0
   955
TBool CIsciiImplementation::IsInThisCharacterSetL(
sl@0
   956
         TBool& aSetToTrue, 
sl@0
   957
         TInt& aConfidenceLevel, 
sl@0
   958
         const TDesC8& )
sl@0
   959
	{
sl@0
   960
    	aSetToTrue = EFalse;
sl@0
   961
	aConfidenceLevel = 0;
sl@0
   962
	return EFalse;
sl@0
   963
	}
sl@0
   964
sl@0
   965
// -----------------------------------------------------------------------------
sl@0
   966
// NewL()
sl@0
   967
//Factory function for CIsciiImplementation(). Instantiates a CIsciiImplementation object on heap
sl@0
   968
//and returns the pointer to it.
sl@0
   969
//
sl@0
   970
// Returns: CIsciiImplementation*
sl@0
   971
//
sl@0
   972
// -----------------------------------------------------------------------------
sl@0
   973
//
sl@0
   974
	
sl@0
   975
CIsciiImplementation* CIsciiImplementation::NewL()
sl@0
   976
    {
sl@0
   977
    CIsciiImplementation* self = new(ELeave) CIsciiImplementation;
sl@0
   978
    return self;
sl@0
   979
    }
sl@0
   980
sl@0
   981
// -----------------------------------------------------------------------------
sl@0
   982
// CIsciiImplementation()
sl@0
   983
//default constructor, does nothing
sl@0
   984
//
sl@0
   985
// Returns: Nothing
sl@0
   986
//
sl@0
   987
// -----------------------------------------------------------------------------
sl@0
   988
//
sl@0
   989
CIsciiImplementation::CIsciiImplementation()
sl@0
   990
    {
sl@0
   991
    }
sl@0
   992
sl@0
   993
// -----------------------------------------------------------------------------
sl@0
   994
// ~CIsciiImplementation()
sl@0
   995
//default desstructor, does nothing
sl@0
   996
//
sl@0
   997
// Returns: Nothing
sl@0
   998
//
sl@0
   999
// -----------------------------------------------------------------------------
sl@0
  1000
//
sl@0
  1001
sl@0
  1002
CIsciiImplementation::~CIsciiImplementation()
sl@0
  1003
    {
sl@0
  1004
    }
sl@0
  1005
sl@0
  1006
// ECOM CREATION FUNCTION
sl@0
  1007
const TImplementationProxy ImplementationTable[] = 
sl@0
  1008
    {
sl@0
  1009
    // Used also in 0x1027508E.rss ( implementation_uid )
sl@0
  1010
    IMPLEMENTATION_PROXY_ENTRY( 0x1027508E, CIsciiImplementation::NewL )
sl@0
  1011
    };
sl@0
  1012
sl@0
  1013
// -----------------------------------------------------------------------------
sl@0
  1014
// ImplementationGroupProxy()
sl@0
  1015
//Returns a pointer to TImplementationProxy object which contains the implementation uid vs factory
sl@0
  1016
//function table. Also on return sets the aTableCount to the number of entries in the table.
sl@0
  1017
//
sl@0
  1018
// Returns: TImplementationProxy*
sl@0
  1019
//
sl@0
  1020
// -----------------------------------------------------------------------------
sl@0
  1021
//
sl@0
  1022
EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
sl@0
  1023
    {
sl@0
  1024
    aTableCount = sizeof( ImplementationTable ) / sizeof(TImplementationProxy);
sl@0
  1025
    return ImplementationTable;
sl@0
  1026
    }
sl@0
  1027
#else
sl@0
  1028
sl@0
  1029
#include <convplug.h>
sl@0
  1030
sl@0
  1031
#ifndef EKA2
sl@0
  1032
// -----------------------------------------------------------------------------
sl@0
  1033
// E32Dll()
sl@0
  1034
//For EKA1 this is the entry point for the DLL.
sl@0
  1035
//
sl@0
  1036
// Returns: KErrNone
sl@0
  1037
//
sl@0
  1038
// -----------------------------------------------------------------------------
sl@0
  1039
//
sl@0
  1040
GLDEF_C TInt E32Dll(TDllReason)
sl@0
  1041
{
sl@0
  1042
	return KErrNone;
sl@0
  1043
}
sl@0
  1044
#endif
sl@0
  1045
sl@0
  1046
//Checks if a descriptor starts with another descriptor at the begining.
sl@0
  1047
LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer)
sl@0
  1048
{
sl@0
  1049
	const TInt lengthOfStart=aEscapeSequence.Length();
sl@0
  1050
	return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence);
sl@0
  1051
}
sl@0
  1052
// -----------------------------------------------------------------------------
sl@0
  1053
// MatchesEscapeSequence()
sl@0
  1054
//If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text
sl@0
  1055
//and  sets the homogeneous run buffer that uses the same conversion data.
sl@0
  1056
//The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code
sl@0
  1057
// neither it contains the script switching code.
sl@0
  1058
//The aRemainderOfForeign buffer 
sl@0
  1059
sl@0
  1060
// Returns: ETrue: If the sequence contains the escape sequence
sl@0
  1061
//              EFalse: If the sequence does not contain the escape sequence
sl@0
  1062
//
sl@0
  1063
// -----------------------------------------------------------------------------
sl@0
  1064
//
sl@0
  1065
LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun,
sl@0
  1066
		TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence)
sl@0
  1067
{
sl@0
  1068
	const TInt lengthOfEscapeSequence=aEscapeSequence.Length();
sl@0
  1069
	if (IsStartOf(aEscapeSequence, aRemainderOfForeign))
sl@0
  1070
		{
sl@0
  1071
		aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence));
sl@0
  1072
		const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape);
sl@0
  1073
		if (startOfNextEscapeSequence==KErrNotFound)
sl@0
  1074
			{
sl@0
  1075
			aHomogeneousRun.Set(aRemainderOfForeign);
sl@0
  1076
			aRemainderOfForeign.Set(NULL, 0);
sl@0
  1077
			}
sl@0
  1078
		else
sl@0
  1079
			{
sl@0
  1080
			aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence));
sl@0
  1081
			aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence));
sl@0
  1082
			}
sl@0
  1083
		aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence;
sl@0
  1084
		return ETrue;
sl@0
  1085
		}
sl@0
  1086
	return EFalse;
sl@0
  1087
}
sl@0
  1088
sl@0
  1089
// -----------------------------------------------------------------------------
sl@0
  1090
// NextHomogeneousForeignRun()
sl@0
  1091
//Matches the escape sequence of each of the elements of the SState array with the remainder of
sl@0
  1092
//foreign text and if the escape sequence matches with the start of remainder of the foreign text, 
sl@0
  1093
//then the conversion data is set to the conversion data corresponding to the escape sequence
sl@0
  1094
//Also the homogeneous foreign text for conversion with the same escape sequence is set.
sl@0
  1095
sl@0
  1096
// Returns: ETrue: If length of the remainder of foreign buffer is nonzero.
sl@0
  1097
//              EFalse: If length of the remainder of foreign buffer is zero.
sl@0
  1098
//
sl@0
  1099
// -----------------------------------------------------------------------------
sl@0
  1100
//
sl@0
  1101
sl@0
  1102
sl@0
  1103
LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags)
sl@0
  1104
{
sl@0
  1105
	TBool returnValue = EFalse;
sl@0
  1106
	TBool foundState = EFalse;
sl@0
  1107
	__ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign));
sl@0
  1108
	if (aRemainderOfForeign.Length()==0)
sl@0
  1109
		{
sl@0
  1110
		return returnValue;
sl@0
  1111
		}
sl@0
  1112
	const TInt numberOfStates=aArrayOfStates.Count();
sl@0
  1113
	TInt i;
sl@0
  1114
	for (i=0; i<numberOfStates; ++i)
sl@0
  1115
		{
sl@0
  1116
		const CnvUtilities::SState& state=aArrayOfStates[i];
sl@0
  1117
		if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence))
sl@0
  1118
			{
sl@0
  1119
			aConversionData=state.iConversionData;
sl@0
  1120
			foundState = ETrue;
sl@0
  1121
			}
sl@0
  1122
		}
sl@0
  1123
	if(!foundState)
sl@0
  1124
		{
sl@0
  1125
		for (i=0; i<numberOfStates; ++i)
sl@0
  1126
			{
sl@0
  1127
			if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence))
sl@0
  1128
				{
sl@0
  1129
				// aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more
sl@0
  1130
				aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated;
sl@0
  1131
				break;
sl@0
  1132
				}
sl@0
  1133
			}
sl@0
  1134
sl@0
  1135
		MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2));
sl@0
  1136
		aConversionData = &conversionDataDummy;	
sl@0
  1137
		returnValue = ETrue;
sl@0
  1138
		}
sl@0
  1139
		if (aHomogeneousRun.Length()>0)
sl@0
  1140
			{
sl@0
  1141
			returnValue = ETrue;
sl@0
  1142
			}
sl@0
  1143
		return returnValue;		
sl@0
  1144
}
sl@0
  1145
// -----------------------------------------------------------------------------
sl@0
  1146
// ConvertFromUnicodeIntermediateBufferInPlace()
sl@0
  1147
//Default implementation for conversion to the intermediate buffer
sl@0
  1148
//It modifies the unicode buffer before it is converted back to iscii.
sl@0
  1149
//The current implementation of iscii plug-in doesn't require any
sl@0
  1150
//modification to the default implementation
sl@0
  1151
// Returns: Nothing
sl@0
  1152
//
sl@0
  1153
// -----------------------------------------------------------------------------
sl@0
  1154
//
sl@0
  1155
sl@0
  1156
sl@0
  1157
LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
sl@0
  1158
{
sl@0
  1159
	CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1);
sl@0
  1160
}
sl@0
  1161
sl@0
  1162
// -----------------------------------------------------------------------------
sl@0
  1163
// DoFindAndModifyBuffer()
sl@0
  1164
//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
sl@0
  1165
//Introduced for handling multibyte iscii sequence.
sl@0
  1166
//Takes the search buffer array and the replacement buffer arrays as input to it and replaces all
sl@0
  1167
//the occurances of the search buffer with the corresponding replace buffer.
sl@0
  1168
// Returns: Nothing
sl@0
  1169
//
sl@0
  1170
// -----------------------------------------------------------------------------
sl@0
  1171
//
sl@0
  1172
sl@0
  1173
LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer)
sl@0
  1174
{
sl@0
  1175
	FOREVER
sl@0
  1176
	{
sl@0
  1177
		TInt offset;
sl@0
  1178
		__ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer));
sl@0
  1179
		if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound)
sl@0
  1180
		{
sl@0
  1181
			TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr());
sl@0
  1182
			Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length());
sl@0
  1183
			Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset);
sl@0
  1184
			aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length());
sl@0
  1185
		}
sl@0
  1186
		else
sl@0
  1187
			break;
sl@0
  1188
	}
sl@0
  1189
	
sl@0
  1190
}
sl@0
  1191
sl@0
  1192
// -----------------------------------------------------------------------------
sl@0
  1193
// FindAndModifyBuffer()
sl@0
  1194
//Modifies the iscii buffer by replacing the search buffer with the replacement buffer.
sl@0
  1195
//Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer.
sl@0
  1196
//Introduced for handling multibyte iscii sequence.
sl@0
  1197
// Returns: Nothing
sl@0
  1198
//
sl@0
  1199
// -----------------------------------------------------------------------------
sl@0
  1200
//
sl@0
  1201
sl@0
  1202
LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer)
sl@0
  1203
{
sl@0
  1204
	RArray<TPtrC8> searchBuffer;
sl@0
  1205
	RArray<TPtrC8> replaceBuffer;
sl@0
  1206
	
sl@0
  1207
	TInt ret = KErrNone;
sl@0
  1208
	ret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
  1209
	ret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
  1210
	ret |= searchBuffer.Append(KOm().Mid(0));
sl@0
  1211
	ret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
  1212
	
sl@0
  1213
	ret |= replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
sl@0
  1214
	ret |= replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
sl@0
  1215
	ret |= replaceBuffer.Append(KReplacementForOm().Mid(0));
sl@0
  1216
	ret |= replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
sl@0
  1217
	
sl@0
  1218
	__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
sl@0
  1219
	
sl@0
  1220
	for(TInt counter=0;counter<searchBuffer.Count();counter++)
sl@0
  1221
	{
sl@0
  1222
		DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]);
sl@0
  1223
	}
sl@0
  1224
	searchBuffer.Reset();
sl@0
  1225
	replaceBuffer.Reset();
sl@0
  1226
	
sl@0
  1227
}
sl@0
  1228
sl@0
  1229
// -----------------------------------------------------------------------------
sl@0
  1230
// DoNormalizeReturnValue()
sl@0
  1231
//Modifies the return value(Number of bytes did not get converted) according to the modified
sl@0
  1232
//intermediate buffer. Takes the modified intermediate buffer, return value, search and replace
sl@0
  1233
//buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for
sl@0
  1234
//the actual buffer corresponding to the replace buffer and adds the difference of the lengths
sl@0
  1235
//of the actual to replace buffer to the return value.
sl@0
  1236
// Returns: Nothing
sl@0
  1237
//
sl@0
  1238
// -----------------------------------------------------------------------------
sl@0
  1239
//
sl@0
  1240
sl@0
  1241
LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces)
sl@0
  1242
{
sl@0
  1243
	TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length());
sl@0
  1244
	TUint count = anArrayOfSearches.Count();
sl@0
  1245
	FOREVER
sl@0
  1246
	{
sl@0
  1247
		TBool flag = EFalse;
sl@0
  1248
		for(TUint i=0;i<count;i++)
sl@0
  1249
		{
sl@0
  1250
			TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length()));
sl@0
  1251
			TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]);
sl@0
  1252
			if(returnCompare == 0)
sl@0
  1253
			{
sl@0
  1254
				flag =ETrue;
sl@0
  1255
				aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length());
sl@0
  1256
				buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length());
sl@0
  1257
				break;
sl@0
  1258
			}
sl@0
  1259
		}
sl@0
  1260
		
sl@0
  1261
		if(buffer.Length() == 0)
sl@0
  1262
		{
sl@0
  1263
			break;
sl@0
  1264
		}
sl@0
  1265
		
sl@0
  1266
		if(!flag)
sl@0
  1267
		{
sl@0
  1268
			buffer=buffer.MidTPtr(0,buffer.Length()-1);
sl@0
  1269
		}
sl@0
  1270
	}
sl@0
  1271
sl@0
  1272
}
sl@0
  1273
sl@0
  1274
// -----------------------------------------------------------------------------
sl@0
  1275
// NormalizeReturnValue()
sl@0
  1276
//Modifies the return value(Number of bytes did not get converted) according to the 
sl@0
  1277
//replacements done to the iscii buffer before conversion.
sl@0
  1278
//Internally calls DoNormalizeReturnValue() by suppling the search and replacement 
sl@0
  1279
//buffers.
sl@0
  1280
sl@0
  1281
// Returns: Nothing
sl@0
  1282
//
sl@0
  1283
// -----------------------------------------------------------------------------
sl@0
  1284
//
sl@0
  1285
sl@0
  1286
LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer)
sl@0
  1287
{
sl@0
  1288
	RArray<TPtrC8> searchBuffer;
sl@0
  1289
	RArray<TPtrC8> replaceBuffer;
sl@0
  1290
	TInt ret =KErrNone;
sl@0
  1291
	ret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
  1292
	ret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
  1293
	ret |= searchBuffer.Append(KOm().Mid(0));
sl@0
  1294
	ret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
  1295
	
sl@0
  1296
	ret |= replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0));
sl@0
  1297
	ret |= replaceBuffer.Append(KReplacementForSoftHalant().Mid(0));
sl@0
  1298
	ret |= replaceBuffer.Append(KReplacementForOm().Mid(0));
sl@0
  1299
	ret |= replaceBuffer.Append(KReplacementForAvagraha().Mid(0));
sl@0
  1300
	
sl@0
  1301
	__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
sl@0
  1302
	
sl@0
  1303
	DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer);
sl@0
  1304
	searchBuffer.Reset();
sl@0
  1305
	replaceBuffer.Reset();
sl@0
  1306
}
sl@0
  1307
sl@0
  1308
// -----------------------------------------------------------------------------
sl@0
  1309
// HandleHomogeneousRun()
sl@0
  1310
//Handles a homogeneous foreign buffer and converts the foreign buffer to unicode
sl@0
  1311
//On return the aUnicode argument contains the converted unicode data.
sl@0
  1312
//Also it sets the return value, returned from the conversion. The return value also
sl@0
  1313
//takes into account if there is any buffer modification done before passing it to
sl@0
  1314
//CCnvCharacterSetConverter::DoConvertToUnicode()
sl@0
  1315
//buffers.
sl@0
  1316
sl@0
  1317
// Returns: Nothing
sl@0
  1318
//
sl@0
  1319
// -----------------------------------------------------------------------------
sl@0
  1320
//
sl@0
  1321
sl@0
  1322
LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, 
sl@0
  1323
							CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
sl@0
  1324
							TDes16& aUnicode,
sl@0
  1325
							const TDesC8& aHomogeneousForeign,
sl@0
  1326
							TInt& aNumberOfUnconvertibleCharacters,
sl@0
  1327
							TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter,
sl@0
  1328
							TUint& aOutputConversionFlags,
sl@0
  1329
							TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed,
sl@0
  1330
							TInt& aReturnValue)
sl@0
  1331
{
sl@0
  1332
	TInt numberOfUnconvertibleCharacters;
sl@0
  1333
	TInt indexOfFirstByteOfFirstUnconvertibleCharacter;
sl@0
  1334
	TUint noOfConsumedBytes = 0;
sl@0
  1335
	if(aConversionData == NULL)
sl@0
  1336
		{
sl@0
  1337
		aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
  1338
		return;
sl@0
  1339
		}
sl@0
  1340
	aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters,
sl@0
  1341
															  aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters,
sl@0
  1342
															  indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,
sl@0
  1343
sl@0
  1344
	//The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with
sl@0
  1345
	//respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and 
sl@0
  1346
	//aNumberOfUnconvertibleCharacters need to be adjusted accordingly.
sl@0
  1347
	
sl@0
  1348
	aInputConversionFlags);
sl@0
  1349
	if(numberOfUnconvertibleCharacters>0)
sl@0
  1350
		{
sl@0
  1351
		if(aNumberOfUnconvertibleCharacters == 0)
sl@0
  1352
			{
sl@0
  1353
			aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter;
sl@0
  1354
			}
sl@0
  1355
		aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters;
sl@0
  1356
		}
sl@0
  1357
	noOfConsumedBytes = aHomogeneousForeign.Length();
sl@0
  1358
	//To Check whether it is really required.
sl@0
  1359
	NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign);
sl@0
  1360
	aNumberOfForeignBytesConsumed+=noOfConsumedBytes;
sl@0
  1361
	if(aReturnValue>0)
sl@0
  1362
		{
sl@0
  1363
		TUint normalizedReturnValue = aReturnValue;
sl@0
  1364
		
sl@0
  1365
		//There original iscii buffer copied to an intermediate iscii buffer and then modified 
sl@0
  1366
		//and is then passed for conversion. Now, after conversion, the return value needs to
sl@0
  1367
		//be adjusted according to the original buffer. NormalizeReturnValue() does the 
sl@0
  1368
		//same thing.
sl@0
  1369
		
sl@0
  1370
		NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign);
sl@0
  1371
		aNumberOfForeignBytesConsumed-=normalizedReturnValue;
sl@0
  1372
		aReturnValue=normalizedReturnValue;
sl@0
  1373
		}
sl@0
  1374
	
sl@0
  1375
	//The HandleHomogeneousRun() method is called in a loop and once there is some
sl@0
  1376
	//iscii codes converted to unicode, the ConvertToUnicode() should not return
sl@0
  1377
	//CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion
sl@0
  1378
	//method does not convert any of the iscii codes ppassed. To ensure that once the
sl@0
  1379
	//first non-zero number of iscii codes are converted, the internal input conversion
sl@0
  1380
	//flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable.
sl@0
  1381
	
sl@0
  1382
	if(aNumberOfForeignBytesConsumed>0)
sl@0
  1383
		{
sl@0
  1384
		aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable;
sl@0
  1385
		}
sl@0
  1386
	return;
sl@0
  1387
}
sl@0
  1388
sl@0
  1389
// -----------------------------------------------------------------------------
sl@0
  1390
// IsTruncatedDoubleByteIsciiSequence()
sl@0
  1391
//Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle.
sl@0
  1392
//If it is a truncated sequence, then returns ETrue else returns EFalse.
sl@0
  1393
//
sl@0
  1394
// Returns: ETrue: If the intermediate input iscii buffer is truncated
sl@0
  1395
//              EFalse: If the intermediate input iscii buffer is not truncated
sl@0
  1396
//
sl@0
  1397
// -----------------------------------------------------------------------------
sl@0
  1398
//
sl@0
  1399
sl@0
  1400
LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer)
sl@0
  1401
{
sl@0
  1402
	RArray<TPtrC8> searchBuffer;
sl@0
  1403
	if(anIsciiBuffer.Length () == 0)
sl@0
  1404
		return EFalse;
sl@0
  1405
	if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF)
sl@0
  1406
	return ETrue;
sl@0
  1407
	
sl@0
  1408
	TInt appendret = KErrNone;
sl@0
  1409
	appendret |= searchBuffer.Append(KSoftHalant().Mid(0));
sl@0
  1410
	appendret |= searchBuffer.Append(KOm().Mid(0));
sl@0
  1411
	appendret |= searchBuffer.Append(KAvagraha().Mid(0));
sl@0
  1412
	appendret |= searchBuffer.Append(KExplicitHalant().Mid(0));
sl@0
  1413
	__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
sl@0
  1414
	
sl@0
  1415
	TBool ret = EFalse;
sl@0
  1416
	TBool isNotTruncated =EFalse;
sl@0
  1417
	
sl@0
  1418
	//First check if the intermediate iscii buffer is ending with a complete multi byte sequence.
sl@0
  1419
	//If it ends with a complete multi byte sequence, no need to check if the last character of 
sl@0
  1420
	//intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse.
sl@0
  1421
	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
sl@0
  1422
		{
sl@0
  1423
		if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0)
sl@0
  1424
			{
sl@0
  1425
			isNotTruncated = ETrue;
sl@0
  1426
			break;
sl@0
  1427
			}
sl@0
  1428
		}
sl@0
  1429
	//If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the 
sl@0
  1430
	//last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a 
sl@0
  1431
	//truncated sequence and in that case return ETrue.
sl@0
  1432
	
sl@0
  1433
	for(TUint counter = 0;counter<searchBuffer.Count();counter++)
sl@0
  1434
		{
sl@0
  1435
		if(isNotTruncated)
sl@0
  1436
			break;
sl@0
  1437
		else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0]))
sl@0
  1438
			{
sl@0
  1439
			ret =ETrue;
sl@0
  1440
			break;
sl@0
  1441
			}
sl@0
  1442
		}
sl@0
  1443
	searchBuffer.Reset();
sl@0
  1444
	return ret;
sl@0
  1445
}
sl@0
  1446
sl@0
  1447
// -----------------------------------------------------------------------------
sl@0
  1448
// ReplacementForUnconvertibleUnicodeCharacters()
sl@0
  1449
//Returns the replacement character for unconvertible unicode character.
sl@0
  1450
//In the current implementation it is 0x1a (ASCII Substitute character)
sl@0
  1451
//The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal()
sl@0
  1452
//in turn which is generated by cnvtool.
sl@0
  1453
//
sl@0
  1454
// Returns: Replacemt for unconvertible unicode characters (0x1a)
sl@0
  1455
//
sl@0
  1456
// -----------------------------------------------------------------------------
sl@0
  1457
//
sl@0
  1458
sl@0
  1459
EXPORT_C const TDesC8& ReplacementForUnconvertibleUnicodeCharacters()
sl@0
  1460
	{
sl@0
  1461
    return ReplacementForUnconvertibleUnicodeCharacters_internal();
sl@0
  1462
	}
sl@0
  1463
sl@0
  1464
// -----------------------------------------------------------------------------
sl@0
  1465
// ConvertFromUnicode()
sl@0
  1466
//The main conversion function for converting from unicode to iscii
sl@0
  1467
//Loaded and called by the character conversion framework.
sl@0
  1468
//In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide
sl@0
  1469
//utility method for converting unicode to modal character codes.
sl@0
  1470
//
sl@0
  1471
// Returns: The numbet of unicode codes it could not convert.
sl@0
  1472
//
sl@0
  1473
// -----------------------------------------------------------------------------
sl@0
  1474
//
sl@0
  1475
sl@0
  1476
EXPORT_C TInt ConvertFromUnicode(
sl@0
  1477
         CCnvCharacterSetConverter::TEndianness 
sl@0
  1478
         aDefaultEndiannessOfForeignCharacters, 
sl@0
  1479
         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
  1480
         TDes8& aForeign, 
sl@0
  1481
         const TDesC16& aUnicode, 
sl@0
  1482
         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters )
sl@0
  1483
	{
sl@0
  1484
	TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets;
sl@0
  1485
	aArrayOfCharacterSets[0].iConversionData = &conversionData;
sl@0
  1486
	aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace;
sl@0
  1487
	aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari();
sl@0
  1488
sl@0
  1489
		return CnvUtilities::ConvertFromUnicode(
sl@0
  1490
				aDefaultEndiannessOfForeignCharacters, 
sl@0
  1491
				aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
  1492
				aForeign, 
sl@0
  1493
				aUnicode, 
sl@0
  1494
				aIndicesOfUnconvertibleCharacters, 
sl@0
  1495
				aArrayOfCharacterSets.Array());
sl@0
  1496
	}
sl@0
  1497
sl@0
  1498
// -----------------------------------------------------------------------------
sl@0
  1499
// ConvertToUnicode()
sl@0
  1500
//The main conversion function for converting from iscii to unicode
sl@0
  1501
//Loaded and called by the character conversion framework.
sl@0
  1502
//To support some of the iscii characters, the input forign buffer is
sl@0
  1503
//copied to an intermediate buffer and then is then modified and 
sl@0
  1504
//CCnvCharactersetConverter::DoConvertToUnicode() is called with
sl@0
  1505
//the modified buffer. For extensibility of iscii to other Indic languages
sl@0
  1506
//it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a
sl@0
  1507
//Symbian defined class for modal charactersets. The escape sequence 
sl@0
  1508
//is specified to ATR followed by the script selection code and the conversion
sl@0
  1509
//data is specified to be the conversion for the particular script. For the time
sl@0
  1510
//being only Devanagari with script selection code 0x42 is supported. If 
sl@0
  1511
//any of the other script codes are used the conversion leads to unconvertible
sl@0
  1512
//character i.e. 0xFFFD.
sl@0
  1513
// Returns: The numbet of iscii codes it could not convert.
sl@0
  1514
//
sl@0
  1515
// -----------------------------------------------------------------------------
sl@0
  1516
//
sl@0
  1517
sl@0
  1518
EXPORT_C TInt ConvertToUnicode(
sl@0
  1519
         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
  1520
         TDes16& aUnicode, 
sl@0
  1521
         const TDesC8& aForeign, 
sl@0
  1522
         TInt& aState, 
sl@0
  1523
         TInt& aNumberOfUnconvertibleCharacters, 
sl@0
  1524
         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter )
sl@0
  1525
	{
sl@0
  1526
	aNumberOfUnconvertibleCharacters = 0;
sl@0
  1527
	TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault;
sl@0
  1528
	aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1;
sl@0
  1529
	TUint internalInputConversionFlags = 0;
sl@0
  1530
	TInt numberOfForeignBytesConsumed=0;
sl@0
  1531
	TPtrC8 remainderOfForeign(aForeign);
sl@0
  1532
	TInt returnValue;
sl@0
  1533
	TBool flag = EFalse;
sl@0
  1534
	TBool isSkipMatchSequence = EFalse;
sl@0
  1535
	const SCnvConversionData* convData;
sl@0
  1536
	//Set the iscii conversion data and escape sequence for Devanagari.
sl@0
  1537
	TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals;
sl@0
  1538
	modals[0].iConversionData = &conversionData;
sl@0
  1539
	modals[0].iEscapeSequence = &KEscapeSequenceDevanagari();
sl@0
  1540
sl@0
  1541
	aUnicode.SetLength(0);
sl@0
  1542
	
sl@0
  1543
	//The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend
sl@0
  1544
	//so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer.
sl@0
  1545
	internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend;
sl@0
  1546
	if (aForeign.Length()==0)
sl@0
  1547
	{
sl@0
  1548
		return 0;
sl@0
  1549
	}
sl@0
  1550
	//Get the conversion data from the previous call else the conversion data is set to the default 
sl@0
  1551
	//conversion data, i.e. Devanagari.
sl@0
  1552
	convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData;
sl@0
  1553
	FOREVER
sl@0
  1554
	{
sl@0
  1555
		TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer;
sl@0
  1556
		TUint numberOfForeignBytesConsumedThisTime = 0;
sl@0
  1557
		if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer))
sl@0
  1558
		{
sl@0
  1559
			numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer;
sl@0
  1560
			intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
  1561
			//If the intermediate buffer is a part of truncated buffer sequence but the
sl@0
  1562
			//actual input buffer is not truncated then truncated sequence is not converted.
sl@0
  1563
			//The intermediate buffer is modified so as not to contain the truncated sequence.
sl@0
  1564
			
sl@0
  1565
			flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer);
sl@0
  1566
			if(flag)
sl@0
  1567
				{
sl@0
  1568
					numberOfForeignBytesConsumedThisTime --;
sl@0
  1569
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);					
sl@0
  1570
				}
sl@0
  1571
			
sl@0
  1572
		}
sl@0
  1573
		else
sl@0
  1574
		{
sl@0
  1575
			flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length()));
sl@0
  1576
			if(!flag)
sl@0
  1577
				{
sl@0
  1578
				numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
sl@0
  1579
				intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
  1580
				}
sl@0
  1581
			else
sl@0
  1582
				{
sl@0
  1583
				if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length()))
sl@0
  1584
					{
sl@0
  1585
					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1;
sl@0
  1586
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
  1587
					break;
sl@0
  1588
					}
sl@0
  1589
				else
sl@0
  1590
					{
sl@0
  1591
					numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length();
sl@0
  1592
					intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime);
sl@0
  1593
					}
sl@0
  1594
				}
sl@0
  1595
		}			
sl@0
  1596
		
sl@0
  1597
		//The input intermediate iscii buffer is modified with the search and replace
sl@0
  1598
		//buffers. It is required for supporting multibyte iscii sequences.		
sl@0
  1599
		FindAndModifyBuffer(intermediateBuffer);
sl@0
  1600
		TPtrC8 remainderOfForeignInternal(intermediateBuffer);
sl@0
  1601
		TPtrC8 homogeneousRun;
sl@0
  1602
		const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape);
sl@0
  1603
		if (startOfNextEscapeSequence!=0) 
sl@0
  1604
			{
sl@0
  1605
			if (startOfNextEscapeSequence==KErrNotFound)
sl@0
  1606
				{
sl@0
  1607
				homogeneousRun.Set(remainderOfForeignInternal);
sl@0
  1608
				remainderOfForeignInternal.Set(NULL, 0);
sl@0
  1609
				}
sl@0
  1610
			else
sl@0
  1611
				{
sl@0
  1612
				__ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence));
sl@0
  1613
				homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence));
sl@0
  1614
				remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence));
sl@0
  1615
				}
sl@0
  1616
			isSkipMatchSequence = ETrue;
sl@0
  1617
			}
sl@0
  1618
		FOREVER
sl@0
  1619
			{
sl@0
  1620
			if(!isSkipMatchSequence)
sl@0
  1621
				{
sl@0
  1622
				if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, 
sl@0
  1623
											remainderOfForeignInternal, modals.Array(), aOutputConversionFlags))
sl@0
  1624
					{
sl@0
  1625
					break;
sl@0
  1626
					}
sl@0
  1627
				}
sl@0
  1628
			HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, 
sl@0
  1629
								aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags,
sl@0
  1630
								numberOfForeignBytesConsumed,returnValue);
sl@0
  1631
			if(returnValue<0)
sl@0
  1632
				{
sl@0
  1633
				return returnValue;
sl@0
  1634
				}
sl@0
  1635
			isSkipMatchSequence = EFalse;
sl@0
  1636
			}
sl@0
  1637
		if(returnValue > 0)
sl@0
  1638
			break;
sl@0
  1639
		if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) )))
sl@0
  1640
			break;
sl@0
  1641
		remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed));				
sl@0
  1642
	}
sl@0
  1643
	//If the number of iscii bytes consumed by the conversion is zero also the output conversion
sl@0
  1644
	//flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput.
sl@0
  1645
	if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated))
sl@0
  1646
		{
sl@0
  1647
		return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
  1648
		}
sl@0
  1649
	//Set the conversion data sothat next time when ConvertToUnicode() is called,
sl@0
  1650
	//will use the previous conversion data.
sl@0
  1651
	aState=REINTERPRET_CAST(TInt, convData);
sl@0
  1652
	return aForeign.Length()-numberOfForeignBytesConsumed;
sl@0
  1653
    }
sl@0
  1654
sl@0
  1655
// -----------------------------------------------------------------------------
sl@0
  1656
// IsInThisCharacterSetL()
sl@0
  1657
//The method tells how probable it is that a sample piece of text is encoded in this character set.
sl@0
  1658
//On return aConfidenceLevel, indicates how confident the function is about its return value. For
sl@0
  1659
//iscii it is the default implementation and it does not implement the autodetect functionality.
sl@0
  1660
//Loaded and called by the character conversion framework.
sl@0
  1661
//
sl@0
  1662
// Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL()  that the plug-in DLL
sl@0
  1663
//                          is not implementing a function of this signature and is therefore empty.
sl@0
  1664
//
sl@0
  1665
// -----------------------------------------------------------------------------
sl@0
  1666
//
sl@0
  1667
sl@0
  1668
sl@0
  1669
//Default implementation for IsInThisCharacterSetL()
sl@0
  1670
sl@0
  1671
EXPORT_C TBool IsInThisCharacterSetL(
sl@0
  1672
         TBool& aSetToTrue, 
sl@0
  1673
         TInt& aConfidenceLevel, 
sl@0
  1674
         const TDesC8& )
sl@0
  1675
	{
sl@0
  1676
    	aSetToTrue = EFalse;
sl@0
  1677
	aConfidenceLevel = 0;
sl@0
  1678
	return EFalse;
sl@0
  1679
	}
sl@0
  1680
sl@0
  1681
EXPORT_C void Reserved_2()
sl@0
  1682
	{
sl@0
  1683
	}
sl@0
  1684
sl@0
  1685
EXPORT_C void Reserved_3()
sl@0
  1686
	{
sl@0
  1687
	}
sl@0
  1688
sl@0
  1689
EXPORT_C void Reserved_4()
sl@0
  1690
	{
sl@0
  1691
	}
sl@0
  1692
sl@0
  1693
EXPORT_C void Reserved_5()
sl@0
  1694
	{
sl@0
  1695
	}
sl@0
  1696
sl@0
  1697
EXPORT_C void Reserved_6()
sl@0
  1698
	{
sl@0
  1699
	}
sl@0
  1700
sl@0
  1701
EXPORT_C void Reserved_7()
sl@0
  1702
	{
sl@0
  1703
	}
sl@0
  1704
sl@0
  1705
EXPORT_C void Reserved_8()
sl@0
  1706
	{
sl@0
  1707
	}
sl@0
  1708
sl@0
  1709
#endif //EKA2