charconvfw/charconvplugins/src/plugins/eucjp_packed.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     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".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <charconv.h>
       
    21 #include <convutils.h>
       
    22 #include "jisx0201.h"
       
    23 #include "jisx0208.h"
       
    24 #include "jisx0212.h"
       
    25 #include <ecom/implementationproxy.h>
       
    26 #include <charactersetconverter.h>
       
    27 
       
    28 const TUint KSingleShift2=0x8e;
       
    29 const TUint KSingleShift3=0x8f;
       
    30 
       
    31 _LIT8(KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters, "\xa1\xa9"); // fullwidth question mark
       
    32 
       
    33 #if defined(_DEBUG)
       
    34 
       
    35 _LIT(KLitPanicText, "EUCJP_PACKED");
       
    36 
       
    37 enum TPanic
       
    38 	{
       
    39 	EPanicNothingToConvert1=1,
       
    40 	EPanicNothingToConvert2,
       
    41 	EPanicNothingToConvert3,
       
    42 	EPanicNothingToConvert4,
       
    43 	EPanicNothingToConvert5,
       
    44 	EPanicNothingToConvert6,
       
    45 	EPanicOddNumberOfBytes1,
       
    46 	EPanicOddNumberOfBytes2,
       
    47 	EPanicOddNumberOfBytes3,
       
    48 	EPanicOddNumberOfBytes4,
       
    49 	EPanicOddNumberOfBytes5,
       
    50 	EPanicOddNumberOfBytes6,
       
    51 	EPanicBadHighBit1,
       
    52 	EPanicBadHighBit2,
       
    53 	EPanicBadHighBit3,
       
    54 	EPanicBadHighBit4,
       
    55 	EPanicBadHighBit5,
       
    56 	EPanicBadHighBit6,
       
    57 	EPanicBadHighBit7,
       
    58 	EPanicBadPointers1,
       
    59 	EPanicBadPointers2,
       
    60 	EPanicBadPointers3,
       
    61 	EPanicBadPointers4,
       
    62 	EPanicBadPointers5,
       
    63 	EPanicBadPointers6,
       
    64 	EPanicBadPointers7,
       
    65 	EPanicBadPointers8,
       
    66 	EPanicBadPointers9,
       
    67 	EPanicBadPointers10,
       
    68 	EPanicBadPointers11,
       
    69 	EPanicBadPointers12,
       
    70 	EPanicBadPointers13,
       
    71 	EPanicBadPointers14,
       
    72 	EPanicBadPointers15,
       
    73 	EPanicBadPointers16,
       
    74 	EPanicBadPointers17,
       
    75 	EPanicBadPointers18,
       
    76 	EPanicBadPointers19,
       
    77 	EPanicBadPointers20,
       
    78 	EPanicBadPointers21,
       
    79 	EPanicBadPointers22,
       
    80 	EPanicBadPointers23,
       
    81 	EPanicBadPointers24,
       
    82 	EPanicBadPointers25,
       
    83 	EPanicBadPointers26,
       
    84 	EPanicBadPointers27,
       
    85 	EPanicBadPointers28,
       
    86 	EPanicBadPointers29,
       
    87 	EPanicBadPointers30,
       
    88 	EPanicBadPointers31,
       
    89 	EPanicBadPointers32,
       
    90 	EPanicBadPointers33,
       
    91 	EPanicBadPointers34,
       
    92 	EPanicBadPointers35,
       
    93 	EPanicBadPointers36,
       
    94 	EPanicBadCalculation1,
       
    95 	EPanicBadCalculation2,
       
    96 	EPanicNumberOfBytesIsNotMultipleOfThree1,
       
    97 	EPanicNumberOfBytesIsNotMultipleOfThree2,
       
    98 	EPanicSingleShift2Expected,
       
    99 	EPanicSingleShift3Expected
       
   100 	};
       
   101 
       
   102 LOCAL_C void Panic(TPanic aPanic)
       
   103 	{
       
   104 	User::Panic(KLitPanicText, aPanic);
       
   105 	}
       
   106 
       
   107 #endif
       
   108 
       
   109 
       
   110 class CEucjpPackedConverterImpl : public CCharacterSetConverterPluginInterface
       
   111 	{
       
   112 
       
   113 public:
       
   114 	virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
       
   115 
       
   116 	virtual TInt ConvertFromUnicode(
       
   117 		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
       
   118 		const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
       
   119 		TDes8& aForeign, 
       
   120 		const TDesC16& aUnicode, 
       
   121 		CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
       
   122 
       
   123 	virtual TInt ConvertToUnicode(
       
   124 		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
       
   125 		TDes16& aUnicode, 
       
   126 		const TDesC8& aForeign, 
       
   127 		TInt& aState, 
       
   128 		TInt& aNumberOfUnconvertibleCharacters, 
       
   129 		TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
       
   130 
       
   131 	virtual TBool IsInThisCharacterSetL(
       
   132 		TBool& aSetToTrue, 
       
   133 		TInt& aConfidenceLevel, 
       
   134 		const TDesC8& aSample);
       
   135 
       
   136 	static CEucjpPackedConverterImpl* NewL();
       
   137 	virtual ~CEucjpPackedConverterImpl();
       
   138 
       
   139 private:
       
   140 	CEucjpPackedConverterImpl();
       
   141 
       
   142 	};
       
   143 
       
   144 
       
   145 
       
   146 
       
   147 
       
   148 const TDesC8& CEucjpPackedConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
       
   149 	{
       
   150 	return KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters;
       
   151 	}
       
   152 
       
   153 LOCAL_C void DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut)
       
   154 	{
       
   155 	aNumberOfCharactersThatDroppedOut=0;
       
   156 	}
       
   157 
       
   158 LOCAL_C void ConvertFromJisX0208ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
       
   159 	{
       
   160 	aNumberOfCharactersThatDroppedOut=0;
       
   161 	const TInt descriptorLength=aDescriptor.Length();
       
   162 	__ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert1));
       
   163 	__ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes1));
       
   164 	TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
       
   165 	const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1);
       
   166 	pointerToCurrentByte+=aStartPositionInDescriptor;
       
   167 	FOREVER
       
   168 		{
       
   169 		const TUint currentByte=*pointerToCurrentByte;
       
   170 		__ASSERT_DEBUG((currentByte&0x80)==0, Panic(EPanicBadHighBit1));
       
   171 		*pointerToCurrentByte=STATIC_CAST(TUint8, currentByte|0x80);
       
   172 		__ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers1));
       
   173 		if (pointerToCurrentByte>=pointerToLastByte)
       
   174 			{
       
   175 			break;
       
   176 			}
       
   177 		++pointerToCurrentByte;
       
   178 		}
       
   179 	}
       
   180 
       
   181 LOCAL_C void ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
       
   182 	{
       
   183 	TInt descriptorLength=aDescriptor.Length();
       
   184 	__ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert2));
       
   185 	aNumberOfCharactersThatDroppedOut=Max(0, (descriptorLength-aStartPositionInDescriptor)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/2));
       
   186 	descriptorLength-=aNumberOfCharactersThatDroppedOut;
       
   187 	__ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation1));
       
   188 	if (descriptorLength<=aStartPositionInDescriptor)
       
   189 		{
       
   190 		aDescriptor.SetLength(descriptorLength);
       
   191 		}
       
   192 	else
       
   193 		{
       
   194 		TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor
       
   195 		const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor;
       
   196 		const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1);
       
   197 		descriptorLength=((descriptorLength-aStartPositionInDescriptor)*2)+aStartPositionInDescriptor;
       
   198 		__ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes2));
       
   199 		aDescriptor.SetLength(descriptorLength);
       
   200 		pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here
       
   201 		FOREVER
       
   202 			{
       
   203 			*pointerToTargetByte=*pointerToSourceByte;
       
   204 			__ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers2));
       
   205 			--pointerToTargetByte;
       
   206 			*pointerToTargetByte=KSingleShift2;
       
   207 			__ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers3));
       
   208 			if (pointerToTargetByte<=pointerToFirstByte)
       
   209 				{
       
   210 				break;
       
   211 				}
       
   212 			--pointerToTargetByte;
       
   213 			__ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers4));
       
   214 			--pointerToSourceByte;
       
   215 			}
       
   216 		__ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers5));
       
   217 		__ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers6));
       
   218 		}
       
   219 	}
       
   220 
       
   221 LOCAL_C void ConvertFromJisX0212ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
       
   222 	{
       
   223 	TInt descriptorLength=aDescriptor.Length();
       
   224 	__ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert3));
       
   225 	__ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes3));
       
   226 	aNumberOfCharactersThatDroppedOut=Max(0, ((descriptorLength-aStartPositionInDescriptor)/2)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/3));
       
   227 	descriptorLength-=aNumberOfCharactersThatDroppedOut*2;
       
   228 	__ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation2));
       
   229 	if (descriptorLength<=aStartPositionInDescriptor)
       
   230 		{
       
   231 		aDescriptor.SetLength(descriptorLength);
       
   232 		}
       
   233 	else
       
   234 		{
       
   235 		__ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes4));
       
   236 		TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor
       
   237 		const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor;
       
   238 		const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1);
       
   239 		descriptorLength=(((descriptorLength-aStartPositionInDescriptor)*3)/2)+aStartPositionInDescriptor;
       
   240 		__ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree1));
       
   241 		aDescriptor.SetLength(descriptorLength);
       
   242 		pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here
       
   243 		FOREVER
       
   244 			{
       
   245 			__ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit2));
       
   246 			*pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80);
       
   247 			__ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers7));
       
   248 			--pointerToTargetByte;
       
   249 			__ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers8));
       
   250 			--pointerToSourceByte;
       
   251 			__ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit3));
       
   252 			*pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80);
       
   253 			__ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers9));
       
   254 			--pointerToTargetByte;
       
   255 			*pointerToTargetByte=KSingleShift3;
       
   256 			__ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers10));
       
   257 			if (pointerToTargetByte<=pointerToFirstByte)
       
   258 				{
       
   259 				break;
       
   260 				}
       
   261 			--pointerToTargetByte;
       
   262 			__ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers11));
       
   263 			--pointerToSourceByte;
       
   264 			}
       
   265 		__ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers12));
       
   266 		__ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers13));
       
   267 		}
       
   268 	}
       
   269 
       
   270 TInt CEucjpPackedConverterImpl::ConvertFromUnicode(
       
   271 		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
       
   272 		const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
       
   273 		TDes8& aForeign, 
       
   274 		const TDesC16& aUnicode, 
       
   275 		CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters)
       
   276 	{
       
   277 	TFixedArray<CnvUtilities::SCharacterSet, 4> characterSets;
       
   278 	characterSets[0].iConversionData=&CnvJisRoman::ConversionData();
       
   279 	characterSets[0].iConvertFromIntermediateBufferInPlace=DummyConvertFromIntermediateBufferInPlace;
       
   280 	characterSets[0].iEscapeSequence=&KNullDesC8;
       
   281 	characterSets[1].iConversionData=&CnvJisX0208::ConversionData();
       
   282 	characterSets[1].iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToEucJpPackedInPlace;
       
   283 	characterSets[1].iEscapeSequence=&KNullDesC8;
       
   284 	characterSets[2].iConversionData=&CnvHalfWidthKatakana8::ConversionData();
       
   285 	characterSets[2].iConvertFromIntermediateBufferInPlace=ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace;
       
   286 	characterSets[2].iEscapeSequence=&KNullDesC8;
       
   287 	characterSets[3].iConversionData=&CnvJisX0212::ConversionData();
       
   288 	characterSets[3].iConvertFromIntermediateBufferInPlace=ConvertFromJisX0212ToEucJpPackedInPlace;
       
   289 	characterSets[3].iEscapeSequence=&KNullDesC8;
       
   290 	return CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, characterSets.Array());
       
   291 	}
       
   292 
       
   293 LOCAL_C TInt NumberOfBytesAbleToConvertToJisRoman(const TDesC8& aDescriptor)
       
   294 	{
       
   295 	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
       
   296 	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
       
   297 	if (pointerToPreviousByte==pointerToLastByte)
       
   298 		{
       
   299 		return 0;
       
   300 		}
       
   301 	FOREVER
       
   302 		{
       
   303 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers14));
       
   304 		const TUint currentByte=*(pointerToPreviousByte+1);
       
   305 		if (currentByte&0x80)
       
   306 			{
       
   307 			break;
       
   308 			}
       
   309 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers15));
       
   310 		++pointerToPreviousByte;
       
   311 		__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers16));
       
   312 		if (pointerToPreviousByte>=pointerToLastByte)
       
   313 			{
       
   314 			break;
       
   315 			}
       
   316 		}
       
   317 	return (pointerToPreviousByte+1)-aDescriptor.Ptr();
       
   318 	}
       
   319 
       
   320 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0208(const TDesC8& aDescriptor)
       
   321 	{
       
   322 	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
       
   323 	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
       
   324 	if (pointerToPreviousByte==pointerToLastByte)
       
   325 		{
       
   326 		return 0;
       
   327 		}
       
   328 	FOREVER
       
   329 		{
       
   330 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers17));
       
   331 		TUint currentByte=*(pointerToPreviousByte+1);
       
   332 		if (currentByte<0xa0)
       
   333 			{
       
   334 			break;
       
   335 			}
       
   336 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers18));
       
   337 		if (pointerToLastByte-pointerToPreviousByte<2)
       
   338 			{
       
   339 			break;
       
   340 			}
       
   341 		++pointerToPreviousByte;
       
   342 		currentByte=*(pointerToPreviousByte+1);
       
   343 		if (currentByte<0xa0)
       
   344 			{
       
   345 			return CCnvCharacterSetConverter::EErrorIllFormedInput;
       
   346 			}
       
   347 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers19));
       
   348 		++pointerToPreviousByte;
       
   349 		__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers20));
       
   350 		if (pointerToPreviousByte>=pointerToLastByte)
       
   351 			{
       
   352 			break;
       
   353 			}
       
   354 		}
       
   355 	return (pointerToPreviousByte+1)-aDescriptor.Ptr();
       
   356 	}
       
   357 
       
   358 LOCAL_C TInt NumberOfBytesAbleToConvertToHalfWidthKatakana8(const TDesC8& aDescriptor)
       
   359 	{
       
   360 	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
       
   361 	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
       
   362 	if (pointerToPreviousByte==pointerToLastByte)
       
   363 		{
       
   364 		return 0;
       
   365 		}
       
   366 	FOREVER
       
   367 		{
       
   368 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers21));
       
   369 		TUint currentByte=*(pointerToPreviousByte+1);
       
   370 		if (currentByte!=KSingleShift2)
       
   371 			{
       
   372 			break;
       
   373 			}
       
   374 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers22));
       
   375 		if (pointerToLastByte-pointerToPreviousByte<2)
       
   376 			{
       
   377 			break;
       
   378 			}
       
   379 		++pointerToPreviousByte;
       
   380 		currentByte=*(pointerToPreviousByte+1);
       
   381 		if (currentByte<0xa0)
       
   382 			{
       
   383 			return CCnvCharacterSetConverter::EErrorIllFormedInput;
       
   384 			}
       
   385 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers23));
       
   386 		++pointerToPreviousByte;
       
   387 		__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers24));
       
   388 		if (pointerToPreviousByte>=pointerToLastByte)
       
   389 			{
       
   390 			break;
       
   391 			}
       
   392 		}
       
   393 	return (pointerToPreviousByte+1)-aDescriptor.Ptr();
       
   394 	}
       
   395 
       
   396 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0212(const TDesC8& aDescriptor)
       
   397 	{
       
   398 	const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
       
   399 	const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
       
   400 	if (pointerToPreviousByte==pointerToLastByte)
       
   401 		{
       
   402 		return 0;
       
   403 		}
       
   404 	FOREVER
       
   405 		{
       
   406 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers25));
       
   407 		TUint currentByte=*(pointerToPreviousByte+1);
       
   408 		if (currentByte!=KSingleShift3)
       
   409 			{
       
   410 			break;
       
   411 			}
       
   412 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers26));
       
   413 		if (pointerToLastByte-pointerToPreviousByte<3)
       
   414 			{
       
   415 			break;
       
   416 			}
       
   417 		++pointerToPreviousByte;
       
   418 		currentByte=*(pointerToPreviousByte+1);
       
   419 		if (currentByte<0xa0)
       
   420 			{
       
   421 			return CCnvCharacterSetConverter::EErrorIllFormedInput;
       
   422 			}
       
   423 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers27));
       
   424 		++pointerToPreviousByte;
       
   425 		currentByte=*(pointerToPreviousByte+1);
       
   426 		if (currentByte<0xa0)
       
   427 			{
       
   428 			return CCnvCharacterSetConverter::EErrorIllFormedInput;
       
   429 			}
       
   430 		__ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers28));
       
   431 		++pointerToPreviousByte;
       
   432 		__ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers29));
       
   433 		if (pointerToPreviousByte>=pointerToLastByte)
       
   434 			{
       
   435 			break;
       
   436 			}
       
   437 		}
       
   438 	return (pointerToPreviousByte+1)-aDescriptor.Ptr();
       
   439 	}
       
   440 
       
   441 LOCAL_C void DummyConvertToIntermediateBufferInPlace(TDes8&)
       
   442 	{
       
   443 	}
       
   444 
       
   445 LOCAL_C void ConvertToJisX0208FromEucJpPackedInPlace(TDes8& aDescriptor)
       
   446 	{
       
   447 	const TInt descriptorLength=aDescriptor.Length();
       
   448 	__ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert4));
       
   449 	__ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes5));
       
   450 	TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
       
   451 	const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1);
       
   452 	FOREVER
       
   453 		{
       
   454 		const TUint currentByte=*pointerToCurrentByte;
       
   455 		__ASSERT_DEBUG(currentByte&0x80, Panic(EPanicBadHighBit4));
       
   456 		*pointerToCurrentByte=STATIC_CAST(TUint8, currentByte&~0x80);
       
   457 		__ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers30));
       
   458 		if (pointerToCurrentByte>=pointerToLastByte)
       
   459 			{
       
   460 			break;
       
   461 			}
       
   462 		++pointerToCurrentByte;
       
   463 		}
       
   464 	}
       
   465 
       
   466 LOCAL_C void ConvertToHalfWidthKatakana8FromEucJpPackedInPlace(TDes8& aDescriptor)
       
   467 	{
       
   468 	const TInt descriptorLength=aDescriptor.Length();
       
   469 	__ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert5));
       
   470 	__ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes6));
       
   471 	TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
       
   472 	const TUint8* pointerToSourceByte=pointerToTargetByte;
       
   473 	const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1);
       
   474 	FOREVER
       
   475 		{
       
   476 		__ASSERT_DEBUG(*pointerToSourceByte==KSingleShift2, Panic(EPanicSingleShift2Expected));
       
   477 		__ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers31));
       
   478 		++pointerToSourceByte;
       
   479 		const TUint sourceByte=*pointerToSourceByte;
       
   480 		__ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit5));
       
   481 		*pointerToTargetByte=STATIC_CAST(TUint8, sourceByte);
       
   482 		__ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers32));
       
   483 		if (pointerToSourceByte>=pointerToLastByte)
       
   484 			{
       
   485 			break;
       
   486 			}
       
   487 		++pointerToSourceByte;
       
   488 		++pointerToTargetByte;
       
   489 		}
       
   490 	aDescriptor.SetLength(descriptorLength/2);
       
   491 	}
       
   492 
       
   493 LOCAL_C void ConvertToJisX0212FromEucJpPackedInPlace(TDes8& aDescriptor)
       
   494 	{
       
   495 	const TInt descriptorLength=aDescriptor.Length();
       
   496 	__ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert6));
       
   497 	__ASSERT_DEBUG(descriptorLength%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree2));
       
   498 	TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
       
   499 	const TUint8* pointerToSourceByte=pointerToTargetByte;
       
   500 	const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1);
       
   501 	FOREVER
       
   502 		{
       
   503 		__ASSERT_DEBUG(*pointerToSourceByte==KSingleShift3, Panic(EPanicSingleShift3Expected));
       
   504 		__ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers33));
       
   505 		++pointerToSourceByte;
       
   506 		TUint sourceByte=*pointerToSourceByte;
       
   507 		__ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit6));
       
   508 		*pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80);
       
   509 		__ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers34));
       
   510 		++pointerToSourceByte;
       
   511 		sourceByte=*pointerToSourceByte;
       
   512 		__ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit7));
       
   513 		__ASSERT_DEBUG(pointerToTargetByte<pointerToLastByte, Panic(EPanicBadPointers35));
       
   514 		++pointerToTargetByte;
       
   515 		*pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80);
       
   516 		__ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers36));
       
   517 		if (pointerToSourceByte>=pointerToLastByte)
       
   518 			{
       
   519 			break;
       
   520 			}
       
   521 		++pointerToSourceByte;
       
   522 		++pointerToTargetByte;
       
   523 		}
       
   524 	aDescriptor.SetLength((descriptorLength/3)*2);
       
   525 	}
       
   526 
       
   527 TInt CEucjpPackedConverterImpl::ConvertToUnicode(
       
   528 		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
       
   529 		TDes16& aUnicode, 
       
   530 		const TDesC8& aForeign, 
       
   531 		TInt& /*aState*/, 
       
   532 		TInt& aNumberOfUnconvertibleCharacters, 
       
   533 		TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter)
       
   534 	{
       
   535 	TFixedArray<CnvUtilities::SMethod, 4> methods;
       
   536 	methods[0].iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisRoman;
       
   537 	methods[0].iConvertToIntermediateBufferInPlace=DummyConvertToIntermediateBufferInPlace;
       
   538 	methods[0].iConversionData=&CnvJisRoman::ConversionData();
       
   539 	methods[0].iNumberOfBytesPerCharacter=1;
       
   540 	methods[0].iNumberOfCoreBytesPerCharacter=1;
       
   541 	methods[1].iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0208;
       
   542 	methods[1].iConvertToIntermediateBufferInPlace=ConvertToJisX0208FromEucJpPackedInPlace;
       
   543 	methods[1].iConversionData=&CnvJisX0208::ConversionData();
       
   544 	methods[1].iNumberOfBytesPerCharacter=2;
       
   545 	methods[1].iNumberOfCoreBytesPerCharacter=2;
       
   546 	methods[2].iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToHalfWidthKatakana8;
       
   547 	methods[2].iConvertToIntermediateBufferInPlace=ConvertToHalfWidthKatakana8FromEucJpPackedInPlace;
       
   548 	methods[2].iConversionData=&CnvHalfWidthKatakana8::ConversionData();
       
   549 	methods[2].iNumberOfBytesPerCharacter=2;
       
   550 	methods[2].iNumberOfCoreBytesPerCharacter=1;
       
   551 	methods[3].iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0212;
       
   552 	methods[3].iConvertToIntermediateBufferInPlace=ConvertToJisX0212FromEucJpPackedInPlace;
       
   553 	methods[3].iConversionData=&CnvJisX0212::ConversionData();
       
   554 	methods[3].iNumberOfBytesPerCharacter=3;
       
   555 	methods[3].iNumberOfCoreBytesPerCharacter=2;
       
   556 	return CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array());
       
   557 	}
       
   558 
       
   559 TBool CEucjpPackedConverterImpl::IsInThisCharacterSetL(
       
   560 		TBool& aSetToTrue, 
       
   561 		TInt& aConfidenceLevel, 
       
   562 		const TDesC8& aSample)
       
   563 	{
       
   564 	aSetToTrue=ETrue;
       
   565 	// check for the SS2 and SS3 which specifies Code Set 2 & 3 respectively from the Code space
       
   566 	// between 00-7f only... then ambiguous 
       
   567 	aSetToTrue = ETrue; 
       
   568 	TInt sampleLength = aSample.Length();
       
   569 	TInt eucjpPacked = 0;
       
   570 	aConfidenceLevel = 0;
       
   571 
       
   572 	for (TInt i = 0; i < sampleLength; ++i)
       
   573 		{
       
   574 		// Code set 1 JISX 0208 support
       
   575 		TInt increment1 = i+1;
       
   576 		if (increment1 >= sampleLength)
       
   577 			break;
       
   578 		if (((aSample[i] >= 0xa1) && (aSample[i] <= 0xfe)) && 
       
   579 			((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe)))
       
   580 			{
       
   581 			eucjpPacked = eucjpPacked +2;
       
   582 			i++;
       
   583 			}
       
   584 		// Single Shift 2 (SS2) sequence - Code Set 2
       
   585 		if (aSample[i]==0x8e)
       
   586 			{
       
   587 			TInt increment1 = i+1;
       
   588 			if (increment1 >= sampleLength)
       
   589 				break;
       
   590 			if ((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xdf))
       
   591 				{
       
   592 				eucjpPacked = eucjpPacked+2;
       
   593 				i++;
       
   594 				}
       
   595 			else
       
   596 				{
       
   597 				eucjpPacked = 0;
       
   598 				break;
       
   599 				}
       
   600 			}
       
   601 		// Single Shift 3 (SS3) sequence - Code Set 3
       
   602 		if (aSample[i]==0x8f)
       
   603 			{
       
   604 			TInt increment1 = i+1;
       
   605 			TInt increment2 = i+2;
       
   606 			if ((increment1 >= sampleLength) || (increment2 >= sampleLength))
       
   607 				break;
       
   608 			if (((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe)) && 
       
   609 				((aSample[increment2] >= 0xa1) && (aSample[increment2] <= 0xfe)))
       
   610 				{
       
   611 				eucjpPacked = eucjpPacked +3;
       
   612 				i+=2;
       
   613 				}
       
   614 			else
       
   615 				{
       
   616 				eucjpPacked =0;
       
   617 				break;
       
   618 				}
       
   619 			}
       
   620 		}
       
   621 	if (eucjpPacked)
       
   622 		aConfidenceLevel = (eucjpPacked*100)/sampleLength;
       
   623 	else
       
   624 		aConfidenceLevel = 0;
       
   625 	aConfidenceLevel=(aConfidenceLevel >100)?100:aConfidenceLevel; 
       
   626 	return ETrue;
       
   627 	}
       
   628 
       
   629 CEucjpPackedConverterImpl* CEucjpPackedConverterImpl::NewL()
       
   630 	{
       
   631 	CEucjpPackedConverterImpl* self = new(ELeave) CEucjpPackedConverterImpl();
       
   632 	return self;
       
   633 	}
       
   634 
       
   635 CEucjpPackedConverterImpl::~CEucjpPackedConverterImpl()
       
   636 	{
       
   637 	}
       
   638 
       
   639 CEucjpPackedConverterImpl::CEucjpPackedConverterImpl()
       
   640 	{
       
   641 	}
       
   642 
       
   643 const TImplementationProxy ImplementationTable[] = 
       
   644 	{
       
   645 		IMPLEMENTATION_PROXY_ENTRY(0x10006067,CEucjpPackedConverterImpl::NewL)
       
   646 	};
       
   647 
       
   648 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   649 	{
       
   650 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   651 
       
   652 	return ImplementationTable;
       
   653 	}
       
   654