os/textandloc/charconvfw/charconvplugins/src/plugins/gb18030.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) 2009 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:  GB18030 converter implementation
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <e32std.h>
sl@0
    20
#include <charconv.h>
sl@0
    21
#include <convutils.h>
sl@0
    22
#include <convdata.h>
sl@0
    23
#include "gb2312.h"
sl@0
    24
#include "gbk.h"
sl@0
    25
#include "gb18030_4byte.h"
sl@0
    26
#include "gb18030_diff_gbk.h"
sl@0
    27
#include <ecom/implementationproxy.h>
sl@0
    28
#include <charactersetconverter.h>
sl@0
    29
sl@0
    30
class CGB18030ConverterImpl : public CCharacterSetConverterPluginInterface
sl@0
    31
	{
sl@0
    32
sl@0
    33
public:
sl@0
    34
	virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
sl@0
    35
sl@0
    36
	virtual TInt ConvertFromUnicode(
sl@0
    37
		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
    38
		const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
    39
		TDes8& aForeign, 
sl@0
    40
		const TDesC16& aUnicode, 
sl@0
    41
		CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
sl@0
    42
sl@0
    43
	virtual TInt ConvertToUnicode(
sl@0
    44
		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
    45
		TDes16& aUnicode, 
sl@0
    46
		const TDesC8& aForeign, 
sl@0
    47
		TInt& aState, 
sl@0
    48
		TInt& aNumberOfUnconvertibleCharacters, 
sl@0
    49
		TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
sl@0
    50
sl@0
    51
	virtual TBool IsInThisCharacterSetL(
sl@0
    52
		TBool& aSetToTrue, 
sl@0
    53
		TInt& aConfidenceLevel, 
sl@0
    54
		const TDesC8& aSample);
sl@0
    55
sl@0
    56
	static CGB18030ConverterImpl* NewL();
sl@0
    57
	virtual ~CGB18030ConverterImpl();
sl@0
    58
sl@0
    59
private:
sl@0
    60
	CGB18030ConverterImpl();
sl@0
    61
	TInt ConstructL();
sl@0
    62
	SCnvConversionData * completeGb18030_2byteConversionData; // a merged conversion data including Gb18030-diff-g2312, GB2312, Gb18030-diff-gbk and Gbk
sl@0
    63
	TUint8 * workingMemory;
sl@0
    64
	};
sl@0
    65
sl@0
    66
// Implement gb18030 plug-in using cnvutils framework in which gb2312 and gbk conversion data is re-used for memory saving 
sl@0
    67
// 1) foreign->unicode:
sl@0
    68
//    1.1) 1 byte->unicode bmp: use gb2312 mapping table;
sl@0
    69
//
sl@0
    70
//    1.2) 2 byte->unicode bmp: use gb18030-2byte mapping table (gb18030_diff_gb2312ConversionData + gb2312ConversionData + gb18030_diff_gbkConversionData + gbkConversionData);
sl@0
    71
//
sl@0
    72
//    1.3) 4 byte->unicode bmp: use gb18030-4byte mapping table;
sl@0
    73
//
sl@0
    74
//    1.4) 4 byte->unicode non-bmp: calculate with formula.
sl@0
    75
//
sl@0
    76
// 2) unicode->foreign:
sl@0
    77
//    2.1) firstly check gb18030-2byte mapping table (gb18030_diff_gb2312ConversionData + gb2312ConversionData + gb18030_diff_gbkConversionData + gbkConversionData);
sl@0
    78
//
sl@0
    79
//    2.2) if not found in 2.1), check gb18030-4byte mapping table;
sl@0
    80
//
sl@0
    81
//    2.3) if not found in 2.2), calculate with formula (gb18030-4byte non BMP);
sl@0
    82
//
sl@0
    83
sl@0
    84
sl@0
    85
// GB18030-diff-gb2312 defines 1 foreign-to-Unicode range and 2 unicode-to-Foreign range
sl@0
    86
// GB2312.CTL defines 21 foreign-to-Unicode ranges and 21 Unicode-to-foreign ranges
sl@0
    87
// GB18030-diff-gbk defines 1 foreign-to-Unicode ranges and 2 Unicode-to-foreign range
sl@0
    88
// GBK.CTL defines 2 foreign-to-Unicode ranges and 2 Unicode-to-foreign range
sl@0
    89
const TInt KNumberOfBytesOfWorkingMemory=(1+2+21+21+1+2+2+2)*sizeof(SCnvConversionData::SOneDirectionData::SRange);  //totally 1040 bytes
sl@0
    90
sl@0
    91
const TDesC8& CGB18030ConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
sl@0
    92
	{
sl@0
    93
	return CnvGb18030_diff_gbk::ReplacementForUnconvertibleUnicodeCharacters();
sl@0
    94
	}
sl@0
    95
sl@0
    96
_LIT(KLitPanicText, "GB18030");
sl@0
    97
enum TPanic
sl@0
    98
	{
sl@0
    99
	EPanicNothingToConvert1=1,
sl@0
   100
	EPanicNothingToConvert2,
sl@0
   101
	EPanicNothingToConvert3,
sl@0
   102
	EPanicNothingToConvert4,
sl@0
   103
	EPanicNothingToConvert5,
sl@0
   104
	EPanicNothingToConvert6,
sl@0
   105
	EPanicOddNumberOfBytes1,
sl@0
   106
	EPanicOddNumberOfBytes2,
sl@0
   107
	EPanicOddNumberOfBytes3,
sl@0
   108
	EPanicOddNumberOfBytes4,
sl@0
   109
	EPanicOddNumberOfBytes5,
sl@0
   110
	EPanicOddNumberOfBytes6,
sl@0
   111
	EPanicBadHighBit1,
sl@0
   112
	EPanicBadHighBit2,
sl@0
   113
	EPanicBadHighBit3,
sl@0
   114
	EPanicBadHighBit4,
sl@0
   115
	EPanicBadHighBit5,
sl@0
   116
	EPanicBadHighBit6,
sl@0
   117
	EPanicBadHighBit7,
sl@0
   118
	EPanicBadPointers1,
sl@0
   119
	EPanicBadPointers2,
sl@0
   120
	EPanicBadPointers3,
sl@0
   121
	EPanicBadPointers4,
sl@0
   122
	EPanicBadPointers5,
sl@0
   123
	EPanicBadPointers6,
sl@0
   124
	EPanicBadPointers7,
sl@0
   125
	EPanicBadPointers8,
sl@0
   126
	EPanicBadPointers9,
sl@0
   127
	EPanicBadPointers10,
sl@0
   128
	EPanicBadPointers11,
sl@0
   129
	EPanicBadPointers12,
sl@0
   130
	EPanicBadPointers13,
sl@0
   131
	EPanicBadPointers14,
sl@0
   132
	EPanicBadPointers15,
sl@0
   133
	EPanicBadPointers16,
sl@0
   134
	EPanicBadPointers17,
sl@0
   135
	EPanicBadPointers18,
sl@0
   136
	EPanicBadPointers19,
sl@0
   137
	EPanicBadPointers20,
sl@0
   138
	EPanicBadPointers21,
sl@0
   139
	EPanicBadPointers22,
sl@0
   140
	EPanicBadPointers23,
sl@0
   141
	EPanicBadPointers24,
sl@0
   142
	EPanicBadPointers25,
sl@0
   143
	EPanicBadPointers26,
sl@0
   144
	EPanicBadPointers27,
sl@0
   145
	EPanicBadPointers28,
sl@0
   146
	EPanicBadPointers29,
sl@0
   147
	EPanicBadPointers30,
sl@0
   148
	EPanicBadPointers31,
sl@0
   149
	EPanicBadPointers32,
sl@0
   150
	EPanicBadPointers33,
sl@0
   151
	EPanicBadPointers34,
sl@0
   152
	EPanicBadPointers35,
sl@0
   153
	EPanicBadPointers36,
sl@0
   154
	EPanicBadCalculation1,
sl@0
   155
	EPanicBadCalculation2,
sl@0
   156
	EPanicNumberOfBytesIsNotMultipleOfThree1,
sl@0
   157
	EPanicNumberOfBytesIsNotMultipleOfThree2,
sl@0
   158
	EPanicSingleShift2Expected,
sl@0
   159
	EPanicSingleShift3Expected,
sl@0
   160
	EPanicTooManyBytesOfWorkingMemoryUsed1,
sl@0
   161
	EPanicTooManyBytesOfWorkingMemoryUsed2
sl@0
   162
	};
sl@0
   163
sl@0
   164
LOCAL_C void Panic(TPanic aPanic)
sl@0
   165
	{
sl@0
   166
	User::Panic(KLitPanicText, aPanic);
sl@0
   167
	}
sl@0
   168
sl@0
   169
#define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
sl@0
   170
sl@0
   171
LOCAL_C void Step12DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut)
sl@0
   172
	{
sl@0
   173
	aNumberOfCharactersThatDroppedOut=0;
sl@0
   174
	}
sl@0
   175
sl@0
   176
// Perform the actual conversion (unicode -> gb18030 4byte non-BMP) using formula in this function
sl@0
   177
LOCAL_C void Step3ConvertFromIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
sl@0
   178
	{
sl@0
   179
	aNumberOfCharactersThatDroppedOut = 0;		// no drop out, because all GB18030 outside BMP are exactly 4-bytes
sl@0
   180
	
sl@0
   181
	const TInt descriptorLength=aDescriptor.Length();
sl@0
   182
	TUint8* pVeryFrom = CONST_CAST(TUint8*, aDescriptor.Ptr());
sl@0
   183
	const TUint8* pEnd = pVeryFrom + descriptorLength;
sl@0
   184
	TUint8* pFrom = pVeryFrom + aStartPositionInDescriptor;
sl@0
   185
	FOREVER
sl@0
   186
		{
sl@0
   187
		if (pFrom + 4 > pEnd)
sl@0
   188
			{
sl@0
   189
			__ASSERT_DEBUG(pFrom==pEnd, Panic(EPanicBadPointers25));
sl@0
   190
			break;
sl@0
   191
			}
sl@0
   192
		TUint characterCode = 0;
sl@0
   193
		for (TInt i=0; i<4; i++)
sl@0
   194
			{
sl@0
   195
			characterCode <<= 8;
sl@0
   196
			characterCode += pFrom[i];
sl@0
   197
			}
sl@0
   198
		
sl@0
   199
		// to gb18030
sl@0
   200
		characterCode -= 0x10000;
sl@0
   201
		TUint b4 = characterCode % 10 + 0x30;
sl@0
   202
		characterCode /= 10;
sl@0
   203
		TUint b3 = characterCode % 126 + 0x81;
sl@0
   204
		characterCode /= 126;
sl@0
   205
		TUint b2 = characterCode % 10 + 0x30;
sl@0
   206
		TUint b1 = characterCode / 10 + 0x90;
sl@0
   207
		
sl@0
   208
		*pFrom++ = b1;
sl@0
   209
		*pFrom++ = b2;
sl@0
   210
		*pFrom++ = b3;
sl@0
   211
		*pFrom++ = b4;
sl@0
   212
		}
sl@0
   213
	aDescriptor.SetLength(pFrom-pVeryFrom);
sl@0
   214
	}
sl@0
   215
sl@0
   216
// gb2312-1byte ->unicode (0x00 - 0x7F)
sl@0
   217
LOCAL_C TInt Step0NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
sl@0
   218
	{
sl@0
   219
	const TInt descriptorLength=aDescriptor.Length();
sl@0
   220
	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
sl@0
   221
	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
sl@0
   222
	
sl@0
   223
	TInt numOfBytes = 0;
sl@0
   224
	FOREVER
sl@0
   225
		{
sl@0
   226
		if (pointerToPreviousByte>=pointerToLastByte)
sl@0
   227
			{
sl@0
   228
			break;
sl@0
   229
			}
sl@0
   230
		// byte 1
sl@0
   231
		TUint b1 = pointerToPreviousByte[1];
sl@0
   232
		if (b1 <= 0x7F)
sl@0
   233
			{
sl@0
   234
			pointerToPreviousByte++;
sl@0
   235
			numOfBytes++;
sl@0
   236
			}
sl@0
   237
		else
sl@0
   238
			break;
sl@0
   239
		}
sl@0
   240
		return numOfBytes;
sl@0
   241
	}
sl@0
   242
sl@0
   243
// gb18030-2byte --> unicode (0x8140 - 0xFE7E, 0x8180 - 0xFEFE)
sl@0
   244
LOCAL_C TInt Step1NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
sl@0
   245
	{
sl@0
   246
	const TInt descriptorLength=aDescriptor.Length();
sl@0
   247
	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
sl@0
   248
	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
sl@0
   249
sl@0
   250
	TInt numOfBytes = 0;
sl@0
   251
	FOREVER
sl@0
   252
		{
sl@0
   253
		if (pointerToPreviousByte>=pointerToLastByte)
sl@0
   254
			{
sl@0
   255
			break;
sl@0
   256
			}
sl@0
   257
		// byte 1
sl@0
   258
		TUint b1 = pointerToPreviousByte[1];
sl@0
   259
		if (b1 <= 0x80 || b1 > 0xFE)
sl@0
   260
			break;
sl@0
   261
sl@0
   262
		// byte 2
sl@0
   263
		if (pointerToPreviousByte+1 >= pointerToLastByte)
sl@0
   264
			break;
sl@0
   265
		TUint b2 = pointerToPreviousByte[2];
sl@0
   266
		if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F)		// all gb18030 2-byte code
sl@0
   267
			{
sl@0
   268
			pointerToPreviousByte = pointerToPreviousByte + 2;
sl@0
   269
			numOfBytes = numOfBytes + 2;
sl@0
   270
			}
sl@0
   271
		else if (b2 < 0x30 || b2 > 0x39)
sl@0
   272
			{
sl@0
   273
			if (numOfBytes <= 0)
sl@0
   274
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   275
			else
sl@0
   276
				break;
sl@0
   277
			}
sl@0
   278
		else
sl@0
   279
			break;
sl@0
   280
		}
sl@0
   281
		return numOfBytes;
sl@0
   282
	}
