fep/aknfep/src/AknFepZhuyinAnalyser.cpp
changeset 36 a7632c26d895
parent 35 0f326f2e628e
child 42 b3eaa440ab06
equal deleted inserted replaced
35:0f326f2e628e 36:a7632c26d895
     1 /*
       
     2 * Copyright (c) 2002-2005 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:            Implementation of the vkb data manager
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 
       
    28 
       
    29 // system includes
       
    30 
       
    31 
       
    32 // user includes
       
    33 #include "AknFepZhuyinAnalyser.h"
       
    34 #include "AknFepZhuyinAnalyserDb.h"
       
    35 
       
    36 class TSpellBand
       
    37     {
       
    38 public:
       
    39     int iStart;
       
    40     int iCount;
       
    41     };
       
    42 
       
    43 class TSpellAnalysis : public TPriQueLink
       
    44     {
       
    45 public:
       
    46     RArray<TInt> iSeparators;
       
    47     TSpellAnalysis( )
       
    48         {
       
    49         iPriority = -0x10000;
       
    50         }
       
    51     ~TSpellAnalysis( )
       
    52         {
       
    53         iSeparators.Close( );
       
    54         }
       
    55 
       
    56     TSpellAnalysis( const TSpellAnalysis& aSource )
       
    57         {
       
    58         iPriority = aSource.iPriority;
       
    59         for (TInt i = 0; i < aSource.iSeparators.Count( ); ++i )
       
    60             {
       
    61             iSeparators.Append( aSource.iSeparators[i] );
       
    62             }
       
    63         }
       
    64     void Calculate( )
       
    65         {
       
    66         iPriority = (iSeparators.Count() + 1) << 16;
       
    67         TInt multi = 12;
       
    68         for (TInt i = 0; i < iSeparators.Count(); ++i )
       
    69             {
       
    70             iPriority += ( 6 - iSeparators[i]) << multi;
       
    71             if ( multi >= 3 )
       
    72                 {
       
    73                 multi -= 3;
       
    74                 }
       
    75             }
       
    76         iPriority = -iPriority;
       
    77         }
       
    78     TInt GetStartPos( )
       
    79         {
       
    80         if ( iSeparators.Count() == 0 )
       
    81             {
       
    82             return 0;
       
    83             }
       
    84         else
       
    85             {
       
    86             return iSeparators[ iSeparators.Count() - 1 ];
       
    87             }
       
    88         }
       
    89     void AddSeparator( TInt aPos )
       
    90         {
       
    91         iSeparators.Append( aPos );
       
    92         Calculate( );
       
    93         }
       
    94     };
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // CAknFepVkbPinyinAnalyser::CAknFepVkbPinyinAnalyser
       
    98 // (other items were commented in a header).
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 CAknFepZhuyinAnalyser::CAknFepZhuyinAnalyser( )
       
   102     {
       
   103     iAnalysisFlag = EFalse;
       
   104     }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CAknFepVkbPinyinAnalyser::NewL
       
   108 // (other items were commented in a header).
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 CAknFepZhuyinAnalyser* CAknFepZhuyinAnalyser::NewL( CZhuyinAnalyserDbFeed* aDb )
       
   112     {
       
   113     CAknFepZhuyinAnalyser* self = new ( ELeave ) CAknFepZhuyinAnalyser();
       
   114     CleanupStack::PushL( self );
       
   115     self->ConstructL( aDb );
       
   116     CleanupStack::Pop( self );
       
   117     return self;
       
   118     }
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 // CAknFepVkbPinyinAnalyser::~CAknFepVkbPinyinAnalyser
       
   122 // (other items were commented in a header).
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 CAknFepZhuyinAnalyser::~CAknFepZhuyinAnalyser( )
       
   126     {
       
   127     delete []iParagraph;
       
   128     delete []iSpellLibrary;
       
   129     delete iLastResult;
       
   130     delete iDb;
       
   131     }
       
   132 
       
   133 void CAknFepZhuyinAnalyser::ConstructL( CZhuyinAnalyserDbFeed* aDb )
       
   134     {
       
   135     ASSERT( aDb != NULL );
       
   136     iDb = aDb;
       
   137 
       
   138     TInt length = iDb->GetSpellCount( );
       
   139 
       
   140     iSpellLibrary = new(ELeave) TPtrC[length];
       
   141     for (TInt i = 0; i < length; ++i )
       
   142         {
       
   143         iSpellLibrary[i].Set( aDb->GetSpellByIndex( i ) );
       
   144         }
       
   145 
       
   146     TInt current = 0;
       
   147     TInt pinyinElementCount = iDb->GetSpellElementCount( );
       
   148     iParagraph = new(ELeave) TSpellBand[pinyinElementCount];
       
   149     iParagraph[current].iStart = 0;
       
   150     for (TInt i = 0; i < length; ++i )
       
   151         {
       
   152         if ( iSpellLibrary[i][0] != iDb->GetSpellElementByIndex( current ) )
       
   153             {
       
   154             iParagraph[current].iCount = i - iParagraph[current].iStart;
       
   155             current++;
       
   156             iParagraph[current].iStart = i;
       
   157             while (iSpellLibrary[i][0]
       
   158                 != iDb->GetSpellElementByIndex( current ) )
       
   159                 {
       
   160                 iParagraph[current].iCount = 0;
       
   161                 current ++;
       
   162                 iParagraph[current].iStart = i;
       
   163                 }
       
   164             }
       
   165         }
       
   166 
       
   167     iParagraph[current].iCount = length - iParagraph[current].iStart;
       
   168 
       
   169     }
       
   170 
       
   171 HBufC* CAknFepZhuyinAnalyser::LastAnalysisResult( )
       
   172     {
       
   173     return iLastResult;
       
   174     }
       
   175 
       
   176 TBool CAknFepZhuyinAnalyser::AnalyzeL( const TDesC& aInputString )
       
   177     {
       
   178     delete iLastResult;
       
   179     iLastResult = NULL;
       
   180 
       
   181     iLastResult = HBufC::NewL( aInputString.Length( ) * 2 );
       
   182 
       
   183     if ( aInputString.Length( ) < 1 )
       
   184         {
       
   185         return ETrue;
       
   186         }
       
   187 
       
   188     if ( aInputString.Length( ) == 1 )
       
   189         {
       
   190         iLastResult->Des().Append( aInputString[0] );
       
   191         if ( iDb->IsFirstElement( aInputString[0] ) )
       
   192             {
       
   193             return ETrue;
       
   194             }
       
   195         else
       
   196             {
       
   197             return EFalse;
       
   198             }
       
   199         }
       
   200 
       
   201     if ( !iDb->IsFirstElement( aInputString[0] ) )
       
   202         {
       
   203         iLastResult->Des().Append( aInputString );
       
   204         return EFalse;
       
   205         }
       
   206 
       
   207     int first = 0, second = 1;
       
   208     TBool seriateTonemark = EFalse;
       
   209     for (; second < aInputString.Length( ); first++, second++ )
       
   210         {
       
   211         if ( iDb->IsToneMark( aInputString[first], aInputString[second] ) )
       
   212             {
       
   213             iLastResult->Des().Append( aInputString );
       
   214             seriateTonemark = ETrue;
       
   215             break;
       
   216             }
       
   217         }
       
   218 
       
   219     first = 0;
       
   220     second = 1;
       
   221     int previous = 0;
       
   222     iAnalysisFlag = ETrue;
       
   223     //rough spilit
       
   224     for (; second < aInputString.Length( ) && !seriateTonemark; first++, second++ )
       
   225         {
       
   226         if ( !iDb->IsNormalElement( aInputString[first] ) )
       
   227             {
       
   228             //go to detail analysis
       
   229             if ( first > previous )
       
   230                 {
       
   231                 TPtrC toanalysis = aInputString.Mid( previous, first
       
   232                     - previous );
       
   233                 DetailAnalyseL( toanalysis );
       
   234                 }
       
   235 
       
   236             iLastResult->Des().Append( aInputString[first] );
       
   237             previous = first + 1;
       
   238             }
       
   239         else if ( !iDb->IsNormalElement( aInputString[second] ) )
       
   240             {
       
   241             //go to detail analysis
       
   242             if ( second > previous )
       
   243                 {
       
   244                 TPtrC toanalysis = aInputString.Mid( previous, second
       
   245                     - previous );
       
   246                 DetailAnalyseL( toanalysis );
       
   247                 }
       
   248 
       
   249             iLastResult->Des().Append( aInputString[second] );
       
   250             previous = second + 1;
       
   251             first ++;
       
   252             second ++;
       
   253             }
       
   254         else if ( iDb->GetSpellElementType( aInputString[first] )
       
   255             == ESpellVowel || iDb->GetSpellElementType( aInputString[second] )
       
   256             == ESpellVowel )
       
   257             {
       
   258             continue;
       
   259             }
       
   260         else if ( iDb->GetSpellElementType( aInputString[first] )
       
   261             == ESpellConsonant
       
   262             || iDb->GetSpellElementType( aInputString[second] )
       
   263                 == ESpellConsonant )
       
   264             {
       
   265             //go to detail analysis
       
   266             TPtrC toanalysis = aInputString.Mid( previous, second - previous );
       
   267             DetailAnalyseL( toanalysis );
       
   268             iLastResult->Des().Append( KProgramSeparator );
       
   269             previous = second;
       
   270             }
       
   271         else
       
   272             {
       
   273             if ( (aInputString[second] == L'h'&& ( aInputString[first] == L'z' || aInputString[first] == L'c' || aInputString[first] == L's')) || //ch, sh, zh
       
   274             (aInputString[second] == L'g' && aInputString[first] == L'n') || //ng
       
   275             (aInputString[second] == L'n' && aInputString[first] == L'h') //hn 
       
   276             )
       
   277                 {
       
   278                 }
       
   279             else
       
   280                 {
       
   281                 //go to detail analysis
       
   282                 TPtrC toanalysis = aInputString.Mid(previous, second - previous);
       
   283                 DetailAnalyseL(toanalysis);
       
   284                 iLastResult->Des().Append(KProgramSeparator);
       
   285                 previous = second;
       
   286                 }
       
   287             }
       
   288         }
       
   289 
       
   290     if( aInputString.Length() <= previous 
       
   291     		|| second> aInputString.Length() 
       
   292     		|| seriateTonemark )
       
   293         {
       
   294         return TRUE;
       
   295         }
       
   296 
       
   297     TPtrC toanalysis = aInputString.Mid(previous, second - previous);
       
   298     DetailAnalyseL(toanalysis);
       
   299     return iAnalysisFlag;
       
   300     }
       
   301 
       
   302 TBool CAknFepZhuyinAnalyser::DetailAnalyseL( const TDesC& aInputString )
       
   303     {
       
   304     TPriQue<TSpellAnalysis> open;
       
   305     TSpellAnalysis* p = new(ELeave) TSpellAnalysis();
       
   306 
       
   307     open.Add( *p );
       
   308 
       
   309     int sameLength;
       
   310     int startPos;
       
   311     TBool findRes;
       
   312     TSpellAnalysis* pNext= NULL;
       
   313 
       
   314     while ( !open.IsEmpty( ) )
       
   315         {
       
   316         pNext = open.First( );
       
   317         pNext->Deque( );
       
   318 
       
   319         startPos = pNext->GetStartPos( );
       
   320         findRes = FindSpell( aInputString.Mid( startPos ), sameLength );
       
   321 
       
   322         if ( findRes || sameLength + startPos == aInputString.Length( ) )
       
   323             {
       
   324             //got it!
       
   325             int start = 0;
       
   326             for (TInt j = 0; j < pNext->iSeparators.Count( ); ++j )
       
   327                 {
       
   328                 iLastResult->Des().Append( aInputString.Mid( start, pNext->iSeparators[j]
       
   329                     - start ) );
       
   330                 start = pNext->iSeparators[j];
       
   331                 iLastResult->Des().Append( KProgramSeparator );
       
   332                 }
       
   333 
       
   334             iLastResult->Des().Append( aInputString.Mid( start, aInputString.Length( )
       
   335                 - start ) );
       
   336             break;
       
   337             }
       
   338         else if ( sameLength == 0 )
       
   339             {
       
   340             delete pNext;
       
   341             pNext = NULL;
       
   342             }
       
   343         else
       
   344             {
       
   345             int partLength = sameLength - 1;
       
   346             while (partLength > 0 )
       
   347                 {
       
   348                 int templen;
       
   349                 if ( FindSpell( aInputString.Mid( startPos, partLength ),
       
   350                     templen ) )
       
   351                     {
       
   352                     TSpellAnalysis* q = new TSpellAnalysis(*pNext);
       
   353                     q->AddSeparator( startPos + partLength );
       
   354                     open.Add( *q );
       
   355                     }
       
   356                 partLength --;
       
   357                 }
       
   358             pNext->AddSeparator( startPos + sameLength );
       
   359             open.Add( *pNext );
       
   360             }
       
   361         }
       
   362     if ( pNext )
       
   363         {
       
   364         delete pNext;
       
   365         pNext = NULL;
       
   366         while ( !open.IsEmpty( ) )
       
   367             {
       
   368             TSpellAnalysis* p = open.First( );
       
   369             p->Deque( );
       
   370             delete p;
       
   371             }
       
   372         return true;
       
   373         }
       
   374     else
       
   375         {
       
   376         //not found
       
   377         /*
       
   378          FindSpell(aInputString, sameLength);
       
   379          int offset = 0;
       
   380          TBool rtn = sameLength > 0;
       
   381          while( sameLength > 0 )
       
   382          {
       
   383          iLastResult->Des().Append(aInputString.Mid(offset, sameLength));
       
   384          iLastResult->Des().Append(KProgramSeparator);
       
   385          offset += sameLength;
       
   386          FindSpell(aInputString.Mid(offset), sameLength);
       
   387          }
       
   388          */
       
   389         //FindSpell(aInputString, sameLength);
       
   390         int offset = 0;
       
   391 
       
   392         while (offset < aInputString.Length( ) )
       
   393             {
       
   394             FindSpell( aInputString.Mid( offset ), sameLength );
       
   395 
       
   396             if ( sameLength )
       
   397                 {
       
   398                 iLastResult->Des().Append( aInputString.Mid( offset, sameLength ) );
       
   399                 iLastResult->Des().Append( KProgramSeparator );
       
   400                 offset += sameLength;
       
   401                 }
       
   402             else
       
   403                 {
       
   404                 iLastResult->Des().Append( aInputString.Mid( offset, 1 ) );
       
   405 
       
   406                 iLastResult->Des().Append( KProgramSeparator );
       
   407 
       
   408                 offset += 1;
       
   409                 }
       
   410             }
       
   411         if ( iLastResult->Des()[ iLastResult->Length() - 1 ] == KProgramSeparator )
       
   412             {
       
   413             iLastResult->Des().SetLength( iLastResult->Length( ) - 1 );
       
   414             }
       
   415         iAnalysisFlag = EFalse;
       
   416         return EFalse;
       
   417         }
       
   418     }
       
   419 
       
   420 TBool CAknFepZhuyinAnalyser::FindSpell( const TDesC& aSpell, TInt& aSameLength )
       
   421     {
       
   422     int index = aSpell[0] - iDb->GetSpellElementByIndex( 0 );
       
   423 
       
   424     int start = iParagraph[index].iStart;
       
   425     int end = iParagraph[index].iCount + iParagraph[index].iStart - 1;
       
   426     int mid = (start + end ) >> 1;
       
   427     int result = 0;
       
   428     aSameLength = 0;
       
   429     while (mid > start && mid < end )
       
   430         {
       
   431         result = Compare( iSpellLibrary[mid], aSpell, aSameLength );
       
   432         if ( result == 0 )
       
   433             {
       
   434             return true;
       
   435             }
       
   436         else if ( result < 0 )
       
   437             {
       
   438             start = mid;
       
   439             mid = (start + end ) >> 1;
       
   440             }
       
   441         else
       
   442             {
       
   443             end = mid;
       
   444             mid = (start + end) >> 1;
       
   445             }
       
   446         }
       
   447     int newLength;
       
   448     if ( result > 0 )
       
   449         {
       
   450         result = Compare( iSpellLibrary[start], aSpell, newLength );
       
   451         }
       
   452     else
       
   453         {
       
   454         result = Compare( iSpellLibrary[end], aSpell, newLength );
       
   455         }
       
   456     newLength > aSameLength ? aSameLength = newLength : aSameLength;
       
   457 
       
   458     return result == 0;
       
   459     }
       
   460 
       
   461 TInt CAknFepZhuyinAnalyser::Compare( const TDesC& aFirst,
       
   462     const TDesC& aSecond, TInt& aSameLength )
       
   463     {
       
   464     aSameLength = 0;
       
   465 
       
   466     TInt length = aFirst.Length( ) > aSecond.Length( ) ? aSecond.Length( )
       
   467         : aFirst.Length( );
       
   468 
       
   469     for (TInt i = 0; i < length; ++i )
       
   470         {
       
   471         if ( aFirst[i] != aSecond[i] )
       
   472             {
       
   473             return aFirst[i] - aSecond[i];
       
   474             }
       
   475 
       
   476         aSameLength ++;
       
   477         }
       
   478 
       
   479     return aFirst.Length( ) - aSecond.Length( );
       
   480     }
       
   481