uiutils/Findutil/src/FindUtilJapanese.cpp
author William Roberts <williamr@symbian.org>
Wed, 10 Nov 2010 12:08:34 +0000
branchRCL_3
changeset 76 5c9f0ba5102a
parent 4 8ca85d2f0db7
permissions -rw-r--r--
Improve debug tracing of AknGlobalNote::StartL - Bug 2673

/*
* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:         Japanese Find Utilities implementation file.
*
*/










// INCLUDE FILES
#include "FindUtilJapanese.h"
#include <jplangutil.h>

// CONSTANTS
_LIT(KDesWildCard, "*");

const TInt KLitTab('\t');
const TInt KLitSpace(' ');
const TInt KLitHyphen('-');
const TInt KLitQuestion('?');
const TInt KLitWildCard('*');
const TInt KLitFullWidthSpace(0x3000);
const TInt KLitFullWidthHyphen(0x2015);
const TInt KLitFullWidthQuestion(0xff1f);
const TInt KLitFullWidthWildCard(0xff0a);
const TInt KLitStartHiragana(0x3041);
const TInt KLitEndHiragana(0x3096);
const TInt KLitStartKatakana(0x30A1);
const TInt KLitLineFeed(8233);

const TInt KMaxWordLength = 200;
const TUint KFullWidthSpace = 0x3000;

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CFindUtilJapanese::CFindUtilJapanese
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CFindUtilJapanese::CFindUtilJapanese()
    {
    }