sl@0
   283
sl@0
   284
sl@0
   285
// gb18030 4-bytes bmp --> unicode (0x81308130 - 0x8439FE39)
sl@0
   286
LOCAL_C TInt Step2NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
sl@0
   287
	{
sl@0
   288
	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
sl@0
   289
	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
sl@0
   290
	__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers25));
sl@0
   291
	
sl@0
   292
	TInt numOfBytes = 0;
sl@0
   293
	FOREVER
sl@0
   294
		{
sl@0
   295
		if (pointerToPreviousByte>=pointerToLastByte)
sl@0
   296
			{
sl@0
   297
			break;
sl@0
   298
			}
sl@0
   299
	
sl@0
   300
		// byte 1
sl@0
   301
		TUint b1 = pointerToPreviousByte[1];
sl@0
   302
		if ((b1 < 0x81) || (b1 > 0x84)){
sl@0
   303
			break;
sl@0
   304
		}
sl@0
   305
			
sl@0
   306
		// byte 2
sl@0
   307
		if (pointerToPreviousByte+1 >= pointerToLastByte)
sl@0
   308
			break;
sl@0
   309
		TUint b2 = pointerToPreviousByte[2];
sl@0
   310
		if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F)		// all gb18030 2-byte code
sl@0
   311
			break;
