First public contribution.
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
14 * Description: GB18030 converter implementation
21 #include <convutils.h>
25 #include "gb18030_4byte.h"
26 #include "gb18030_diff_gbk.h"
27 #include <ecom/implementationproxy.h>
28 #include <charactersetconverter.h>
30 class CGB18030ConverterImpl : public CCharacterSetConverterPluginInterface
34 virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
36 virtual TInt ConvertFromUnicode(
37 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
38 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters,
40 const TDesC16& aUnicode,
41 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
43 virtual TInt ConvertToUnicode(
44 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
46 const TDesC8& aForeign,
48 TInt& aNumberOfUnconvertibleCharacters,
49 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
51 virtual TBool IsInThisCharacterSetL(
53 TInt& aConfidenceLevel,
54 const TDesC8& aSample);
56 static CGB18030ConverterImpl* NewL();
57 virtual ~CGB18030ConverterImpl();
60 CGB18030ConverterImpl();
62 SCnvConversionData * completeGb18030_2byteConversionData; // a merged conversion data including Gb18030-diff-g2312, GB2312, Gb18030-diff-gbk and Gbk
63 TUint8 * workingMemory;
66 // Implement gb18030 plug-in using cnvutils framework in which gb2312 and gbk conversion data is re-used for memory saving
67 // 1) foreign->unicode:
68 // 1.1) 1 byte->unicode bmp: use gb2312 mapping table;
70 // 1.2) 2 byte->unicode bmp: use gb18030-2byte mapping table (gb18030_diff_gb2312ConversionData + gb2312ConversionData + gb18030_diff_gbkConversionData + gbkConversionData);
72 // 1.3) 4 byte->unicode bmp: use gb18030-4byte mapping table;
74 // 1.4) 4 byte->unicode non-bmp: calculate with formula.
76 // 2) unicode->foreign:
77 // 2.1) firstly check gb18030-2byte mapping table (gb18030_diff_gb2312ConversionData + gb2312ConversionData + gb18030_diff_gbkConversionData + gbkConversionData);
79 // 2.2) if not found in 2.1), check gb18030-4byte mapping table;
81 // 2.3) if not found in 2.2), calculate with formula (gb18030-4byte non BMP);
85 // GB18030-diff-gb2312 defines 1 foreign-to-Unicode range and 2 unicode-to-Foreign range
86 // GB2312.CTL defines 21 foreign-to-Unicode ranges and 21 Unicode-to-foreign ranges
87 // GB18030-diff-gbk defines 1 foreign-to-Unicode ranges and 2 Unicode-to-foreign range
88 // GBK.CTL defines 2 foreign-to-Unicode ranges and 2 Unicode-to-foreign range
89 const TInt KNumberOfBytesOfWorkingMemory=(1+2+21+21+1+2+2+2)*sizeof(SCnvConversionData::SOneDirectionData::SRange); //totally 1040 bytes
91 const TDesC8& CGB18030ConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
93 return CnvGb18030_diff_gbk::ReplacementForUnconvertibleUnicodeCharacters();
96 _LIT(KLitPanicText, "GB18030");
99 EPanicNothingToConvert1=1,
100 EPanicNothingToConvert2,
101 EPanicNothingToConvert3,
102 EPanicNothingToConvert4,
103 EPanicNothingToConvert5,
104 EPanicNothingToConvert6,
105 EPanicOddNumberOfBytes1,
106 EPanicOddNumberOfBytes2,
107 EPanicOddNumberOfBytes3,
108 EPanicOddNumberOfBytes4,
109 EPanicOddNumberOfBytes5,
110 EPanicOddNumberOfBytes6,
154 EPanicBadCalculation1,
155 EPanicBadCalculation2,
156 EPanicNumberOfBytesIsNotMultipleOfThree1,
157 EPanicNumberOfBytesIsNotMultipleOfThree2,
158 EPanicSingleShift2Expected,
159 EPanicSingleShift3Expected,
160 EPanicTooManyBytesOfWorkingMemoryUsed1,
161 EPanicTooManyBytesOfWorkingMemoryUsed2
164 LOCAL_C void Panic(TPanic aPanic)
166 User::Panic(KLitPanicText, aPanic);
169 #define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
171 LOCAL_C void Step12DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut)
173 aNumberOfCharactersThatDroppedOut=0;
176 // Perform the actual conversion (unicode -> gb18030 4byte non-BMP) using formula in this function
177 LOCAL_C void Step3ConvertFromIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
179 aNumberOfCharactersThatDroppedOut = 0; // no drop out, because all GB18030 outside BMP are exactly 4-bytes
181 const TInt descriptorLength=aDescriptor.Length();
182 TUint8* pVeryFrom = CONST_CAST(TUint8*, aDescriptor.Ptr());
183 const TUint8* pEnd = pVeryFrom + descriptorLength;
184 TUint8* pFrom = pVeryFrom + aStartPositionInDescriptor;
187 if (pFrom + 4 > pEnd)
189 __ASSERT_DEBUG(pFrom==pEnd, Panic(EPanicBadPointers25));
192 TUint characterCode = 0;
193 for (TInt i=0; i<4; i++)
196 characterCode += pFrom[i];
200 characterCode -= 0x10000;
201 TUint b4 = characterCode % 10 + 0x30;
203 TUint b3 = characterCode % 126 + 0x81;
204 characterCode /= 126;
205 TUint b2 = characterCode % 10 + 0x30;
206 TUint b1 = characterCode / 10 + 0x90;
213 aDescriptor.SetLength(pFrom-pVeryFrom);
216 // gb2312-1byte ->unicode (0x00 - 0x7F)
217 LOCAL_C TInt Step0NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
219 const TInt descriptorLength=aDescriptor.Length();
220 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
221 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
226 if (pointerToPreviousByte>=pointerToLastByte)
231 TUint b1 = pointerToPreviousByte[1];
234 pointerToPreviousByte++;
243 // gb18030-2byte --> unicode (0x8140 - 0xFE7E, 0x8180 - 0xFEFE)
244 LOCAL_C TInt Step1NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
246 const TInt descriptorLength=aDescriptor.Length();
247 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
248 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
253 if (pointerToPreviousByte>=pointerToLastByte)
258 TUint b1 = pointerToPreviousByte[1];
259 if (b1 <= 0x80 || b1 > 0xFE)
263 if (pointerToPreviousByte+1 >= pointerToLastByte)
265 TUint b2 = pointerToPreviousByte[2];
266 if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F) // all gb18030 2-byte code
268 pointerToPreviousByte = pointerToPreviousByte + 2;
269 numOfBytes = numOfBytes + 2;
271 else if (b2 < 0x30 || b2 > 0x39)
274 return CCnvCharacterSetConverter::EErrorIllFormedInput;
285 // gb18030 4-bytes bmp --> unicode (0x81308130 - 0x8439FE39)
286 LOCAL_C TInt Step2NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
288 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
289 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
290 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers25));
295 if (pointerToPreviousByte>=pointerToLastByte)
301 TUint b1 = pointerToPreviousByte[1];
302 if ((b1 < 0x81) || (b1 > 0x84)){
307 if (pointerToPreviousByte+1 >= pointerToLastByte)
309 TUint b2 = pointerToPreviousByte[2];
310 if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F) // all gb18030 2-byte code
312 else if (b2 < 0x30 || b2 > 0x39)
315 return CCnvCharacterSetConverter::EErrorIllFormedInput;
322 if (pointerToPreviousByte+2 >= pointerToLastByte)
324 TUint b3 = pointerToPreviousByte[3];
325 if (b3 < 0x81 || b3 > 0xFE)
328 return CCnvCharacterSetConverter::EErrorIllFormedInput;
334 if (pointerToPreviousByte+3 >= pointerToLastByte)
336 TUint b4 = pointerToPreviousByte[4];
337 if (b4 < 0x30 || b4 > 0x39)
340 return CCnvCharacterSetConverter::EErrorIllFormedInput;
346 numOfBytes = numOfBytes + 4;
347 pointerToPreviousByte = pointerToPreviousByte+4;
354 // gb18030 4-bytes non-bmp --> unicode (0x90308130~0xE339FE39)
355 LOCAL_C TInt Step3NumberOfBytesAbleToConvertToUnicode(const TDesC8& aDescriptor)
357 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
358 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
359 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers25));
364 if (pointerToPreviousByte>=pointerToLastByte)
370 TUint b1 = pointerToPreviousByte[1];
371 if (b1 < 0x90 || b1 > 0xE3)
375 if (pointerToPreviousByte+1 >= pointerToLastByte)
377 TUint b2 = pointerToPreviousByte[2];
378 if (b2 >= 0x40 && b2 <= 0xFE && b2 != 0x7F)
380 else if (b2 < 0x30 || b2 > 0x39)
383 return CCnvCharacterSetConverter::EErrorIllFormedInput;
389 if (pointerToPreviousByte+2 >= pointerToLastByte)
391 TUint b3 = pointerToPreviousByte[3];
392 if (b3 < 0x81 || b3 > 0xFE)
395 return CCnvCharacterSetConverter::EErrorIllFormedInput;
401 if (pointerToPreviousByte+3 >= pointerToLastByte)
403 TUint b4 = pointerToPreviousByte[4];
404 if (b4 < 0x30 || b4 > 0x39)
407 return CCnvCharacterSetConverter::EErrorIllFormedInput;
413 numOfBytes = numOfBytes + 4;
414 pointerToPreviousByte = pointerToPreviousByte + 4;
420 void Step012DummyConvertToIntermediateBufferInPlace(TDes8&)
424 // Perform the actual conversion (gb18030 4byte non-BMP -> unicode) using formula in this function
425 LOCAL_C void Step3ConvertToIntermediateBufferInPlace(TDes8& aDescriptor)
427 const TInt descriptorLength=aDescriptor.Length();
428 __ASSERT_DEBUG(descriptorLength%4 == 0, Panic(EPanicNothingToConvert5));
429 TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
430 const TUint8* pointerToSourceByte=pointerToTargetByte;
431 const TUint8* const pointerToLastByte=pointerToSourceByte+descriptorLength;
435 if (pointerToLastByte - pointerToSourceByte < 4)
439 TUint8 b1 = pointerToSourceByte[0];
440 TUint8 b2 = pointerToSourceByte[1];
441 TUint8 b3 = pointerToSourceByte[2];
442 TUint8 b4 = pointerToSourceByte[3];
444 TUint characterCode = 0x10000 + (b1 - 0x90) * 12600 +
449 pointerToTargetByte[0] = ((characterCode >> 24) & 0xFF);
450 pointerToTargetByte[1] = ((characterCode >> 16) & 0xFF);
451 pointerToTargetByte[2] = ((characterCode >> 8) & 0xFF);
452 pointerToTargetByte[3] = (characterCode & 0xFF);
454 pointerToSourceByte = pointerToSourceByte + 4;
455 pointerToTargetByte = pointerToTargetByte + 4;
458 aDescriptor.SetLength(descriptorLength);
462 // A dummy "direct" mapping table for non-Bmp chars in step 3
463 // Use 32-bit Unicode value as intermediate coding
464 LOCAL_D const SCnvConversionData::SVariableByteData::SRange step3ForeignVariableByteDataRanges[]=
467 0x00, // from 0x10000
473 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange step3ForeignToUnicodeDataRanges[]=
476 0x10000, // from 0x10000
477 0x10ffff, // to 0x10FFFF
478 SCnvConversionData::SOneDirectionData::SRange::EDirect,
482 0 // map from intermediate to unicode with offset = 0
486 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange step3UnicodeToForeignDataRanges[]=
489 0x10000, //from 0x10000
490 0x10FFFF, //to 0x10FFFF
491 SCnvConversionData::SOneDirectionData::SRange::EDirect,
492 4, // output byte count = 4
499 GLDEF_D const SCnvConversionData step3ConversionData=
501 SCnvConversionData::EFixedBigEndian,
503 ARRAY_LENGTH(step3ForeignVariableByteDataRanges),
504 step3ForeignVariableByteDataRanges
507 ARRAY_LENGTH(step3ForeignToUnicodeDataRanges),
508 step3ForeignToUnicodeDataRanges
511 ARRAY_LENGTH(step3UnicodeToForeignDataRanges),
512 step3UnicodeToForeignDataRanges
519 // An internal mapping table to reslove the conflict introduced in symbian GB2312-80 plug-in.
520 // It will be merged into the gb18030-2byte Conversion Data.
521 // It includes mapping: (0xA1A4 -> 0x00B7, 0xA1AA -> 0x2014, 0xA844 <- 0x2015, 0x8139A739 <- 0x30FB)
522 LOCAL_D const SCnvConversionData::SVariableByteData::SRange gb18030_diff_gb2312ForeignVariableByteDataRanges[]=
531 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_foreignToUnicode_1[]=
542 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange gb18030_diff_gb2312ForeignToUnicodeDataRanges[]=
547 SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
551 UData_SKeyedTable1616(keyedTable1616_foreignToUnicode_1)
555 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_unicodeToForeign_1[]=
562 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable3232::SEntry keyedTable3232_unicodeToForeign_1[]=
570 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange gb18030_diff_gb2312UnicodeToForeignDataRanges[]=
575 SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616,
576 2, // output byte count = 2
579 UData_SKeyedTable1616(keyedTable1616_unicodeToForeign_1)
585 SCnvConversionData::SOneDirectionData::SRange::EKeyedTable3232,
586 4, // output byte count = 4
589 UData_SKeyedTable3232(keyedTable3232_unicodeToForeign_1)
593 GLDEF_D const SCnvConversionData gb18030_diff_gb2312ConversionData=
595 SCnvConversionData::EFixedBigEndian,
597 ARRAY_LENGTH(gb18030_diff_gb2312ForeignVariableByteDataRanges),
598 gb18030_diff_gb2312ForeignVariableByteDataRanges
601 ARRAY_LENGTH(gb18030_diff_gb2312ForeignToUnicodeDataRanges),
602 gb18030_diff_gb2312ForeignToUnicodeDataRanges
605 ARRAY_LENGTH(gb18030_diff_gb2312UnicodeToForeignDataRanges),
606 gb18030_diff_gb2312UnicodeToForeignDataRanges
612 LOCAL_D const SCnvConversionData::SVariableByteData::SRange foreignVariableByteDataRanges[]=
628 LOCAL_C void SetUpCompleteGb18030_2byteConversionData(SCnvConversionData& aCompleteGb18030_2byteConversionData, TUint8* aWorkingMemory)
630 const SCnvConversionData& gb2312ConversionData=CnvGb2312::ConversionData();
631 const SCnvConversionData& gb18030_diff_gbkConversionData=CnvGb18030_diff_gbk::ConversionData();
632 const SCnvConversionData& gbkConversionData=CnvGbk::ConversionData();
633 // create a SCnvConversionData that is the combination of gb18030_diff_gb2312ConversionData, gb2312ConversionData, gb18030_diff_gbkConversionData and gbkConversionData;
634 aCompleteGb18030_2byteConversionData.iEndiannessOfForeignCharacters=SCnvConversionData::EFixedBigEndian;
635 aCompleteGb18030_2byteConversionData.iForeignVariableByteData.iNumberOfRanges=ARRAY_LENGTH(foreignVariableByteDataRanges);
636 aCompleteGb18030_2byteConversionData.iForeignVariableByteData.iRangeArray=foreignVariableByteDataRanges;
637 TInt numberOfBytesOfWorkingMemoryUsed=0;
639 // set up the foreign-to-Unicode data
640 const TInt numberOfForeignToUnicodeDataRanges=gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges + gb18030_diff_gbkConversionData.iForeignToUnicodeData.iNumberOfRanges + gbkConversionData.iForeignToUnicodeData.iNumberOfRanges;
641 aCompleteGb18030_2byteConversionData.iForeignToUnicodeData.iNumberOfRanges=numberOfForeignToUnicodeDataRanges;
642 SCnvConversionData::SOneDirectionData::SRange* foreignToUnicodeDataRangeArray=REINTERPRET_CAST(SCnvConversionData::SOneDirectionData::SRange*, aWorkingMemory+numberOfBytesOfWorkingMemoryUsed);
643 numberOfBytesOfWorkingMemoryUsed+=(numberOfForeignToUnicodeDataRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
644 __ASSERT_ALWAYS(numberOfBytesOfWorkingMemoryUsed<=KNumberOfBytesOfWorkingMemory, Panic(EPanicTooManyBytesOfWorkingMemoryUsed1));
645 aCompleteGb18030_2byteConversionData.iForeignToUnicodeData.iRangeArray=foreignToUnicodeDataRangeArray;
646 Mem::Copy(foreignToUnicodeDataRangeArray, gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iRangeArray, gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
647 Mem::Copy(foreignToUnicodeDataRangeArray + gb18030_diff_gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges, gb2312ConversionData.iForeignToUnicodeData.iRangeArray, gb2312ConversionData.iForeignToUnicodeData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
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));
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));
651 // set up the Unicode-to-foreign data
652 const TInt numberOfUnicodeToForeignDataRanges=gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges + gb18030_diff_gbkConversionData.iUnicodeToForeignData.iNumberOfRanges + gbkConversionData.iUnicodeToForeignData.iNumberOfRanges;
653 aCompleteGb18030_2byteConversionData.iUnicodeToForeignData.iNumberOfRanges=numberOfUnicodeToForeignDataRanges;
654 SCnvConversionData::SOneDirectionData::SRange* unicodeToForeignDataRangeArray=REINTERPRET_CAST(SCnvConversionData::SOneDirectionData::SRange*, aWorkingMemory+numberOfBytesOfWorkingMemoryUsed);
655 numberOfBytesOfWorkingMemoryUsed+=(numberOfUnicodeToForeignDataRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
656 __ASSERT_ALWAYS(numberOfBytesOfWorkingMemoryUsed<=KNumberOfBytesOfWorkingMemory, Panic(EPanicTooManyBytesOfWorkingMemoryUsed2));
657 aCompleteGb18030_2byteConversionData.iUnicodeToForeignData.iRangeArray=unicodeToForeignDataRangeArray;
658 Mem::Copy(unicodeToForeignDataRangeArray, gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iRangeArray, gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
659 Mem::Copy(unicodeToForeignDataRangeArray + gb18030_diff_gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges, gb2312ConversionData.iUnicodeToForeignData.iRangeArray, gb2312ConversionData.iUnicodeToForeignData.iNumberOfRanges*sizeof(SCnvConversionData::SOneDirectionData::SRange));
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));
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));
665 TInt CGB18030ConverterImpl::ConvertFromUnicode(
666 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
667 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters,
669 const TDesC16& aUnicode,
670 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters)
672 TFixedArray<CnvUtilities::SCharacterSet, 3> characterSets;
674 // step 1) gb18030-2byte
675 characterSets[0].iConversionData = completeGb18030_2byteConversionData;
676 characterSets[0].iConvertFromIntermediateBufferInPlace = Step12DummyConvertFromIntermediateBufferInPlace;
677 characterSets[0].iEscapeSequence = &KNullDesC8;
679 // step 2) gb18030-4byte BMP
680 characterSets[1].iConversionData = &CnvGb18030_4byte::ConversionData();
681 characterSets[1].iConvertFromIntermediateBufferInPlace = Step12DummyConvertFromIntermediateBufferInPlace;
682 characterSets[1].iEscapeSequence = &KNullDesC8;
684 // step 3) gb18030-4byte non-BMP
685 characterSets[2].iConversionData = &step3ConversionData;
686 characterSets[2].iConvertFromIntermediateBufferInPlace = Step3ConvertFromIntermediateBufferInPlace;
687 characterSets[2].iEscapeSequence = &KNullDesC8;
689 return CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, characterSets.Array());
693 TInt CGB18030ConverterImpl::ConvertToUnicode(
694 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
696 const TDesC8& aForeign,
698 TInt& aNumberOfUnconvertibleCharacters,
699 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter)
701 TFixedArray<CnvUtilities::SMethod, 4> methods;
702 // step 0) gb2312-1byte
703 methods[0].iNumberOfBytesAbleToConvert = Step0NumberOfBytesAbleToConvertToUnicode;
704 methods[0].iConvertToIntermediateBufferInPlace = Step012DummyConvertToIntermediateBufferInPlace;
705 methods[0].iConversionData = &CnvGb2312::ConversionData(); //only use one byte part
706 methods[0].iNumberOfBytesPerCharacter = 1;
707 methods[0].iNumberOfCoreBytesPerCharacter = 1;
709 // step 1) gb18030-2byte
710 methods[1].iNumberOfBytesAbleToConvert = Step1NumberOfBytesAbleToConvertToUnicode;
711 methods[1].iConvertToIntermediateBufferInPlace = Step012DummyConvertToIntermediateBufferInPlace;
712 methods[1].iConversionData = completeGb18030_2byteConversionData;
713 methods[1].iNumberOfBytesPerCharacter = 2;
714 methods[1].iNumberOfCoreBytesPerCharacter = 2;
716 // step 2) gb18030 4-byte BMP
717 methods[2].iNumberOfBytesAbleToConvert = Step2NumberOfBytesAbleToConvertToUnicode;
718 methods[2].iConvertToIntermediateBufferInPlace = Step012DummyConvertToIntermediateBufferInPlace;
719 methods[2].iConversionData = &CnvGb18030_4byte::ConversionData();
720 methods[2].iNumberOfBytesPerCharacter = 4;
721 methods[2].iNumberOfCoreBytesPerCharacter = 4;
723 // step 3) gb18030 4-byte non-BMP
724 methods[3].iNumberOfBytesAbleToConvert = Step3NumberOfBytesAbleToConvertToUnicode;
725 methods[3].iConvertToIntermediateBufferInPlace = Step3ConvertToIntermediateBufferInPlace;
726 methods[3].iConversionData = &step3ConversionData;
727 methods[3].iNumberOfBytesPerCharacter = 4;
728 methods[3].iNumberOfCoreBytesPerCharacter = 4;
730 return CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array());
733 TBool CGB18030ConverterImpl::IsInThisCharacterSetL(
735 TInt& aConfidenceLevel,
736 const TDesC8& aSample)
739 return CnvGb2312::IsCharGBBased(aConfidenceLevel, aSample);
742 CGB18030ConverterImpl* CGB18030ConverterImpl::NewL()
744 CGB18030ConverterImpl* self = new(ELeave) CGB18030ConverterImpl();
745 CleanupStack::PushL(self);
747 CleanupStack::Pop(); // self
751 CGB18030ConverterImpl::~CGB18030ConverterImpl()
754 delete[] workingMemory;
755 if (completeGb18030_2byteConversionData)
756 delete completeGb18030_2byteConversionData;
759 CGB18030ConverterImpl::CGB18030ConverterImpl()
763 TInt CGB18030ConverterImpl::ConstructL()
765 completeGb18030_2byteConversionData = new (ELeave)SCnvConversionData;
766 CleanupStack::PushL(completeGb18030_2byteConversionData);
767 workingMemory = new (ELeave) TUint8[KNumberOfBytesOfWorkingMemory]; //1040 bytes
768 CleanupStack::Pop(); // completeGb18030_2byteConversionData
769 SetUpCompleteGb18030_2byteConversionData(*completeGb18030_2byteConversionData, workingMemory);
773 const TImplementationProxy ImplementationTable[] =
775 IMPLEMENTATION_PROXY_ENTRY(0x10287038,CGB18030ConverterImpl::NewL)
778 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
780 aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
782 return ImplementationTable;