phonebookui/Phonebook/Engine/src/PbkEngUtils.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002 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: 
       
    15 *		Namespace structure for Phonebook engine helper functions
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <PbkEngUtils.h>
       
    22 #include <f32file.h>
       
    23 #include <barsc.h>
       
    24 #include <bautils.h>
       
    25 #include <featmgr.h>
       
    26 #include "PbkDataCaging.hrh"
       
    27 
       
    28 /// Unnamed namespace for local definitions
       
    29 namespace __RVCT_UNS_PbkEngUtils {
       
    30 
       
    31 // LOCAL CONSTANTS
       
    32 enum TPanicCode
       
    33     {
       
    34     EPanicPreCond_CopyAndReplaceChars = 1,
       
    35     EPanicPostCond_TrimAllLength,
       
    36     EPanicPostCond_TrimRightLength,
       
    37     EPanicPreCond_TrimAllAppend,
       
    38     EPanicPostCond_TrimAllAppend,
       
    39     EPanicPreCond_TrimRightAppend,
       
    40     EPanicPostCond_TrimRightAppend
       
    41 
       
    42     };
       
    43 
       
    44 _LIT(KEngDefResFileName, "PbkEng.rsc");  // default resource file name
       
    45 _LIT(KEngChineseResFileName, "PbkEngChinese.rsc");   // Chinese resource
       
    46 _LIT(KEngJapaneseResFileName, "PbkEngJapanese.rsc"); // Japanese resource
       
    47 
       
    48 // ================= LOCAL FUNCTIONS =======================
       
    49 #ifdef _DEBUG
       
    50 void Panic(TPanicCode aReason)
       
    51     {
       
    52     _LIT(KPanicText, "PbkEngUtils");
       
    53     User::Panic(KPanicText, aReason);
       
    54     }
       
    55 #endif
       
    56 
       
    57 const TUint KPbkZWSCharacter = 0x200B;
       
    58 const TUint KPbkZWNJCharacter = 0x200C;
       
    59 
       
    60 // Check if the given char is a Zero Width Space or Non-Joiner character
       
    61 inline TBool ZWSCharacter( const TChar aChar )
       
    62     {
       
    63     const TChar zwsChar( KPbkZWSCharacter );
       
    64     const TChar zwnjChar( KPbkZWNJCharacter );
       
    65     return (aChar == zwsChar) || (aChar == zwnjChar);
       
    66     }
       
    67 
       
    68 /**
       
    69  * Implementation class for PbkEngUtils::BreakInWordsLC.
       
    70  */
       
    71 NONSHARABLE_CLASS(CWords) : 
       
    72         public CBase, 
       
    73         public MDesCArray
       
    74     {
       
    75     public:  // Constructors and destructor
       
    76         /**
       
    77          * Creates a new instance of this class.
       
    78 		 * @param aText the text to separate
       
    79 		 * @param aWordSeparatorFunc function for detecting
       
    80 		 *        word separator characters
       
    81          */
       
    82         static CWords* NewLC
       
    83             (const TDesC& aText, 
       
    84             PbkEngUtils::TIsWordSeparator aWordSeparatorFunc);
       
    85         /**
       
    86          * Destructor.
       
    87 		 */
       
    88         ~CWords();
       
    89         
       
    90     public:  // from MDesCArray
       
    91         TInt MdcaCount() const;
       
    92         TPtrC16 MdcaPoint(TInt aIndex) const;
       
    93 
       
    94     private:  // Implementation
       
    95         CWords(PbkEngUtils::TIsWordSeparator aWordSeparatorFunc);
       
    96         void ConstructL
       
    97             (const TDesC& aText);
       
    98         static TBool DefaultIsWordSeparator(TChar aChar);
       
    99 
       
   100     private:
       
   101 		/// Own: function for detecting word separator characters
       
   102         PbkEngUtils::TIsWordSeparator iWordSeparatorFunc;
       
   103 		/// Own: array of words
       
   104         RArray<TPtrC> iWords;
       
   105     };
       
   106     
       
   107 /**
       
   108  * Solves correct language specific engine resource filename. 
       
   109  *
       
   110  * @return A reference to resource file
       
   111  */
       
   112 inline const TDesC& EngResFileName()
       
   113     {
       
   114     if (FeatureManager::FeatureSupported(KFeatureIdChinese))
       
   115         {
       
   116         return KEngChineseResFileName;
       
   117         }
       
   118     else if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
       
   119         {
       
   120         return KEngJapaneseResFileName;
       
   121         }
       
   122     return KEngDefResFileName;
       
   123     }
       
   124     
       
   125     
       
   126 }
       
   127 using namespace __RVCT_UNS_PbkEngUtils;
       
   128 
       
   129 
       
   130 // ================= MEMBER FUNCTIONS =======================
       
   131 
       
   132 EXPORT_C void PbkEngUtils::FindAndOpenResourceFileLC
       
   133         (RFs& aFs, 
       
   134         const TDesC& aResFileName, 
       
   135         const TDesC& aResFilePath, 
       
   136         const TDesC& aResFileDrive,
       
   137         RResourceFile& aResFile)
       
   138     {
       
   139     _LIT(KSeparator, "\\");
       
   140     TFileName fileName;
       
   141     fileName.Copy(aResFileDrive);
       
   142     fileName.Append(aResFilePath);
       
   143     fileName.Append(KSeparator);
       
   144     fileName.Append(aResFileName);
       
   145 
       
   146 	BaflUtils::NearestLanguageFile(aFs, fileName);
       
   147     aResFile.OpenL(aFs, fileName);
       
   148     CleanupClosePushL(aResFile);
       
   149     }
       
   150 
       
   151 EXPORT_C void PbkEngUtils::FindAndOpenDefaultResourceFileLC
       
   152         (RFs& aFs, 
       
   153         RResourceFile& aResFile)
       
   154     {
       
   155     FindAndOpenResourceFileLC(aFs, EngResFileName(), KDC_RESOURCE_FILES_DIR, 
       
   156             KPbkRomFileDrive, aResFile);
       
   157     aResFile.ConfirmSignatureL();
       
   158     }
       
   159 
       
   160 EXPORT_C TInt PbkEngUtils::CopyDigitsFromEnd(
       
   161         const TDesC& aNumText, 
       
   162         TInt aNumberOfDigits,
       
   163         TDes& aDigitsText)
       
   164     {
       
   165     aDigitsText.Zero();
       
   166     // Scan aNumText from the end
       
   167     TInt pos = aNumText.Length();
       
   168 
       
   169     // Loop for number of digits to extract
       
   170     TInt digit = 0;
       
   171     for (; digit < aNumberOfDigits; ++digit)
       
   172         {
       
   173         // Scan aNumText backwars for the next number
       
   174         while (--pos >= 0 && !TChar(aNumText[pos]).IsDigit()) { }
       
   175         if (pos < 0)
       
   176             break;
       
   177         // Number found, append it to result string
       
   178         aDigitsText.Append(aNumText[pos]);
       
   179         }
       
   180 
       
   181     // Reverse result string to correct order
       
   182     TInt end = aDigitsText.Length();
       
   183     for (pos = 0; pos < --end ; ++pos)
       
   184         {
       
   185         const TText tmp = aDigitsText[pos];
       
   186         aDigitsText[pos] = aDigitsText[end];
       
   187         aDigitsText[end] = tmp;
       
   188         }
       
   189 
       
   190     // Return number of digits extracted
       
   191     return digit;
       
   192     }
       
   193 
       
   194 EXPORT_C TBool PbkEngUtils::ContainSameDigits
       
   195         (const TDesC& aNumText1, 
       
   196         const TDesC& aNumText2, 
       
   197         TInt aNumberOfDigits/*=0*/)
       
   198     {
       
   199     TInt pos1 = aNumText1.Length();
       
   200     TInt pos2 = aNumText2.Length();
       
   201     FOREVER
       
   202         {
       
   203         // Scan for the next digit in both strings
       
   204         while (--pos1 >= 0 && !TChar(aNumText1[pos1]).IsDigit()) { }
       
   205         while (--pos2 >= 0 && !TChar(aNumText2[pos2]).IsDigit()) { }
       
   206 
       
   207         if (pos1 < 0 && pos2 < 0)
       
   208             {
       
   209             // Run to the end of both strings
       
   210             break;
       
   211             }
       
   212 
       
   213         if ((pos1 < 0 && pos2 >= 0) || (pos1 >= 0 && pos2 < 0))
       
   214             {
       
   215             // Run out of the other string while the other still
       
   216             // contains digits to compare
       
   217             return EFalse;
       
   218             }
       
   219 
       
   220         if (pos1 >= 0 && pos2 >= 0 && aNumText1[pos1] != aNumText2[pos2])
       
   221             {
       
   222             // Different digits found
       
   223             return EFalse;
       
   224             }
       
   225 
       
   226         if (--aNumberOfDigits == 0)
       
   227             {
       
   228             // All requested digits compared ok
       
   229             break;
       
   230             }
       
   231         }
       
   232 
       
   233     // Didn't find nonmatching digits
       
   234     return ETrue;
       
   235     }
       
   236 
       
   237 EXPORT_C TInt PbkEngUtils::AppendAndReplaceChars
       
   238         (TDes& aDest, const TDesC& aSrc, 
       
   239         const TDesC& aCharsToReplace, const TDesC& aReplaceChars)
       
   240     {
       
   241     // Check that aDest has enough capacity
       
   242     __ASSERT_DEBUG((aDest.MaxLength()-aDest.Length()) >= aSrc.Length(),
       
   243         Panic(EPanicPreCond_CopyAndReplaceChars));
       
   244     // Check that a replacament is provided for all characters
       
   245     __ASSERT_DEBUG(aCharsToReplace.Length() == aReplaceChars.Length(),
       
   246         Panic(EPanicPreCond_CopyAndReplaceChars));
       
   247 
       
   248     TInt count, i;
       
   249     const TInt sourceLenght = aSrc.Length();
       
   250     for (count=0, i=0; i < sourceLenght; ++i)
       
   251         {
       
   252         TText ch = aSrc[i];
       
   253         const TInt replacePos = aCharsToReplace.Locate(aSrc[i]);
       
   254         if (replacePos != KErrNotFound)
       
   255             {
       
   256             ++count;
       
   257             ch = aReplaceChars[replacePos];
       
   258             }
       
   259         aDest.Append(ch);
       
   260         }
       
   261 
       
   262     return count;
       
   263     }
       
   264 
       
   265 EXPORT_C TInt PbkEngUtils::CountSpaces(const TDesC& aText)
       
   266     {
       
   267     TInt result = 0;
       
   268     const TInt length = aText.Length();
       
   269     for (TInt i=0; i<length; ++i)
       
   270         {
       
   271         if (TChar(aText[i]).IsSpace())
       
   272             {
       
   273             ++result;
       
   274             }
       
   275         }
       
   276     return result;
       
   277     }
       
   278 
       
   279 EXPORT_C void PbkEngUtils::ReplaceNonGraphicCharacters
       
   280         (TDes& aText, TText aChar)
       
   281     {
       
   282     const TInt len = aText.Length();
       
   283     for (TInt i=0; i < len; ++i)
       
   284         {
       
   285         if (!TChar(aText[i]).IsGraph() &&
       
   286             !ZWSCharacter( aText[i] ) )
       
   287             {
       
   288             // replace non-graphic character with aChar
       
   289             aText[i] = aChar;
       
   290             }
       
   291         }
       
   292     }
       
   293 
       
   294 EXPORT_C void PbkEngUtils::AppendGraphicCharacters
       
   295         (TDes& aDest, const TDesC& aSrc, TText aChar)
       
   296     {
       
   297     const TInt len = aSrc.Length();
       
   298     for (TInt i=0; i < len; ++i)
       
   299         {
       
   300         TText ch(aSrc[i]);
       
   301         if (TChar(ch).IsGraph() || 
       
   302             ZWSCharacter(ch))
       
   303             {
       
   304             aDest.Append(ch);
       
   305             }
       
   306         else
       
   307             {
       
   308             aDest.Append(aChar);
       
   309             }
       
   310         }
       
   311     }
       
   312 
       
   313 EXPORT_C MDesCArray* PbkEngUtils::BreakInWordsLC
       
   314         (const TDesC& aText, 
       
   315         TIsWordSeparator aWordSeparatorFunc/*=NULL*/)
       
   316     {
       
   317     return CWords::NewLC(aText,aWordSeparatorFunc);
       
   318     }
       
   319 
       
   320 EXPORT_C HBufC* PbkEngUtils::AllocL(HBufC* aBuffer, TInt aMaxLength)
       
   321     {
       
   322     if (aBuffer)
       
   323         {
       
   324         TPtr bufPtr(aBuffer->Des());
       
   325         if (bufPtr.MaxLength() < aMaxLength)
       
   326             {
       
   327             aBuffer = aBuffer->ReAllocL(aMaxLength);
       
   328             }
       
   329         }
       
   330     else
       
   331         {
       
   332         aBuffer = HBufC::NewL(aMaxLength);
       
   333         }
       
   334     return aBuffer;
       
   335     }
       
   336 
       
   337 EXPORT_C HBufC* PbkEngUtils::CopyL
       
   338         (HBufC* aBuffer, const TDesC& aText, TInt aMinBufLength/*=0*/)
       
   339     {
       
   340     aBuffer = AllocL(aBuffer,Max(aText.Length(),aMinBufLength));
       
   341     *aBuffer = aText;
       
   342     return aBuffer;
       
   343     }
       
   344 
       
   345 EXPORT_C TInt PbkEngUtils::TrimAllLength(const TDesC& aText)
       
   346     {
       
   347     const TInt textLength=aText.Length();
       
   348     TInt result=0;
       
   349     TBool uncommittedSpace=EFalse;
       
   350     for (TInt i=0; i < textLength; ++i)
       
   351         {
       
   352         if (TChar(aText[i]).IsSpace())
       
   353             {
       
   354             if (result > 0)
       
   355                 {
       
   356                 // Not a leading space, set uncommitted space flag
       
   357                 uncommittedSpace = ETrue;
       
   358                 }
       
   359             }
       
   360         else
       
   361             {
       
   362             if (uncommittedSpace)
       
   363                 {
       
   364                 // Add previously encountered space(s)
       
   365                 ++result;
       
   366                 uncommittedSpace = EFalse;
       
   367                 }
       
   368             // Add the character
       
   369             ++result;
       
   370             }
       
   371         }
       
   372 
       
   373     __ASSERT_DEBUG(result <= aText.Length(), 
       
   374         Panic(EPanicPostCond_TrimAllLength));
       
   375     return result;
       
   376     }
       
   377 
       
   378 EXPORT_C TInt PbkEngUtils::TrimAllAppend(const TDesC& aText, TDes& aDest)
       
   379     {
       
   380 #ifdef _DEBUG
       
   381     const TInt oldDestLength = aDest.Length();
       
   382     __ASSERT_DEBUG(aDest.MaxLength()-oldDestLength >= TrimAllLength(aText), 
       
   383         Panic(EPanicPreCond_TrimAllAppend));
       
   384 #endif
       
   385 
       
   386     const TInt textLength=aText.Length();
       
   387     TInt result=0;
       
   388     TBool uncommittedSpace=EFalse;
       
   389     for (TInt i=0; i < textLength; ++i)
       
   390         {
       
   391         const TChar ch(aText[i]);
       
   392         if (ch.IsSpace() &&
       
   393             !ZWSCharacter( ch ) )
       
   394             {
       
   395             if (result > 0)
       
   396                 {
       
   397                 // Not a leading space, set uncommitted space flag
       
   398                 uncommittedSpace = ETrue;
       
   399                 }
       
   400             }
       
   401         else
       
   402             {
       
   403             if (uncommittedSpace)
       
   404                 {
       
   405                 // Add previously encountered space(s)
       
   406                 ++result;
       
   407                 aDest.Append(' ');
       
   408                 uncommittedSpace = EFalse;
       
   409                 }
       
   410             // Add the character
       
   411             ++result;
       
   412             aDest.Append(ch);
       
   413             }
       
   414         }
       
   415 
       
   416     __ASSERT_DEBUG(aDest.Length()-oldDestLength == TrimAllLength(aText), 
       
   417         Panic(EPanicPostCond_TrimAllAppend));
       
   418     return result;
       
   419     }
       
   420 
       
   421 EXPORT_C TInt PbkEngUtils::TrimRightLength(const TDesC& aText)
       
   422     {
       
   423     const TInt textLength=aText.Length();
       
   424     TInt result=0;
       
   425     TBool uncommittedSpace=EFalse;
       
   426     TBool leadingSpace=ETrue;
       
   427     for (TInt i=0; i < textLength; ++i)
       
   428         {
       
   429         if (TChar(aText[i]).IsSpace() &&
       
   430             !ZWSCharacter( aText[i] ) )
       
   431             {
       
   432             if (leadingSpace)
       
   433                 {
       
   434                 // Add all leading spaces
       
   435                 ++result;
       
   436                 }
       
   437             else
       
   438                 {
       
   439                 // Not a leading space, set uncommitted space flag
       
   440                 uncommittedSpace = ETrue;
       
   441                 }
       
   442             }
       
   443         else
       
   444             {
       
   445             // First non-space character found, adjust leading space flag
       
   446             leadingSpace = EFalse;
       
   447             if (uncommittedSpace)
       
   448                 {
       
   449                 // Add previously encountered space(s)
       
   450                 ++result;
       
   451                 uncommittedSpace = EFalse;
       
   452                 }
       
   453             // Add the character
       
   454             ++result;
       
   455             }
       
   456         }
       
   457 
       
   458     __ASSERT_DEBUG(result <= aText.Length(), 
       
   459         Panic(EPanicPostCond_TrimRightLength));
       
   460     return result;
       
   461     }
       
   462 
       
   463 EXPORT_C TInt PbkEngUtils::TrimRightAppend(const TDesC& aText, TDes& aDest)
       
   464     {
       
   465 #ifdef _DEBUG
       
   466     const TInt oldDestLength = aDest.Length();
       
   467     __ASSERT_DEBUG(aDest.MaxLength()-oldDestLength >= TrimRightLength(aText), 
       
   468         Panic(EPanicPreCond_TrimRightAppend));
       
   469 #endif
       
   470 
       
   471     const TInt textLength=aText.Length();
       
   472     TInt result=0;
       
   473     TBool uncommittedSpace=EFalse;
       
   474     TBool leadingSpace=ETrue;
       
   475     for (TInt i=0; i < textLength; ++i)
       
   476         {
       
   477         const TChar ch(aText[i]);
       
   478         if (ch.IsSpace() &&
       
   479             !ZWSCharacter( ch ) )
       
   480             {
       
   481             if (leadingSpace)
       
   482                 {
       
   483                 // Add all leading spaces
       
   484                 ++result;
       
   485                 aDest.Append(' ');
       
   486                 }
       
   487             else
       
   488                 {
       
   489                 // Not a leading space, set uncommitted space flag
       
   490                 uncommittedSpace = ETrue;
       
   491                 }
       
   492             }
       
   493         else
       
   494             {
       
   495             // First non-space character found, adjust leading space flag
       
   496             leadingSpace = EFalse;
       
   497             if (uncommittedSpace)
       
   498                 {
       
   499                 // Add previously encountered space(s)
       
   500                 ++result;
       
   501                 aDest.Append(' ');
       
   502                 uncommittedSpace = EFalse;
       
   503                 }
       
   504             // Add the character
       
   505             ++result;
       
   506             aDest.Append(ch);
       
   507             }
       
   508         }
       
   509 
       
   510     __ASSERT_DEBUG(aDest.Length()-oldDestLength == TrimRightLength(aText), 
       
   511         Panic(EPanicPostCond_TrimRightAppend));
       
   512     return result;
       
   513     }
       
   514 
       
   515 
       
   516 
       
   517 // CWords
       
   518 inline CWords::CWords(PbkEngUtils::TIsWordSeparator aWordSeparatorFunc)
       
   519     : iWordSeparatorFunc
       
   520         (aWordSeparatorFunc ? 
       
   521         aWordSeparatorFunc : CWords::DefaultIsWordSeparator)
       
   522     {
       
   523     }
       
   524 
       
   525 CWords* CWords::NewLC
       
   526         (const TDesC& aText, 
       
   527         PbkEngUtils::TIsWordSeparator aWordSeparatorFunc)
       
   528     {
       
   529     CWords* self = new(ELeave) CWords(aWordSeparatorFunc);
       
   530     CleanupStack::PushL(self);
       
   531     self->ConstructL(aText);
       
   532     return self;
       
   533     }
       
   534 
       
   535 CWords::~CWords()
       
   536     {
       
   537     iWords.Close();
       
   538     }
       
   539 
       
   540 TInt CWords::MdcaCount() const
       
   541     {
       
   542     return iWords.Count();
       
   543     }
       
   544 
       
   545 TPtrC16 CWords::MdcaPoint(TInt aIndex) const
       
   546     {
       
   547     return iWords[aIndex];
       
   548     }
       
   549 
       
   550 void CWords::ConstructL(const TDesC& aText)
       
   551     {
       
   552     const TInt textLength = aText.Length();
       
   553     for (TInt beg=0; beg < textLength; ++beg)
       
   554         {
       
   555         // Skip separators before next word
       
   556         if (!iWordSeparatorFunc(aText[beg]))
       
   557             {
       
   558             // Scan the end of the word
       
   559             TInt end = beg;
       
   560             for (; end < textLength && !iWordSeparatorFunc(aText[end]); ++end)
       
   561                 {
       
   562                 }
       
   563             const TInt len = end-beg;
       
   564             // Append found word to the array
       
   565             User::LeaveIfError(iWords.Append(aText.Mid(beg,len)));
       
   566             // Scan for next word
       
   567             beg = end;
       
   568             }
       
   569         }
       
   570 
       
   571     if (iWords.Count()==0 && textLength > 0)
       
   572         {
       
   573         // aText is all word separator characters -> make a "word" out of those
       
   574         User::LeaveIfError(iWords.Append(aText));
       
   575         }
       
   576     }
       
   577 
       
   578 TBool CWords::DefaultIsWordSeparator(TChar aChar)
       
   579     {
       
   580     return (aChar.IsSpace());
       
   581     }
       
   582 
       
   583 
       
   584 // End of File