sl@0
   312
		else if (b2 < 0x30 || b2 > 0x39)
sl@0
   313
			{
sl@0
   314
			if (numOfBytes == 0)
sl@0
   315
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   316
			else 
sl@0
   317
				break;
sl@0
   318
			}
sl@0
   319
sl@0
   320
		
sl@0
   321
		// byte 3
sl@0
   322
		if (pointerToPreviousByte+2 >= pointerToLastByte)
sl@0
   323
			break;
sl@0
   324
		TUint b3 = pointerToPreviousByte[3];
sl@0
   325
		if (b3 < 0x81 || b3 > 0xFE)
sl@0
   326
			{
sl@0
   327
			if (numOfBytes == 0)
sl@0
   328
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   329
			else 
sl@0
   330
				break;
sl@0
   331
			}
sl@0
   332
		
sl@0
   333
		// byte 4
sl@0
   334
		if (pointerToPreviousByte+3 >= pointerToLastByte)
sl@0
   335
			break;
sl@0
   336
		TUint b4 = pointerToPreviousByte[4];
sl@0
   337
		if (b4 < 0x30 || b4 > 0x39)
sl@0
   338
			{
sl@0
   339
			if (numOfBytes == 0)
sl@0
   340
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   341
			else 
sl@0
   342
				break;
sl@0
   343
			}
