os/textandloc/charconvfw/charconvplugins/src/plugins/EUCJP_PACKED_2.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 #include "PictographObserver.h"
    19 
    20 #include <e32std.h>
    21 #include <charconv.h>
    22 #include <convutils.h>
    23 #include "jisx0201.h"
    24 #include "jisx0208.h"
    25 #include "jisx0212.h"
    26 #include <ecom/implementationproxy.h>
    27 #include "charactersetconverter.h"
    28 #include "featmgr/featmgr.h" 
    29 
    30 const TUint KSingleShift2=0x8e;
    31 const TUint KSingleShift3=0x8f;
    32 
    33 // SecureID for Brower app
    34 const TUint32 KBrowserSecureId = 0x10008D39;
    35 // Define for converting from YenSign to BackSlash
    36 const TUint KCharacterCodeForYenSign = 0x00A5;
    37 const TUint KCharacterCodeForBackSlash = 0x005C;
    38 
    39 _LIT8(KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters, "\xa1\xa9"); // fullwidth question mark
    40 
    41 #if defined(_DEBUG)
    42 
    43 _LIT(KLitPanicText, "EUCJP_PACKED");
    44 
    45 enum TPanic
    46     {
    47     EPanicNothingToConvert1=1,
    48     EPanicNothingToConvert2,
    49     EPanicNothingToConvert3,
    50     EPanicNothingToConvert4,
    51     EPanicNothingToConvert5,
    52     EPanicNothingToConvert6,
    53     EPanicOddNumberOfBytes1,
    54     EPanicOddNumberOfBytes2,
    55     EPanicOddNumberOfBytes3,
    56     EPanicOddNumberOfBytes4,
    57     EPanicOddNumberOfBytes5,
    58     EPanicOddNumberOfBytes6,
    59     EPanicBadHighBit1,
    60     EPanicBadHighBit2,
    61     EPanicBadHighBit3,
    62     EPanicBadHighBit4,
    63     EPanicBadHighBit5,
    64     EPanicBadHighBit6,
    65     EPanicBadHighBit7,
    66     EPanicBadPointers1,
    67     EPanicBadPointers2,
    68     EPanicBadPointers3,
    69     EPanicBadPointers4,
    70     EPanicBadPointers5,
    71     EPanicBadPointers6,
    72     EPanicBadPointers7,
    73     EPanicBadPointers8,
    74     EPanicBadPointers9,
    75     EPanicBadPointers10,
    76     EPanicBadPointers11,
    77     EPanicBadPointers12,
    78     EPanicBadPointers13,
    79     EPanicBadPointers14,
    80     EPanicBadPointers15,
    81     EPanicBadPointers16,
    82     EPanicBadPointers17,
    83     EPanicBadPointers18,
    84     EPanicBadPointers19,
    85     EPanicBadPointers20,
    86     EPanicBadPointers21,
    87     EPanicBadPointers22,
    88     EPanicBadPointers23,
    89     EPanicBadPointers24,
    90     EPanicBadPointers25,
    91     EPanicBadPointers26,
    92     EPanicBadPointers27,
    93     EPanicBadPointers28,
    94     EPanicBadPointers29,
    95     EPanicBadPointers30,
    96     EPanicBadPointers31,
    97     EPanicBadPointers32,
    98     EPanicBadPointers33,
    99     EPanicBadPointers34,
   100     EPanicBadPointers35,
   101     EPanicBadPointers36,
   102     EPanicBadCalculation1,
   103     EPanicBadCalculation2,
   104     EPanicNumberOfBytesIsNotMultipleOfThree1,
   105     EPanicNumberOfBytesIsNotMultipleOfThree2,
   106     EPanicSingleShift2Expected,
   107     EPanicSingleShift3Expected
   108     };
   109 
   110 LOCAL_C void Panic(TPanic aPanic)
   111     {
   112     User::Panic(KLitPanicText, aPanic);
   113     }
   114 
   115 #endif
   116 
   117 
   118 class CEucjpPackedConverterImpl : public CCharacterSetConverterPluginInterface
   119     {
   120 
   121 public:
   122     virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
   123 
   124     virtual TInt ConvertFromUnicode(
   125         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
   126         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters,
   127         TDes8& aForeign,
   128         const TDesC16& aUnicode,
   129         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
   130 
   131     virtual TInt ConvertToUnicode(
   132         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
   133         TDes16& aUnicode,
   134         const TDesC8& aForeign,
   135         TInt& aState,
   136         TInt& aNumberOfUnconvertibleCharacters,
   137         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
   138 
   139     virtual TBool IsInThisCharacterSetL(
   140         TBool& aSetToTrue,
   141         TInt& aConfidenceLevel,
   142         const TDesC8& aSample);
   143 
   144     static CEucjpPackedConverterImpl* NewL();
   145     virtual ~CEucjpPackedConverterImpl();
   146 
   147 private:
   148     CEucjpPackedConverterImpl();
   149     void ConstructL();
   150 
   151     };
   152 
   153 
   154 
   155 
   156 
   157 const TDesC8& CEucjpPackedConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
   158     {
   159     return KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters;
   160     }
   161 
   162 LOCAL_C void DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut)
   163     {
   164     aNumberOfCharactersThatDroppedOut=0;
   165     }
   166 
   167 LOCAL_C void ConvertFromJisX0208ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
   168     {
   169     aNumberOfCharactersThatDroppedOut=0;
   170     const TInt descriptorLength=aDescriptor.Length();
   171     __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert1));
   172     __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes1));
   173     TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
   174     const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1);
   175     pointerToCurrentByte+=aStartPositionInDescriptor;
   176     FOREVER
   177         {
   178         const TUint currentByte=*pointerToCurrentByte;
   179         __ASSERT_DEBUG((currentByte&0x80)==0, Panic(EPanicBadHighBit1));
   180         *pointerToCurrentByte=STATIC_CAST(TUint8, currentByte|0x80);
   181         __ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers1));
   182         if (pointerToCurrentByte>=pointerToLastByte)
   183             {
   184             break;
   185             }
   186         ++pointerToCurrentByte;
   187         }
   188     }
   189 
   190 LOCAL_C void ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
   191     {
   192     TInt descriptorLength=aDescriptor.Length();
   193     __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert2));
   194     aNumberOfCharactersThatDroppedOut=Max(0, (descriptorLength-aStartPositionInDescriptor)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/2));
   195     descriptorLength-=aNumberOfCharactersThatDroppedOut;
   196     __ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation1));
   197     if (descriptorLength<=aStartPositionInDescriptor)
   198         {
   199         aDescriptor.SetLength(descriptorLength);
   200         }
   201     else
   202         {
   203         TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor
   204         const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor;
   205         const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1);
   206         descriptorLength=((descriptorLength-aStartPositionInDescriptor)*2)+aStartPositionInDescriptor;
   207         __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes2));
   208         aDescriptor.SetLength(descriptorLength);
   209         pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here
   210         FOREVER
   211             {
   212             *pointerToTargetByte=*pointerToSourceByte;
   213             __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers2));
   214             --pointerToTargetByte;
   215             *pointerToTargetByte=KSingleShift2;
   216             __ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers3));
   217             if (pointerToTargetByte<=pointerToFirstByte)
   218                 {
   219                 break;
   220                 }
   221             --pointerToTargetByte;
   222             __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers4));
   223             --pointerToSourceByte;
   224             }
   225         __ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers5));
   226         __ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers6));
   227         }
   228     }
   229 
   230 LOCAL_C void ConvertFromJisX0212ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
   231     {
   232     TInt descriptorLength=aDescriptor.Length();
   233     __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert3));
   234     __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes3));
   235     aNumberOfCharactersThatDroppedOut=Max(0, ((descriptorLength-aStartPositionInDescriptor)/2)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/3));
   236     descriptorLength-=aNumberOfCharactersThatDroppedOut*2;
   237     __ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation2));
   238     if (descriptorLength<=aStartPositionInDescriptor)
   239         {
   240         aDescriptor.SetLength(descriptorLength);
   241         }
   242     else
   243         {
   244         __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes4));
   245         TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor
   246         const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor;
   247         const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1);
   248         descriptorLength=(((descriptorLength-aStartPositionInDescriptor)*3)/2)+aStartPositionInDescriptor;
   249         __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree1));
   250         aDescriptor.SetLength(descriptorLength);
   251         pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here
   252         FOREVER
   253             {
   254             __ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit2));
   255             *pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80);
   256             __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers7));
   257             --pointerToTargetByte;
   258             __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers8));
   259             --pointerToSourceByte;
   260             __ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit3));
   261             *pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80);
   262             __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers9));
   263             --pointerToTargetByte;
   264             *pointerToTargetByte=KSingleShift3;
   265             __ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers10));
   266             if (pointerToTargetByte<=pointerToFirstByte)
   267                 {
   268                 break;
   269                 }
   270             --pointerToTargetByte;
   271             __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers11));
   272             --pointerToSourceByte;
   273             }
   274         __ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers12));
   275         __ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers13));
   276         }
   277     }
   278 
   279 TInt CEucjpPackedConverterImpl::ConvertFromUnicode(
   280         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
   281         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters,
   282         TDes8& aForeign,
   283         const TDesC16& aUnicode,
   284         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters)
   285     {
   286     TInt ret = KErrNone;
   287     RArray<CnvUtilities::SCharacterSet> characterSets;
   288     if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) )
   289         {      
   290         CnvUtilities::SCharacterSet characterSet;
   291 
   292         characterSet.iConversionData=&CnvJisRoman::ConversionData();
   293         characterSet.iConvertFromIntermediateBufferInPlace=DummyConvertFromIntermediateBufferInPlace;
   294         characterSet.iEscapeSequence=&KNullDesC8;
   295         ret |= characterSets.Append(characterSet);
   296         characterSet.iConversionData=&CnvJisX0208::ConversionData();
   297         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToEucJpPackedInPlace;
   298         characterSet.iEscapeSequence=&KNullDesC8;
   299         ret |= characterSets.Append(characterSet);
   300         characterSet.iConversionData=&CnvHalfWidthKatakana8::ConversionData();
   301         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace;
   302         characterSet.iEscapeSequence=&KNullDesC8;
   303         ret |= characterSets.Append(characterSet);
   304         characterSet.iConversionData=&CnvJisX0212::ConversionData();
   305         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0212ToEucJpPackedInPlace;
   306         characterSet.iEscapeSequence=&KNullDesC8;
   307         ret |= characterSets.Append(characterSet);
   308 
   309         SetCharacterSetsForPictograph(characterSets, ECharsetEucJp);
   310         }
   311     else
   312         {            
   313         CnvUtilities::SCharacterSet characterSet;
   314         characterSet.iConversionData=&CnvJisRoman::ConversionData();
   315         characterSet.iConvertFromIntermediateBufferInPlace=DummyConvertFromIntermediateBufferInPlace;
   316         characterSet.iEscapeSequence=&KNullDesC8;
   317         ret |= characterSets.Append(characterSet);
   318         characterSet.iConversionData=&CnvJisX0208::ConversionData();
   319         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToEucJpPackedInPlace;
   320         characterSet.iEscapeSequence=&KNullDesC8;
   321         ret |= characterSets.Append(characterSet);
   322         characterSet.iConversionData=&CnvHalfWidthKatakana8::ConversionData();
   323         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace;
   324         characterSet.iEscapeSequence=&KNullDesC8;
   325         ret |= characterSets.Append(characterSet);
   326         characterSet.iConversionData=&CnvJisX0212::ConversionData();
   327         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0212ToEucJpPackedInPlace;
   328         characterSet.iEscapeSequence=&KNullDesC8;
   329         ret |= characterSets.Append(characterSet);
   330         }
   331     __ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
   332     TInt unconvert = CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, characterSets.Array());
   333 
   334     characterSets.Close();
   335     return unconvert;
   336     }
   337 
   338 LOCAL_C TInt NumberOfBytesAbleToConvertToJisRoman(const TDesC8& aDescriptor)
   339     {
   340     const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
   341     const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
   342     if (pointerToPreviousByte==pointerToLastByte)
   343         {
   344         return 0;
   345         }
   346     FOREVER
   347         {
   348         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers14));
   349         const TUint currentByte=*(pointerToPreviousByte+1);
   350         if (currentByte&0x80)
   351             {
   352             break;
   353             }
   354         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers15));
   355         ++pointerToPreviousByte;
   356         __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers16));
   357         if (pointerToPreviousByte>=pointerToLastByte)
   358             {
   359             break;
   360             }
   361         }
   362     return (pointerToPreviousByte+1)-aDescriptor.Ptr();
   363     }
   364 
   365 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0208(const TDesC8& aDescriptor)
   366     {
   367     const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
   368     const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
   369     if (pointerToPreviousByte==pointerToLastByte)
   370         {
   371         return 0;
   372         }
   373     FOREVER
   374         {
   375         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers17));
   376         TUint currentByte=*(pointerToPreviousByte+1);
   377         if (currentByte<0xa0)
   378             {
   379             break;
   380             }
   381         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers18));
   382         if (pointerToLastByte-pointerToPreviousByte<2)
   383             {
   384             break;
   385             }
   386         ++pointerToPreviousByte;
   387         currentByte=*(pointerToPreviousByte+1);
   388         if (currentByte<0xa0)
   389             {
   390             return CCnvCharacterSetConverter::EErrorIllFormedInput;
   391             }
   392         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers19));
   393         ++pointerToPreviousByte;
   394         __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers20));
   395         if (pointerToPreviousByte>=pointerToLastByte)
   396             {
   397             break;
   398             }
   399         }
   400     return (pointerToPreviousByte+1)-aDescriptor.Ptr();
   401     }
   402 
   403 LOCAL_C TInt NumberOfBytesAbleToConvertToHalfWidthKatakana8(const TDesC8& aDescriptor)
   404     {
   405     const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
   406     const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
   407     if (pointerToPreviousByte==pointerToLastByte)
   408         {
   409         return 0;
   410         }
   411     FOREVER
   412         {
   413         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers21));
   414         TUint currentByte=*(pointerToPreviousByte+1);
   415         if (currentByte!=KSingleShift2)
   416             {
   417             break;
   418             }
   419         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers22));
   420         if (pointerToLastByte-pointerToPreviousByte<2)
   421             {
   422             break;
   423             }
   424         ++pointerToPreviousByte;
   425         currentByte=*(pointerToPreviousByte+1);
   426         if (currentByte<0xa0)
   427             {
   428             return CCnvCharacterSetConverter::EErrorIllFormedInput;
   429             }
   430         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers23));
   431         ++pointerToPreviousByte;
   432         __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers24));
   433         if (pointerToPreviousByte>=pointerToLastByte)
   434             {
   435             break;
   436             }
   437         }
   438     return (pointerToPreviousByte+1)-aDescriptor.Ptr();
   439     }
   440 
   441 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0212(const TDesC8& aDescriptor)
   442     {
   443     const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1;
   444     const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length();
   445     if (pointerToPreviousByte==pointerToLastByte)
   446         {
   447         return 0;
   448         }
   449     FOREVER
   450         {
   451         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers25));
   452         TUint currentByte=*(pointerToPreviousByte+1);
   453         if (currentByte!=KSingleShift3)
   454             {
   455             break;
   456             }
   457         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers26));
   458         if (pointerToLastByte-pointerToPreviousByte<3)
   459             {
   460             break;
   461             }
   462         ++pointerToPreviousByte;
   463         currentByte=*(pointerToPreviousByte+1);
   464         if (currentByte<0xa0)
   465             {
   466             return CCnvCharacterSetConverter::EErrorIllFormedInput;
   467             }
   468         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers27));
   469         ++pointerToPreviousByte;
   470         currentByte=*(pointerToPreviousByte+1);
   471         if (currentByte<0xa0)
   472             {
   473             return CCnvCharacterSetConverter::EErrorIllFormedInput;
   474             }
   475         __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers28));
   476         ++pointerToPreviousByte;
   477         __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers29));
   478         if (pointerToPreviousByte>=pointerToLastByte)
   479             {
   480             break;
   481             }
   482         }
   483     return (pointerToPreviousByte+1)-aDescriptor.Ptr();
   484     }
   485 
   486 LOCAL_C void DummyConvertToIntermediateBufferInPlace(TDes8&)
   487     {
   488     }
   489 
   490 LOCAL_C void ConvertToJisX0208FromEucJpPackedInPlace(TDes8& aDescriptor)
   491     {
   492     const TInt descriptorLength=aDescriptor.Length();
   493     __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert4));
   494     __ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes5));
   495     TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
   496     const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1);
   497     FOREVER
   498         {
   499         const TUint currentByte=*pointerToCurrentByte;
   500         __ASSERT_DEBUG(currentByte&0x80, Panic(EPanicBadHighBit4));
   501         *pointerToCurrentByte=STATIC_CAST(TUint8, currentByte&~0x80);
   502         __ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers30));
   503         if (pointerToCurrentByte>=pointerToLastByte)
   504             {
   505             break;
   506             }
   507         ++pointerToCurrentByte;
   508         }
   509     }
   510 
   511 LOCAL_C void ConvertToHalfWidthKatakana8FromEucJpPackedInPlace(TDes8& aDescriptor)
   512     {
   513     const TInt descriptorLength=aDescriptor.Length();
   514     __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert5));
   515     __ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes6));
   516     TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
   517     const TUint8* pointerToSourceByte=pointerToTargetByte;
   518     const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1);
   519     FOREVER
   520         {
   521         __ASSERT_DEBUG(*pointerToSourceByte==KSingleShift2, Panic(EPanicSingleShift2Expected));
   522         __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers31));
   523         ++pointerToSourceByte;
   524         const TUint sourceByte=*pointerToSourceByte;
   525         __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit5));
   526         *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte);
   527         __ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers32));
   528         if (pointerToSourceByte>=pointerToLastByte)
   529             {
   530             break;
   531             }
   532         ++pointerToSourceByte;
   533         ++pointerToTargetByte;
   534         }
   535     aDescriptor.SetLength(descriptorLength/2);
   536     }
   537 
   538 LOCAL_C void ConvertToJisX0212FromEucJpPackedInPlace(TDes8& aDescriptor)
   539     {
   540     const TInt descriptorLength=aDescriptor.Length();
   541     __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert6));
   542     __ASSERT_DEBUG(descriptorLength%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree2));
   543     TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr());
   544     const TUint8* pointerToSourceByte=pointerToTargetByte;
   545     const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1);
   546     FOREVER
   547         {
   548         __ASSERT_DEBUG(*pointerToSourceByte==KSingleShift3, Panic(EPanicSingleShift3Expected));
   549         __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers33));
   550         ++pointerToSourceByte;
   551         TUint sourceByte=*pointerToSourceByte;
   552         __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit6));
   553         *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80);
   554         __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers34));
   555         ++pointerToSourceByte;
   556         sourceByte=*pointerToSourceByte;
   557         __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit7));
   558         __ASSERT_DEBUG(pointerToTargetByte<pointerToLastByte, Panic(EPanicBadPointers35));
   559         ++pointerToTargetByte;
   560         *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80);
   561         __ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers36));
   562         if (pointerToSourceByte>=pointerToLastByte)
   563             {
   564             break;
   565             }
   566         ++pointerToSourceByte;
   567         ++pointerToTargetByte;
   568         }
   569     aDescriptor.SetLength((descriptorLength/3)*2);
   570     }
   571 
   572 TInt CEucjpPackedConverterImpl::ConvertToUnicode(
   573         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters,
   574         TDes16& aUnicode,
   575         const TDesC8& aForeign,
   576         TInt& /*aState*/,
   577         TInt& aNumberOfUnconvertibleCharacters,
   578         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter)
   579     {
   580     TInt ret =KErrNone;
   581     RArray<CnvUtilities::SMethod> methods;
   582     if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) )
   583         {      
   584         CnvUtilities::SMethod method;
   585         SetMethodsForPictograph(methods, ECharsetEucJp);
   586         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisRoman;
   587         method.iConvertToIntermediateBufferInPlace=DummyConvertToIntermediateBufferInPlace;
   588         method.iConversionData=&CnvJisRoman::ConversionData();
   589         method.iNumberOfBytesPerCharacter=1;
   590         method.iNumberOfCoreBytesPerCharacter=1;
   591         ret |= methods.Append(method);
   592         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0208;
   593         method.iConvertToIntermediateBufferInPlace=ConvertToJisX0208FromEucJpPackedInPlace;
   594         method.iConversionData=&CnvJisX0208::ConversionData();
   595         method.iNumberOfBytesPerCharacter=2;
   596         method.iNumberOfCoreBytesPerCharacter=2;
   597         ret |= methods.Append(method);
   598         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToHalfWidthKatakana8;
   599         method.iConvertToIntermediateBufferInPlace=ConvertToHalfWidthKatakana8FromEucJpPackedInPlace;
   600         method.iConversionData=&CnvHalfWidthKatakana8::ConversionData();
   601         method.iNumberOfBytesPerCharacter=2;
   602         method.iNumberOfCoreBytesPerCharacter=1;
   603         ret |= methods.Append(method);
   604         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0212;
   605         method.iConvertToIntermediateBufferInPlace=ConvertToJisX0212FromEucJpPackedInPlace;
   606         method.iConversionData=&CnvJisX0212::ConversionData();
   607         method.iNumberOfBytesPerCharacter=3;
   608         method.iNumberOfCoreBytesPerCharacter=2;
   609         ret |= methods.Append(method);
   610         }
   611     else
   612         {
   613         CnvUtilities::SMethod method;
   614         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisRoman;
   615         method.iConvertToIntermediateBufferInPlace=DummyConvertToIntermediateBufferInPlace;
   616         method.iConversionData=&CnvJisRoman::ConversionData();
   617         method.iNumberOfBytesPerCharacter=1;
   618         method.iNumberOfCoreBytesPerCharacter=1;
   619         ret |= methods.Append(method);
   620         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0208;
   621         method.iConvertToIntermediateBufferInPlace=ConvertToJisX0208FromEucJpPackedInPlace;
   622         method.iConversionData=&CnvJisX0208::ConversionData();
   623         method.iNumberOfBytesPerCharacter=2;
   624         method.iNumberOfCoreBytesPerCharacter=2;
   625         ret |= methods.Append(method);
   626         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToHalfWidthKatakana8;
   627         method.iConvertToIntermediateBufferInPlace=ConvertToHalfWidthKatakana8FromEucJpPackedInPlace;
   628         method.iConversionData=&CnvHalfWidthKatakana8::ConversionData();
   629         method.iNumberOfBytesPerCharacter=2;
   630         method.iNumberOfCoreBytesPerCharacter=1;
   631         ret |= methods.Append(method);
   632         method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0212;
   633         method.iConvertToIntermediateBufferInPlace=ConvertToJisX0212FromEucJpPackedInPlace;
   634         method.iConversionData=&CnvJisX0212::ConversionData();
   635         method.iNumberOfBytesPerCharacter=3;
   636         method.iNumberOfCoreBytesPerCharacter=2;
   637         ret |= methods.Append(method);
   638         }
   639     __ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
   640     TInt unconvert = CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array());
   641 
   642     // The following is specific impelementation for brower.
   643     // If brower app calls this API, the yen sign code(0xA5)
   644     // must be converted to backslash code(0x5C).
   645     // Becasue Javascript supports backslash code ony.
   646     TBool browserProcess = (RProcess().SecureId().iId == KBrowserSecureId);
   647     if (browserProcess && aUnicode.Length() > 0)
   648         {
   649         const TUint16* pB = aUnicode.Ptr();
   650         const TUint16* pbase = pB;
   651         const TUint16* pE = pB + aUnicode.Length() -1;
   652         while (pE>=pbase)
   653             {
   654             if (*pbase == KCharacterCodeForYenSign)
   655                 {
   656                 aUnicode[pbase - pB] = KCharacterCodeForBackSlash;
   657                 }
   658             pbase++;
   659             }
   660         }
   661 
   662     methods.Close();
   663     return unconvert;
   664     }
   665 
   666 TBool CEucjpPackedConverterImpl::IsInThisCharacterSetL(
   667         TBool& aSetToTrue,
   668         TInt& aConfidenceLevel,
   669         const TDesC8& aSample)
   670     {
   671     aSetToTrue=ETrue;
   672     // check for the SS2 and SS3 which specifies Code Set 2 & 3 respectively from the Code space
   673     // between 00-7f only... then ambiguous
   674     aSetToTrue = ETrue;
   675     TInt sampleLength = aSample.Length();
   676     TInt eucjpPacked = 0;
   677     aConfidenceLevel = 0;
   678 
   679     for (TInt i = 0; i < sampleLength; ++i)
   680         {
   681         // Code set 1 JISX 0208 support
   682         TInt increment1 = i+1;
   683         if (increment1 >= sampleLength)
   684             break;
   685         if (((aSample[i] >= 0xa1) && (aSample[i] <= 0xfe)) &&
   686             ((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe)))
   687             {
   688             eucjpPacked = eucjpPacked +2;
   689             i++;
   690             }
   691         // Single Shift 2 (SS2) sequence - Code Set 2
   692         if (aSample[i]==0x8e)
   693             {
   694             TInt increment1 = i+1;
   695             if (increment1 >= sampleLength)
   696                 break;
   697             if ((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xdf))
   698                 {
   699                 eucjpPacked = eucjpPacked+2;
   700                 i++;
   701                 }
   702             else
   703                 {
   704                 eucjpPacked = 0;
   705                 break;
   706                 }
   707             }
   708         // Single Shift 3 (SS3) sequence - Code Set 3
   709         if (aSample[i]==0x8f)
   710             {
   711             TInt increment1 = i+1;
   712             TInt increment2 = i+2;
   713             if ((increment1 >= sampleLength) || (increment2 >= sampleLength))
   714                 break;
   715             if (((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe)) &&
   716                 ((aSample[increment2] >= 0xa1) && (aSample[increment2] <= 0xfe)))
   717                 {
   718                 eucjpPacked = eucjpPacked +3;
   719                 i+=2;
   720                 }
   721             else
   722                 {
   723                 eucjpPacked =0;
   724                 break;
   725                 }
   726             }
   727         }
   728     if (eucjpPacked)
   729         aConfidenceLevel = (eucjpPacked*100)/sampleLength;
   730     else
   731         aConfidenceLevel = 0;
   732     aConfidenceLevel=(aConfidenceLevel >100)?100:aConfidenceLevel;
   733     return ETrue;
   734     }
   735 
   736 CEucjpPackedConverterImpl* CEucjpPackedConverterImpl::NewL()
   737     {
   738     CEucjpPackedConverterImpl* self = new(ELeave) CEucjpPackedConverterImpl();
   739     CleanupStack::PushL(self);
   740     self->ConstructL();
   741     CleanupStack::Pop(self);
   742     return self;
   743     }
   744 
   745 CEucjpPackedConverterImpl::~CEucjpPackedConverterImpl()
   746     {
   747     FeatureManager::UnInitializeLib();    
   748     }
   749 
   750 CEucjpPackedConverterImpl::CEucjpPackedConverterImpl()
   751     {
   752     }
   753 
   754 void CEucjpPackedConverterImpl::ConstructL()
   755     {
   756     FeatureManager::InitializeLibL();
   757     }
   758 
   759 const TImplementationProxy ImplementationTable[] =
   760     {
   761 #ifdef S60_TEST
   762     IMPLEMENTATION_PROXY_ENTRY(0x01000005,CEucjpPackedConverterImpl::NewL)
   763 #else
   764     IMPLEMENTATION_PROXY_ENTRY(0x10006067,CEucjpPackedConverterImpl::NewL)
   765 #endif
   766     };
   767 
   768 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
   769     {
   770     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
   771 
   772     return ImplementationTable;
   773     }
   774