uiutils/Findutil/src/FindUtilKorean.cpp
branchRCL_3
changeset 72 a5e7a4f63858
parent 56 d48ab3b357f1
equal deleted inserted replaced
64:85902f042028 72:a5e7a4f63858
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 #include "FindUtilKorean.h"
    19 #include "FindUtilKorean.h"
    20 #include <e32svr.h>
       
    21 
       
    22 #ifdef _DEBUG
       
    23 #include <charconv.h>
       
    24 #endif
       
    25 
    20 
    26 const TInt KSBase = 0xac00; // base address for hangul syllables
    21 const TInt KSBase = 0xac00; // base address for hangul syllables
    27 const TInt KLBase = 0x1100; // base address for L-jamo
    22 const TInt KLBase = 0x1100; // base address for L-jamo
    28 const TInt KVBase = 0x1161; // base address for V-jamo
    23 const TInt KVBase = 0x1161; // base address for V-jamo
    29 const TInt KTBase = 0x11a7; // base address for T-jamo
    24 const TInt KTBase = 0x11a7; // base address for T-jamo
    96 0x1173,
    91 0x1173,
    97 0x1174,
    92 0x1174,
    98 0x1175,
    93 0x1175,
    99 };
    94 };
   100 
    95 
   101 const TUint16 conversionTableFromLJamoToCompatibilityJamo[] = {
       
   102 0x3131, /* ? */
       
   103 0x3132, /* ? */
       
   104 0x3134, /* ? */
       
   105 0x3137, /* ? */
       
   106 0x3138, /* ? */
       
   107 0x3139, /* ? */
       
   108 0x3141, /* ? */
       
   109 0x3142, /* ? */
       
   110 0x3143, /* ? */
       
   111 0x3145, /* ? */
       
   112 0x3146, /* ? */
       
   113 0x3147, /* ? */
       
   114 0x3148, /* ? */
       
   115 0x3149, /* ? */
       
   116 0x314A, /* ? */
       
   117 0x314B, /* ? */
       
   118 0x314C, /* ? */
       
   119 0x314D, /* ? */
       
   120 0x314E  /* ? */
       
   121 };
       
   122 
       
   123 #define KCCount (sizeof(conversionTableFromCompatibilityJamoToJamo) / sizeof(TUint16))
    96 #define KCCount (sizeof(conversionTableFromCompatibilityJamoToJamo) / sizeof(TUint16))
   124 
       
   125 #define KCountCompToJamo (sizeof(conversionTableFromCompatibilityJamoToJamo) / sizeof(TUint16))
       
   126 
       
   127 #define KCountLJamoToComp (sizeof(conversionTableFromLJamoToCompatibilityJamo) / sizeof(TUint16))
       
   128 
       
   129 #define ISLJamo(a) (KLBase <= a && a <= KLBase + KLCount)
       
   130 
       
   131 #define IsCompatibilityJamo(a) (0x3130 <= a && a <= 0x318F)
       
   132 
       
   133 const TInt KNextCharsGranuarity = 20;
       
   134 
       
   135 const TUid KUidPhoneBook = {0x101F4CCE};
       
   136 const TUid KUidPhoneBookServer = {0x10207277};
       
   137 const TUid KUidSymbianContactModel = {0x10003A73};
       
   138 
       
   139 #define IsPhoneBookProcess(a) ( a == KUidSymbianContactModel || a == KUidPhoneBook || a == KUidPhoneBookServer )
       
   140 
       
   141 
       
   142 
    97 
   143 // ============================ MEMBER FUNCTIONS =============================
    98 // ============================ MEMBER FUNCTIONS =============================
   144 
    99 
   145 
   100 
   146 // ---------------------------------------------------------------------------
   101 // ---------------------------------------------------------------------------
   160 // Symbian second-phase constructor
   115 // Symbian second-phase constructor
   161 // ---------------------------------------------------------------------------
   116 // ---------------------------------------------------------------------------
   162 //
   117 //
   163 void CFindUtilKorean::ConstructL()
   118 void CFindUtilKorean::ConstructL()
   164     {
   119     {
   165 #ifdef _DEBUG
       
   166     User::LeaveIfError( iFs.Connect() );
       
   167     iConv = CCnvCharacterSetConverter::NewL();
       
   168     iConv->PrepareToConvertToOrFromL(0x200100FF, iFs);
       
   169 #endif
       
   170     
       
   171     iCurrentProcessUid3 = ( RProcess().Type() )[2];
       
   172     }
   120     }
   173 
   121 
   174 // ---------------------------------------------------------------------------
   122 // ---------------------------------------------------------------------------
   175 // Default constructor
   123 // Default constructor
   176 // ---------------------------------------------------------------------------
   124 // ---------------------------------------------------------------------------
   183 // Destructor
   131 // Destructor
   184 // ---------------------------------------------------------------------------
   132 // ---------------------------------------------------------------------------
   185 //
   133 //
   186 CFindUtilKorean::~CFindUtilKorean()
   134 CFindUtilKorean::~CFindUtilKorean()
   187     {
   135     {
   188 #ifdef _DEBUG
       
   189     delete iConv;
       
   190     iFs.Close();
       
   191 #endif
       
   192     }
   136     }
   193 
   137 
   194 // ---------------------------------------------------------------------------
   138 // ---------------------------------------------------------------------------
   195 // Checks that is given character korean language or not.
   139 // Checks that is given character korean language or not.
   196 // ---------------------------------------------------------------------------
   140 // ---------------------------------------------------------------------------
   210 
   154 
   211 // ---------------------------------------------------------------------------
   155 // ---------------------------------------------------------------------------
   212 // Compares two strings against others.
   156 // Compares two strings against others.
   213 // ---------------------------------------------------------------------------
   157 // ---------------------------------------------------------------------------
   214 //
   158 //
   215 TInt CFindUtilKorean::IsFindMatch( 
   159 TBool CFindUtilKorean::IsFindMatchL( 
   216         const TDesC& aItemString, 
   160     const TDesC& aItemString, 
   217         const TDesC& aSearchText,
   161     const TDesC& aSearchText )
   218         const TMatchFlag aFlag)
   162     {
   219     {
   163     TBool result( EFalse );
   220     
       
   221 #ifdef _DEBUG
       
   222     TRAP_IGNORE(
       
   223         HBufC8* bufItemString = HBufC8::NewLC((aItemString.Length() + 1) * 2);
       
   224         HBufC8* bufSearchText = HBufC8::NewLC((aSearchText.Length() + 1) * 2);
       
   225         TPtr8 ptrItemString(bufItemString->Des());
       
   226         ptrItemString.FillZ(ptrItemString.MaxLength());
       
   227         TPtr8 ptrSearchText(bufSearchText->Des());
       
   228         ptrSearchText.FillZ(ptrSearchText.MaxLength());
       
   229         iConv->ConvertFromUnicode(ptrItemString, aItemString);
       
   230         iConv->ConvertFromUnicode(ptrSearchText, aSearchText);
       
   231         RDebug::Printf("DBG: comparing %s, %s", bufItemString->Ptr(), bufSearchText->Ptr());
       
   232         CleanupStack::PopAndDestroy(2);
       
   233     );
       
   234 #endif
       
   235     
   164     
   236     // To disable the wildchar matching provided by MatchC.
   165     // To disable the wildchar matching provided by MatchC.
   237     if ( aFlag == EMatchFlagNone &&
   166     if ( KErrNotFound != aSearchText.Locate( KLitQuestion ) && 
   238         KErrNotFound != aSearchText.Locate( KLitQuestion ) && 
       
   239         KErrNotFound != aSearchText.Locate( KLitStar ) )
   167         KErrNotFound != aSearchText.Locate( KLitStar ) )
   240     	{
   168     	{
   241 #ifdef _DEBUG
   169     	return EFalse;
   242     	RDebug::Printf("DBG: comparing includes wild");
       
   243 #endif
       
   244     	return KErrNotFound;
       
   245     	}
   170     	}
   246 
   171     
   247 #if 1 // 2009.08.14 consonent based search
       
   248     TUint flag = aFlag;
       
   249 
       
   250     TInt lenItemString = aItemString.Length();
       
   251     TInt lenSearchText = aSearchText.Length();
       
   252 
       
   253     // detect asterik in end of string
       
   254     if (lenSearchText > 0 && aSearchText[lenSearchText - 1] == KLitStar)
       
   255         {
       
   256         flag |= EMatchFlagAsterikInLast;
       
   257         lenSearchText--;
       
   258         }
       
   259 
       
   260     // set asterik start
       
   261     if (!IsPhoneBookProcess(iCurrentProcessUid3) || 
       
   262         (aSearchText.Length() > 0 && aSearchText[0] == KLitStar))
       
   263         {
       
   264         flag |= EMatchFlagAsterikInStart;
       
   265         }
       
   266 
       
   267     if (lenItemString < lenSearchText)
       
   268         {
       
   269         return KErrNotFound;
       
   270         }
       
   271 
       
   272     if (IsPhoneBookProcess(iCurrentProcessUid3))
       
   273         {
       
   274         TInt i = 0;
       
   275         TInt j = 0;
       
   276         for (; i < lenItemString && j < lenSearchText; i++)
       
   277             {
       
   278             TChar ch(aItemString[i]);
       
   279             if (IsFindWordSeparator(ch))
       
   280                 {
       
   281                 continue;
       
   282                 }
       
   283             
       
   284             if (MatchConsonentBased(ch, aSearchText[j]))
       
   285                 {
       
   286                 j++;
       
   287                 }
       
   288             else
       
   289                 {
       
   290                 break;
       
   291                 }
       
   292             }
       
   293         
       
   294         if (j == lenSearchText)
       
   295             return 0;
       
   296         }
       
   297 
       
   298     for (TInt i = 0; i < lenItemString - lenSearchText + 1; i++)
       
   299         {
       
   300         if (!(flag & EMatchFlagAsterikInStart))
       
   301             {
       
   302             if (0 != i && !IsFindWordSeparator(aItemString[i - 1]))
       
   303                 {
       
   304                 continue;
       
   305                 }
       
   306             }
       
   307 
       
   308         TBool matched(ETrue);
       
   309         for (TInt j = 0; j < lenSearchText; j++)
       
   310             {
       
   311             if (!MatchConsonentBased(aItemString[i + j], aSearchText[j]))
       
   312                 {
       
   313 #ifdef _DEBUG
       
   314                 RDebug::Printf("DBG: mismatch between %d %d", i + j, j);
       
   315 #endif
       
   316                 matched = EFalse;
       
   317                 break;
       
   318                 }
       
   319             }
       
   320 
       
   321         if (matched)
       
   322             {
       
   323 #ifdef _DEBUG
       
   324             RDebug::Print(_L("DBG: comparing matched"));
       
   325 #endif
       
   326             return i;
       
   327             }
       
   328         }
       
   329 
       
   330     return KErrNotFound;
       
   331 
       
   332 #else
       
   333     // Convert aItemString to single jamo's.
   172     // Convert aItemString to single jamo's.
   334     HBufC* itemString = HBufC::NewLC( aItemString.Length() * KMaxLengthDecomposedSyllable );
   173     HBufC* itemString = HBufC::NewLC( aItemString.Length() * KMaxLengthDecomposedSyllable );
   335     DecomposeToPlainJamos( aItemString, itemString );
   174     DecomposeToPlainJamos( aItemString, itemString );
   336 
   175     
   337     HBufC* searchText = HBufC::NewLC( aSearchText.Length() * KMaxLengthDecomposedSyllable + 2 );
   176     HBufC* searchText = HBufC::NewLC( aSearchText.Length() * KMaxLengthDecomposedSyllable + 2 );
   338     searchText->Des().Append( KLitStar );
   177     searchText->Des().Append( KLitStar );
   339 
   178 
   340     // Convert aSearchText to single jamo's.
   179     // Convert aSearchText to single jamo's.
   341     DecomposeToPlainJamos( aSearchText, searchText );
   180     DecomposeToPlainJamos( aSearchText, searchText );
   342     searchText->Des().Append( KLitStar );
   181     searchText->Des().Append( KLitStar );
   343 
   182     
   344     // Compare strings containing plain jamo's against others.
   183     // Compare strings containing plain jamo's against others.
   345     for ( TInt i = 0; i < itemString->Length() && !result; i++ )
   184     for ( TInt i = 0; i < itemString->Length() && !result; i++ )
   346         {
   185         {
   347         if ( 0 == i || IsFindWordSeparator(
   186         if ( 0 == i || IsFindWordSeparator( 
   348                         static_cast<TChar>( itemString->Des()[ i - 1 ] ) ) )
   187             static_cast<TChar>( itemString->Des()[ i - 1 ] ) ) )
   349             {
   188             {
   350             if ( KErrNotFound != itemString->Mid( i ).MatchC( *searchText ) )
   189             if ( KErrNotFound != itemString->Mid( i ).MatchC( *searchText ) )
   351                 {
   190                 {
   352                 result = ETrue; // match found
   191                 result = ETrue; // match found
   353                 }
   192                 }
   354             }
   193             }
   355         }
   194         }
   356 
   195     
   357     CleanupStack::PopAndDestroy( searchText );
   196     CleanupStack::PopAndDestroy( searchText );
   358     CleanupStack::PopAndDestroy( itemString );
   197     CleanupStack::PopAndDestroy( itemString );
   359 
   198     
   360     return result;
   199     return result;    
   361 #endif
       
   362     }
   200     }
   363 
   201 
   364 // ---------------------------------------------------------------------------
   202 // ---------------------------------------------------------------------------
   365 // Decomposes given string to plain jamos.
   203 // Decomposes given string to plain jamos.
   366 // ---------------------------------------------------------------------------
   204 // ---------------------------------------------------------------------------
   390             aDecomposedString->Des().Append( aString[ i ] );
   228             aDecomposedString->Des().Append( aString[ i ] );
   391             }
   229             }
   392         }
   230         }
   393     }
   231     }
   394 
   232 
   395 void CFindUtilKorean::DecomposeChar( TChar aChar, TDes& aDecomposedString )
       
   396     {
       
   397     aDecomposedString.Zero();
       
   398     if ( IsHangulSyllable( aChar ) )
       
   399         {
       
   400         Decompose( aChar, aDecomposedString );
       
   401         }
       
   402     else if ( IsHangulCompatibilityJamo( aChar ) )
       
   403         {
       
   404         TUint16 jamo = conversionTableFromCompatibilityJamoToJamo[ (TInt)aChar - KCBase ];
       
   405         aDecomposedString.Append( jamo );    
       
   406         }
       
   407     // Otherwise append character directly to 'decomposed string'.
       
   408     else
       
   409         {
       
   410         aDecomposedString.Append( aChar );
       
   411         }    
       
   412     }
       
   413 
       
   414 // ---------------------------------------------------------------------------
   233 // ---------------------------------------------------------------------------
   415 // Decomposes hangul syllables to single jamos.
   234 // Decomposes hangul syllables to single jamos.
   416 // ---------------------------------------------------------------------------
   235 // ---------------------------------------------------------------------------
   417 //
   236 //
   418 void CFindUtilKorean::Decompose( TChar aChar, TDes& aDecomposedString )
   237 void CFindUtilKorean::Decompose( TChar aChar, TDes& aDecomposedString )
   464 //
   283 //
   465 TBool CFindUtilKorean::IsHangulCompatibilityJamo( TChar aChar )
   284 TBool CFindUtilKorean::IsHangulCompatibilityJamo( TChar aChar )
   466     {
   285     {
   467     // Character is 'hangul compatibility jamo' 
   286     // Character is 'hangul compatibility jamo' 
   468     // if it's numeric value is between KCBase and KCBase + KCCount.
   287     // if it's numeric value is between KCBase and KCBase + KCCount.
   469     TInt index = static_cast<TInt>( aChar ) - KCBase;
   288     TInt index = static_cast<TInt> ( aChar ) - KCBase;
   470     if ( index < 0 || index >= KCCount )
   289     if ( index < 0 || index >= KCCount )
   471         {
   290         {
   472         return EFalse;
   291         return EFalse;
   473         }
   292         }
   474     return ETrue;
   293     return ETrue;
   483     TBool retVal = EFalse;
   302     TBool retVal = EFalse;
   484     // Match does not occur if string where search is made,
   303     // Match does not occur if string where search is made,
   485     // does not contain any characters.
   304     // does not contain any characters.
   486     if ( aContactsField.Length() )
   305     if ( aContactsField.Length() )
   487         {
   306         {
   488 	    // In case that both of strings contain some characters,
   307        // In case that both of strings contain some characters,
   489 	    // matching is made with function below.
   308        // matching is made with function below.
   490 #ifdef _DEBUG
   309       TRAPD(err, retVal = IsFindMatchL( aContactsField, aWord ));
   491         RDebug::Printf("DBG: Comparing from Match");
   310     	
   492 #endif
   311       if (err != KErrNone)
   493 	    retVal = (IsFindMatch( aContactsField, aWord ) != KErrNotFound);
   312     	{
       
   313     	retVal = EFalse;
       
   314     	}
   494         }
   315         }
   495 	
   316 	
   496 	return retVal;
   317    return retVal;
   497     }
   318     }
       
   319 
   498 
   320 
   499 // ---------------------------------------------------------------------------
   321 // ---------------------------------------------------------------------------
   500 // It tests a partial matching.
   322 // It tests a partial matching.
   501 // ---------------------------------------------------------------------------
   323 // ---------------------------------------------------------------------------
   502 //
   324 //
   518         return ETrue;
   340         return ETrue;
   519         }
   341         }
   520 
   342 
   521     // In case that both of strings contain some characters,
   343     // In case that both of strings contain some characters,
   522     // matching is made with function below.
   344     // matching is made with function below.
   523 #ifdef _DEBUG
   345     return IsFindMatchL( aItemString, aSearchText );
   524     RDebug::Printf("DBG: Comparing from MatchRefineL");
       
   525 #endif
       
   526     
       
   527     return (IsFindMatch( aItemString, aSearchText ) != KErrNotFound);
       
   528     }
   346     }
   529 
   347 
   530 // -----------------------------------------------------------------------------
   348 // -----------------------------------------------------------------------------
   531 // CFindUtilKorean::MatchAdaptiveRefineL
   349 // CFindUtilKorean::MatchAdaptiveRefineL
   532 // (other items were commented in a header).
   350 // (other items were commented in a header).
   533 // -----------------------------------------------------------------------------
   351 // -----------------------------------------------------------------------------
   534 //  
   352 //  
   535 TBool CFindUtilKorean::MatchAdaptiveRefineL(const TDesC& aItemString,
   353 TBool CFindUtilKorean::MatchAdaptiveRefineL( const TDesC& /*aItemString*/, 
   536         const TDesC& aSearchText, HBufC*& aNextChars)
   354 	const TDesC& /*aSearchText*/, HBufC*& /*aNextChars*/ )
   537     {
   355 	{
   538     if (aSearchText.Length() == 0)
   356 	return 0;	
   539         {
   357 	}
   540         TakeIntoNextCharsL(aNextChars, aItemString[0]);
   358 
   541         return ETrue;
   359 // ---------------------------------------------------------------------------
   542         }
   360 // It checks whether aWord is valid.
   543     else
   361 // ---------------------------------------------------------------------------
   544         {
   362 //
   545         const TInt lenItemString = aItemString.Length();
   363 TBool CFindUtilKorean::IsWordValidForMatching( const TDesC& /*aWord*/ )
   546         const TInt lenSearchText = aSearchText.Length();
   364     {
   547 
       
   548         if (lenItemString < lenSearchText)
       
   549             {
       
   550             return EFalse;
       
   551             }
       
   552 
       
   553 #ifdef _DEBUG
       
   554         RDebug::Printf("DBG: Comparing from MatchAdaptiveRefineL");
       
   555 #endif
       
   556         TInt idx = IsFindMatch(aItemString, aSearchText,
       
   557                 EMatchFlagAsterikInLast);
       
   558 
       
   559         if (idx == KErrNotFound)
       
   560             {
       
   561             return EFalse;
       
   562             }
       
   563 
       
   564         TLex lexItemString(aItemString);
       
   565         if (IsPhoneBookProcess(iCurrentProcessUid3) && idx == 0)
       
   566             {
       
   567             // find out the position next to last matched string.
       
   568             // work through strings when it reaches length of search string,
       
   569             // while skipping spaces due to ingnoring space matching scheme.
       
   570             for (TInt compareCount = 0; compareCount < lenSearchText;)
       
   571                 {
       
   572                 if (!IsFindWordSeparator(lexItemString.Get()))
       
   573                     {
       
   574                     compareCount++;
       
   575                     }
       
   576                 }
       
   577             
       
   578             if (lexItemString.Eos())
       
   579                 return EFalse;
       
   580 
       
   581             // Skip spaces
       
   582             while (IsFindWordSeparator(lexItemString.Peek()))
       
   583                 {
       
   584                 lexItemString.Inc();
       
   585                 }
       
   586             
       
   587             if (lexItemString.Eos())
       
   588                 {
       
   589                 return EFalse;
       
   590                 }
       
   591             }
       
   592         else
       
   593             {
       
   594             lexItemString.Inc(idx + lenSearchText);
       
   595             }
       
   596 
       
   597         TChar next = lexItemString.Peek();
       
   598         if (next == 0)
       
   599             {
       
   600             // nothing to take
       
   601             }
       
   602         else
       
   603             {
       
   604             TakeIntoNextCharsL(aNextChars, next);
       
   605             }
       
   606         }
       
   607     
       
   608     return ETrue;
   365     return ETrue;
   609     }
   366     }
   610 
   367 
   611 void CFindUtilKorean::TakeIntoNextCharsL(HBufC*& aNextChars,
       
   612         TChar aCharToInsert)
       
   613     {
       
   614     // examine the characters to be inserted
       
   615     TBuf<3> jamo;
       
   616     if (IsHangulSyllable(aCharToInsert))
       
   617         {
       
   618         Decompose(aCharToInsert, jamo);
       
   619         }
       
   620     else if (IsHangulCompatibilityJamo(aCharToInsert))
       
   621         {
       
   622         TUint16 ljamo = 
       
   623                 conversionTableFromCompatibilityJamoToJamo[(TInt)aCharToInsert - KCBase];
       
   624         jamo.Append(ljamo);
       
   625         }
       
   626     else
       
   627         {
       
   628         aCharToInsert.UpperCase();
       
   629         }
       
   630 
       
   631     TPtr nextChar(aNextChars->Des());
       
   632     TBool reAlloced(EFalse);
       
   633 
       
   634     // in case there is no character in the list
       
   635     if (nextChar.Length() == 0)
       
   636         {
       
   637         __ASSERT_ALWAYS(nextChar.MaxLength() > 2, User::Panic(_L("FINDUTIL"), __LINE__));
       
   638         
       
   639         // Hangul only
       
   640         if (jamo.Length() && ISLJamo(jamo[0]))
       
   641             {
       
   642             const TChar consonentToInsert =
       
   643                     conversionTableFromLJamoToCompatibilityJamo[jamo[0] - KLBase];
       
   644             
       
   645             InsertNextCharsL(aNextChars, reAlloced, consonentToInsert);
       
   646 
       
   647             // if Jamo only character, return...
       
   648             if (jamo.Length() == 1)
       
   649                 {
       
   650                 return;
       
   651                 }
       
   652             }
       
   653         
       
   654         InsertNextCharsL(aNextChars, reAlloced, aCharToInsert);
       
   655         return;
       
   656         }
       
   657 
       
   658     TBool jamoInserted(EFalse);
       
   659     TInt length = nextChar.Length();
       
   660     const TBool isPB(IsPhoneBookProcess(iCurrentProcessUid3));
       
   661     
       
   662     for (TInt i = 0; i < length; i++)
       
   663         {
       
   664         const TChar ch = nextChar[i];
       
   665         // Hangul consonent check
       
   666         if (!jamoInserted && jamo.Length() && ISLJamo(jamo[0]))
       
   667             {
       
   668             const TChar consonentToInsert =
       
   669                     conversionTableFromLJamoToCompatibilityJamo[jamo[0] - KLBase];
       
   670             
       
   671             if (ch == consonentToInsert)
       
   672                 {
       
   673                 // Jamo only character finished
       
   674                 if (jamo.Length() == 1)
       
   675                     {
       
   676                     return;
       
   677                     }
       
   678 
       
   679                 jamoInserted = ETrue;
       
   680                 }
       
   681             else if ((isPB && !IsCompatibilityJamo(ch)) || (ch > consonentToInsert))
       
   682                 {
       
   683                 InsertNextCharsL(aNextChars, reAlloced, consonentToInsert, i);
       
   684                 // Jamo only character finished
       
   685                 if (jamo.Length() == 1)
       
   686                     {
       
   687                     return;
       
   688                     }
       
   689 
       
   690                 jamoInserted = ETrue;
       
   691                 }
       
   692             else
       
   693                 {
       
   694                 // pass
       
   695                 }
       
   696             }
       
   697         // Hangul or Latin
       
   698         else
       
   699             {
       
   700             if (ch == aCharToInsert)
       
   701                 {
       
   702                 return; // already exist
       
   703                 }
       
   704             else if (isPB && IsCompatibilityJamo(ch))
       
   705                 {
       
   706                 // pass
       
   707                 }
       
   708             else if (ch > aCharToInsert)
       
   709                 {
       
   710                 InsertNextCharsL(aNextChars, reAlloced, aCharToInsert, i);
       
   711                 return; // finished
       
   712                 }
       
   713             else
       
   714                 {
       
   715                 // pass
       
   716                 }
       
   717             }
       
   718         
       
   719         if (reAlloced)
       
   720             {
       
   721             nextChar.Set(aNextChars->Des());
       
   722             length = nextChar.Length();
       
   723             }
       
   724         }
       
   725     
       
   726     InsertNextCharsL(aNextChars, reAlloced, aCharToInsert);
       
   727     }
       
   728 
       
   729 void CFindUtilKorean::InsertNextCharsL(HBufC*& aNextChars, TBool& aReAlloced,
       
   730         const TChar& aChar, const TInt aIndex)
       
   731     {
       
   732     aReAlloced = EFalse;
       
   733     TPtr ptr(aNextChars->Des());
       
   734     const TInt len = ptr.Length();
       
   735     const TInt maxLen = ptr.MaxLength();
       
   736 
       
   737     if (KErrNotFound != ptr.Locate(aChar))
       
   738         {
       
   739         // Do not insert duplicate characters
       
   740         return;
       
   741         }
       
   742 
       
   743     if (len == maxLen)
       
   744         {
       
   745         aNextChars = aNextChars->ReAllocL(maxLen + KNextCharsGranuarity);
       
   746         ptr.Set(aNextChars->Des());
       
   747         aReAlloced = ETrue;
       
   748         
       
   749 #ifdef _DEBUG
       
   750         RDebug::Printf("DBG: Next Character buffer created with %d",
       
   751                 ptr.MaxLength());
       
   752 #endif
       
   753         }
       
   754 
       
   755     if (aIndex == KErrNotFound)
       
   756         {
       
   757         ptr.Append(aChar);
       
   758         }
       
   759     else
       
   760         {
       
   761         TBuf<1> buf;
       
   762         buf.Append(aChar);
       
   763         ptr.Insert(aIndex, buf);
       
   764         }
       
   765     }
       
   766 
       
   767 // ---------------------------------------------------------------------------
       
   768 // It checks whether aWord is valid.
       
   769 // ---------------------------------------------------------------------------
       
   770 //
       
   771 TBool CFindUtilKorean::IsWordValidForMatching(const TDesC& /*aWord*/)
       
   772     {
       
   773     return ETrue;
       
   774     }
       
   775 
       
   776 TBool CFindUtilKorean::MatchConsonentBased(const TChar& aA, const TChar& aB)
       
   777     {
       
   778     TBuf<3> jamoItemString;
       
   779     TBuf<3> jamoSearchText;
       
   780     DecomposeChar(aA, jamoItemString);
       
   781     DecomposeChar(aB, jamoSearchText);
       
   782     const TInt lenJamoItemString = jamoItemString.Length();
       
   783     const TInt lenJamoSearchText = jamoSearchText.Length();
       
   784 
       
   785     // check consonent match for one character
       
   786     if (lenJamoSearchText == 1 && 
       
   787         ISLJamo(jamoItemString[0]) && ISLJamo(jamoSearchText[0]))
       
   788         {
       
   789         if (jamoItemString[0] == jamoSearchText[0])
       
   790             {
       
   791             return ETrue;
       
   792             }
       
   793         }
       
   794     else
       
   795         {
       
   796         TChar chItemString(aA);
       
   797         TChar chSearchText(aB);
       
   798         chItemString.UpperCase();
       
   799         chSearchText.UpperCase();
       
   800         if (chItemString == chSearchText)
       
   801             {
       
   802             return ETrue;
       
   803             }
       
   804         }
       
   805     return EFalse;
       
   806     }
       
   807 // End of file
   368 // End of file