--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/aknfep/src/AknFepZhuyinAnalyser.cpp Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,481 @@
+/*
+* 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: Implementation of the vkb data manager
+ *
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+// system includes
+
+
+// user includes
+#include "AknFepZhuyinAnalyser.h"
+#include "AknFepZhuyinAnalyserDb.h"
+
+class TSpellBand
+ {
+public:
+ int iStart;
+ int iCount;
+ };
+
+class TSpellAnalysis : public TPriQueLink
+ {
+public:
+ RArray<TInt> iSeparators;
+ TSpellAnalysis( )
+ {
+ iPriority = -0x10000;
+ }
+ ~TSpellAnalysis( )
+ {
+ iSeparators.Close( );
+ }
+
+ TSpellAnalysis( const TSpellAnalysis& aSource )
+ {
+ iPriority = aSource.iPriority;
+ for (TInt i = 0; i < aSource.iSeparators.Count( ); ++i )
+ {
+ iSeparators.Append( aSource.iSeparators[i] );
+ }
+ }
+ void Calculate( )
+ {
+ iPriority = (iSeparators.Count() + 1) << 16;
+ TInt multi = 12;
+ for (TInt i = 0; i < iSeparators.Count(); ++i )
+ {
+ iPriority += ( 6 - iSeparators[i]) << multi;
+ if ( multi >= 3 )
+ {
+ multi -= 3;
+ }
+ }
+ iPriority = -iPriority;
+ }
+ TInt GetStartPos( )
+ {
+ if ( iSeparators.Count() == 0 )
+ {
+ return 0;
+ }
+ else
+ {
+ return iSeparators[ iSeparators.Count() - 1 ];
+ }
+ }
+ void AddSeparator( TInt aPos )
+ {
+ iSeparators.Append( aPos );
+ Calculate( );
+ }
+ };
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::CAknFepVkbPinyinAnalyser
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepZhuyinAnalyser::CAknFepZhuyinAnalyser( )
+ {
+ iAnalysisFlag = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::NewL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepZhuyinAnalyser* CAknFepZhuyinAnalyser::NewL( CZhuyinAnalyserDbFeed* aDb )
+ {
+ CAknFepZhuyinAnalyser* self = new ( ELeave ) CAknFepZhuyinAnalyser();
+ CleanupStack::PushL( self );
+ self->ConstructL( aDb );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::~CAknFepVkbPinyinAnalyser
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepZhuyinAnalyser::~CAknFepZhuyinAnalyser( )
+ {
+ delete []iParagraph;
+ delete []iSpellLibrary;
+ delete iLastResult;
+ delete iDb;
+ }
+
+void CAknFepZhuyinAnalyser::ConstructL( CZhuyinAnalyserDbFeed* aDb )
+ {
+ ASSERT( aDb != NULL );
+ iDb = aDb;
+
+ TInt length = iDb->GetSpellCount( );
+
+ iSpellLibrary = new(ELeave) TPtrC[length];
+ for (TInt i = 0; i < length; ++i )
+ {
+ iSpellLibrary[i].Set( aDb->GetSpellByIndex( i ) );
+ }
+
+ TInt current = 0;
+ TInt pinyinElementCount = iDb->GetSpellElementCount( );
+ iParagraph = new(ELeave) TSpellBand[pinyinElementCount];
+ iParagraph[current].iStart = 0;
+ for (TInt i = 0; i < length; ++i )
+ {
+ if ( iSpellLibrary[i][0] != iDb->GetSpellElementByIndex( current ) )
+ {
+ iParagraph[current].iCount = i - iParagraph[current].iStart;
+ current++;
+ iParagraph[current].iStart = i;
+ while (iSpellLibrary[i][0]
+ != iDb->GetSpellElementByIndex( current ) )
+ {
+ iParagraph[current].iCount = 0;
+ current ++;
+ iParagraph[current].iStart = i;
+ }
+ }
+ }
+
+ iParagraph[current].iCount = length - iParagraph[current].iStart;
+
+ }
+
+HBufC* CAknFepZhuyinAnalyser::LastAnalysisResult( )
+ {
+ return iLastResult;
+ }
+
+TBool CAknFepZhuyinAnalyser::AnalyzeL( const TDesC& aInputString )
+ {
+ delete iLastResult;
+ iLastResult = NULL;
+
+ iLastResult = HBufC::NewL( aInputString.Length( ) * 2 );
+
+ if ( aInputString.Length( ) < 1 )
+ {
+ return ETrue;
+ }
+
+ if ( aInputString.Length( ) == 1 )
+ {
+ iLastResult->Des().Append( aInputString[0] );
+ if ( iDb->IsFirstElement( aInputString[0] ) )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ if ( !iDb->IsFirstElement( aInputString[0] ) )
+ {
+ iLastResult->Des().Append( aInputString );
+ return EFalse;
+ }
+
+ int first = 0, second = 1;
+ TBool seriateTonemark = EFalse;
+ for (; second < aInputString.Length( ); first++, second++ )
+ {
+ if ( iDb->IsToneMark( aInputString[first], aInputString[second] ) )
+ {
+ iLastResult->Des().Append( aInputString );
+ seriateTonemark = ETrue;
+ break;
+ }
+ }
+
+ first = 0;
+ second = 1;
+ int previous = 0;
+ iAnalysisFlag = ETrue;
+ //rough spilit
+ for (; second < aInputString.Length( ) && !seriateTonemark; first++, second++ )
+ {
+ if ( !iDb->IsNormalElement( aInputString[first] ) )
+ {
+ //go to detail analysis
+ if ( first > previous )
+ {
+ TPtrC toanalysis = aInputString.Mid( previous, first
+ - previous );
+ DetailAnalyseL( toanalysis );
+ }
+
+ iLastResult->Des().Append( aInputString[first] );
+ previous = first + 1;
+ }
+ else if ( !iDb->IsNormalElement( aInputString[second] ) )
+ {
+ //go to detail analysis
+ if ( second > previous )
+ {
+ TPtrC toanalysis = aInputString.Mid( previous, second
+ - previous );
+ DetailAnalyseL( toanalysis );
+ }
+
+ iLastResult->Des().Append( aInputString[second] );
+ previous = second + 1;
+ first ++;
+ second ++;
+ }
+ else if ( iDb->GetSpellElementType( aInputString[first] )
+ == ESpellVowel || iDb->GetSpellElementType( aInputString[second] )
+ == ESpellVowel )
+ {
+ continue;
+ }
+ else if ( iDb->GetSpellElementType( aInputString[first] )
+ == ESpellConsonant
+ || iDb->GetSpellElementType( aInputString[second] )
+ == ESpellConsonant )
+ {
+ //go to detail analysis
+ TPtrC toanalysis = aInputString.Mid( previous, second - previous );
+ DetailAnalyseL( toanalysis );
+ iLastResult->Des().Append( KProgramSeparator );
+ previous = second;
+ }
+ else
+ {
+ if ( (aInputString[second] == L'h'&& ( aInputString[first] == L'z' || aInputString[first] == L'c' || aInputString[first] == L's')) || //ch, sh, zh
+ (aInputString[second] == L'g' && aInputString[first] == L'n') || //ng
+ (aInputString[second] == L'n' && aInputString[first] == L'h') //hn
+ )
+ {
+ }
+ else
+ {
+ //go to detail analysis
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyseL(toanalysis);
+ iLastResult->Des().Append(KProgramSeparator);
+ previous = second;
+ }
+ }
+ }
+
+ if( aInputString.Length() <= previous
+ || second> aInputString.Length()
+ || seriateTonemark )
+ {
+ return TRUE;
+ }
+
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyseL(toanalysis);
+ return iAnalysisFlag;
+ }
+
+TBool CAknFepZhuyinAnalyser::DetailAnalyseL( const TDesC& aInputString )
+ {
+ TPriQue<TSpellAnalysis> open;
+ TSpellAnalysis* p = new(ELeave) TSpellAnalysis();
+
+ open.Add( *p );
+
+ int sameLength;
+ int startPos;
+ TBool findRes;
+ TSpellAnalysis* pNext= NULL;
+
+ while ( !open.IsEmpty( ) )
+ {
+ pNext = open.First( );
+ pNext->Deque( );
+
+ startPos = pNext->GetStartPos( );
+ findRes = FindSpell( aInputString.Mid( startPos ), sameLength );
+
+ if ( findRes || sameLength + startPos == aInputString.Length( ) )
+ {
+ //got it!
+ int start = 0;
+ for (TInt j = 0; j < pNext->iSeparators.Count( ); ++j )
+ {
+ iLastResult->Des().Append( aInputString.Mid( start, pNext->iSeparators[j]
+ - start ) );
+ start = pNext->iSeparators[j];
+ iLastResult->Des().Append( KProgramSeparator );
+ }
+
+ iLastResult->Des().Append( aInputString.Mid( start, aInputString.Length( )
+ - start ) );
+ break;
+ }
+ else if ( sameLength == 0 )
+ {
+ delete pNext;
+ pNext = NULL;
+ }
+ else
+ {
+ int partLength = sameLength - 1;
+ while (partLength > 0 )
+ {
+ int templen;
+ if ( FindSpell( aInputString.Mid( startPos, partLength ),
+ templen ) )
+ {
+ TSpellAnalysis* q = new TSpellAnalysis(*pNext);
+ q->AddSeparator( startPos + partLength );
+ open.Add( *q );
+ }
+ partLength --;
+ }
+ pNext->AddSeparator( startPos + sameLength );
+ open.Add( *pNext );
+ }
+ }
+ if ( pNext )
+ {
+ delete pNext;
+ pNext = NULL;
+ while ( !open.IsEmpty( ) )
+ {
+ TSpellAnalysis* p = open.First( );
+ p->Deque( );
+ delete p;
+ }
+ return true;
+ }
+ else
+ {
+ //not found
+ /*
+ FindSpell(aInputString, sameLength);
+ int offset = 0;
+ TBool rtn = sameLength > 0;
+ while( sameLength > 0 )
+ {
+ iLastResult->Des().Append(aInputString.Mid(offset, sameLength));
+ iLastResult->Des().Append(KProgramSeparator);
+ offset += sameLength;
+ FindSpell(aInputString.Mid(offset), sameLength);
+ }
+ */
+ //FindSpell(aInputString, sameLength);
+ int offset = 0;
+
+ while (offset < aInputString.Length( ) )
+ {
+ FindSpell( aInputString.Mid( offset ), sameLength );
+
+ if ( sameLength )
+ {
+ iLastResult->Des().Append( aInputString.Mid( offset, sameLength ) );
+ iLastResult->Des().Append( KProgramSeparator );
+ offset += sameLength;
+ }
+ else
+ {
+ iLastResult->Des().Append( aInputString.Mid( offset, 1 ) );
+
+ iLastResult->Des().Append( KProgramSeparator );
+
+ offset += 1;
+ }
+ }
+ if ( iLastResult->Des()[ iLastResult->Length() - 1 ] == KProgramSeparator )
+ {
+ iLastResult->Des().SetLength( iLastResult->Length( ) - 1 );
+ }
+ iAnalysisFlag = EFalse;
+ return EFalse;
+ }
+ }
+
+TBool CAknFepZhuyinAnalyser::FindSpell( const TDesC& aSpell, TInt& aSameLength )
+ {
+ int index = aSpell[0] - iDb->GetSpellElementByIndex( 0 );
+
+ int start = iParagraph[index].iStart;
+ int end = iParagraph[index].iCount + iParagraph[index].iStart - 1;
+ int mid = (start + end ) >> 1;
+ int result = 0;
+ aSameLength = 0;
+ while (mid > start && mid < end )
+ {
+ result = Compare( iSpellLibrary[mid], aSpell, aSameLength );
+ if ( result == 0 )
+ {
+ return true;
+ }
+ else if ( result < 0 )
+ {
+ start = mid;
+ mid = (start + end ) >> 1;
+ }
+ else
+ {
+ end = mid;
+ mid = (start + end) >> 1;
+ }
+ }
+ int newLength;
+ if ( result > 0 )
+ {
+ result = Compare( iSpellLibrary[start], aSpell, newLength );
+ }
+ else
+ {
+ result = Compare( iSpellLibrary[end], aSpell, newLength );
+ }
+ newLength > aSameLength ? aSameLength = newLength : aSameLength;
+
+ return result == 0;
+ }
+
+TInt CAknFepZhuyinAnalyser::Compare( const TDesC& aFirst,
+ const TDesC& aSecond, TInt& aSameLength )
+ {
+ aSameLength = 0;
+
+ TInt length = aFirst.Length( ) > aSecond.Length( ) ? aSecond.Length( )
+ : aFirst.Length( );
+
+ for (TInt i = 0; i < length; ++i )
+ {
+ if ( aFirst[i] != aSecond[i] )
+ {
+ return aFirst[i] - aSecond[i];
+ }
+
+ aSameLength ++;
+ }
+
+ return aFirst.Length( ) - aSecond.Length( );
+ }
+