--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/charconvfw/SortUtil/src/SortUtilJapan.cpp Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,280 @@
+/*
+* Copyright (c) 2002-2004 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:
+*
+*/
+
+
+
+
+
+
+// INCLUDE FILES
+#include "SortUtilJapan.h"
+#include "SortUtilImpl.h"
+#include "SortUtilImplExport.h"
+#include <JpLangUtil.h>
+
+// Unnamed namespace for local definitions
+namespace
+ {
+
+ /**
+ * Character classes for Japanese sorting, in sorting order.
+ */
+ enum TJapaneseCharClass
+ {
+ ECharClassKana,
+ ECharClassLatin,
+ ECharClassDigit,
+ ECharClassKanji,
+ ECharClassSpecial
+ };
+
+ /**
+ * Returns the Japanese character class of aChar.
+ */
+ TJapaneseCharClass CharClass(TUint aChar)
+ {
+ const TChar ch(aChar);
+ // Special characters
+ if (ch.IsSpace() || ch.IsPunctuation() || ch.IsControl()
+ || aChar >= 0xF0000 && aChar <= 0xFFFD)
+ {
+ return ECharClassSpecial;
+ }
+ // Digit
+ else if (aChar >= '0' && aChar <= '9' ||
+ aChar >= 0xFF10 && aChar <= 0xFF19)
+ {
+ return ECharClassDigit;
+ }
+ // Latin
+ else if (aChar >= 'A' && aChar <= 'Z' ||
+ aChar >= 'a' && aChar <= 'z' ||
+ aChar >= 0x00C0 && aChar <= 0x1EF3 && aChar != 0x00D7 && aChar != 0x00F7 ||
+ aChar >= 0xFF21 && aChar <= 0xFF3A ||
+ aChar >= 0xFF41 && aChar <= 0xFF5A)
+ {
+ return ECharClassLatin;
+ }
+ // Kana
+ else if (JPLangUtil::IsKatakana(static_cast<TText>(aChar)) ||
+ JPLangUtil::IsHiragana(static_cast<TText>(aChar)))
+ {
+ return ECharClassKana;
+ }
+ // Kanji
+ else if (JPLangUtil::IsKanji(static_cast<TText>(aChar)))
+ {
+ return ECharClassKanji;
+ }
+ // All other charcters are "special"
+ else
+ {
+ return ECharClassSpecial;
+ }
+ }
+
+ /**
+ * Compares two characters with Japanese comparison rules.
+ */
+ TInt JapaneseCompareC(TUint aLhs, TUint aRhs)
+ {
+ // First compare character classes
+ const TInt lhsCls = CharClass(aLhs);
+ const TInt rhsCls = CharClass(aRhs);
+ return lhsCls - rhsCls;
+ }
+
+ /**
+ * Compares two strings with Japanese comparison rules.
+ */
+ TInt JapaneseCompareS(const TDesC& aLhs, const TDesC& aRhs)
+ {
+ TInt result = 0;
+
+ const TInt minLen = Min(aLhs.Length(), aRhs.Length());
+ TInt i;
+ TInt prevCompPos(0);
+ for (i = 0; i < minLen && result == 0; ++i)
+ {
+ result = JapaneseCompareC(aLhs[i], aRhs[i]);
+ if (result == 0)
+ {
+ TInt orgClass = CharClass(aLhs[i]);
+ TPtrC lPart;
+ TPtrC rPart;
+ if (orgClass == ECharClassKana)
+ {
+ int j = i;
+ for (; j < aLhs.Length(); ++j)
+ {
+ if (orgClass != CharClass(aLhs[j]))
+ {
+ break;
+ }
+ }
+ lPart.Set(aLhs.Mid(prevCompPos, j - prevCompPos));
+ for (j = i; j < aRhs.Length(); ++j)
+ {
+ if (orgClass != CharClass(aRhs[j]))
+ {
+ break;
+ }
+ }
+ rPart.Set(aRhs.Mid(prevCompPos, j - prevCompPos));
+ result = lPart.CompareC(rPart);
+ if (result != 0)
+ {
+ const TInt minKanaLen = Min(lPart.Length(), rPart.Length());
+ TPtrC lKanaPart(lPart.Left(minKanaLen));
+ TPtrC rKanaPart(rPart.Left(minKanaLen));
+ TInt resultKana = lKanaPart.MatchC(rKanaPart);
+ if (resultKana == 0)
+ {
+ TInt maxKanaLen = i+minKanaLen;
+ if (i+minKanaLen+1 >= minLen)
+ {
+ if (maxKanaLen < aLhs.Length()
+ || maxKanaLen < aRhs.Length())
+ {
+ result = 0;
+ i += (minKanaLen-1);
+ }
+ else
+ {
+ result = lKanaPart.CompareC(rKanaPart);;
+ }
+ }
+ else
+ {
+ result = 0;
+ i += (minKanaLen-1);
+ }
+ }
+ }
+
+ }
+ else
+ {
+ lPart.Set(aLhs.Mid(i, 1));
+ rPart.Set(aRhs.Mid(i, 1));
+ result = lPart.CompareC(rPart);
+ }
+ }
+ else
+ {
+ prevCompPos = i;
+ }
+ }
+ if (result == 0)
+ {
+ if (i < aLhs.Length())
+ {
+ // aLhs is longer than aRhs
+ result += User::Collate(aLhs[i]);
+ }
+ if (i < aRhs.Length())
+ {
+ // aRhs is longer that aLhs
+ result -= User::Collate(aRhs[i]);
+ }
+ }
+ return result;
+ }
+ } // namespace
+
+// Only export in DLL
+EXPORT_C MSortUtil* SortUtilFactoryFunctionL()
+ {
+ MSortUtil* util = new (ELeave) TSortUtilJapan;
+ return util;
+ }
+
+inline TSortUtilJapan::TSortUtilJapan()
+ {
+ }
+
+TSortUtilJapan::~TSortUtilJapan()
+ {
+ }
+
+TInt TSortUtilJapan::CompareItems
+ (const MSortKeyArray& aLhs,
+ const MSortKeyArray& aRhs) const
+ {
+ TInt result(0);
+ TInt lhsIndex(0);
+ TInt rhsIndex(0);
+
+ // Compare only pronounciation keys in the first pass
+ do
+ {
+ const TDesC& lhsText =
+ SortUtilImpl::FindNextNonEmptyKey(aLhs, ESortKeyPronounciation, lhsIndex);
+ const TDesC& rhsText =
+ SortUtilImpl::FindNextNonEmptyKey(aRhs, ESortKeyPronounciation, rhsIndex);
+ if (lhsText.Length() > 0)
+ {
+ // lhs has pronounciation key
+ if (rhsText.Length() > 0)
+ {
+ // Both lhs and rhs have pronounciation key: compare the key texts
+ result = JapaneseCompareS(lhsText, rhsText);
+ }
+ else
+ {
+ // Only lhs has pronounciation key
+ result = -1;
+ }
+ }
+ else
+ {
+ // lhs does not have pronounciation key
+ if (rhsText.Length() > 0)
+ {
+ // Only rhs has pronounciation key
+ result = 1;
+ }
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ while (lhsIndex <= aLhs.SortKeyCount() && rhsIndex < aRhs.SortKeyCount());
+
+ // No difference found with pronounciation keys: compare basic keys
+ lhsIndex = 0;
+ rhsIndex = 0;
+ do
+ {
+ const TDesC& lhsText =
+ SortUtilImpl::FindNextNonEmptyKey(aLhs, ESortKeyBasic, lhsIndex);
+ const TDesC& rhsText =
+ SortUtilImpl::FindNextNonEmptyKey(aRhs, ESortKeyBasic, rhsIndex);
+ result = JapaneseCompareS(lhsText, rhsText);
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ while (lhsIndex <= aLhs.SortKeyCount() && rhsIndex < aRhs.SortKeyCount());
+
+ return result;
+ }
+
+// End of file