sl@0
   344
		else
sl@0
   345
			{
sl@0
   346
				numOfBytes = numOfBytes + 4;
sl@0
   347
				pointerToPreviousByte = pointerToPreviousByte+4;
sl@0
   348
			}
sl@0
   349
		}
sl@0
   350
		
sl@0
   351
		return numOfBytes;
sl@0
   352
	}
sl@0
   353
sl@0
   354
// gb18030 4-bytes non-bmp --> unicode (0x90308130~0xE339FE39)
sl@0
   355
LOCAL_C TInt Step3NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
sl@0
   356
	{
sl@0
   357
	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
sl@0
   358
	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
sl@0
   359
	__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers25));
sl@0
   360
sl@0
   361
	TInt numOfBytes = 0;
sl@0
   362
	FOREVER
sl@0
   363
		{
sl@0
   364
		if (pointerToPreviousByte>=pointerToLastByte)
sl@0
   365
			{
sl@0
   366
			break;
sl@0
   367
			}
sl@0
   368
		
sl@0
   369
		// byte 1
sl@0
   370
		TUint b1 = pointerToPreviousByte[1];
sl@0
   371
		if (b1 < 0x90 || b1 > 0xE3)
sl@0
   372
			break;
sl@0
   373
		
sl@0
   374
		// byte 2
sl@0
   375
		if (pointerToPreviousByte+1 >= pointerToLastByte)
sl@0
   376
			break;
sl@0
   377
		TUint b2 = pointerToPreviousByte[2];
sl@0
   378
		if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F)
sl@0
   379
			break;
sl@0
   380
		else if (b2 < 0x30 || b2 > 0x39)
sl@0
   381
			{
sl@0
   382
			if (numOfBytes == 0)
sl@0
   383
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   384
			else 
sl@0
   385
				break;
sl@0
   386
			}
sl@0
   387
			
sl@0
   388
		// byte 3
sl@0
   389
		if (pointerToPreviousByte+2 >= pointerToLastByte)
sl@0
   390
			break;
sl@0
   391
		TUint b3 = pointerToPreviousByte[3];
sl@0
   392
		if (b3 < 0x81 || b3 > 0xFE)
sl@0
   393
			{
sl@0
   394
			if (numOfBytes == 0)
sl@0
   395
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   396
			else 
sl@0
   397
				break;
sl@0
   398
			}
sl@0
   399
		
sl@0
   400
		// byte 4
sl@0
   401
		if (pointerToPreviousByte+3 >= pointerToLastByte)
sl@0
   402
			break;
sl@0
   403
		TUint b4 = pointerToPreviousByte[4];
sl@0
   404
		if (b4 < 0x30 || b4 > 0x39)
sl@0
   405
			{
sl@0
   406
			if (numOfBytes == 0)
sl@0
   407
				return CCnvCharacterSetConverter::EErrorIllFormedInput;
sl@0
   408
			else 
sl@0
   409
				break;
sl@0
   410
			}
sl@0
   411
		else 
sl@0
   412
			{
sl@0
   413
			numOfBytes = numOfBytes + 4;
sl@0
   414
			pointerToPreviousByte = pointerToPreviousByte + 4;
sl@0
   415
			}
sl@0
   416
		}
sl@0
   417
		return numOfBytes;
sl@0
   418
	}
sl@0
   419
	
sl@0
   420
void Step012DummyConvertToIntermediateBufferInPlace(TDes8&)
sl@0
   421
	{
sl@0
   422
	}
sl@0
   423
sl@0
   424
// Perform the actual conversion (gb18030 4byte non-BMP -> unicode) using formula in this function
sl@0
   425
LOCAL_C void Step3ConvertToIntermediateBufferInPlace(TDes8& aDescriptor)
sl@0
   426
	{
sl@0
   427
	const TInt descriptorLength=aDescriptor.Length();
sl@0
   428
	__ASSERT_DEBUG(descriptorLength%4 == 0, Panic(EPanicNothingToConvert5));
sl@0
   429
	TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
sl@0
   430
	const TUint8* pointerToSourceByte=pointerToTargetByte;
sl@0
   431
	const TUint8* const pointerToLastByte=pointerToSourceByte+descriptorLength;
sl@0
   432
	
sl@0
   433
	FOREVER
sl@0
   434
		{
sl@0
   435
		if (pointerToLastByte - pointerToSourceByte < 4)
sl@0
   436
			break;
sl@0
   437
		
sl@0
   438
		// conversion
sl@0
   439
		TUint8 b1 = pointerToSourceByte[0];
sl@0
   440
		TUint8 b2 = pointerToSourceByte[1];
sl@0
   441
		TUint8 b3 = pointerToSourceByte[2];
sl@0
   442
		TUint8 b4 = pointerToSourceByte[3];
sl@0
   443
		
sl@0
   444
		TUint characterCode = 0x10000 + (b1 - 0x90) * 12600 +
sl@0
   445
										(b2 - 0x30) * 1260 +
sl@0
   446
										(b3 - 0x81) * 10 +
sl@0
   447
										(b4 - 0x30);
sl@0
   448
		
sl@0
   449
		pointerToTargetByte[0] = ((characterCode >> 24) & 0xFF);
sl@0
   450
		pointerToTargetByte[1] = ((characterCode >> 16) & 0xFF);
sl@0
   451
		pointerToTargetByte[2] = ((characterCode >> 8) & 0xFF);
sl@0
   452
		pointerToTargetByte[3] = (characterCode & 0xFF);
sl@0
   453
		
sl@0
   454
		pointerToSourceByte = pointerToSourceByte + 4;
sl@0
   455
		pointerToTargetByte = pointerToTargetByte + 4;
sl@0
   456
		}
sl@0
   457
	
sl@0
   458
		aDescriptor.SetLength(descriptorLength);
sl@0
   459
	}
