diff -r b9ad20498fb4 -r 8b9155204a54 charconvfw/Charconvplugin/src/EucJpDirectmap.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/charconvfw/Charconvplugin/src/EucJpDirectmap.CPP Fri Jun 04 10:37:54 2010 +0100 @@ -0,0 +1,1084 @@ +/* +* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This file is a source code file for a charconv plug-in. +* This plug-in supports EUC-JP with direct mapped pictograph. +* +*/ + + + + +// INCLUDE FILES +#include +#include + +#ifndef EKA2 +#include +#else +#include +#include +#include "charactersetconverter.h" +#endif // !EKA2 + +#include +#include +#include +#include +#include +// LOCAL CONSTANTS AND MACROS +const TUint KSingleShift2=0x8e; +const TUint KSingleShift3=0x8f; +const TUint KFirstByteRangeFirstBlockStart = 0xF5; +const TUint KFirstByteRangeFirstBlockEnd = 0xFE; +const TUint KSecondByteRangeSecondBlockStart = 0xA1; +const TUint KSecondByteRangeSecondBlockEnd = 0xFE; +const TUint KPictographStartFirstByte = 0xF0; +const TUint KPictographStartSecondByte = 0x40; +const TUint KEUCJPSecondBlockStart = 0xF5; +const TUint KEUCJPBlockSize = 0x5D; +const TUint KShiftJisTrailByteIllegal = 0x7F; + +// SecureID for Brower app +const TUint32 KBrowserSecureId = 0x10008D39; +// Define for converting from YenSign to BackSlash +const TUint KCharacterCodeForYenSign = 0x00A5; +const TUint KCharacterCodeForBackSlash = 0x005C; + +// fullwidth question mark +_LIT8(KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters, "\xa1\xa9"); +#if defined(_DEBUG) +_LIT(KLitPanicText, "EucJpDirectmap"); +enum TPanic + { + EPanicNothingToConvert1=1, + EPanicNothingToConvert2, + EPanicNothingToConvert3, + EPanicNothingToConvert4, + EPanicNothingToConvert5, + EPanicNothingToConvert6, + EPanicOddNumberOfBytes1, + EPanicOddNumberOfBytes2, + EPanicOddNumberOfBytes3, + EPanicOddNumberOfBytes4, + EPanicOddNumberOfBytes5, + EPanicOddNumberOfBytes6, + EPanicBadHighBit1, + EPanicBadHighBit2, + EPanicBadHighBit3, + EPanicBadHighBit4, + EPanicBadHighBit5, + EPanicBadHighBit6, + EPanicBadHighBit7, + EPanicBadPointers1, + EPanicBadPointers2, + EPanicBadPointers3, + EPanicBadPointers4, + EPanicBadPointers5, + EPanicBadPointers6, + EPanicBadPointers7, + EPanicBadPointers8, + EPanicBadPointers9, + EPanicBadPointers10, + EPanicBadPointers11, + EPanicBadPointers12, + EPanicBadPointers13, + EPanicBadPointers14, + EPanicBadPointers15, + EPanicBadPointers16, + EPanicBadPointers17, + EPanicBadPointers18, + EPanicBadPointers19, + EPanicBadPointers20, + EPanicBadPointers21, + EPanicBadPointers22, + EPanicBadPointers23, + EPanicBadPointers24, + EPanicBadPointers25, + EPanicBadPointers26, + EPanicBadPointers27, + EPanicBadPointers28, + EPanicBadPointers29, + EPanicBadPointers30, + EPanicBadPointers31, + EPanicBadPointers32, + EPanicBadPointers33, + EPanicBadPointers34, + EPanicBadPointers35, + EPanicBadPointers36, + EPanicBadCalculation1, + EPanicBadCalculation2, + EPanicNumberOfBytesIsNotMultipleOfThree1, + EPanicNumberOfBytesIsNotMultipleOfThree2, + EPanicSingleShift2Expected, + EPanicSingleShift3Expected + }; + +LOCAL_C void Panic(TPanic aPanic) + { + User::Panic(KLitPanicText, aPanic); + } +#endif + +// ----------------------------------------------------------------------------- +// DummyConvertFromIntermediateBufferInPlace +// +// ----------------------------------------------------------------------------- +// +LOCAL_C void DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, + TInt& aNumberOfCharactersThatDroppedOut) + { + aNumberOfCharactersThatDroppedOut = 0; + } + +// ----------------------------------------------------------------------------- +// ConvertFromJisX0208ToEucJpPackedInPlace +// Converts from JIS code to EUC-JP +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertFromJisX0208ToEucJpPackedInPlace( + TInt aStartPositionInDescriptor, TDes8& aDescriptor, + TInt& aNumberOfCharactersThatDroppedOut) + { + aNumberOfCharactersThatDroppedOut = 0; + const TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > aStartPositionInDescriptor, + Panic(EPanicNothingToConvert1)); + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes1)); + TUint8* pointerToCurrentByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* const pointerToLastByte = + pointerToCurrentByte + (descriptorLength - 1); + pointerToCurrentByte += aStartPositionInDescriptor; + FOREVER + { + const TUint currentByte = *pointerToCurrentByte; + __ASSERT_DEBUG((currentByte & 0x80) == 0, Panic(EPanicBadHighBit1)); + *pointerToCurrentByte = STATIC_CAST(TUint8, currentByte | 0x80); + __ASSERT_DEBUG(pointerToCurrentByte <= pointerToLastByte, + Panic(EPanicBadPointers1)); + if (pointerToCurrentByte >= pointerToLastByte) + { + break; + } + ++pointerToCurrentByte; + } + } + +// ----------------------------------------------------------------------------- +// ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace +// Converts from half width Katakana code to EUC-JP +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace( + TInt aStartPositionInDescriptor, TDes8& aDescriptor, + TInt& aNumberOfCharactersThatDroppedOut) + { + TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > aStartPositionInDescriptor, + Panic(EPanicNothingToConvert2)); + aNumberOfCharactersThatDroppedOut = Max(0, (descriptorLength - + aStartPositionInDescriptor) - ((aDescriptor.MaxLength() - + aStartPositionInDescriptor) / 2)); + descriptorLength -= aNumberOfCharactersThatDroppedOut; + __ASSERT_DEBUG(descriptorLength >= aStartPositionInDescriptor, + Panic(EPanicBadCalculation1)); + if (descriptorLength <= aStartPositionInDescriptor) + { + aDescriptor.SetLength(descriptorLength); + } + else + { + // pointerToTargetByte is initialized properly when descriptorLength + // has been offset to the actual final length of aDescriptor + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* const pointerToFirstByte = + pointerToTargetByte + aStartPositionInDescriptor; + const TUint8* pointerToSourceByte = + pointerToTargetByte + (descriptorLength - 1); + descriptorLength = + ((descriptorLength - aStartPositionInDescriptor) * 2) + + aStartPositionInDescriptor; + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes2)); + aDescriptor.SetLength(descriptorLength); + // pointerToTargetByte is is initialized properly here + pointerToTargetByte += descriptorLength - 1; + FOREVER + { + *pointerToTargetByte = *pointerToSourceByte; + __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, + Panic(EPanicBadPointers2)); + --pointerToTargetByte; + *pointerToTargetByte = KSingleShift2; + __ASSERT_DEBUG(pointerToTargetByte >= pointerToFirstByte, + Panic(EPanicBadPointers3)); + if (pointerToTargetByte <= pointerToFirstByte) + { + break; + } + --pointerToTargetByte; + __ASSERT_DEBUG(pointerToSourceByte > pointerToFirstByte, + Panic(EPanicBadPointers4)); + --pointerToSourceByte; + } + __ASSERT_DEBUG(pointerToTargetByte == pointerToFirstByte, + Panic(EPanicBadPointers5)); + __ASSERT_DEBUG(pointerToSourceByte == pointerToFirstByte, + Panic(EPanicBadPointers6)); + } + } + +// ----------------------------------------------------------------------------- +// ConvertFromJisX0212ToEucJpPackedInPlace +// Converts from JIS code to EUC-JP +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertFromJisX0212ToEucJpPackedInPlace( + TInt aStartPositionInDescriptor, TDes8& aDescriptor, + TInt& aNumberOfCharactersThatDroppedOut) + { + TInt descriptorLength=aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > aStartPositionInDescriptor, + Panic(EPanicNothingToConvert3)); + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes3)); + aNumberOfCharactersThatDroppedOut = + Max(0, ((descriptorLength - aStartPositionInDescriptor) / 2) - + ((aDescriptor.MaxLength() - aStartPositionInDescriptor) / 3)); + descriptorLength -= aNumberOfCharactersThatDroppedOut * 2; + __ASSERT_DEBUG(descriptorLength >= aStartPositionInDescriptor, + Panic(EPanicBadCalculation2)); + if (descriptorLength <= aStartPositionInDescriptor) + { + aDescriptor.SetLength(descriptorLength); + } + else + { + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes4)); + // pointerToTargetByte is initialized properly when descriptorLength + // has been offset to the actual final length of aDescriptor + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* const pointerToFirstByte = + pointerToTargetByte + aStartPositionInDescriptor; + const TUint8* pointerToSourceByte = + pointerToTargetByte + (descriptorLength - 1); + descriptorLength = (((descriptorLength - aStartPositionInDescriptor) + * 3) / 2) + aStartPositionInDescriptor; + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 3 ==0, + Panic(EPanicNumberOfBytesIsNotMultipleOfThree1)); + aDescriptor.SetLength(descriptorLength); + // pointerToTargetByte is is initialized properly here + pointerToTargetByte += descriptorLength - 1; + FOREVER + { + __ASSERT_DEBUG((*pointerToSourceByte & 0x80) == 0, + Panic(EPanicBadHighBit2)); + *pointerToTargetByte = + STATIC_CAST(TUint8, *pointerToSourceByte | 0x80); + __ASSERT_DEBUG(pointerToTargetByte > pointerToFirstByte, + Panic(EPanicBadPointers7)); + --pointerToTargetByte; + __ASSERT_DEBUG(pointerToSourceByte > pointerToFirstByte, + Panic(EPanicBadPointers8)); + --pointerToSourceByte; + __ASSERT_DEBUG((*pointerToSourceByte & 0x80) == 0, + Panic(EPanicBadHighBit3)); + *pointerToTargetByte = + STATIC_CAST(TUint8, *pointerToSourceByte | 0x80); + __ASSERT_DEBUG(pointerToTargetByte > pointerToFirstByte, + Panic(EPanicBadPointers9)); + --pointerToTargetByte; + *pointerToTargetByte = KSingleShift3; + __ASSERT_DEBUG(pointerToTargetByte >= pointerToFirstByte, + Panic(EPanicBadPointers10)); + if (pointerToTargetByte <= pointerToFirstByte) + { + break; + } + --pointerToTargetByte; + __ASSERT_DEBUG(pointerToSourceByte > pointerToFirstByte, + Panic(EPanicBadPointers11)); + --pointerToSourceByte; + } + __ASSERT_DEBUG(pointerToTargetByte == pointerToFirstByte, + Panic(EPanicBadPointers12)); + __ASSERT_DEBUG(pointerToSourceByte == pointerToFirstByte, + Panic(EPanicBadPointers13)); + } + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToJisRoman +// Counts the bytes of be able to convert to JIS +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToJisRoman(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + FOREVER + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers14)); + const TUint currentByte = *(pointerToPreviousByte + 1); + if (currentByte & 0x80) + { + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers15)); + ++pointerToPreviousByte; + __ASSERT_DEBUG(pointerToPreviousByte <= pointerToLastByte, + Panic(EPanicBadPointers16)); + if (pointerToPreviousByte >= pointerToLastByte) + { + break; + } + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToJisX0208 +// Counts the bytes of be able to convert to JIS +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0208(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + FOREVER + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers17)); + TUint currentByte = *(pointerToPreviousByte + 1); + if (currentByte < 0xa0) + { + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers18)); + if (pointerToLastByte - pointerToPreviousByte < 2) + { + break; + } + ++pointerToPreviousByte; + currentByte = *(pointerToPreviousByte + 1); + if (currentByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers19)); + ++pointerToPreviousByte; + __ASSERT_DEBUG(pointerToPreviousByte <= pointerToLastByte, + Panic(EPanicBadPointers20)); + if (pointerToPreviousByte >= pointerToLastByte) + { + break; + } + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToHalfWidthKatakana8 +// Counts the bytes of be able to convert to half width Katakana +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToHalfWidthKatakana8(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + FOREVER + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers21)); + TUint currentByte = *(pointerToPreviousByte + 1); + if (currentByte != KSingleShift2) + { + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers22)); + if (pointerToLastByte - pointerToPreviousByte < 2) + { + break; + } + ++pointerToPreviousByte; + currentByte = *(pointerToPreviousByte + 1); + if (currentByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers23)); + ++pointerToPreviousByte; + __ASSERT_DEBUG(pointerToPreviousByte <= pointerToLastByte, + Panic(EPanicBadPointers24)); + if (pointerToPreviousByte >= pointerToLastByte) + { + break; + } + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToJisX0212 +// Counts the bytes of be able to convert to JIS +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0212(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + FOREVER + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers25)); + TUint currentByte = *(pointerToPreviousByte + 1); + if (currentByte != KSingleShift3) + { + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers26)); + if (pointerToLastByte - pointerToPreviousByte < 3) + { + break; + } + ++pointerToPreviousByte; + currentByte = *(pointerToPreviousByte + 1); + if (currentByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers27)); + ++pointerToPreviousByte; + currentByte = *(pointerToPreviousByte + 1); + if (currentByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers28)); + ++pointerToPreviousByte; + __ASSERT_DEBUG(pointerToPreviousByte <= pointerToLastByte, + Panic(EPanicBadPointers29)); + if (pointerToPreviousByte >= pointerToLastByte) + { + break; + } + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// DummyConvertToIntermediateBufferInPlace +// +// ----------------------------------------------------------------------------- +// +LOCAL_C void DummyConvertToIntermediateBufferInPlace(TDes8&) + { + } + +// ----------------------------------------------------------------------------- +// ConvertToJisX0208FromEucJpPackedInPlace +// Converts from EUC-JP to JIS code +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertToJisX0208FromEucJpPackedInPlace(TDes8& aDescriptor) + { + const TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > 0, Panic(EPanicNothingToConvert4)); + __ASSERT_DEBUG(descriptorLength % 2 == 0, Panic(EPanicOddNumberOfBytes5)); + TUint8* pointerToCurrentByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* const pointerToLastByte = + pointerToCurrentByte + (descriptorLength - 1); + FOREVER + { + const TUint currentByte = *pointerToCurrentByte; + __ASSERT_DEBUG(currentByte & 0x80, Panic(EPanicBadHighBit4)); + *pointerToCurrentByte = STATIC_CAST(TUint8, currentByte & ~0x80); + __ASSERT_DEBUG(pointerToCurrentByte <= pointerToLastByte, + Panic(EPanicBadPointers30)); + if (pointerToCurrentByte >= pointerToLastByte) + { + break; + } + ++pointerToCurrentByte; + } + } + +// ----------------------------------------------------------------------------- +// ConvertToHalfWidthKatakana8FromEucJpPackedInPlace +// Converts from EUC-JP to half width Katakana +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertToHalfWidthKatakana8FromEucJpPackedInPlace( + TDes8& aDescriptor) + { + const TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > 0, Panic(EPanicNothingToConvert5)); + __ASSERT_DEBUG(descriptorLength % 2 == 0, Panic(EPanicOddNumberOfBytes6)); + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* pointerToSourceByte = pointerToTargetByte; + const TUint8* const pointerToLastByte = pointerToSourceByte + + (descriptorLength - 1); + FOREVER + { + __ASSERT_DEBUG(*pointerToSourceByte == KSingleShift2, + Panic(EPanicSingleShift2Expected)); + __ASSERT_DEBUG(pointerToSourceByte < pointerToLastByte, + Panic(EPanicBadPointers31)); + ++pointerToSourceByte; + const TUint sourceByte = *pointerToSourceByte; + __ASSERT_DEBUG(sourceByte & 0x80, Panic(EPanicBadHighBit5)); + *pointerToTargetByte = STATIC_CAST(TUint8, sourceByte); + __ASSERT_DEBUG(pointerToSourceByte <= pointerToLastByte, + Panic(EPanicBadPointers32)); + if (pointerToSourceByte >= pointerToLastByte) + { + break; + } + ++pointerToSourceByte; + ++pointerToTargetByte; + } + aDescriptor.SetLength(descriptorLength / 2); + } + +// ----------------------------------------------------------------------------- +// ConvertToJisX0212FromEucJpPackedInPlace +// Converts from EUC-JP to JIS +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertToJisX0212FromEucJpPackedInPlace(TDes8& aDescriptor) + { + const TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > 0, Panic(EPanicNothingToConvert6)); + __ASSERT_DEBUG(descriptorLength % 3 == 0, + Panic(EPanicNumberOfBytesIsNotMultipleOfThree2)); + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* pointerToSourceByte = pointerToTargetByte; + const TUint8* const pointerToLastByte = + pointerToSourceByte + (descriptorLength - 1); + FOREVER + { + __ASSERT_DEBUG(*pointerToSourceByte == KSingleShift3, + Panic(EPanicSingleShift3Expected)); + __ASSERT_DEBUG(pointerToSourceByte < pointerToLastByte, + Panic(EPanicBadPointers33)); + ++pointerToSourceByte; + TUint sourceByte = *pointerToSourceByte; + __ASSERT_DEBUG(sourceByte & 0x80, Panic(EPanicBadHighBit6)); + *pointerToTargetByte = STATIC_CAST(TUint8, sourceByte & ~0x80); + __ASSERT_DEBUG(pointerToSourceByte= pointerToLastByte) + { + break; + } + ++pointerToSourceByte; + ++pointerToTargetByte; + } + aDescriptor.SetLength((descriptorLength / 3) * 2); + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToPictograph +// +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToPictograph1(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + for (;pointerToPreviousByte < pointerToLastByte;) + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers14)); + TUint currentByte = *(pointerToPreviousByte + 1); + const TUint nextByte = *(pointerToPreviousByte + 2); + if (((currentByte < KFirstByteRangeFirstBlockStart) || + (currentByte > KFirstByteRangeFirstBlockEnd)) || + ((nextByte < KSecondByteRangeSecondBlockStart) || + (nextByte > KSecondByteRangeSecondBlockEnd))) + { + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers15)); + pointerToPreviousByte += 2; + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// NumberOfBytesAbleToConvertToPictograph +// +// ----------------------------------------------------------------------------- +// +LOCAL_C TInt NumberOfBytesAbleToConvertToPictograph2(const TDesC8& aDescriptor) + { + const TUint8* pointerToPreviousByte = aDescriptor.Ptr() - 1; + const TUint8* const pointerToLastByte = + pointerToPreviousByte + aDescriptor.Length(); + if (pointerToPreviousByte == pointerToLastByte) + { + return 0; + } + for (;pointerToPreviousByte < pointerToLastByte;) + { + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers14)); + TUint currentByte = *(pointerToPreviousByte + 1); + if (currentByte == KSingleShift3) + { + pointerToPreviousByte++; + currentByte = *(pointerToPreviousByte + 1); + } + else + { + break; + } + if (currentByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + const TUint nextByte = *(pointerToPreviousByte + 2); + if (nextByte < 0xa0) + { + return CCnvCharacterSetConverter::EErrorIllFormedInput; + } + if (((currentByte < KFirstByteRangeFirstBlockStart) || + (currentByte > KFirstByteRangeFirstBlockEnd)) || + ((nextByte < KSecondByteRangeSecondBlockStart) || + (nextByte > KSecondByteRangeSecondBlockEnd))) + { + // return the previous byte to the beginning of loop. + pointerToPreviousByte--; + break; + } + __ASSERT_DEBUG(pointerToPreviousByte < pointerToLastByte, + Panic(EPanicBadPointers15)); + pointerToPreviousByte += 2; + } + return (pointerToPreviousByte + 1) - aDescriptor.Ptr(); + } + +// ----------------------------------------------------------------------------- +// ConvertFromPictogaphToEucJpDirectmapInPlace +// Converts from EucJp packed Pictograph to Unicode +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertFromPictogaphToEucJpDirectmapInPlace( + TInt aStartPositionInDescriptor, TDes8& aDescriptor, + TInt& aNumberOfCharactersThatDroppedOut) + { + TInt descriptorLength=aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > aStartPositionInDescriptor, + Panic(EPanicNothingToConvert3)); + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes3)); + TInt bytesPerCharacter = 2; + if (aDescriptor[0] >= KEUCJPSecondBlockStart) + { + bytesPerCharacter = 3; + } + + aNumberOfCharactersThatDroppedOut = + Max(0, ((descriptorLength - aStartPositionInDescriptor) / 2) - + ((aDescriptor.MaxLength() - aStartPositionInDescriptor) / + bytesPerCharacter)); + descriptorLength -= aNumberOfCharactersThatDroppedOut * 2; + __ASSERT_DEBUG(descriptorLength >= aStartPositionInDescriptor, + Panic(EPanicBadCalculation2)); + if (descriptorLength <= aStartPositionInDescriptor) + { + aDescriptor.SetLength(descriptorLength); + } + else + { + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % 2 == 0, + Panic(EPanicOddNumberOfBytes4)); + // pointerToTargetByte is initialized properly when descriptorLength + // has been offset to the actual final length of aDescriptor + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* const pointerToFirstByte = + pointerToTargetByte + aStartPositionInDescriptor; + const TUint8* pointerToSourceByte = + pointerToTargetByte + (descriptorLength - 1); + descriptorLength = (((descriptorLength - aStartPositionInDescriptor) + * bytesPerCharacter) / 2) + aStartPositionInDescriptor; + __ASSERT_DEBUG((descriptorLength - aStartPositionInDescriptor) % + bytesPerCharacter == 0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree1)); + aDescriptor.SetLength(descriptorLength); + // pointerToTargetByte is is initialized properly here + pointerToTargetByte += descriptorLength - 1; + for (;pointerToTargetByte > pointerToFirstByte; ) + { + TInt secondByte = *pointerToSourceByte; + TInt firstByte = *(pointerToSourceByte - 1); + + if (bytesPerCharacter == 3) + { + firstByte = (firstByte - KEUCJPSecondBlockStart) * 2 + + KFirstByteRangeFirstBlockStart; + } + else + { + firstByte = (firstByte - KPictographStartFirstByte) * 2 + + KFirstByteRangeFirstBlockStart; + } + if (static_cast(KEUCJPBlockSize + KPictographStartSecondByte + 1) + < secondByte) + { + if (secondByte > KShiftJisTrailByteIllegal) + secondByte -= 1; + secondByte = secondByte -(KPictographStartSecondByte + + KEUCJPBlockSize + 1) + KSecondByteRangeSecondBlockStart; + firstByte++; + } + else + { + if (secondByte > KShiftJisTrailByteIllegal) + secondByte -= 1; + secondByte += KSecondByteRangeSecondBlockStart - KPictographStartSecondByte; + } + *pointerToTargetByte = static_cast(secondByte); + --pointerToTargetByte; + *pointerToTargetByte = static_cast(firstByte); + if (bytesPerCharacter == 3) + { + --pointerToTargetByte; + *pointerToTargetByte = KSingleShift3; + } + __ASSERT_DEBUG(pointerToTargetByte >= pointerToFirstByte, + Panic(EPanicBadPointers10)); + --pointerToTargetByte; + pointerToSourceByte -= 2; + } + } + } + +// ----------------------------------------------------------------------------- +// ConvertToPictographFromEucJpPackedInPlace1 +// Converts from EucJp packed Pictograph to Unicode +// ----------------------------------------------------------------------------- +// +LOCAL_C void ConvertToPictographFromEucJpPackedInPlace(TDes8& aDescriptor) + { + const TInt descriptorLength = aDescriptor.Length(); + __ASSERT_DEBUG(descriptorLength > 0, Panic(EPanicNothingToConvert6)); + TUint8* pointerToTargetByte = CONST_CAST(TUint8*, aDescriptor.Ptr()); + const TUint8* pointerToSourceByte = pointerToTargetByte; + const TUint8* const pointerToLastByte = + pointerToSourceByte + (descriptorLength - 1); + TInt bytesPerCharacter = 2; + TInt sjisStartbyte = KPictographStartFirstByte; + if (*pointerToSourceByte == KSingleShift3) + { + ++pointerToSourceByte; + bytesPerCharacter = 3; + sjisStartbyte = KEUCJPSecondBlockStart; + } + for (;pointerToSourceByte < pointerToLastByte; ) + { + __ASSERT_DEBUG(pointerToSourceByte < pointerToLastByte, + Panic(EPanicBadPointers33)); + TUint firstByte = (*pointerToSourceByte + - KFirstByteRangeFirstBlockStart) / 2 + sjisStartbyte; + TUint secondByte = *(pointerToSourceByte + 1); + if ((*pointerToSourceByte % 2) == 0) + { + secondByte += KPictographStartSecondByte - + KSecondByteRangeSecondBlockStart + KEUCJPBlockSize + 1; + if (secondByte >= KShiftJisTrailByteIllegal) + secondByte++; + } + else + { + secondByte += KPictographStartSecondByte - KSecondByteRangeSecondBlockStart; + if (secondByte >= KShiftJisTrailByteIllegal) + secondByte++; + } + *pointerToTargetByte = static_cast(firstByte); + + __ASSERT_DEBUG(pointerToTargetByte < pointerToLastByte, + Panic(EPanicBadPointers35)); + ++pointerToTargetByte; + *pointerToTargetByte = static_cast(secondByte); + __ASSERT_DEBUG(pointerToSourceByte <= pointerToLastByte, + Panic(EPanicBadPointers36)); + pointerToSourceByte += 2; + ++pointerToTargetByte; + } + aDescriptor.SetLength((descriptorLength / bytesPerCharacter) * 2); + } + +// New Interface class +class CEucJpDirectmapImplementation : public CCharacterSetConverterPluginInterface +{ + public: + virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters(); + + virtual TInt ConvertFromUnicode( + CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, + const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, + TDes8& aForeign, + const TDesC16& aUnicode, + CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters ); + + virtual TInt ConvertToUnicode( + CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, + TDes16& aUnicode, + const TDesC8& aForeign, + TInt&, + TInt& aNumberOfUnconvertibleCharacters, + TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter ); + + virtual TBool IsInThisCharacterSetL( + TBool& aSetToTrue, + TInt& aConfidenceLevel, + const TDesC8& ); + + static CEucJpDirectmapImplementation* NewL(); + + virtual ~CEucJpDirectmapImplementation(); + private: + CEucJpDirectmapImplementation(); +}; + +// ----------------------------------------------------------------------------- +// ReplacementForUnconvertibleUnicodeCharacters +// Retruns the character to replacement for unconvertible unicode character. +// Returns: '?': +// ----------------------------------------------------------------------------- +// +const TDesC8& CEucJpDirectmapImplementation::ReplacementForUnconvertibleUnicodeCharacters() + { + return KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters; + } + +// ----------------------------------------------------------------------------- +// ConvertFromUnicode +// Converts from Unicode to EUC-JP +// Returns: The number of unconverted characters +// ----------------------------------------------------------------------------- +// +TInt CEucJpDirectmapImplementation::ConvertFromUnicode( + CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, + const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, + TDes8& aForeign, const TDesC16& aUnicode, + CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters) + { + TFixedArray characterSets; + characterSets[0].iConversionData = &CnvJisRoman::ConversionData(); + characterSets[0].iConvertFromIntermediateBufferInPlace = + DummyConvertFromIntermediateBufferInPlace; + characterSets[0].iEscapeSequence = &KNullDesC8; + characterSets[1].iConversionData = &CnvJisX0208::ConversionData(); + characterSets[1].iConvertFromIntermediateBufferInPlace = + ConvertFromJisX0208ToEucJpPackedInPlace; + characterSets[1].iEscapeSequence = &KNullDesC8; + characterSets[2].iConversionData = &CnvHalfWidthKatakana8::ConversionData(); + characterSets[2].iConvertFromIntermediateBufferInPlace = + ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace; + characterSets[2].iEscapeSequence = &KNullDesC8; + characterSets[3].iConversionData = &CnvJisX0212::ConversionData(); + characterSets[3].iConvertFromIntermediateBufferInPlace = + ConvertFromJisX0212ToEucJpPackedInPlace; + characterSets[3].iEscapeSequence = &KNullDesC8; + characterSets[4].iConversionData = &CnvShiftJisDirectmap::ConversionData(); + characterSets[4].iConvertFromIntermediateBufferInPlace = + ConvertFromPictogaphToEucJpDirectmapInPlace; + characterSets[4].iEscapeSequence = &KNullDesC8; + characterSets[5].iConversionData = &CnvShiftJisDirectmap::ConversionData(); + characterSets[5].iConvertFromIntermediateBufferInPlace = + ConvertFromPictogaphToEucJpDirectmapInPlace; + characterSets[5].iEscapeSequence = &KNullDesC8; + + TInt unconvert = CnvUtilities::ConvertFromUnicode( + aDefaultEndiannessOfForeignCharacters, + aReplacementForUnconvertibleUnicodeCharacters, + aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, + characterSets.Array()); + + return unconvert; + } + +// ----------------------------------------------------------------------------- +// ConvertToUnicode +// Converts from EUC-JP to Unicode. +// Returns: The number of unconverted bytes +// ----------------------------------------------------------------------------- +// +TInt CEucJpDirectmapImplementation::ConvertToUnicode( + CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, + TDes16& aUnicode, const TDesC8& aForeign, TInt&, + TInt& aNumberOfUnconvertibleCharacters, + TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter) + { + TFixedArray methods; + + methods[0].iNumberOfBytesAbleToConvert = + NumberOfBytesAbleToConvertToPictograph1; + methods[0].iConvertToIntermediateBufferInPlace = + ConvertToPictographFromEucJpPackedInPlace; + methods[0].iConversionData = &CnvShiftJisDirectmap::ConversionData(); + methods[0].iNumberOfBytesPerCharacter = 2; + methods[0].iNumberOfCoreBytesPerCharacter = 2; + methods[1].iNumberOfBytesAbleToConvert = + NumberOfBytesAbleToConvertToPictograph2; + methods[1].iConvertToIntermediateBufferInPlace = + ConvertToPictographFromEucJpPackedInPlace; + methods[1].iConversionData = &CnvShiftJisDirectmap::ConversionData(); + methods[1].iNumberOfBytesPerCharacter = 3; + methods[1].iNumberOfCoreBytesPerCharacter = 2; + + methods[2].iNumberOfBytesAbleToConvert = NumberOfBytesAbleToConvertToJisRoman; + methods[2].iConvertToIntermediateBufferInPlace = + DummyConvertToIntermediateBufferInPlace; + methods[2].iConversionData = &CnvJisRoman::ConversionData(); + methods[2].iNumberOfBytesPerCharacter = 1; + methods[2].iNumberOfCoreBytesPerCharacter = 1; + methods[3].iNumberOfBytesAbleToConvert = NumberOfBytesAbleToConvertToJisX0208; + methods[3].iConvertToIntermediateBufferInPlace = + ConvertToJisX0208FromEucJpPackedInPlace; + methods[3].iConversionData = &CnvJisX0208::ConversionData(); + methods[3].iNumberOfBytesPerCharacter = 2; + methods[3].iNumberOfCoreBytesPerCharacter = 2; + methods[4].iNumberOfBytesAbleToConvert = + NumberOfBytesAbleToConvertToHalfWidthKatakana8; + methods[4].iConvertToIntermediateBufferInPlace = + ConvertToHalfWidthKatakana8FromEucJpPackedInPlace; + methods[4].iConversionData = &CnvHalfWidthKatakana8::ConversionData(); + methods[4].iNumberOfBytesPerCharacter = 2; + methods[4].iNumberOfCoreBytesPerCharacter = 1; + methods[5].iNumberOfBytesAbleToConvert = + NumberOfBytesAbleToConvertToJisX0212; + methods[5].iConvertToIntermediateBufferInPlace = + ConvertToJisX0212FromEucJpPackedInPlace; + methods[5].iConversionData = &CnvJisX0212::ConversionData(); + methods[5].iNumberOfBytesPerCharacter = 3; + methods[5].iNumberOfCoreBytesPerCharacter = 2; + + TInt unconvert = CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign( + aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, + aNumberOfUnconvertibleCharacters, + aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array()); + + // The following is specific impelementation for brower. + // If brower app calls this API, the yen sign code(0xA5) + // must be converted to backslash code(0x5C). + // Becasue Javascript supports backslash code ony. + TBool browserProcess = (RProcess().SecureId().iId == KBrowserSecureId); + if (browserProcess && aUnicode.Length() > 0) + { + const TUint16* pB = aUnicode.Ptr(); + const TUint16* pbase = pB; + const TUint16* pE = pB + aUnicode.Length() -1; + while (pE>=pbase) + { + if (*pbase == KCharacterCodeForYenSign) + { + aUnicode[pbase - pB] = KCharacterCodeForBackSlash; + } + pbase++; + } + } + + return unconvert; + } + +// ----------------------------------------------------------------------------- +// IsInThisCharacterSetL +// Detects whether the text is the character code or not. +// Returns: ETrue: +// ----------------------------------------------------------------------------- +// +TBool CEucJpDirectmapImplementation::IsInThisCharacterSetL(TBool& /*aSetToTrue*/, TInt& /*aConfidenceLevel*/, + const TDesC8& /*aSample*/) + { + return EFalse; + } + +CEucJpDirectmapImplementation* CEucJpDirectmapImplementation::NewL() + { + CEucJpDirectmapImplementation* self = new(ELeave) CEucJpDirectmapImplementation; + return self; + } + +CEucJpDirectmapImplementation::CEucJpDirectmapImplementation() + { + //default constructor.. do nothing + } + +CEucJpDirectmapImplementation::~CEucJpDirectmapImplementation() + { + //default destructor .. do nothing + } + +// ECOM CREATION FUNCTION +const TImplementationProxy ImplementationTable[] = + { + // Note: This is the same UID as defined in old mmp-file + // Used also in 12221212.rss ( implementation_uid ) + IMPLEMENTATION_PROXY_ENTRY( 0x101F86A6, CEucJpDirectmapImplementation::NewL ) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable ) / sizeof(TImplementationProxy); + return ImplementationTable; + } + +// End of file