sl@0: /* sl@0: * Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "PictographObserver.h" sl@0: #include "featmgr/featmgr.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include "jisx0201.h" sl@0: #include "jisx0208.h" sl@0: #include "SHIFTJIS_2.H" sl@0: #include sl@0: sl@0: //const TUint KSingleByteRangeFirstBlockStart=0x00; sl@0: const TUint KSingleByteRangeFirstBlockEnd=0x7f; sl@0: const TUint KSingleByteRangeSecondBlockStart=0xa1; sl@0: const TUint KSingleByteRangeSecondBlockEnd=0xdf; sl@0: const TUint KFirstByteRangeFirstBlockStart=0x81; sl@0: const TUint KFirstByteRangeFirstBlockEnd=0x9f; sl@0: const TUint KFirstByteRangeFirstBlockLength=(KFirstByteRangeFirstBlockEnd+1)-KFirstByteRangeFirstBlockStart; sl@0: const TUint KFirstByteRangeSecondBlockStart=0xe0; sl@0: // Ken Lunde's book "CJKV Information Processing" (page 176) says this sl@0: // constant should be 0xef, but no Shift-JIS characters in sl@0: // \charconv\data\JISX0208.TXT have a first byte greater than 0xea, and sl@0: // some extensions of Shift-JIS may use the 0xeb-0xef range for the first sl@0: // byte of their characters (e.g. "MOPERA"), and in order for users of this sl@0: // DLL to be able to implement these extensions using the sl@0: // aArrayOfAdditionalXxxxx parameters, this constant therefore needs to sl@0: // be set as low as possible, i.e. to 0xea sl@0: const TUint KFirstByteRangeSecondBlockEnd=0xea; sl@0: const TUint KFirstByteRangeOtherBlockEnd = 0xfc; sl@0: sl@0: const TUint KPictoFirstByteStart = 0xF0; sl@0: const TUint KPictoFirstByteEnd = 0xF9; sl@0: sl@0: const TUint KSecondByteRangeFirstBlockStart=0x40; sl@0: const TUint KSecondByteRangeFirstBlockEnd=0x7e; sl@0: const TUint KSecondByteRangeFirstBlockLength=(KSecondByteRangeFirstBlockEnd+1)-KSecondByteRangeFirstBlockStart; sl@0: const TUint KSecondByteRangeSecondBlockStart=0x80; sl@0: const TUint KSecondByteRangeSecondBlockEnd=0xfc; sl@0: sl@0: // SecureID for Brower app sl@0: const TUint32 KBrowserSecureId = 0x10008D39; sl@0: // Define for converting from YenSign to BackSlash sl@0: const TUint KCharacterCodeForYenSign = 0x00A5; sl@0: const TUint KCharacterCodeForBackSlash = 0x005C; sl@0: sl@0: TInt BytesInOtherDoubleByteAreas(const TDesC8& aShiftJis); sl@0: TInt OneIfNotValid(const TDesC8& aShiftJis); sl@0: sl@0: TBool IsJisX0208LeadByte(TUint a) sl@0: { sl@0: return (KFirstByteRangeFirstBlockStart <= a sl@0: && a <= KFirstByteRangeFirstBlockEnd) sl@0: || (KFirstByteRangeSecondBlockStart <= a sl@0: && a <= KFirstByteRangeSecondBlockEnd); sl@0: } sl@0: sl@0: TBool IsValidTrailByte(TUint a) sl@0: { sl@0: return KSecondByteRangeFirstBlockStart <= a sl@0: && a <= KSecondByteRangeSecondBlockEnd sl@0: && a != KSecondByteRangeFirstBlockEnd + 1; sl@0: } sl@0: sl@0: TBool IsOtherLeadByte(TUint a) sl@0: { sl@0: if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) ) sl@0: { sl@0: return ((KFirstByteRangeSecondBlockEnd < a && a <= KFirstByteRangeOtherBlockEnd) sl@0: && (a < KPictoFirstByteStart || a > KPictoFirstByteEnd)); sl@0: } sl@0: else sl@0: { sl@0: return KFirstByteRangeSecondBlockEnd < a sl@0: && a <= KFirstByteRangeOtherBlockEnd; sl@0: } sl@0: } sl@0: sl@0: _LIT8(KLit8ShiftJisReplacementForUnconvertibleUnicodeCharacters, "\x81\x48"); // fullwidth question mark sl@0: sl@0: #if defined(_DEBUG) sl@0: sl@0: _LIT(KLitPanicText, "SHIFTJIS_SHARED"); sl@0: sl@0: enum TPanic sl@0: { sl@0: EPanicIndexOverflow1=1, sl@0: EPanicIndexOverflow2, sl@0: EPanicNothingToConvert1, sl@0: EPanicNothingToConvert2, sl@0: EPanicOddNumberOfBytes1, sl@0: EPanicOddNumberOfBytes2, sl@0: EPanicBadPointers1, sl@0: EPanicBadPointers2, sl@0: EPanicBadPointers3, sl@0: EPanicBadPointers4, sl@0: EPanicBadPointers5, sl@0: EPanicBadPointers6, sl@0: EPanicBadPointers7, sl@0: EPanicBadPointers8, sl@0: EPanicBadPointers9 sl@0: }; sl@0: sl@0: LOCAL_C void Panic(TPanic aPanic) sl@0: { sl@0: User::Panic(KLitPanicText, aPanic); sl@0: } sl@0: sl@0: #endif sl@0: sl@0: // TCombinedArrayOfCharacterSets sl@0: sl@0: class TCombinedArrayOfCharacterSets sl@0: { sl@0: public: sl@0: TCombinedArrayOfCharacterSets(const TArray* aArrayOfAdditionalCharacterSets); sl@0: ~TCombinedArrayOfCharacterSets(); sl@0: TArray Array() const; sl@0: private: sl@0: static TInt CombinedCount(const CBase* aThis); sl@0: static const TAny* CombinedAccessor(const CBase* aThis, TInt aIndex); sl@0: private: sl@0: RArray iArrayOfCoreCharacterSets; sl@0: const TArray* iArrayOfAdditionalCharacterSets; sl@0: }; sl@0: sl@0: TCombinedArrayOfCharacterSets::TCombinedArrayOfCharacterSets(const TArray* aArrayOfAdditionalCharacterSets) sl@0: :iArrayOfAdditionalCharacterSets(aArrayOfAdditionalCharacterSets) sl@0: { sl@0: if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) ) sl@0: { sl@0: CnvUtilities::SCharacterSet characterSet; sl@0: characterSet.iConversionData=&CnvJisX0201::ConversionData(); sl@0: characterSet.iConvertFromIntermediateBufferInPlace=CnvShiftJis::DummyConvertFromIntermediateBufferInPlace; sl@0: characterSet.iEscapeSequence=&KNullDesC8; sl@0: iArrayOfCoreCharacterSets.Append(characterSet); sl@0: characterSet.iConversionData=&CnvJisX0208::ConversionData(); sl@0: characterSet.iConvertFromIntermediateBufferInPlace=CnvShiftJis::ConvertFromJisX0208ToShiftJisInPlace; sl@0: characterSet.iEscapeSequence=&KNullDesC8; sl@0: iArrayOfCoreCharacterSets.Append(characterSet); sl@0: sl@0: SetCharacterSetsForPictograph(iArrayOfCoreCharacterSets, ECharsetShiftJis); sl@0: } sl@0: else sl@0: { sl@0: CnvUtilities::SCharacterSet characterSet; sl@0: characterSet.iConversionData=&CnvJisX0201::ConversionData(); sl@0: characterSet.iConvertFromIntermediateBufferInPlace=CnvShiftJis::DummyConvertFromIntermediateBufferInPlace; sl@0: characterSet.iEscapeSequence=&KNullDesC8; sl@0: iArrayOfCoreCharacterSets.Append(characterSet); sl@0: characterSet.iConversionData=&CnvJisX0208::ConversionData(); sl@0: characterSet.iConvertFromIntermediateBufferInPlace=CnvShiftJis::ConvertFromJisX0208ToShiftJisInPlace; sl@0: characterSet.iEscapeSequence=&KNullDesC8; sl@0: iArrayOfCoreCharacterSets.Append(characterSet); sl@0: } sl@0: } sl@0: sl@0: TCombinedArrayOfCharacterSets::~TCombinedArrayOfCharacterSets() sl@0: { sl@0: iArrayOfCoreCharacterSets.Close(); sl@0: } sl@0: sl@0: sl@0: TArray TCombinedArrayOfCharacterSets::Array() const sl@0: { sl@0: return TArray(CombinedCount, CombinedAccessor, REINTERPRET_CAST(const CBase*, this)); sl@0: } sl@0: sl@0: TInt TCombinedArrayOfCharacterSets::CombinedCount(const CBase* aThis) sl@0: { sl@0: const TCombinedArrayOfCharacterSets& thisReference=*REINTERPRET_CAST(const TCombinedArrayOfCharacterSets*, aThis); sl@0: const TInt numberOfCoreCharacterSets=thisReference.iArrayOfCoreCharacterSets.Count(); sl@0: if (thisReference.iArrayOfAdditionalCharacterSets!=NULL) sl@0: { sl@0: return numberOfCoreCharacterSets+thisReference.iArrayOfAdditionalCharacterSets->Count(); sl@0: } sl@0: return numberOfCoreCharacterSets; sl@0: } sl@0: sl@0: const TAny* TCombinedArrayOfCharacterSets::CombinedAccessor(const CBase* aThis, TInt aIndex) sl@0: { sl@0: const TCombinedArrayOfCharacterSets& thisReference=*REINTERPRET_CAST(const TCombinedArrayOfCharacterSets*, aThis); sl@0: const TInt numberOfCoreCharacterSets=thisReference.iArrayOfCoreCharacterSets.Count(); sl@0: if (aIndex>=numberOfCoreCharacterSets) sl@0: { sl@0: __ASSERT_DEBUG(thisReference.iArrayOfAdditionalCharacterSets!=NULL, Panic(EPanicIndexOverflow1)); sl@0: return &(*thisReference.iArrayOfAdditionalCharacterSets)[aIndex-numberOfCoreCharacterSets]; sl@0: } sl@0: return &thisReference.iArrayOfCoreCharacterSets[aIndex]; sl@0: } sl@0: sl@0: // TCombinedArrayOfMethods sl@0: sl@0: class TCombinedArrayOfMethods sl@0: { sl@0: public: sl@0: TCombinedArrayOfMethods(const TArray* aArrayOfAdditionalMethods); sl@0: ~TCombinedArrayOfMethods(); sl@0: TArray Array() const; sl@0: private: sl@0: static TInt CombinedCount(const CBase* aThis); sl@0: static const TAny* CombinedAccessor(const CBase* aThis, TInt aIndex); sl@0: private: sl@0: RArray iArrayOfCoreMethods; sl@0: const TArray* iArrayOfAdditionalMethods; sl@0: }; sl@0: sl@0: TCombinedArrayOfMethods::TCombinedArrayOfMethods(const TArray* aArrayOfAdditionalMethods) sl@0: :iArrayOfAdditionalMethods(aArrayOfAdditionalMethods) sl@0: { sl@0: if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) ) sl@0: { sl@0: SetMethodsForPictograph(iArrayOfCoreMethods, ECharsetShiftJis); sl@0: CnvUtilities::SMethod method; sl@0: method.iNumberOfBytesAbleToConvert=CnvShiftJis::NumberOfBytesAbleToConvertToJisX0201; sl@0: method.iConvertToIntermediateBufferInPlace=CnvShiftJis::DummyConvertToIntermediateBufferInPlace; sl@0: method.iConversionData=&CnvJisX0201::ConversionData(); sl@0: method.iNumberOfBytesPerCharacter=1; sl@0: method.iNumberOfCoreBytesPerCharacter=1; sl@0: iArrayOfCoreMethods.Append(method); sl@0: method.iNumberOfBytesAbleToConvert=CnvShiftJis::NumberOfBytesAbleToConvertToJisX0208; sl@0: method.iConvertToIntermediateBufferInPlace=CnvShiftJis::ConvertToJisX0208FromShiftJisInPlace; sl@0: method.iConversionData=&CnvJisX0208::ConversionData(); sl@0: method.iNumberOfBytesPerCharacter=2; sl@0: method.iNumberOfCoreBytesPerCharacter=2; sl@0: iArrayOfCoreMethods.Append(method); sl@0: } sl@0: else sl@0: { sl@0: CnvUtilities::SMethod method; sl@0: method.iNumberOfBytesAbleToConvert=CnvShiftJis::NumberOfBytesAbleToConvertToJisX0201; sl@0: method.iConvertToIntermediateBufferInPlace=CnvShiftJis::DummyConvertToIntermediateBufferInPlace; sl@0: method.iConversionData=&CnvJisX0201::ConversionData(); sl@0: method.iNumberOfBytesPerCharacter=1; sl@0: method.iNumberOfCoreBytesPerCharacter=1; sl@0: iArrayOfCoreMethods.Append(method); sl@0: method.iNumberOfBytesAbleToConvert=CnvShiftJis::NumberOfBytesAbleToConvertToJisX0208; sl@0: method.iConvertToIntermediateBufferInPlace=CnvShiftJis::ConvertToJisX0208FromShiftJisInPlace; sl@0: method.iConversionData=&CnvJisX0208::ConversionData(); sl@0: method.iNumberOfBytesPerCharacter=2; sl@0: method.iNumberOfCoreBytesPerCharacter=2; sl@0: iArrayOfCoreMethods.Append(method); sl@0: } sl@0: } sl@0: sl@0: TCombinedArrayOfMethods::~TCombinedArrayOfMethods() sl@0: { sl@0: iArrayOfCoreMethods.Close(); sl@0: } sl@0: sl@0: sl@0: TArray TCombinedArrayOfMethods::Array() const sl@0: { sl@0: return TArray(CombinedCount, CombinedAccessor, REINTERPRET_CAST(const CBase*, this)); sl@0: } sl@0: sl@0: TInt TCombinedArrayOfMethods::CombinedCount(const CBase* aThis) sl@0: { sl@0: const TCombinedArrayOfMethods& thisReference=*REINTERPRET_CAST(const TCombinedArrayOfMethods*, aThis); sl@0: const TInt numberOfCoreMethods=thisReference.iArrayOfCoreMethods.Count(); sl@0: if (thisReference.iArrayOfAdditionalMethods!=NULL) sl@0: { sl@0: return numberOfCoreMethods+thisReference.iArrayOfAdditionalMethods->Count(); sl@0: } sl@0: return numberOfCoreMethods; sl@0: } sl@0: sl@0: const TAny* TCombinedArrayOfMethods::CombinedAccessor(const CBase* aThis, TInt aIndex) sl@0: { sl@0: const TCombinedArrayOfMethods& thisReference=*REINTERPRET_CAST(const TCombinedArrayOfMethods*, aThis); sl@0: const TInt numberOfCoreMethods=thisReference.iArrayOfCoreMethods.Count(); sl@0: if (aIndex>=numberOfCoreMethods) sl@0: { sl@0: __ASSERT_DEBUG(thisReference.iArrayOfAdditionalMethods!=NULL, Panic(EPanicIndexOverflow2)); sl@0: return &(*thisReference.iArrayOfAdditionalMethods)[aIndex-numberOfCoreMethods]; sl@0: } sl@0: return &thisReference.iArrayOfCoreMethods[aIndex]; sl@0: } sl@0: sl@0: // CnvShiftJis sl@0: sl@0: EXPORT_C const TDesC8& CnvShiftJis::ReplacementForUnconvertibleUnicodeCharacters() sl@0: { sl@0: return KLit8ShiftJisReplacementForUnconvertibleUnicodeCharacters; sl@0: } sl@0: sl@0: EXPORT_C TInt CnvShiftJis::ConvertFromUnicode(CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, TDes8& aForeign, const TDesC16& aUnicode, CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters) sl@0: { sl@0: return DoConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, NULL); sl@0: } sl@0: sl@0: /** sl@0: * Converts text from Unicode to Shift-JIS (aArrayOfAdditionalCharacterSets provides support sl@0: * for Shift-JIS extensions) sl@0: * sl@0: * @since Internationalization_6.2 sl@0: */ sl@0: EXPORT_C TInt CnvShiftJis::ConvertFromUnicode(CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, TDes8& aForeign, const TDesC16& aUnicode, CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters, const TArray& aArrayOfAdditionalCharacterSets) sl@0: { sl@0: return DoConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, &aArrayOfAdditionalCharacterSets); sl@0: } sl@0: sl@0: EXPORT_C TInt CnvShiftJis::ConvertToUnicode( sl@0: CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, sl@0: TDes16& aUnicode, const TDesC8& aForeign, sl@0: TInt& aNumberOfUnconvertibleCharacters, sl@0: TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter) sl@0: { sl@0: // DummyData converts any pair of bytes into FFFD sl@0: static const SCnvConversionData::SVariableByteData::SRange sl@0: DummyByteLengths = {0, 255, 1, 0}; sl@0: static const SCnvConversionData::SOneDirectionData::SRange DummyConv = sl@0: { 0xFFFD, 0xFFFD, sl@0: SCnvConversionData::SOneDirectionData::SRange::EDirect, 2, 0 }; sl@0: static const SCnvConversionData DummyData = sl@0: { sl@0: SCnvConversionData::EFixedBigEndian, sl@0: {1, &DummyByteLengths}, sl@0: {1, &DummyConv}, sl@0: {1, &DummyConv} sl@0: }; sl@0: TFixedArray nullExtension; sl@0: // First extension converts unrecognised double byte characters to FFFD sl@0: nullExtension[0].iNumberOfBytesAbleToConvert sl@0: = BytesInOtherDoubleByteAreas; sl@0: nullExtension[0].iConvertToIntermediateBufferInPlace sl@0: = CnvShiftJis::DummyConvertToIntermediateBufferInPlace; sl@0: // This conversion data won't do anything for us: it will just get us sl@0: // a load of FFFD, which is what we want. sl@0: nullExtension[0].iConversionData = &DummyData; sl@0: nullExtension[0].iNumberOfBytesPerCharacter = 2; sl@0: nullExtension[0].iNumberOfCoreBytesPerCharacter = 2; sl@0: // Second extension converts any other single byte to FFFD, sl@0: // but only ever one! sl@0: nullExtension[1].iNumberOfBytesAbleToConvert sl@0: = OneIfNotValid; sl@0: nullExtension[1].iConvertToIntermediateBufferInPlace sl@0: = CnvShiftJis::DummyConvertToIntermediateBufferInPlace; sl@0: // This conversion data won't do anything for us: it will just get us sl@0: // a load of FFFD, which is what we want. sl@0: nullExtension[1].iConversionData = &CnvJisX0201::ConversionData(); sl@0: nullExtension[1].iNumberOfBytesPerCharacter = 1; sl@0: nullExtension[1].iNumberOfCoreBytesPerCharacter = 1; sl@0: const TArray nullExtensionArray = nullExtension.Array(); sl@0: return DoConvertToUnicode(aDefaultEndiannessOfForeignCharacters, sl@0: aUnicode, aForeign, aNumberOfUnconvertibleCharacters, sl@0: aIndexOfFirstByteOfFirstUnconvertibleCharacter, sl@0: &nullExtensionArray); sl@0: } sl@0: sl@0: /** sl@0: * Converts text from Shift-JIS to Unicode (aArrayOfAdditionalMethods provides support sl@0: * for Shift-JIS extensions) sl@0: * sl@0: * @since Internationalization_6.2 sl@0: */ sl@0: EXPORT_C TInt CnvShiftJis::ConvertToUnicode(CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, TDes16& aUnicode, const TDesC8& aForeign, TInt& aNumberOfUnconvertibleCharacters, TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter, const TArray& aArrayOfAdditionalMethods) sl@0: { sl@0: return DoConvertToUnicode(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, &aArrayOfAdditionalMethods); sl@0: } sl@0: sl@0: TInt CnvShiftJis::DoConvertFromUnicode( sl@0: CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, sl@0: const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, sl@0: TDes8& aForeign, const TDesC16& aUnicode, sl@0: CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters, sl@0: const TArray* aArrayOfAdditionalCharacterSets) sl@0: { sl@0: TCombinedArrayOfCharacterSets combinedArrayOfCharacterSets(aArrayOfAdditionalCharacterSets); sl@0: return CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, combinedArrayOfCharacterSets.Array()); sl@0: } sl@0: sl@0: TInt CnvShiftJis::DoConvertToUnicode( sl@0: CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, sl@0: TDes16& aUnicode, const TDesC8& aForeign, sl@0: TInt& aNumberOfUnconvertibleCharacters, sl@0: TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter, sl@0: const TArray* aArrayOfAdditionalMethods) sl@0: { sl@0: TCombinedArrayOfMethods combinedArrayOfMethods(aArrayOfAdditionalMethods); sl@0: TInt unconvert = CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign( sl@0: aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, sl@0: aNumberOfUnconvertibleCharacters, sl@0: aIndexOfFirstByteOfFirstUnconvertibleCharacter, sl@0: combinedArrayOfMethods.Array()); sl@0: sl@0: // The following is specific impelementation for brower. sl@0: // If brower app calls this API, the yen sign code(0xA5) sl@0: // must be converted to backslash code(0x5C). sl@0: // Becasue Javascript supports backslash code ony. sl@0: TBool browserProcess = (RProcess().SecureId().iId == KBrowserSecureId); sl@0: if (browserProcess && aUnicode.Length() > 0) sl@0: { sl@0: const TUint16* pB = aUnicode.Ptr(); sl@0: const TUint16* pbase = pB; sl@0: const TUint16* pE = pB + aUnicode.Length() -1; sl@0: while (pE>=pbase) sl@0: { sl@0: if (*pbase == KCharacterCodeForYenSign) sl@0: { sl@0: aUnicode[pbase - pB] = KCharacterCodeForBackSlash; sl@0: } sl@0: pbase++; sl@0: } sl@0: } sl@0: sl@0: return unconvert; sl@0: } sl@0: sl@0: void CnvShiftJis::DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut) sl@0: { sl@0: aNumberOfCharactersThatDroppedOut=0; sl@0: } sl@0: sl@0: void CnvShiftJis::ConvertFromJisX0208ToShiftJisInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) sl@0: { sl@0: aNumberOfCharactersThatDroppedOut=0; sl@0: const TInt descriptorLength=aDescriptor.Length(); sl@0: __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert1)); sl@0: __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes1)); sl@0: TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); sl@0: const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1); sl@0: pointerToCurrentByte+=aStartPositionInDescriptor; sl@0: FOREVER sl@0: { sl@0: TUint firstByte=*pointerToCurrentByte-0x21; sl@0: TUint secondByte=*(pointerToCurrentByte+1)-0x21; sl@0: if (firstByte%2!=0) sl@0: { sl@0: secondByte+=94; sl@0: } sl@0: firstByte/=2; sl@0: if (firstByte=pointerToLastByte) sl@0: { sl@0: break; sl@0: } sl@0: ++pointerToCurrentByte; sl@0: } sl@0: } sl@0: sl@0: TInt CnvShiftJis::NumberOfBytesAbleToConvertToJisX0201(const TDesC8& aDescriptor) sl@0: { sl@0: const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; sl@0: const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); sl@0: if (pointerToPreviousByte==pointerToLastByte) sl@0: { sl@0: return 0; sl@0: } sl@0: FOREVER sl@0: { sl@0: __ASSERT_DEBUG(pointerToPreviousByteKSingleByteRangeFirstBlockEnd) && (currentByteKSingleByteRangeSecondBlockEnd)) sl@0: { sl@0: break; sl@0: } sl@0: __ASSERT_DEBUG(pointerToPreviousByte=pointerToLastByte) sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: return (pointerToPreviousByte+1)-aDescriptor.Ptr(); sl@0: } sl@0: sl@0: TInt CnvShiftJis::NumberOfBytesAbleToConvertToJisX0208(const TDesC8& aDescriptor) sl@0: { sl@0: const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; sl@0: const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); sl@0: if (pointerToPreviousByte==pointerToLastByte) sl@0: { sl@0: return 0; sl@0: } sl@0: FOREVER sl@0: { sl@0: __ASSERT_DEBUG(pointerToPreviousByte=pointerToLastByte) sl@0: { sl@0: break; sl@0: } sl@0: __ASSERT_DEBUG(pointerToPreviousByte+2<=pointerToLastByte, Panic(EPanicBadPointers7)); sl@0: currentByte=*(pointerToPreviousByte+2); sl@0: if (!IsValidTrailByte(currentByte)) sl@0: { sl@0: break; sl@0: } sl@0: pointerToPreviousByte+=2; sl@0: __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers8)); sl@0: if (pointerToPreviousByte>=pointerToLastByte) sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: return (pointerToPreviousByte+1)-aDescriptor.Ptr(); sl@0: } sl@0: sl@0: void CnvShiftJis::DummyConvertToIntermediateBufferInPlace(TDes8&) sl@0: { sl@0: } sl@0: sl@0: void CnvShiftJis::ConvertToJisX0208FromShiftJisInPlace(TDes8& aDescriptor) sl@0: { sl@0: const TInt descriptorLength=aDescriptor.Length(); sl@0: __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert2)); sl@0: __ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes2)); sl@0: TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); sl@0: const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1); sl@0: FOREVER sl@0: { sl@0: TUint firstByte=*pointerToCurrentByte; sl@0: TUint secondByte=*(pointerToCurrentByte+1); sl@0: if (firstByte=94) sl@0: { sl@0: ++firstByte; sl@0: secondByte-=94; sl@0: } sl@0: firstByte+=0x21; sl@0: secondByte+=0x21; sl@0: *pointerToCurrentByte=STATIC_CAST(TUint8, firstByte); sl@0: ++pointerToCurrentByte; sl@0: *pointerToCurrentByte=STATIC_CAST(TUint8, secondByte); sl@0: __ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers9)); sl@0: if (pointerToCurrentByte>=pointerToLastByte) sl@0: { sl@0: break; sl@0: } sl@0: ++pointerToCurrentByte; sl@0: } sl@0: } sl@0: sl@0: TInt BytesInOtherDoubleByteAreas(const TDesC8& aShiftJis) sl@0: { sl@0: const TText8* start = aShiftJis.Ptr(); sl@0: const TText8* end = start + aShiftJis.Length() - 1; sl@0: const TText8* p = start; sl@0: while (p < end && IsOtherLeadByte(p[0]) && IsValidTrailByte(p[1])) sl@0: p += 2; sl@0: return p - start; sl@0: } sl@0: sl@0: TInt OneIfNotValid(const TDesC8& aShiftJis) sl@0: { sl@0: TInt length = aShiftJis.Length(); sl@0: if (length == 0) sl@0: return 0; sl@0: TInt c = aShiftJis[0]; sl@0: // If the next byte is not a lead byte, we can swallow it. The sl@0: // double-byte methods obviously can't be waiting for more sl@0: // information. sl@0: if (!IsOtherLeadByte(c) && !IsJisX0208LeadByte(c)) sl@0: return 1; sl@0: // Otherwise we have a lead byte. If it is on its own we cannot sl@0: // swallow it as the double-byte converters will be waiting for sl@0: // more information. If they have the information (i.e. if length > 1) sl@0: // then they have passed on it and we can swallow it. sl@0: return length == 1? 0 : 1; sl@0: }