sl@0
   460
sl@0
   461
sl@0
   462
// A dummy "direct" mapping table for non-Bmp chars in step 3
sl@0
   463
// Use 32-bit Unicode value as intermediate coding
sl@0
   464
LOCAL_D const SCnvConversionData::SVariableByteData::SRange step3ForeignVariableByteDataRanges[]=
sl@0
   465
	{
sl@0
   466
		{
sl@0
   467
		0x00,		// from 0x10000
sl@0
   468
		0x00,		// to  0x10FFFF
sl@0
   469
		3,			// total 4 bytes
sl@0
   470
		0
sl@0
   471
		},		
sl@0
   472
	};
sl@0
   473
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange step3ForeignToUnicodeDataRanges[]=
sl@0
   474
	{
sl@0
   475
		{
sl@0
   476
		0x10000,	// from 0x10000
sl@0
   477
		0x10ffff,	// to  0x10FFFF
sl@0
   478
		SCnvConversionData::SOneDirectionData::SRange::EDirect,
sl@0
   479
		0,
sl@0
   480
		0,
sl@0
   481
			{
sl@0
   482
			0		// map from intermediate to unicode with offset = 0
sl@0
   483
			}
sl@0
   484
		},
sl@0
   485
	};
sl@0
   486
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange step3UnicodeToForeignDataRanges[]=
sl@0
   487
	{
sl@0
   488
		{
sl@0
   489
		0x10000,	//from 0x10000
sl@0
   490
		0x10FFFF, //to 0x10FFFF
sl@0
   491
		SCnvConversionData::SOneDirectionData::SRange::EDirect,
sl@0
   492
		4,			// output byte count = 4
sl@0
   493
		0,
sl@0
   494
			{
sl@0
   495
			0		// offset = 0
sl@0
   496
			}
sl@0
   497
		},
sl@0
   498
	};
sl@0
   499
GLDEF_D const SCnvConversionData step3ConversionData=
sl@0
   500
	{
sl@0
   501
	SCnvConversionData::EFixedBigEndian,
sl@0
   502
		{
sl@0
   503
		ARRAY_LENGTH(step3ForeignVariableByteDataRanges),
sl@0
   504
		step3ForeignVariableByteDataRanges
sl@0
   505
		},
sl@0
   506
		{
sl@0
   507
		ARRAY_LENGTH(step3ForeignToUnicodeDataRanges),
sl@0
   508
		step3ForeignToUnicodeDataRanges
sl@0
   509
		},
sl@0
   510
		{
sl@0
   511
		ARRAY_LENGTH(step3UnicodeToForeignDataRanges),
sl@0
   512
		step3UnicodeToForeignDataRanges
sl@0
   513
		},
sl@0
   514
	NULL,
sl@0
   515
	NULL
sl@0
   516
	};
sl@0
   517
sl@0
   518
sl@0
   519
// An internal mapping table to reslove the conflict introduced in symbian GB2312-80 plug-in.
sl@0
   520
// It will be merged into the gb18030-2byte Conversion Data.
sl@0
   521
// It includes mapping: (0xA1A4 -> 0x00B7, 0xA1AA -> 0x2014, 0xA844 <- 0x2015, 0x8139A739 <- 0x30FB)
sl@0
   522
LOCAL_D const SCnvConversionData::SVariableByteData::SRange gb18030_diff_gb2312ForeignVariableByteDataRanges[]=
sl@0
   523
	{
sl@0
   524
		{
sl@0
   525
		0xA1, //from 0xA1A4
sl@0
   526
		0xA1, //to 0xA1AA
sl@0
   527
		1,			
sl@0
   528
		0
sl@0
   529
		},		
sl@0
   530
	};
sl@0
   531
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_foreignToUnicode_1[]=
sl@0
   532
	{
sl@0
   533
			{
sl@0
   534
			0xA1A4,
sl@0
   535
			0x00B7
sl@0
   536
			},
sl@0
   537
			{
sl@0
   538
			0xA1AA,
sl@0
   539
			0x2014
sl@0
   540
			}
sl@0
   541
	};
sl@0
   542
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange gb18030_diff_gb2312ForeignToUnicodeDataRanges[]=
sl@0
   543
	{
sl@0
   544
		{
sl@0
   545
		0xA1A4,
sl@0
   546
		0xA1AA,
sl@0
   547
		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
sl@0
   548
		0,
sl@0
   549
		0,
sl@0
   550
			{
sl@0
   551
			UData_SKeyedTable1616(keyedTable1616_foreignToUnicode_1)
sl@0
   552
			}
sl@0
   553
		},
sl@0
   554
	};
sl@0
   555
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_unicodeToForeign_1[]=
sl@0
   556
	{
sl@0
   557
			{
sl@0
   558
			0x2015,
sl@0
   559
			0xA844
sl@0
   560
			}
sl@0
   561
	};
