--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/Engine/src/PbkEngUtils.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,584 @@
+/*
+* Copyright (c) 2002 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:
+* Namespace structure for Phonebook engine helper functions
+*
+*/
+
+
+// INCLUDE FILES
+#include <PbkEngUtils.h>
+#include <f32file.h>
+#include <barsc.h>
+#include <bautils.h>
+#include <featmgr.h>
+#include "PbkDataCaging.hrh"
+
+/// Unnamed namespace for local definitions
+namespace __RVCT_UNS_PbkEngUtils {
+
+// LOCAL CONSTANTS
+enum TPanicCode
+ {
+ EPanicPreCond_CopyAndReplaceChars = 1,
+ EPanicPostCond_TrimAllLength,
+ EPanicPostCond_TrimRightLength,
+ EPanicPreCond_TrimAllAppend,
+ EPanicPostCond_TrimAllAppend,
+ EPanicPreCond_TrimRightAppend,
+ EPanicPostCond_TrimRightAppend
+
+ };
+
+_LIT(KEngDefResFileName, "PbkEng.rsc"); // default resource file name
+_LIT(KEngChineseResFileName, "PbkEngChinese.rsc"); // Chinese resource
+_LIT(KEngJapaneseResFileName, "PbkEngJapanese.rsc"); // Japanese resource
+
+// ================= LOCAL FUNCTIONS =======================
+#ifdef _DEBUG
+void Panic(TPanicCode aReason)
+ {
+ _LIT(KPanicText, "PbkEngUtils");
+ User::Panic(KPanicText, aReason);
+ }
+#endif
+
+const TUint KPbkZWSCharacter = 0x200B;
+const TUint KPbkZWNJCharacter = 0x200C;
+
+// Check if the given char is a Zero Width Space or Non-Joiner character
+inline TBool ZWSCharacter( const TChar aChar )
+ {
+ const TChar zwsChar( KPbkZWSCharacter );
+ const TChar zwnjChar( KPbkZWNJCharacter );
+ return (aChar == zwsChar) || (aChar == zwnjChar);
+ }
+
+/**
+ * Implementation class for PbkEngUtils::BreakInWordsLC.
+ */
+NONSHARABLE_CLASS(CWords) :
+ public CBase,
+ public MDesCArray
+ {
+ public: // Constructors and destructor
+ /**
+ * Creates a new instance of this class.
+ * @param aText the text to separate
+ * @param aWordSeparatorFunc function for detecting
+ * word separator characters
+ */
+ static CWords* NewLC
+ (const TDesC& aText,
+ PbkEngUtils::TIsWordSeparator aWordSeparatorFunc);
+ /**
+ * Destructor.
+ */
+ ~CWords();
+
+ public: // from MDesCArray
+ TInt MdcaCount() const;
+ TPtrC16 MdcaPoint(TInt aIndex) const;
+
+ private: // Implementation
+ CWords(PbkEngUtils::TIsWordSeparator aWordSeparatorFunc);
+ void ConstructL
+ (const TDesC& aText);
+ static TBool DefaultIsWordSeparator(TChar aChar);
+
+ private:
+ /// Own: function for detecting word separator characters
+ PbkEngUtils::TIsWordSeparator iWordSeparatorFunc;
+ /// Own: array of words
+ RArray<TPtrC> iWords;
+ };
+
+/**
+ * Solves correct language specific engine resource filename.
+ *
+ * @return A reference to resource file
+ */
+inline const TDesC& EngResFileName()
+ {
+ if (FeatureManager::FeatureSupported(KFeatureIdChinese))
+ {
+ return KEngChineseResFileName;
+ }
+ else if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+ {
+ return KEngJapaneseResFileName;
+ }
+ return KEngDefResFileName;
+ }
+
+
+}
+using namespace __RVCT_UNS_PbkEngUtils;
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+EXPORT_C void PbkEngUtils::FindAndOpenResourceFileLC
+ (RFs& aFs,
+ const TDesC& aResFileName,
+ const TDesC& aResFilePath,
+ const TDesC& aResFileDrive,
+ RResourceFile& aResFile)
+ {
+ _LIT(KSeparator, "\\");
+ TFileName fileName;
+ fileName.Copy(aResFileDrive);
+ fileName.Append(aResFilePath);
+ fileName.Append(KSeparator);
+ fileName.Append(aResFileName);
+
+ BaflUtils::NearestLanguageFile(aFs, fileName);
+ aResFile.OpenL(aFs, fileName);
+ CleanupClosePushL(aResFile);
+ }
+
+EXPORT_C void PbkEngUtils::FindAndOpenDefaultResourceFileLC
+ (RFs& aFs,
+ RResourceFile& aResFile)
+ {
+ FindAndOpenResourceFileLC(aFs, EngResFileName(), KDC_RESOURCE_FILES_DIR,
+ KPbkRomFileDrive, aResFile);
+ aResFile.ConfirmSignatureL();
+ }
+
+EXPORT_C TInt PbkEngUtils::CopyDigitsFromEnd(
+ const TDesC& aNumText,
+ TInt aNumberOfDigits,
+ TDes& aDigitsText)
+ {
+ aDigitsText.Zero();
+ // Scan aNumText from the end
+ TInt pos = aNumText.Length();
+
+ // Loop for number of digits to extract
+ TInt digit = 0;
+ for (; digit < aNumberOfDigits; ++digit)
+ {
+ // Scan aNumText backwars for the next number
+ while (--pos >= 0 && !TChar(aNumText[pos]).IsDigit()) { }
+ if (pos < 0)
+ break;
+ // Number found, append it to result string
+ aDigitsText.Append(aNumText[pos]);
+ }
+
+ // Reverse result string to correct order
+ TInt end = aDigitsText.Length();
+ for (pos = 0; pos < --end ; ++pos)
+ {
+ const TText tmp = aDigitsText[pos];
+ aDigitsText[pos] = aDigitsText[end];
+ aDigitsText[end] = tmp;
+ }
+
+ // Return number of digits extracted
+ return digit;
+ }
+
+EXPORT_C TBool PbkEngUtils::ContainSameDigits
+ (const TDesC& aNumText1,
+ const TDesC& aNumText2,
+ TInt aNumberOfDigits/*=0*/)
+ {
+ TInt pos1 = aNumText1.Length();
+ TInt pos2 = aNumText2.Length();
+ FOREVER
+ {
+ // Scan for the next digit in both strings
+ while (--pos1 >= 0 && !TChar(aNumText1[pos1]).IsDigit()) { }
+ while (--pos2 >= 0 && !TChar(aNumText2[pos2]).IsDigit()) { }
+
+ if (pos1 < 0 && pos2 < 0)
+ {
+ // Run to the end of both strings
+ break;
+ }
+
+ if ((pos1 < 0 && pos2 >= 0) || (pos1 >= 0 && pos2 < 0))
+ {
+ // Run out of the other string while the other still
+ // contains digits to compare
+ return EFalse;
+ }
+
+ if (pos1 >= 0 && pos2 >= 0 && aNumText1[pos1] != aNumText2[pos2])
+ {
+ // Different digits found
+ return EFalse;
+ }
+
+ if (--aNumberOfDigits == 0)
+ {
+ // All requested digits compared ok
+ break;
+ }
+ }
+
+ // Didn't find nonmatching digits
+ return ETrue;
+ }
+
+EXPORT_C TInt PbkEngUtils::AppendAndReplaceChars
+ (TDes& aDest, const TDesC& aSrc,
+ const TDesC& aCharsToReplace, const TDesC& aReplaceChars)
+ {
+ // Check that aDest has enough capacity
+ __ASSERT_DEBUG((aDest.MaxLength()-aDest.Length()) >= aSrc.Length(),
+ Panic(EPanicPreCond_CopyAndReplaceChars));
+ // Check that a replacament is provided for all characters
+ __ASSERT_DEBUG(aCharsToReplace.Length() == aReplaceChars.Length(),
+ Panic(EPanicPreCond_CopyAndReplaceChars));
+
+ TInt count, i;
+ const TInt sourceLenght = aSrc.Length();
+ for (count=0, i=0; i < sourceLenght; ++i)
+ {
+ TText ch = aSrc[i];
+ const TInt replacePos = aCharsToReplace.Locate(aSrc[i]);
+ if (replacePos != KErrNotFound)
+ {
+ ++count;
+ ch = aReplaceChars[replacePos];
+ }
+ aDest.Append(ch);
+ }
+
+ return count;
+ }
+
+EXPORT_C TInt PbkEngUtils::CountSpaces(const TDesC& aText)
+ {
+ TInt result = 0;
+ const TInt length = aText.Length();
+ for (TInt i=0; i<length; ++i)
+ {
+ if (TChar(aText[i]).IsSpace())
+ {
+ ++result;
+ }
+ }
+ return result;
+ }
+
+EXPORT_C void PbkEngUtils::ReplaceNonGraphicCharacters
+ (TDes& aText, TText aChar)
+ {
+ const TInt len = aText.Length();
+ for (TInt i=0; i < len; ++i)
+ {
+ if (!TChar(aText[i]).IsGraph() &&
+ !ZWSCharacter( aText[i] ) )
+ {
+ // replace non-graphic character with aChar
+ aText[i] = aChar;
+ }
+ }
+ }
+
+EXPORT_C void PbkEngUtils::AppendGraphicCharacters
+ (TDes& aDest, const TDesC& aSrc, TText aChar)
+ {
+ const TInt len = aSrc.Length();
+ for (TInt i=0; i < len; ++i)
+ {
+ TText ch(aSrc[i]);
+ if (TChar(ch).IsGraph() ||
+ ZWSCharacter(ch))
+ {
+ aDest.Append(ch);
+ }
+ else
+ {
+ aDest.Append(aChar);
+ }
+ }
+ }
+
+EXPORT_C MDesCArray* PbkEngUtils::BreakInWordsLC
+ (const TDesC& aText,
+ TIsWordSeparator aWordSeparatorFunc/*=NULL*/)
+ {
+ return CWords::NewLC(aText,aWordSeparatorFunc);
+ }
+
+EXPORT_C HBufC* PbkEngUtils::AllocL(HBufC* aBuffer, TInt aMaxLength)
+ {
+ if (aBuffer)
+ {
+ TPtr bufPtr(aBuffer->Des());
+ if (bufPtr.MaxLength() < aMaxLength)
+ {
+ aBuffer = aBuffer->ReAllocL(aMaxLength);
+ }
+ }
+ else
+ {
+ aBuffer = HBufC::NewL(aMaxLength);
+ }
+ return aBuffer;
+ }
+
+EXPORT_C HBufC* PbkEngUtils::CopyL
+ (HBufC* aBuffer, const TDesC& aText, TInt aMinBufLength/*=0*/)
+ {
+ aBuffer = AllocL(aBuffer,Max(aText.Length(),aMinBufLength));
+ *aBuffer = aText;
+ return aBuffer;
+ }
+
+EXPORT_C TInt PbkEngUtils::TrimAllLength(const TDesC& aText)
+ {
+ const TInt textLength=aText.Length();
+ TInt result=0;
+ TBool uncommittedSpace=EFalse;
+ for (TInt i=0; i < textLength; ++i)
+ {
+ if (TChar(aText[i]).IsSpace())
+ {
+ if (result > 0)
+ {
+ // Not a leading space, set uncommitted space flag
+ uncommittedSpace = ETrue;
+ }
+ }
+ else
+ {
+ if (uncommittedSpace)
+ {
+ // Add previously encountered space(s)
+ ++result;
+ uncommittedSpace = EFalse;
+ }
+ // Add the character
+ ++result;
+ }
+ }
+
+ __ASSERT_DEBUG(result <= aText.Length(),
+ Panic(EPanicPostCond_TrimAllLength));
+ return result;
+ }
+
+EXPORT_C TInt PbkEngUtils::TrimAllAppend(const TDesC& aText, TDes& aDest)
+ {
+#ifdef _DEBUG
+ const TInt oldDestLength = aDest.Length();
+ __ASSERT_DEBUG(aDest.MaxLength()-oldDestLength >= TrimAllLength(aText),
+ Panic(EPanicPreCond_TrimAllAppend));
+#endif
+
+ const TInt textLength=aText.Length();
+ TInt result=0;
+ TBool uncommittedSpace=EFalse;
+ for (TInt i=0; i < textLength; ++i)
+ {
+ const TChar ch(aText[i]);
+ if (ch.IsSpace() &&
+ !ZWSCharacter( ch ) )
+ {
+ if (result > 0)
+ {
+ // Not a leading space, set uncommitted space flag
+ uncommittedSpace = ETrue;
+ }
+ }
+ else
+ {
+ if (uncommittedSpace)
+ {
+ // Add previously encountered space(s)
+ ++result;
+ aDest.Append(' ');
+ uncommittedSpace = EFalse;
+ }
+ // Add the character
+ ++result;
+ aDest.Append(ch);
+ }
+ }
+
+ __ASSERT_DEBUG(aDest.Length()-oldDestLength == TrimAllLength(aText),
+ Panic(EPanicPostCond_TrimAllAppend));
+ return result;
+ }
+
+EXPORT_C TInt PbkEngUtils::TrimRightLength(const TDesC& aText)
+ {
+ const TInt textLength=aText.Length();
+ TInt result=0;
+ TBool uncommittedSpace=EFalse;
+ TBool leadingSpace=ETrue;
+ for (TInt i=0; i < textLength; ++i)
+ {
+ if (TChar(aText[i]).IsSpace() &&
+ !ZWSCharacter( aText[i] ) )
+ {
+ if (leadingSpace)
+ {
+ // Add all leading spaces
+ ++result;
+ }
+ else
+ {
+ // Not a leading space, set uncommitted space flag
+ uncommittedSpace = ETrue;
+ }
+ }
+ else
+ {
+ // First non-space character found, adjust leading space flag
+ leadingSpace = EFalse;
+ if (uncommittedSpace)
+ {
+ // Add previously encountered space(s)
+ ++result;
+ uncommittedSpace = EFalse;
+ }
+ // Add the character
+ ++result;
+ }
+ }
+
+ __ASSERT_DEBUG(result <= aText.Length(),
+ Panic(EPanicPostCond_TrimRightLength));
+ return result;
+ }
+
+EXPORT_C TInt PbkEngUtils::TrimRightAppend(const TDesC& aText, TDes& aDest)
+ {
+#ifdef _DEBUG
+ const TInt oldDestLength = aDest.Length();
+ __ASSERT_DEBUG(aDest.MaxLength()-oldDestLength >= TrimRightLength(aText),
+ Panic(EPanicPreCond_TrimRightAppend));
+#endif
+
+ const TInt textLength=aText.Length();
+ TInt result=0;
+ TBool uncommittedSpace=EFalse;
+ TBool leadingSpace=ETrue;
+ for (TInt i=0; i < textLength; ++i)
+ {
+ const TChar ch(aText[i]);
+ if (ch.IsSpace() &&
+ !ZWSCharacter( ch ) )
+ {
+ if (leadingSpace)
+ {
+ // Add all leading spaces
+ ++result;
+ aDest.Append(' ');
+ }
+ else
+ {
+ // Not a leading space, set uncommitted space flag
+ uncommittedSpace = ETrue;
+ }
+ }
+ else
+ {
+ // First non-space character found, adjust leading space flag
+ leadingSpace = EFalse;
+ if (uncommittedSpace)
+ {
+ // Add previously encountered space(s)
+ ++result;
+ aDest.Append(' ');
+ uncommittedSpace = EFalse;
+ }
+ // Add the character
+ ++result;
+ aDest.Append(ch);
+ }
+ }
+
+ __ASSERT_DEBUG(aDest.Length()-oldDestLength == TrimRightLength(aText),
+ Panic(EPanicPostCond_TrimRightAppend));
+ return result;
+ }
+
+
+
+// CWords
+inline CWords::CWords(PbkEngUtils::TIsWordSeparator aWordSeparatorFunc)
+ : iWordSeparatorFunc
+ (aWordSeparatorFunc ?
+ aWordSeparatorFunc : CWords::DefaultIsWordSeparator)
+ {
+ }
+
+CWords* CWords::NewLC
+ (const TDesC& aText,
+ PbkEngUtils::TIsWordSeparator aWordSeparatorFunc)
+ {
+ CWords* self = new(ELeave) CWords(aWordSeparatorFunc);
+ CleanupStack::PushL(self);
+ self->ConstructL(aText);
+ return self;
+ }
+
+CWords::~CWords()
+ {
+ iWords.Close();
+ }
+
+TInt CWords::MdcaCount() const
+ {
+ return iWords.Count();
+ }
+
+TPtrC16 CWords::MdcaPoint(TInt aIndex) const
+ {
+ return iWords[aIndex];
+ }
+
+void CWords::ConstructL(const TDesC& aText)
+ {
+ const TInt textLength = aText.Length();
+ for (TInt beg=0; beg < textLength; ++beg)
+ {
+ // Skip separators before next word
+ if (!iWordSeparatorFunc(aText[beg]))
+ {
+ // Scan the end of the word
+ TInt end = beg;
+ for (; end < textLength && !iWordSeparatorFunc(aText[end]); ++end)
+ {
+ }
+ const TInt len = end-beg;
+ // Append found word to the array
+ User::LeaveIfError(iWords.Append(aText.Mid(beg,len)));
+ // Scan for next word
+ beg = end;
+ }
+ }
+
+ if (iWords.Count()==0 && textLength > 0)
+ {
+ // aText is all word separator characters -> make a "word" out of those
+ User::LeaveIfError(iWords.Append(aText));
+ }
+ }
+
+TBool CWords::DefaultIsWordSeparator(TChar aChar)
+ {
+ return (aChar.IsSpace());
+ }
+
+
+// End of File