uiutils/Findutil/src/FindUtilKorean.cpp
changeset 0 2f259fa3e83a
child 18 fcdfafb36fe7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     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:         Korean Find Utilities implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "FindUtilKorean.h"
       
    20 
       
    21 const TInt KSBase = 0xac00; // base address for hangul syllables
       
    22 const TInt KLBase = 0x1100; // base address for L-jamo
       
    23 const TInt KVBase = 0x1161; // base address for V-jamo
       
    24 const TInt KTBase = 0x11a7; // base address for T-jamo
       
    25 const TInt KCBase = 0x3131; // base address for hangul compatibility jamo
       
    26 
       
    27 const TInt KLCount = 19; // count of L-jamos
       
    28 const TInt KVCount = 21; // count of V-jamos
       
    29 const TInt KTCount = 28; // count of T-jamos
       
    30 const TInt KNCount = KVCount * KTCount; // count of V&T-jamo combinations
       
    31 const TInt KSCount = KLCount * KNCount; // total count of hangul syllables
       
    32 
       
    33 const TInt KMaxLengthDecomposedSyllable = 3; // syllable can contain 3 jamos
       
    34 
       
    35 const TInt KLitTab('\t'); // word separator: <tab>
       
    36 const TInt KLitSpace(' '); // word separator: <space>
       
    37 const TInt KLitHyphen('-'); // word separator: <hyphen>
       
    38 const TInt KLitStar('*'); // wildcard matching: <star>
       
    39 const TInt KLitQuestion('?'); // wildcard matching <question>
       
    40 
       
    41 // Conversion table for hangul compatibility jamo
       
    42 const TUint16 conversionTableFromCompatibilityJamoToJamo[] = {
       
    43 0x1100,
       
    44 0x1101,
       
    45 0x11AA,
       
    46 0x1102,
       
    47 0x11AC,
       
    48 0x11AD,
       
    49 0x1103,
       
    50 0x1104,
       
    51 0x1105,
       
    52 0x11B0,
       
    53 0x11B1,
       
    54 0x11B2,
       
    55 0x11B3,
       
    56 0x11B4,
       
    57 0x11B5,
       
    58 0x11B6,
       
    59 0x1106,
       
    60 0x1107,
       
    61 0x1108,
       
    62 0x11B9,
       
    63 0x1109,
       
    64 0x110A,
       
    65 0x110B,
       
    66 0x110C,
       
    67 0x110D,
       
    68 0x110E,
       
    69 0x110F,
       
    70 0x1110,
       
    71 0x1111,
       
    72 0x1112,
       
    73 0x1161,
       
    74 0x1162,
       
    75 0x1163,
       
    76 0x1164,
       
    77 0x1165,
       
    78 0x1166,
       
    79 0x1167,
       
    80 0x1168,
       
    81 0x1169,
       
    82 0x116A,
       
    83 0x116B,
       
    84 0x116C,
       
    85 0x116D,
       
    86 0x116E,
       
    87 0x116F,
       
    88 0x1170,
       
    89 0x1171,
       
    90 0x1172,
       
    91 0x1173,
       
    92 0x1174,
       
    93 0x1175,
       
    94 };
       
    95 
       
    96 #define KCCount (sizeof(conversionTableFromCompatibilityJamoToJamo) / sizeof(TUint16))
       
    97 
       
    98 // ============================ MEMBER FUNCTIONS =============================
       
    99 
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // Symbian constructor
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 CFindUtilKorean* CFindUtilKorean::NewL()
       
   106     {
       
   107     CFindUtilKorean* self = new ( ELeave ) CFindUtilKorean();
       
   108     CleanupStack::PushL( self );
       
   109     self->ConstructL();
       
   110     CleanupStack::Pop( self );
       
   111     return self;
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // Symbian second-phase constructor
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 void CFindUtilKorean::ConstructL()
       
   119     {
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // Default constructor
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 CFindUtilKorean::CFindUtilKorean()
       
   127     {
       
   128     }
       
   129 
       
   130 // ---------------------------------------------------------------------------
       
   131 // Destructor
       
   132 // ---------------------------------------------------------------------------
       
   133 //
       
   134 CFindUtilKorean::~CFindUtilKorean()
       
   135     {
       
   136     }
       
   137 
       
   138 // ---------------------------------------------------------------------------
       
   139 // Checks that is given character korean language or not.
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 TBool CFindUtilKorean::IsKoreanLanguage( const TDesC& aDes )
       
   143     {
       
   144     for ( TInt i = 0; i < aDes.Length(); i++ )
       
   145     	{
       
   146     	if ( IsHangulSyllable( aDes[ i ] ) || IsHangulCompatibilityJamo( aDes[ i ] ) )
       
   147     		{
       
   148     		return ETrue;
       
   149     		}
       
   150     	}
       
   151 
       
   152     return EFalse;
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------------------------
       
   156 // Compares two strings against others.
       
   157 // ---------------------------------------------------------------------------
       
   158 //
       
   159 TBool CFindUtilKorean::IsFindMatchL( 
       
   160     const TDesC& aItemString, 
       
   161     const TDesC& aSearchText )
       
   162     {
       
   163     TBool result( EFalse );
       
   164     
       
   165     // To disable the wildchar matching provided by MatchC.
       
   166     if ( KErrNotFound != aSearchText.Locate( KLitQuestion ) && 
       
   167         KErrNotFound != aSearchText.Locate( KLitStar ) )
       
   168     	{
       
   169     	return EFalse;
       
   170     	}
       
   171     
       
   172     // Convert aItemString to single jamo's.
       
   173     HBufC* itemString = HBufC::NewLC( aItemString.Length() * KMaxLengthDecomposedSyllable );
       
   174     DecomposeToPlainJamos( aItemString, itemString );
       
   175     
       
   176     HBufC* searchText = HBufC::NewLC( aSearchText.Length() * KMaxLengthDecomposedSyllable + 2 );
       
   177     searchText->Des().Append( KLitStar );
       
   178 
       
   179     // Convert aSearchText to single jamo's.
       
   180     DecomposeToPlainJamos( aSearchText, searchText );
       
   181     searchText->Des().Append( KLitStar );
       
   182     
       
   183     // Compare strings containing plain jamo's against others.
       
   184     for ( TInt i = 0; i < itemString->Length() && !result; i++ )
       
   185         {
       
   186         if ( 0 == i || IsFindWordSeparator( 
       
   187             static_cast<TChar>( itemString->Des()[ i - 1 ] ) ) )
       
   188             {
       
   189             if ( KErrNotFound != itemString->Mid( i ).MatchC( *searchText ) )
       
   190                 {
       
   191                 result = ETrue; // match found
       
   192                 }
       
   193             }
       
   194         }
       
   195     
       
   196     CleanupStack::PopAndDestroy( searchText );
       
   197     CleanupStack::PopAndDestroy( itemString );
       
   198     
       
   199     return result;    
       
   200     }
       
   201 
       
   202 // ---------------------------------------------------------------------------
       
   203 // Decomposes given string to plain jamos.
       
   204 // ---------------------------------------------------------------------------
       
   205 //
       
   206 void CFindUtilKorean::DecomposeToPlainJamos( 
       
   207     const TDesC& aString,
       
   208     HBufC* aDecomposedString )
       
   209     {
       
   210     // Go thought all characters and decompose if needed.
       
   211     for ( TInt i = 0; i < aString.Length(); i++ )
       
   212         {
       
   213         // If character is 'hangul syllable', decompose it to single jamos.
       
   214         if ( IsHangulSyllable( aString[ i ] ) )
       
   215             {
       
   216             TBuf<KMaxLengthDecomposedSyllable> buf ( KNullDesC );
       
   217             Decompose( aString[ i ], buf );
       
   218             aDecomposedString->Des().Append( buf );
       
   219             }
       
   220         else if ( IsHangulCompatibilityJamo( aString[ i ] ) )
       
   221 	        {
       
   222 	        TUint16 jamo = conversionTableFromCompatibilityJamoToJamo[ aString[i] - KCBase ];
       
   223 	        aDecomposedString->Des().Append( jamo );	
       
   224 	        }
       
   225         // Otherwise append character directly to 'decomposed string'.
       
   226         else
       
   227             {
       
   228             aDecomposedString->Des().Append( aString[ i ] );
       
   229             }
       
   230         }
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------------------------
       
   234 // Decomposes hangul syllables to single jamos.
       
   235 // ---------------------------------------------------------------------------
       
   236 //
       
   237 void CFindUtilKorean::Decompose( TChar aChar, TDes& aDecomposedString )
       
   238     {
       
   239     // Calculate single jamo's.
       
   240     TInt index = static_cast<TInt> ( aChar ) - KSBase;
       
   241     TInt l = KLBase + index / KNCount;
       
   242     TInt v = KVBase + ( index % KNCount ) / KTCount;
       
   243     TInt t = KTBase + index % KTCount;
       
   244     
       
   245     // Append single jamo's to 'decomposed string'.
       
   246     aDecomposedString.Append( static_cast<TChar> ( l ) );
       
   247     aDecomposedString.Append( static_cast<TChar> ( v ) );
       
   248     if ( t != KTBase )
       
   249         {
       
   250         aDecomposedString.Append( static_cast<TChar> ( t ) );
       
   251         }
       
   252     }
       
   253 
       
   254 // ---------------------------------------------------------------------------
       
   255 // Checks that is given character hangul syllable or not.
       
   256 // ---------------------------------------------------------------------------
       
   257 //
       
   258 TBool CFindUtilKorean::IsHangulSyllable( TChar aChar )
       
   259     {
       
   260     // Character is 'hangul syllable' 
       
   261     // if it's numeric value is between KSBase and KSBase + KSCount.
       
   262     TInt index = static_cast<TInt> ( aChar ) - KSBase;
       
   263     if ( index < 0 || index >= KSCount )
       
   264         {
       
   265         return EFalse;
       
   266         }
       
   267     return ETrue;
       
   268     }
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // Checks that is given character word separator or not.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 TBool CFindUtilKorean::IsFindWordSeparator( TChar aChar )
       
   275     {
       
   276     return aChar == KLitSpace || aChar == KLitHyphen || aChar == KLitTab;
       
   277     }
       
   278 
       
   279 
       
   280 // ---------------------------------------------------------------------------
       
   281 // Checks that is given character hangul syllable or not.
       
   282 // ---------------------------------------------------------------------------
       
   283 //
       
   284 TBool CFindUtilKorean::IsHangulCompatibilityJamo( TChar aChar )
       
   285     {
       
   286     // Character is 'hangul compatibility jamo' 
       
   287     // if it's numeric value is between KCBase and KCBase + KCCount.
       
   288     TInt index = static_cast<TInt> ( aChar ) - KCBase;
       
   289     if ( index < 0 || index >= KCCount )
       
   290         {
       
   291         return EFalse;
       
   292         }
       
   293     return ETrue;
       
   294     }
       
   295 	
       
   296 // ---------------------------------------------------------------------------
       
   297 // It tests a matching.
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 TBool CFindUtilKorean::Match( const TDesC& aContactsField, const TDesC& aWord )
       
   301     {
       
   302     TBool retVal = EFalse;
       
   303     // Match does not occur if string where search is made,
       
   304     // does not contain any characters.
       
   305     if ( aContactsField.Length() )
       
   306         {
       
   307        // In case that both of strings contain some characters,
       
   308        // matching is made with function below.
       
   309       TRAPD(err, retVal = IsFindMatchL( aContactsField, aWord ));
       
   310     	
       
   311       if (err != KErrNone)
       
   312     	{
       
   313     	retVal = EFalse;
       
   314     	}
       
   315         }
       
   316 	
       
   317    return retVal;
       
   318     }
       
   319 
       
   320 
       
   321 // ---------------------------------------------------------------------------
       
   322 // It tests a partial matching.
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 TBool CFindUtilKorean::MatchRefineL( 
       
   326     const TDesC& aItemString, 
       
   327     const TDesC& aSearchText )
       
   328     {
       
   329     // Match does not occur if string where search is made,
       
   330     // does not contain any characters.
       
   331     if ( aItemString.Length() == 0 )
       
   332         {
       
   333         return EFalse;
       
   334         }
       
   335 
       
   336     // Match occurs if string to be used in searching, 
       
   337     // does not contain any characters.
       
   338     if ( aSearchText.Length() == 0 )
       
   339         {
       
   340         return ETrue;
       
   341         }
       
   342 
       
   343     // In case that both of strings contain some characters,
       
   344     // matching is made with function below.
       
   345     return IsFindMatchL( aItemString, aSearchText );
       
   346     }
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 // CFindUtilKorean::MatchAdaptiveRefineL
       
   350 // (other items were commented in a header).
       
   351 // -----------------------------------------------------------------------------
       
   352 //  
       
   353 TBool CFindUtilKorean::MatchAdaptiveRefineL( const TDesC& /*aItemString*/, 
       
   354 	const TDesC& /*aSearchText*/, HBufC*& /*aNextChars*/ )
       
   355 	{
       
   356 	return 0;	
       
   357 	}
       
   358 
       
   359 // ---------------------------------------------------------------------------
       
   360 // It checks whether aWord is valid.
       
   361 // ---------------------------------------------------------------------------
       
   362 //
       
   363 TBool CFindUtilKorean::IsWordValidForMatching( const TDesC& /*aWord*/ )
       
   364     {
       
   365     return ETrue;
       
   366     }
       
   367 
       
   368 // End of file