sl@0
   562
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable3232::SEntry keyedTable3232_unicodeToForeign_1[]=
sl@0
   563
	{
sl@0
   564
			{
sl@0
   565
			0x30FB,
sl@0
   566
			0x8139A739
sl@0
   567
			}
sl@0
   568
	};
sl@0
   569
sl@0
   570
LOCAL_D const SCnvConversionData::SOneDirectionData::SRange gb18030_diff_gb2312UnicodeToForeignDataRanges[]=
sl@0
   571
	{
sl@0
   572
		{
sl@0
   573
		0x2015,
sl@0
   574
		0x2015,
sl@0
   575
		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
sl@0
   576
		2,			// output byte count = 2
sl@0
   577
		0,
sl@0
   578
			{
sl@0
   579
			UData_SKeyedTable1616(keyedTable1616_unicodeToForeign_1)
sl@0
   580
			}
sl@0
   581
		},
sl@0
   582
		{
sl@0
   583
		0x30FB,
sl@0
   584
		0x30FB,
sl@0
   585
		SCnvConversionData::SOneDirectionData::SRange::EKeyedTable3232,
sl@0
   586
		4,			// output byte count = 4
sl@0
   587
		0,
sl@0
   588
			{
sl@0
   589
			UData_SKeyedTable3232(keyedTable3232_unicodeToForeign_1)
sl@0
   590
			}
sl@0
   591
		},
sl@0
   592
	};
sl@0
   593
GLDEF_D const SCnvConversionData gb18030_diff_gb2312ConversionData=
sl@0
   594
	{
sl@0
   595
	SCnvConversionData::EFixedBigEndian,
sl@0
   596
		{
sl@0
   597
		ARRAY_LENGTH(gb18030_diff_gb2312ForeignVariableByteDataRanges),
sl@0
   598
		gb18030_diff_gb2312ForeignVariableByteDataRanges
sl@0
   599
		},
sl@0
   600
		{
sl@0
   601
		ARRAY_LENGTH(gb18030_diff_gb2312ForeignToUnicodeDataRanges),
sl@0
   602
		gb18030_diff_gb2312ForeignToUnicodeDataRanges
sl@0
   603
		},
sl@0
   604
		{
sl@0
   605
		ARRAY_LENGTH(gb18030_diff_gb2312UnicodeToForeignDataRanges),
sl@0
   606
		gb18030_diff_gb2312UnicodeToForeignDataRanges
sl@0
   607
		},
sl@0
   608
	NULL,
sl@0
   609
	NULL
sl@0
   610
	};
sl@0
   611
sl@0
   612
LOCAL_D const SCnvConversionData::SVariableByteData::SRange foreignVariableByteDataRanges[]=
sl@0
   613
	{
sl@0
   614
		{
sl@0
   615
		0x00,
sl@0
   616
		0x7f,
sl@0
   617
		0,
sl@0
   618
		0
sl@0
   619
		},
sl@0
   620
		{
sl@0
   621
		0x80,
sl@0
   622
		0xff,
sl@0
   623
		1,
sl@0
   624
		0
sl@0
   625
		}
sl@0
   626
	};
sl@0
   627
sl@0
   628
