os/textandloc/charconvfw/charconvplugins/src/plugins/ISO2022JP_2.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 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 #include "featmgr/featmgr.h" 
    20 
    21 #include <e32std.h>
    22 #include <charconv.h>
    23 #include <convutils.h>
    24 #include "jisbase.h"
    25 #include "jisx0201.h"
    26 #include "jisx0208.h"
    27 #include <ecom/implementationproxy.h>
    28 #include "charactersetconverter.h"
    29 
    30 
    31 _LIT8(KLit8EscapeSequenceForJisRoman, "\x1b\x28\x4a");
    32 _LIT8(KLit8EscapeSequenceForAscii, "\x1b\x28\x42");     
    33 _LIT8(KLit8EscapeSequenceForJisX0208_1983, "\x1b\x24\x42");
    34 //_LIT8(KLit8EscapeSequenceForJisC6226_1978, "\x1b\x24\x40");
    35 //_LIT8(KLit8EscapeSequenceForJisX0212_1990, "\x1b\x24\x28\x44"); 
    36 //_LIT8(KLit8EscapeSequenceForHalfWidthKatakana, "\x1b\x28\x49");
    37 _LIT8(KLit8Iso2022JpReplacementForUnconvertibleUnicodeCharacters, "\x1b\x24\x42\x21\x29"); // fullwidth question mark
    38 
    39 
    40 class CISO2022JPConverterImpl : public CCharacterSetConverterPluginInterface
    41     {
    42 
    43 public:
    44     virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
    45 
    46     virtual TInt ConvertFromUnicode(
    47         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
    48         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
    49         TDes8& aForeign, 
    50         const TDesC16& aUnicode, 
    51         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
    52 
    53     virtual TInt ConvertToUnicode(
    54         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
    55         TDes16& aUnicode, 
    56         const TDesC8& aForeign, 
    57         TInt& aState, 
    58         TInt& aNumberOfUnconvertibleCharacters, 
    59         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
    60 
    61     virtual TBool IsInThisCharacterSetL(
    62         TBool& aSetToTrue, 
    63         TInt& aConfidenceLevel, 
    64         const TDesC8& aSample);
    65 
    66     static CISO2022JPConverterImpl* NewL();
    67     virtual ~CISO2022JPConverterImpl();
    68 
    69 private:
    70     CISO2022JPConverterImpl();
    71     void ConstructL();
    72 
    73     };
    74 
    75 
    76 
    77 const TDesC8& CISO2022JPConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
    78     {
    79     return KLit8Iso2022JpReplacementForUnconvertibleUnicodeCharacters;
    80     }
    81 
    82 LOCAL_C void ConvertFromJisRomanToJisInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
    83     {
    84     CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KLit8EscapeSequenceForJisRoman, 1);
    85     }
    86 
    87 LOCAL_C void ConvertFromAsciiToJisInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
    88     {
    89     CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KLit8EscapeSequenceForAscii, 1);
    90     }
    91 
    92 LOCAL_C void ConvertFromJisX0208ToJisInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
    93     {
    94     CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KLit8EscapeSequenceForJisX0208_1983, 2);
    95     }
    96 
    97 struct TConvTblFromHalfKanaToFullKana
    98     {
    99     TUint8  iHalfKana;
   100     TUint8  iHalfKanaMark;
   101     TUint16 iFullKana;
   102     };
   103 
   104 LOCAL_D const TConvTblFromHalfKanaToFullKana convTblFromHalfKanaToFullKana[]=
   105     {
   106         { 0xA1, 0x00, 0x2123 },     // IDEOGRAPHIC FULL STOP
   107         { 0xA2, 0x00, 0x2156 },     // LEFT CORNER BRACKET
   108         { 0xA3, 0x00, 0x2157 },     // RIGHT CORNER BRACKET
   109         { 0xA4, 0x00, 0x2122 },     // IDEOGRAPHIC COMMA
   110         { 0xA5, 0x00, 0x2126 },     // KATAKANA MIDDLE DOT
   111         { 0xA6, 0x00, 0x2572 },     // KATAKANA LETTER WO
   112         { 0xA7, 0x00, 0x2521 },     // KATAKANA LETTER SMALL A
   113         { 0xA8, 0x00, 0x2523 },     // KATAKANA LETTER SMALL I
   114         { 0xA9, 0x00, 0x2525 },     // KATAKANA LETTER SMALL U
   115         { 0xAA, 0x00, 0x2527 },     // KATAKANA LETTER SMALL E
   116         { 0xAB, 0x00, 0x2529 },     // KATAKANA LETTER SMALL O
   117         { 0xAC, 0x00, 0x2563 },     // KATAKANA LETTER SMALL YA
   118         { 0xAD, 0x00, 0x2565 },     // KATAKANA LETTER SMALL YU
   119         { 0xAE, 0x00, 0x2567 },     // KATAKANA LETTER SMALL YO
   120         { 0xAF, 0x00, 0x2543 },     // KATAKANA LETTER SMALL TU
   121         { 0xB0, 0x00, 0x213C },     // KATAKANA-HIRAGANA PROLONGED SOUND MARK
   122         { 0xB1, 0x00, 0x2522 },     // KATAKANA LETTER A
   123         { 0xB2, 0x00, 0x2524 },     // KATAKANA LETTER I
   124         { 0xB3, 0x00, 0x2526 },     // KATAKANA LETTER U
   125         { 0xB3, 0xDE, 0x2574 },     // KATAKANA LETTER VU
   126         { 0xB4, 0x00, 0x2528 },     // KATAKANA LETTER E
   127         { 0xB5, 0x00, 0x252A },     // KATAKANA LETTER O
   128         { 0xB6, 0x00, 0x252B },     // KATAKANA LETTER KA
   129         { 0xB6, 0xDE, 0x252C },     // KATAKANA LETTER GA
   130         { 0xB7, 0x00, 0x252D },     // KATAKANA LETTER KI
   131         { 0xB7, 0xDE, 0x252E },     // KATAKANA LETTER GI
   132         { 0xB8, 0x00, 0x252F },     // KATAKANA LETTER KU
   133         { 0xB8, 0xDE, 0x2530 },     // KATAKANA LETTER GU
   134         { 0xB9, 0x00, 0x2531 },     // KATAKANA LETTER KE
   135         { 0xB9, 0xDE, 0x2532 },     // KATAKANA LETTER GE
   136         { 0xBA, 0x00, 0x2533 },     // KATAKANA LETTER KO
   137         { 0xBA, 0xDE, 0x2534 },     // KATAKANA LETTER GO
   138         { 0xBB, 0x00, 0x2535 },     // KATAKANA LETTER SA
   139         { 0xBB, 0xDE, 0x2536 },     // KATAKANA LETTER ZA
   140         { 0xBC, 0x00, 0x2537 },     // KATAKANA LETTER SI
   141         { 0xBC, 0xDE, 0x2538 },     // KATAKANA LETTER ZI
   142         { 0xBD, 0x00, 0x2539 },     // KATAKANA LETTER SU
   143         { 0xBD, 0xDE, 0x253A },     // KATAKANA LETTER ZU
   144         { 0xBE, 0x00, 0x253B },     // KATAKANA LETTER SE
   145         { 0xBE, 0xDE, 0x253C },     // KATAKANA LETTER ZE
   146         { 0xBF, 0x00, 0x253D },     // KATAKANA LETTER SO
   147         { 0xBF, 0xDE, 0x253E },     // KATAKANA LETTER ZO
   148         { 0xC0, 0x00, 0x253F },     // KATAKANA LETTER TA
   149         { 0xC0, 0xDE, 0x2540 },     // KATAKANA LETTER DA
   150         { 0xC1, 0x00, 0x2541 },     // KATAKANA LETTER TI
   151         { 0xC1, 0xDE, 0x2542 },     // KATAKANA LETTER DI
   152         { 0xC2, 0x00, 0x2544 },     // KATAKANA LETTER TU
   153         { 0xC2, 0xDE, 0x2545 },     // KATAKANA LETTER DU
   154         { 0xC3, 0x00, 0x2546 },     // KATAKANA LETTER TE
   155         { 0xC3, 0xDE, 0x2547 },     // KATAKANA LETTER DE
   156         { 0xC4, 0x00, 0x2548 },     // KATAKANA LETTER TO
   157         { 0xC4, 0xDE, 0x2549 },     // KATAKANA LETTER DO
   158         { 0xC5, 0x00, 0x254A },     // KATAKANA LETTER NA
   159         { 0xC6, 0x00, 0x254B },     // KATAKANA LETTER NI
   160         { 0xC7, 0x00, 0x254C },     // KATAKANA LETTER NU
   161         { 0xC8, 0x00, 0x254D },     // KATAKANA LETTER NE
   162         { 0xC9, 0x00, 0x254E },     // KATAKANA LETTER NO
   163         { 0xCA, 0x00, 0x254F },     // KATAKANA LETTER HA
   164         { 0xCA, 0xDE, 0x2550 },     // KATAKANA LETTER BA
   165         { 0xCA, 0xDF, 0x2551 },     // KATAKANA LETTER PA
   166         { 0xCB, 0x00, 0x2552 },     // KATAKANA LETTER HI
   167         { 0xCB, 0xDE, 0x2553 },     // KATAKANA LETTER BI
   168         { 0xCB, 0xDF, 0x2554 },     // KATAKANA LETTER PI
   169         { 0xCC, 0x00, 0x2555 },     // KATAKANA LETTER HU
   170         { 0xCC, 0xDE, 0x2556 },     // KATAKANA LETTER BU
   171         { 0xCC, 0xDF, 0x2557 },     // KATAKANA LETTER PU
   172         { 0xCD, 0x00, 0x2558 },     // KATAKANA LETTER HE
   173         { 0xCD, 0xDE, 0x2559 },     // KATAKANA LETTER BE
   174         { 0xCD, 0xDF, 0x255A },     // KATAKANA LETTER PE
   175         { 0xCE, 0x00, 0x255B },     // KATAKANA LETTER HO
   176         { 0xCE, 0xDE, 0x255C },     // KATAKANA LETTER BO
   177         { 0xCE, 0xDF, 0x255D },     // KATAKANA LETTER PO
   178         { 0xCF, 0x00, 0x255E },     // KATAKANA LETTER MA
   179         { 0xD0, 0x00, 0x255F },     // KATAKANA LETTER MI
   180         { 0xD1, 0x00, 0x2560 },     // KATAKANA LETTER MU
   181         { 0xD2, 0x00, 0x2561 },     // KATAKANA LETTER ME
   182         { 0xD3, 0x00, 0x2562 },     // KATAKANA LETTER MO
   183         { 0xD4, 0x00, 0x2564 },     // KATAKANA LETTER YA
   184         { 0xD5, 0x00, 0x2566 },     // KATAKANA LETTER YU
   185         { 0xD6, 0x00, 0x2568 },     // KATAKANA LETTER YO
   186         { 0xD7, 0x00, 0x2569 },     // KATAKANA LETTER RA
   187         { 0xD8, 0x00, 0x256A },     // KATAKANA LETTER RI
   188         { 0xD9, 0x00, 0x256B },     // KATAKANA LETTER RU
   189         { 0xDA, 0x00, 0x256C },     // KATAKANA LETTER RE
   190         { 0xDB, 0x00, 0x256D },     // KATAKANA LETTER RO
   191         { 0xDC, 0x00, 0x256F },     // KATAKANA LETTER WA
   192         { 0xDD, 0x00, 0x2573 },     // KATAKANA LETTER N
   193         { 0xDE, 0x00, 0x212B },     // HALFWIDTH KATAKANA VOICED SOUND MARK
   194         { 0xDF, 0x00, 0x212C }      // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
   195     };
   196 #define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
   197 
   198 LOCAL_C void ConvertFromHalfKatakanaToFullKatakana(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut)
   199     {
   200     // half-width Katakana is 1-byte, but full-width Katakana is 2-bytes.
   201     TInt convertlength = aDescriptor.Length()-aStartPositionInDescriptor;
   202     TInt numberOfMarkChar = 0;
   203     HBufC8* hBuf = HBufC8::New(convertlength*2);
   204     if (hBuf)
   205         {
   206         TPtr8 ptr = hBuf->Des();
   207         for (TInt i=aStartPositionInDescriptor; i < aDescriptor.Length(); i++)
   208             {
   209             const TUint8 convchar = (TUint8)(aDescriptor[i]|0x80);
   210             const TUint8 convnextchar = (TUint8)((aDescriptor.Length() > (i+1))?
   211                         (aDescriptor[i+1]|0x80) : TUint8(0x00));
   212             const TConvTblFromHalfKanaToFullKana* curTbl = &(convTblFromHalfKanaToFullKana[0]);
   213             for (TUint j=0; j < ARRAY_LENGTH(convTblFromHalfKanaToFullKana); curTbl++, j++)
   214                 {
   215                 if (convchar == curTbl->iHalfKana)
   216                     {
   217                     for (TInt k=0; (convchar == (curTbl+k)->iHalfKana); k++)
   218                         {
   219                         if (convnextchar == (curTbl+k)->iHalfKanaMark)
   220                             {
   221                             curTbl += k;
   222                             if (convnextchar == 0xDE || convnextchar == 0xDF)
   223                                 {
   224                                 i++;
   225                                 numberOfMarkChar++;
   226                                 }
   227                             break;
   228                             }
   229                         }
   230                     // set to buffer each 8 bit
   231                     const TUint8 highbit = (TUint8)(curTbl->iFullKana>>8);
   232                     const TUint8 lowbit = (TUint8)(curTbl->iFullKana|0xff00);
   233                     ptr.Append(highbit);
   234                     ptr.Append(lowbit);
   235                     break;
   236                     }
   237                 }
   238             }
   239         // add ESC code
   240         CnvUtilities::ConvertFromIntermediateBufferInPlace(
   241                             aStartPositionInDescriptor, 
   242                             aDescriptor, aNumberOfCharactersThatDroppedOut, 
   243                             KLit8EscapeSequenceForJisX0208_1983, 1);
   244         if (!aNumberOfCharactersThatDroppedOut)
   245             {
   246             // delete half-width katakana
   247             aDescriptor.Delete(aStartPositionInDescriptor 
   248                                 + KLit8EscapeSequenceForJisX0208_1983().Length(),
   249                                convertlength);
   250 
   251             TInt freelength = aDescriptor.MaxLength() - aDescriptor.Length();
   252             TInt copylength = ptr.Length();
   253             if (copylength > freelength)
   254                 {
   255                 copylength = freelength - (freelength%2);
   256                 }
   257             if (copylength > 0)
   258                 {
   259                 // not convert, because there is no enough buffer
   260                 aDescriptor.Append(ptr.Ptr(), copylength);
   261                 aNumberOfCharactersThatDroppedOut=(convertlength-numberOfMarkChar) - (copylength/2);
   262                 }
   263             else
   264                 {
   265                 // not convert, because there is no enough buffer.
   266                 aNumberOfCharactersThatDroppedOut=convertlength;
   267                 aDescriptor.SetLength(aStartPositionInDescriptor);
   268                 }
   269             }
   270         delete hBuf;
   271         }
   272     else
   273         {
   274         // not convert, because there is no heap area.
   275         aNumberOfCharactersThatDroppedOut=convertlength;
   276         aDescriptor.SetLength(aStartPositionInDescriptor);
   277         }
   278     }
   279 
   280 TInt CISO2022JPConverterImpl::ConvertFromUnicode(
   281         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
   282         const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
   283         TDes8& aForeign, 
   284         const TDesC16& aUnicode, 
   285         CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters)
   286     {
   287     TInt ret = KErrNone;
   288     RArray<CnvUtilities::SCharacterSet> characterSets;
   289     if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) )
   290         {        
   291         CnvUtilities::SCharacterSet characterSet;
   292         characterSet.iConversionData=&CnvJisRoman::ConversionData();
   293         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisRomanToJisInPlace;
   294         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisRoman;
   295         ret |= characterSets.Append(characterSet);
   296         characterSet.iConversionData=&CCnvCharacterSetConverter::AsciiConversionData();
   297         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromAsciiToJisInPlace;
   298         characterSet.iEscapeSequence=&KLit8EscapeSequenceForAscii;
   299         ret |= characterSets.Append(characterSet);
   300         characterSet.iConversionData=&CnvJisX0208::ConversionData();
   301         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToJisInPlace;
   302         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisX0208_1983;
   303         ret |= characterSets.Append(characterSet);
   304         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisX0208_1983;
   305         characterSet.iConversionData=&CnvJisBase::HalfWidthKatakana7ConversionData();
   306         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfKatakanaToFullKatakana;
   307         ret |= characterSets.Append(characterSet);
   308 
   309         SetCharacterSetsForPictograph(characterSets);
   310         }
   311     else
   312         {            
   313         CnvUtilities::SCharacterSet characterSet;
   314         characterSet.iConversionData=&CCnvCharacterSetConverter::AsciiConversionData();
   315         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromAsciiToJisInPlace;
   316         characterSet.iEscapeSequence=&KLit8EscapeSequenceForAscii;
   317         ret |= characterSets.Append(characterSet);
   318         characterSet.iConversionData=&CnvJisRoman::ConversionData();
   319         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisRomanToJisInPlace;
   320         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisRoman;
   321         ret |= characterSets.Append(characterSet);
   322         characterSet.iConversionData=&CnvJisX0208::ConversionData();
   323         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToJisInPlace;
   324         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisX0208_1983;
   325         ret |= characterSets.Append(characterSet);
   326         characterSet.iEscapeSequence=&KLit8EscapeSequenceForJisX0208_1983;
   327         characterSet.iConversionData=&CnvJisBase::HalfWidthKatakana7ConversionData();
   328         characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfKatakanaToFullKatakana;
   329         ret |= characterSets.Append(characterSet);
   330         }
   331     __ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
   332     TUint notUsed;
   333 //S60 30    TUint inputConversionFlags=CCnvCharacterSetConverter::EInputConversionFlagMustEndInDefaultCharacterSet;
   334     TUint inputConversionFlags=CCnvCharacterSetConverter::EInputConversionFlagMustEndInDefaultCharacterSet |
   335                                CCnvCharacterSetConverter::EInputConversionFlagAssumeStartInDefaultCharacterSet;
   336     TInt unconvert = CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters,
   337                                                       aReplacementForUnconvertibleUnicodeCharacters, 
   338                                                       aForeign, 
   339                                                       aUnicode, 
   340                                                       aIndicesOfUnconvertibleCharacters, 
   341                                                       characterSets.Array(),
   342                                                       notUsed,
   343                                                       inputConversionFlags);
   344         
   345     characterSets.Close();
   346 
   347     return unconvert;
   348     }
   349 
   350 
   351 TInt CISO2022JPConverterImpl::ConvertToUnicode(
   352         CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
   353         TDes16& aUnicode, 
   354         const TDesC8& aForeign, 
   355         TInt& aState, 
   356         TInt& aNumberOfUnconvertibleCharacters, 
   357         TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter)
   358     {
   359     return CnvJisBase::ConvertToUnicode(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aState, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter);
   360     }
   361 
   362 TBool CISO2022JPConverterImpl::IsInThisCharacterSetL(
   363         TBool& aSetToTrue, 
   364         TInt& aConfidenceLevel, 
   365         const TDesC8& aSample)
   366     {
   367     aSetToTrue=ETrue;
   368     CnvJisBase::IsCharacterJISBased(aConfidenceLevel, aSample);
   369     return ETrue;
   370     }
   371 
   372 CISO2022JPConverterImpl* CISO2022JPConverterImpl::NewL()
   373     {
   374     CISO2022JPConverterImpl* self = new(ELeave) CISO2022JPConverterImpl();
   375     CleanupStack::PushL(self);
   376     self->ConstructL();
   377     CleanupStack::Pop(self);
   378     return self;
   379     }
   380 
   381 CISO2022JPConverterImpl::~CISO2022JPConverterImpl()
   382     {
   383     FeatureManager::UnInitializeLib();
   384     }
   385 
   386 CISO2022JPConverterImpl::CISO2022JPConverterImpl()
   387     {
   388     }
   389 
   390 void CISO2022JPConverterImpl::ConstructL()
   391     {
   392     FeatureManager::InitializeLibL();
   393     }
   394 
   395 const TImplementationProxy ImplementationTable[] = 
   396     {
   397 #ifdef S60_TEST
   398     IMPLEMENTATION_PROXY_ENTRY(0x01000006,  CISO2022JPConverterImpl::NewL)
   399 #else
   400     IMPLEMENTATION_PROXY_ENTRY(0x100066A0,  CISO2022JPConverterImpl::NewL)
   401 #endif        
   402     };
   403 
   404 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
   405     {
   406     aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
   407 
   408     return ImplementationTable;
   409     }
   410