// Destructor
CFindUtilJapanese::~CFindUtilJapanese()
    {
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::IsFindWordSeparator
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CFindUtilJapanese::IsFindWordSeparator(TChar aCh)
    {
    return aCh == KLitSpace || aCh == KLitHyphen || aCh == KLitTab ||
        aCh == KLitFullWidthSpace || aCh == KLitFullWidthHyphen ||
        aCh == KLitLineFeed;
    }


// -----------------------------------------------------------------------------
// CFindUtilJapanese::RemoveWordSeparatorsAndWildChars
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CFindUtilJapanese::RemoveWordSeparatorsAndWildChars( TDes16& aSearchPtr )
    {
    TInt len = aSearchPtr.Length();

    for ( TInt ii(0); ii < len; ii++ )
        {
        if ( IsFindWordSeparator(static_cast<TChar>(aSearchPtr[ii])) || 
            aSearchPtr[ii] == KLitWildCard || aSearchPtr[ii] == KLitQuestion ||
            aSearchPtr[ii] == KLitFullWidthWildCard || 
            aSearchPtr[ii] == KLitFullWidthQuestion)
            {
            aSearchPtr.Delete(ii, 1);
            len--;
            continue;
            }
        }

    }

inline TBool IsFindWordSeparator(TChar aCh)
    {
    return (aCh == ' '|| aCh == '-' || aCh == '\t' || aCh==KFullWidthSpace);
    }

void ReplaceCharacters(TDes &aDes, const TDesC &aChars, TChar aReplacement)
    //
    // Running time O(aDes.Length() * aChars.Length())
    // Does not change length of the string.
    // 
    {
    TInt src = 0;
    TInt srclength = aDes.Length();
    while(src < srclength)
        {
        TChar c = aDes[src];
        if (aChars.LocateF(c) != KErrNotFound)
            aDes[src] = TUint16(aReplacement);
        ++src;
        }
    }


// -----------------------------------------------------------------------------
// CFindUtilJapanese::MyFindC
// (other items were commented in a header).
// This method is called by MatchRefineL().
// -----------------------------------------------------------------------------
//
TInt CFindUtilJapanese::MyFindC(const TDesC &aItemString, const TDesC &aSearchText)
    {
    TBuf<KMaxWordLength> searchText;
    TBuf<KMaxWordLength> itemString;
    searchText.Append(aSearchText);
    // The replacecharacters are to disable regexp matching provided
    // by MatchC().
    _LIT(KQuestion,"?");
    _LIT(KStar,"*");
    ReplaceCharacters(searchText, KQuestion, TChar('\t'));
    ReplaceCharacters(searchText, KStar, TChar('\r'));
    searchText.Append(KStar);
    if (aItemString.Length() < KMaxWordLength)
        {
        itemString.Append(aItemString);
        }
    else
        {
        itemString.Append(aItemString.Left(KMaxWordLength));
        }
    ReplaceCharacters(itemString, KQuestion, TChar('\t'));
    ReplaceCharacters(itemString, KStar, TChar('\r'));

    CnvKatakana(searchText);
    CnvKatakana(itemString);

    TInt length = itemString.Length();
    for(int i=0;i<length;i++)
        {
        if (i==0 || IsFindWordSeparator(aItemString[i-1]))
            {
            if (itemString.Mid(i).MatchC(searchText) != KErrNotFound)
                {
                return i;
                }
            }
        }
    return KErrNotFound;
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::IsMatch
// (other items were commented in a header).
// This method is called by MatchRefineL(). 
// This method separates by 4 characters, and this method calls MyFindC().
// -----------------------------------------------------------------------------
//
TBool CFindUtilJapanese::IsMatch( const TDesC& aItemString, const TDesC& aSearchText)
    {
    TPtrC itemptr(aItemString);
    TPtrC searchptr(aSearchText);

    TBool match = EFalse;
    
    FOREVER 
        {
        // Loop invariant: itemptr is next character from ' ' or '-'
        // Loop invariant: seachptr is at beginning of searched item
        TInt val = MyFindC(itemptr,searchptr);
        if (val == 0)
            {
            match = ETrue;
            break;
            }
        if (val != KErrNotFound && IsFindWordSeparator(itemptr[val-1]))
            {
            match = ETrue;
            break;
            }

        // find the word separator characters from list item
        const TInt maxFindChar = 4;
        TChar findchar = KFullWidthSpace;
        TInt findindex;
        for (findindex=0; findindex < maxFindChar; findindex++)
            {
            switch(findindex)
                {
                case 0: findchar = (' ');  break;   // space
                case 1: findchar = KFullWidthSpace; break;   // full space
                case 2: findchar = ('-');  break;   // minus
                case 3: findchar = ('\t'); break;   // tab
                }
            const TInt findpos = itemptr.LocateF(findchar);
            if (findpos != KErrNotFound)
                {
                itemptr.Set(itemptr.Mid(findpos+1));
                break;
                }
            }
        if (findindex >= maxFindChar)
            {
            match = EFalse;
            break;
            }
        if (itemptr.Length() == 0)
            {
            match = EFalse;
            break;
            }
        }
    return match;
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::CnvKatakana
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CFindUtilJapanese::CnvKatakana(TDes& aDes)
    {
    TInt len = aDes.Length();
    for (TInt i(0); i < len; i++)
        {
        TUint16& ch = aDes[i];
        if (ch >= KLitStartHiragana && ch <= KLitEndHiragana)
            {
            ch += (KLitStartKatakana - KLitStartHiragana);
            }
        }
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::Match
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//

TBool CFindUtilJapanese::Match(const TDesC& aContactsField, const TDesC& aWord)
    {
    if (!aContactsField.Length())
        {
        return EFalse;
        }

    TBuf<KMaxWordLength> searchText(aWord);
    TBuf<KMaxWordLength> itemString(aContactsField);

    searchText.Append(KDesWildCard);
    CnvKatakana(searchText);
    CnvKatakana(itemString);

    if (itemString.MatchC(searchText) != KErrNotFound)
        {
        return ETrue;
        }

    return EFalse;
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::MatchRefineL
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CFindUtilJapanese::MatchRefineL( const TDesC& aItemString, const TDesC &aSearchText)
    {
    if ( aItemString.Length() == 0 )
        {
        return EFalse;
        }

    if ( aSearchText.Length() == 0 )
        {
        return ETrue;
        }

    return IsMatch(aItemString, aSearchText);
    }

// -----------------------------------------------------------------------------
// CFindUtilJapanese::IsWordValidForMatching
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CFindUtilJapanese::IsWordValidForMatching(const TDesC& /*aWord*/)
    {
    return ETrue;
    }


// -----------------------------------------------------------------------------
// CFindUtilJapanese::MatchAdaptiveRefineL
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//  
TBool CFindUtilJapanese::MatchAdaptiveRefineL( const TDesC& /*aItemString*/, 
	                                           const TDesC& /*aSearchText*/,
	                                           HBufC*& /*aNextChars*/ )
	{	
  	return EFalse;	
	}
	
// ---------------------------------------------------------
// Match arithmetic for accurate search, special conversion 
// for aItemString is implemented with MFindStringConverter
// before the final match
// ---------------------------------------------------------
//
TBool CFindUtilJapanese::MatchRefineL( const TDesC& /*aItemString*/, const TDesC& /*aSearchText*/, 
                                       TMatchPolicy /*aPolicy*/, MFindStringConverter* /*aConverter*/)
    {
    return EFalse;
    }	

// ========================== OTHER EXPORTED FUNCTIONS =========================

// -----------------------------------------------------------------------------
// FindUtilFactoryFunctionL
// Factory function at first ordinal
// Returns: MFindUtil: It returns MFindUtil I/F.
// -----------------------------------------------------------------------------
//
EXPORT_C MFindUtil* FindUtilFactoryFunctionL()
    {
    return new( ELeave ) CFindUtilJapanese();
    }

//  End of File