LOCAL_C void SetUpCompleteGb18030_2byteConversionData(SCnvConversionData& aCompleteGb18030_2byteConversionData, TUint8* aWorkingMemory)
sl@0
   629
	{
sl@0
   630
	const SCnvConversionData& gb2312ConversionData=CnvGb2312::ConversionData();
sl@0
   631
	const SCnvConversionData& gb18030_diff_gbkConversionData=CnvGb18030_diff_gbk::ConversionData();
sl@0
   632
	const SCnvConversionData& gbkConversionData=CnvGbk::ConversionData();
sl@0
   633
	// create a SCnvConversionData that is the combination of gb18030_diff_gb2312ConversionData, gb2312ConversionData, gb18030_diff_gbkConversionData and gbkConversionData;
sl@0
   634
	aCompleteGb18030_2byteConversionData.iEndiannessOfForeignCharacters=SCnvConversionData::EFixedBigEndian;
sl@0
   635
	aCompleteGb18030_2byteConversionData.iForeignVariableByteData.iNumberOfRanges=ARRAY_LENGTH(foreignVariableByteDataRanges);
sl@0
   636
	aCompleteGb18030_2byteConversionData.iForeignVariableByteData.iRangeArray=foreignVariableByteDataRanges;
sl@0
   637
	TInt numberOfBytesOfWorkingMemoryUsed=0;
sl@0
   638
	
sl@0
   639
	// set up the foreign-to-Unicode data
sl@0
   640
	const TInt numberOfForeignToUnicodeDataRanges=gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb18030_diff_gbkConversionData.iForeignToUnicodeData.iNumberOfRanges + gbkConversionData.iForeignToUnicodeData.iNumberOfRanges;
sl@0
   641
	aCompleteGb18030_2byteConversionData.iForeignToUnicodeData.iNumberOfRanges=numberOfForeignToUnicodeDataRanges;
sl@0
   642
	SCnvConversionData::SOneDirectionData::SRange* foreignToUnicodeDataRangeArray=REINTERPRET_CAST(SCnvConversionData::SOneDirectionData::SRange*, aWorkingMemory+numberOfBytesOfWorkingMemoryUsed);
sl@0
   643
	numberOfBytesOfWorkingMemoryUsed+=(numberOfForeignToUnicodeDataRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   644
	__ASSERT_ALWAYS(numberOfBytesOfWorkingMemoryUsed<=KNumberOfBytesOfWorkingMemory, Panic(EPanicTooManyBytesOfWorkingMemoryUsed1));
sl@0
   645
	aCompleteGb18030_2byteConversionData.iForeignToUnicodeData.iRangeArray=foreignToUnicodeDataRangeArray;
sl@0
   646
	Mem::Copy(foreignToUnicodeDataRangeArray, gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iRangeArray, gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   647
	Mem::Copy(foreignToUnicodeDataRangeArray + gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges, gb2312ConversionData.iForeignToUnicodeData.iRangeArray, gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   648
	Mem::Copy(foreignToUnicodeDataRangeArray + gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges, gb18030_diff_gbkConversionData.iForeignToUnicodeData.iRangeArray, gb18030_diff_gbkConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   649
	Mem::Copy(foreignToUnicodeDataRangeArray + gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb18030_diff_gbkConversionData.iForeignToUnicodeData.iNumberOfRanges, gbkConversionData.iForeignToUnicodeData.iRangeArray, gbkConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   650
sl@0
   651
	// set up the Unicode-to-foreign data
sl@0
   652
	const TInt numberOfUnicodeToForeignDataRanges=gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb18030_diff_gbkConversionData.iUnicodeToForeignData.iNumberOfRanges + gbkConversionData.iUnicodeToForeignData.iNumberOfRanges;
sl@0
   653
	aCompleteGb18030_2byteConversionData.iUnicodeToForeignData.iNumberOfRanges=numberOfUnicodeToForeignDataRanges;
sl@0
   654
	SCnvConversionData::SOneDirectionData::SRange* unicodeToForeignDataRangeArray=REINTERPRET_CAST(SCnvConversionData::SOneDirectionData::SRange*, aWorkingMemory+numberOfBytesOfWorkingMemoryUsed);
sl@0
   655
	numberOfBytesOfWorkingMemoryUsed+=(numberOfUnicodeToForeignDataRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   656
	__ASSERT_ALWAYS(numberOfBytesOfWorkingMemoryUsed<=KNumberOfBytesOfWorkingMemory, Panic(EPanicTooManyBytesOfWorkingMemoryUsed2));
sl@0
   657
	aCompleteGb18030_2byteConversionData.iUnicodeToForeignData.iRangeArray=unicodeToForeignDataRangeArray;
sl@0
   658
	Mem::Copy(unicodeToForeignDataRangeArray, gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iRangeArray, gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   659
	Mem::Copy(unicodeToForeignDataRangeArray + gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges, gb2312ConversionData.iUnicodeToForeignData.iRangeArray, gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   660
	Mem::Copy(unicodeToForeignDataRangeArray + gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges, gb18030_diff_gbkConversionData.iUnicodeToForeignData.iRangeArray, gb18030_diff_gbkConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   661
	Mem::Copy(unicodeToForeignDataRangeArray + gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb18030_diff_gbkConversionData.iUnicodeToForeignData.iNumberOfRanges, gbkConversionData.iUnicodeToForeignData.iRangeArray, gbkConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
sl@0
   662
	}
sl@0
   663
sl@0
   664
sl@0
   665
TInt CGB18030ConverterImpl::ConvertFromUnicode(
sl@0
   666
		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
   667
		const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
sl@0
   668
		TDes8& aForeign, 
sl@0
   669
		const TDesC16& aUnicode, 
sl@0
   670
		CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters)
sl@0
   671
	{
sl@0
   672
	TFixedArray<CnvUtilities::SCharacterSet, 3> characterSets;
sl@0
   673
	
sl@0
   674
	// step 1) gb18030-2byte
sl@0
   675
	characterSets[0].iConversionData						= completeGb18030_2byteConversionData;
sl@0
   676
	characterSets[0].iConvertFromIntermediateBufferInPlace	= Step12DummyConvertFromIntermediateBufferInPlace;
sl@0
   677
	characterSets[0].iEscapeSequence						= &KNullDesC8;
sl@0
   678
	
sl@0
   679
	// step 2) gb18030-4byte BMP
sl@0
   680
	characterSets[1].iConversionData						= &CnvGb18030_4byte::ConversionData();
sl@0
   681
	characterSets[1].iConvertFromIntermediateBufferInPlace	= Step12DummyConvertFromIntermediateBufferInPlace;
sl@0
   682
	characterSets[1].iEscapeSequence						= &KNullDesC8;
sl@0
   683
	
sl@0
   684
	// step 3) gb18030-4byte non-BMP
sl@0
   685
	characterSets[2].iConversionData						= &step3ConversionData;
sl@0
   686
	characterSets[2].iConvertFromIntermediateBufferInPlace	= Step3ConvertFromIntermediateBufferInPlace;
sl@0
   687
	characterSets[2].iEscapeSequence						= &KNullDesC8;
sl@0
   688
	
sl@0
   689
	return CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, characterSets.Array());
sl@0
   690
	}
sl@0
   691
sl@0
   692
sl@0
   693
TInt CGB18030ConverterImpl::ConvertToUnicode(
sl@0
   694
		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
sl@0
   695
		TDes16& aUnicode, 
sl@0
   696
		const TDesC8& aForeign, 
sl@0
   697
		TInt& /*aState*/, 
sl@0
   698
		TInt& aNumberOfUnconvertibleCharacters, 
sl@0
   699
		TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter)
sl@0
   700
	{
sl@0
   701
	TFixedArray<CnvUtilities::SMethod, 4> methods;
sl@0
   702
	// step 0) gb2312-1byte
sl@0
   703
	methods[0].iNumberOfBytesAbleToConvert			= Step0NumberOfBytesAbleToConvertToUnicode;
sl@0
   704
	methods[0].iConvertToIntermediateBufferInPlace	= Step012DummyConvertToIntermediateBufferInPlace;
sl@0
   705
	methods[0].iConversionData						= &CnvGb2312::ConversionData(); //only use one byte part
sl@0
   706
	methods[0].iNumberOfBytesPerCharacter			= 1;
sl@0
   707
	methods[0].iNumberOfCoreBytesPerCharacter		= 1;
sl@0
   708
	
sl@0
   709
	// step 1) gb18030-2byte
sl@0
   710
	methods[1].iNumberOfBytesAbleToConvert			= Step1NumberOfBytesAbleToConvertToUnicode;
sl@0
   711
	methods[1].iConvertToIntermediateBufferInPlace	= Step012DummyConvertToIntermediateBufferInPlace;
sl@0
   712
	methods[1].iConversionData						= completeGb18030_2byteConversionData;
sl@0
   713
	methods[1].iNumberOfBytesPerCharacter			= 2;
sl@0
   714
	methods[1].iNumberOfCoreBytesPerCharacter		= 2;
sl@0
   715
	
sl@0
   716
	// step 2) gb18030 4-byte BMP
sl@0
   717
	methods[2].iNumberOfBytesAbleToConvert			= Step2NumberOfBytesAbleToConvertToUnicode;
sl@0
   718
	methods[2].iConvertToIntermediateBufferInPlace	= Step012DummyConvertToIntermediateBufferInPlace;
sl@0
   719
	methods[2].iConversionData						= &CnvGb18030_4byte::ConversionData();
sl@0
   720
	methods[2].iNumberOfBytesPerCharacter			= 4;
sl@0
   721
	methods[2].iNumberOfCoreBytesPerCharacter		= 4;
sl@0
   722
sl@0
   723
	// step 3) gb18030 4-byte non-BMP
sl@0
   724
	methods[3].iNumberOfBytesAbleToConvert			= Step3NumberOfBytesAbleToConvertToUnicode;
sl@0
   725
	methods[3].iConvertToIntermediateBufferInPlace	= Step3ConvertToIntermediateBufferInPlace;
sl@0
   726
	methods[3].iConversionData						= &step3ConversionData;
sl@0
   727
	methods[3].iNumberOfBytesPerCharacter			= 4;
sl@0
   728
	methods[3].iNumberOfCoreBytesPerCharacter		= 4;
sl@0
   729
	
sl@0
   730
	return CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array());
sl@0
   731
	}
sl@0
   732
sl@0
   733
TBool CGB18030ConverterImpl::IsInThisCharacterSetL(
sl@0
   734
		TBool& aSetToTrue, 
sl@0
   735
		TInt& aConfidenceLevel, 
sl@0
   736
		const TDesC8& aSample)
sl@0
   737
	{
sl@0
   738
	aSetToTrue = ETrue;
sl@0
   739
	return CnvGb2312::IsCharGBBased(aConfidenceLevel, aSample);
sl@0
   740
	}
sl@0
   741
sl@0
   742
CGB18030ConverterImpl* CGB18030ConverterImpl::NewL()
sl@0
   743
	{
sl@0
   744
	CGB18030ConverterImpl* self = new(ELeave) CGB18030ConverterImpl();
sl@0
   745
	CleanupStack::PushL(self);
sl@0
   746
	self->ConstructL();
sl@0
   747
	CleanupStack::Pop(); // self
sl@0
   748
	return self;
sl@0
   749
	}
sl@0
   750
sl@0
   751
CGB18030ConverterImpl::~CGB18030ConverterImpl()
sl@0
   752
	{
sl@0
   753
	if (workingMemory)
sl@0
   754
		delete[] workingMemory;
sl@0
   755
	if (completeGb18030_2byteConversionData)
sl@0
   756
		delete completeGb18030_2byteConversionData;
sl@0
   757
	}
sl@0
   758
sl@0
   759
CGB18030ConverterImpl::CGB18030ConverterImpl()
sl@0
   760
	{
sl@0
   761
	}
sl@0
   762
sl@0
   763
TInt CGB18030ConverterImpl::ConstructL()
sl@0
   764
	{
sl@0
   765
	completeGb18030_2byteConversionData = new (ELeave)SCnvConversionData;
sl@0
   766
	CleanupStack::PushL(completeGb18030_2byteConversionData);
sl@0
   767
	workingMemory = new (ELeave) TUint8[KNumberOfBytesOfWorkingMemory]; //1040 bytes
sl@0
   768
	CleanupStack::Pop(); // completeGb18030_2byteConversionData
sl@0
   769
	SetUpCompleteGb18030_2byteConversionData(*completeGb18030_2byteConversionData, workingMemory);
sl@0
   770
	return 1;
sl@0
   771
	}
sl@0
   772
sl@0
   773
const TImplementationProxy ImplementationTable[] = 
sl@0
   774
	{
sl@0
   775
		IMPLEMENTATION_PROXY_ENTRY(0x10287038,CGB18030ConverterImpl::NewL)
sl@0
   776
	};
sl@0
   777
sl@0
   778
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
sl@0
   779
	{
sl@0
   780
	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
sl@0
   781
sl@0
   782
	return ImplementationTable;
sl@0
   783
	}
sl@0
   784