vpnengine/eventviewer/src/eventformater.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003 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: Event formatting services.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "eventviewer2.h"
       
    20 
       
    21 #define KEventBufferSizeIncrement  1000
       
    22 #define KConvTypeU    1
       
    23 #define KConvTypeN    2
       
    24 #define KConvTypeA    3
       
    25 
       
    26 
       
    27 ///////////////////////////////////////////////////////////////////
       
    28 //  HBufC* aDestBuf = FormatEvent(TInt aDescrCount, TDesc8 aDescrList,
       
    29 //  aEventString)
       
    30 //
       
    31 //  This function formats an event string loaded from the localisation
       
    32 //  file by replacing the conversion specification elements with the data
       
    33 //  description parameters available in a log event read from the 
       
    34 //  log file.
       
    35 //
       
    36 //  -- aDestBuf = the result of formatting. The caller have to release
       
    37 //     the buffer
       
    38 //  -- aDescrCount = number of data description elements (lth/data
       
    39 //     pairs) in aDescrList.
       
    40 //  -- aDescrList  = LTH, LTH, ... , Data , Data, ...
       
    41 //  -- aEventString = text containing 0 - 20 conversion specification
       
    42 //     elements. The format of conversion specification elements is
       
    43 //     as follows: %N %U or %iN %iU, where % starts a specification,
       
    44 //     N is numeric data, U is Unicode data, i is an optional sequence
       
    45 //     number of description used with this specification (1,2,3...).
       
    46 //
       
    47 ///////////////////////////////////////////////////////////////////
       
    48 HBufC* CEventViewer::FormatEvent(TInt   aDescrCount,
       
    49                                  const TDesC8& aDescrList,
       
    50                                  const TDesC&  aEventString)
       
    51     {
       
    52     TInt  err;
       
    53     TInt  beginOffset;
       
    54     TInt  convSpecOffset;
       
    55     TInt  continueToLoop;
       
    56     TInt  descrNumber;
       
    57     TInt  currDescrNumber;
       
    58     TUint32 convType;
       
    59     TUint32 seqNumber;
       
    60     HBufC*  descrBuf = 0;
       
    61     
       
    62     // Allocate a buffer for the result data. This buffer will
       
    63     // contain the modified event string. The buffer may be extended
       
    64     // during the operation.
       
    65 
       
    66     iResultBuf = HBufC::New( KEventBufferSizeIncrement);
       
    67     if (iResultBuf == 0)
       
    68         {
       
    69         return iResultBuf;
       
    70         }
       
    71     //
       
    72     // Prepare to process an event string 
       
    73     //
       
    74     beginOffset = 0;
       
    75     err         = KErrNone;
       
    76     continueToLoop = ETrue;
       
    77     currDescrNumber = 0;
       
    78     //
       
    79     // Loop here until all conversion specifications of an event string
       
    80     // have been processed
       
    81     //
       
    82     while (continueToLoop)
       
    83         {
       
    84 
       
    85     //  
       
    86     // Locate a conversion specification element (It begins with '%'
       
    87     //
       
    88 
       
    89         convSpecOffset = aEventString.Mid(beginOffset).Locate('%');
       
    90 
       
    91     //
       
    92     // If no prefix (%) found, copy the last or the only part
       
    93     // of text to buffer
       
    94     //
       
    95 
       
    96         if (convSpecOffset == KErrNotFound)
       
    97             {
       
    98             TInt lth = aEventString.Length();
       
    99             if (lth > beginOffset)
       
   100                 {
       
   101                 TPtrC tempPtr = aEventString.Mid(beginOffset, lth - beginOffset);
       
   102                 err = BufferAppend(iResultBuf,
       
   103                                    tempPtr);
       
   104                 }
       
   105             continueToLoop = EFalse;
       
   106             continue;
       
   107             }
       
   108         
       
   109     //  
       
   110     // Copy the part preceding the conv spec to the destination buffer
       
   111     //
       
   112         TPtrC tempPtr = aEventString.Mid(beginOffset, convSpecOffset);
       
   113         err = BufferAppend(iResultBuf,
       
   114                            tempPtr);
       
   115         if (err != KErrNone)
       
   116             {
       
   117             continueToLoop = EFalse;
       
   118             continue;
       
   119             }
       
   120 
       
   121     //  
       
   122     // Analyse the conversion specification element
       
   123     //
       
   124         beginOffset += convSpecOffset + 1;
       
   125         err = AnalyseConvSpec(
       
   126                                  aEventString,
       
   127                                  beginOffset,
       
   128                                  convType,
       
   129                                  seqNumber);
       
   130         if (err != KErrNone)
       
   131             {
       
   132             continueToLoop = EFalse;
       
   133             continue;
       
   134             }
       
   135 
       
   136     //
       
   137     // Define the seq number of the descriptor element
       
   138     //
       
   139     
       
   140         if (seqNumber == 0) {
       
   141             currDescrNumber++,                 // no number in conv spec element
       
   142             descrNumber = currDescrNumber;
       
   143             }
       
   144         else
       
   145             {
       
   146             descrNumber = seqNumber;   // number available in conv spec element
       
   147             }
       
   148 
       
   149     //
       
   150     // Find descritptor from the descriptor list and return the data
       
   151     //
       
   152         descrBuf = 0;
       
   153         descrBuf = GetDescriptorData (
       
   154                                    aDescrCount,
       
   155                                    aDescrList,
       
   156                                    convType,
       
   157                                    descrNumber);
       
   158         if (descrBuf == 0) 
       
   159             {
       
   160             continue;
       
   161             }
       
   162     //
       
   163     // Store the data got from the descriptor list to the
       
   164     // destination  buffer
       
   165     //
       
   166 
       
   167         err = BufferAppend(iResultBuf,
       
   168                            descrBuf->Des());
       
   169         if (err != KErrNone)
       
   170             {
       
   171             continueToLoop = EFalse;
       
   172             continue;
       
   173             }
       
   174         delete descrBuf;
       
   175         descrBuf = 0;
       
   176         beginOffset++;
       
   177         }
       
   178     //
       
   179     // While loop completed
       
   180     //
       
   181     delete descrBuf;
       
   182     return iResultBuf;
       
   183     }
       
   184 ///////////////////////////////////////////////////////////////////
       
   185 //  GetDescriptorData - Searches the requested descriptor and
       
   186 //  returns the data.
       
   187 //
       
   188 //  -- returns: converted data in heap buffer. Caller must delete the
       
   189 //     buffer. Null if no descriptor returned.   
       
   190 //
       
   191 //  -- aDescrCount defines the number of LTH/DATA pairs 
       
   192 //
       
   193 //  --aDescrList has the following format:
       
   194 //     LTH LTH ... DATA DATA ..., where
       
   195 //     --  LTH is TUint32 length of corresponding DATA
       
   196 //     --  DATA is either 32-bit integer or 8-bit byte strings.
       
   197 //
       
   198 //  --aConvType has value KConvTypeN (integer to desimal conversion
       
   199 //    needed) or KConvTypeU (Unicode data)
       
   200 //    or KConvTypeA (8-bits data)
       
   201 //
       
   202 //  -- aDescrNumber is the sequence number of LTH/DATA pair (1, 2..)
       
   203 //
       
   204 //
       
   205 ///////////////////////////////////////////////////////////////////
       
   206 HBufC* CEventViewer::GetDescriptorData (
       
   207                                   TUint32 aDescrCount,
       
   208                                   const TDesC8&  aDescrList,
       
   209                                   TUint32 aConvType,
       
   210                                   TUint32 aDescrNumber)
       
   211 
       
   212     {
       
   213     HBufC* descrDataBuf = 0;
       
   214     TBuf8<4> lthBuf;
       
   215     TUint lth = 0;;
       
   216 
       
   217     //
       
   218     // Check that descriptor number is valid
       
   219     //
       
   220     if (aDescrNumber > aDescrCount ||  aDescrNumber == 0)
       
   221         {
       
   222         return descrDataBuf;      // return Null
       
   223         }
       
   224 
       
   225     TInt dataOffset = 0;
       
   226     TInt lthOffset  = 0;
       
   227     TUint32 currDescrNumber = 1;
       
   228 
       
   229     //
       
   230     // Search the requested LTH/DATA pair 
       
   231     //
       
   232     TInt fillerLth = 0;
       
   233     while (currDescrNumber <= aDescrNumber)
       
   234         {
       
   235         lthBuf.Copy(&aDescrList[lthOffset],4);   // Copy lth to 4 byte buffer
       
   236         lth = *(TInt*) (lthBuf.Ptr());
       
   237         dataOffset += 4;
       
   238         fillerLth = 0;
       
   239         if (currDescrNumber < aDescrNumber)
       
   240             {
       
   241             dataOffset += lth;
       
   242             if (lth % 4 != 0)
       
   243                 {
       
   244                 fillerLth = 4 - (lth % 4);
       
   245                 }
       
   246             dataOffset += fillerLth;         // Remainder is filler count in data
       
   247             }
       
   248         lthOffset += 4;
       
   249         currDescrNumber++;
       
   250         }
       
   251     dataOffset += 4 * (aDescrCount - (currDescrNumber - 1)); // rest of lth fields
       
   252     
       
   253     // 
       
   254     // Convert integer to character string
       
   255     //
       
   256 
       
   257     if (aConvType == KConvTypeN)
       
   258         {
       
   259         TInt intValue;
       
   260         if (lth != 4)
       
   261             {
       
   262             return descrDataBuf;      // return 0, because wrong size for integer
       
   263             }
       
   264         descrDataBuf = HBufC::New(16);
       
   265         if (descrDataBuf !=0)
       
   266             {
       
   267             TPtr descrDataPtr(descrDataBuf->Des());
       
   268             TPtrC8 ptr8 = aDescrList.Mid(dataOffset, 4);
       
   269             intValue = *(TInt*) (ptr8.Ptr());
       
   270             descrDataPtr.Num(intValue);
       
   271             }
       
   272         return descrDataBuf;
       
   273         }
       
   274     else if (aConvType == KConvTypeA)
       
   275 
       
   276     //
       
   277     // ConvType == A, convert 8-bit string to unicode   
       
   278     //  
       
   279         {
       
   280         descrDataBuf = HBufC::New(lth);
       
   281         if (descrDataBuf == 0)
       
   282             {
       
   283             return descrDataBuf;
       
   284             }
       
   285         TPtr descrDataPtr(descrDataBuf->Des());
       
   286         TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth);
       
   287         descrDataPtr.Copy(ptr8);
       
   288         return descrDataBuf;
       
   289         }
       
   290     else
       
   291 
       
   292     //
       
   293     // ConvType == U, unicode string, only copy data
       
   294     //  
       
   295         {
       
   296         descrDataBuf = HBufC::New(lth/2);
       
   297         if (descrDataBuf == 0)
       
   298             {
       
   299             return descrDataBuf;
       
   300             }
       
   301         TPtr descrDataPtr(descrDataBuf->Des());
       
   302         TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth);
       
   303         TPtrC ptr16(reinterpret_cast<const TUint16*>(ptr8.Ptr()), ptr8.Length() / 2);;
       
   304         descrDataPtr.Copy(ptr16);
       
   305         return descrDataBuf;
       
   306         }
       
   307     }
       
   308         
       
   309 ///////////////////////////////////////////////////////////////////
       
   310 //  AnalyseConvSpec - Analyse Conversion Specification string
       
   311 //  The format of string is as follows:
       
   312 //  %U or %N or %A or %sU or %sN or %sA where:
       
   313 //  --  % is prefix
       
   314 //  --  U means Unicode (16-bits) data
       
   315 //  --  A means 8-bits data
       
   316 //  --  N means numeric data
       
   317 //  --  s means 1 or 2 character sequence number    
       
   318 ///////////////////////////////////////////////////////////////////
       
   319 TInt CEventViewer::AnalyseConvSpec(
       
   320                                const TDesC&    aSourceBuf,
       
   321                                TInt&     aOffset,         // input/output
       
   322                                TUint32&  aConvType,       // U or N
       
   323                                TUint32&  aSeqNumber)
       
   324     {
       
   325     TInt currOffset = aOffset;
       
   326     TUint32 seqNumber = 0;
       
   327     TUint32 convType;
       
   328     TInt   sourceDataLeft = aSourceBuf.Length() -  aOffset;
       
   329     TBuf<2> seqNumberBuf;
       
   330 
       
   331     // One byte data should exist
       
   332     
       
   333     if (sourceDataLeft < 1)
       
   334         {
       
   335         return KErrNotFound;
       
   336         }
       
   337 
       
   338     // Check if 1 or 2 byte long sequence number follows. Value
       
   339     // should be 1 - 20.
       
   340     
       
   341     if (aSourceBuf[currOffset] >= '0' && 
       
   342           aSourceBuf[currOffset] <= '9')
       
   343         {
       
   344         seqNumberBuf.Copy(&aSourceBuf[currOffset], 1);
       
   345         currOffset++;
       
   346         sourceDataLeft--; 
       
   347         
       
   348         if (aSourceBuf[currOffset] >= '0' && 
       
   349             aSourceBuf[currOffset] <= '9')
       
   350             {
       
   351             seqNumberBuf.Append(&aSourceBuf[currOffset], 1);
       
   352             currOffset++;
       
   353             sourceDataLeft--;
       
   354             }
       
   355         TLex seqNumberLex(seqNumberBuf);
       
   356         seqNumberLex.Val(seqNumber, EDecimal);
       
   357         if (seqNumber == 0 || seqNumber > 20)
       
   358             {
       
   359             return KErrNotFound;
       
   360             }
       
   361         }
       
   362 
       
   363     // One byte data should exist
       
   364 
       
   365     if (sourceDataLeft < 1)
       
   366         {
       
   367         return KErrNotFound;
       
   368         }
       
   369 
       
   370     // Check if the conversion type is U
       
   371 
       
   372 
       
   373     if (aSourceBuf[currOffset] == 'U' || 
       
   374          aSourceBuf[currOffset] == 'u')
       
   375         {
       
   376         convType = KConvTypeU;
       
   377         } 
       
   378 
       
   379     // Check if the conversion type is N
       
   380 
       
   381     else if
       
   382         (aSourceBuf[currOffset] == 'N' || 
       
   383           aSourceBuf[currOffset] == 'n')
       
   384         {
       
   385         convType = KConvTypeN;
       
   386         }
       
   387     
       
   388     // Check if the conversion type is A
       
   389 
       
   390     else if
       
   391         (aSourceBuf[currOffset] == 'A' || 
       
   392           aSourceBuf[currOffset] == 'a')
       
   393         {
       
   394         convType = KConvTypeA;
       
   395         }
       
   396     else
       
   397         {
       
   398         return KErrNotFound;
       
   399         }
       
   400     
       
   401     // Return parameters to caller
       
   402 
       
   403     aConvType   = convType;
       
   404     aOffset     = currOffset;
       
   405     aSeqNumber  = seqNumber;
       
   406     return KErrNone;
       
   407     }
       
   408 
       
   409 
       
   410 
       
   411 ///////////////////////////////////////////////////////////////
       
   412 // BufferAppend()
       
   413 // This function appends a buffer by storing a new string.
       
   414 // If the buffer does not have space enough, the function extends
       
   415 // the buffer.
       
   416 //
       
   417 ///////////////////////////////////////////////////////////////
       
   418 TInt CEventViewer::BufferAppend(HBufC*& aDestBuf,
       
   419                                 const TDesC& aString)
       
   420     {
       
   421     TInt err = KErrNone;
       
   422     // Make sure that we have enough space for the new text
       
   423 
       
   424     TInt spaceLeft = aDestBuf->Des().MaxLength() - aDestBuf->Des().Length();
       
   425     if (aString.Length() > spaceLeft)
       
   426         {
       
   427     // Allocate enough space for the new string + some additional
       
   428     // free space so that allocations are not too frequent
       
   429 
       
   430         TInt newMaxLength = aDestBuf->Des().MaxLength() + aString.Length() + KEventBufferSizeIncrement;
       
   431         HBufC* tempBuf = aDestBuf->ReAlloc(newMaxLength);
       
   432         if (tempBuf != NULL)
       
   433             {
       
   434             aDestBuf = tempBuf;
       
   435             }
       
   436         else
       
   437             {
       
   438             err = KErrNoMemory;
       
   439             }
       
   440         }
       
   441     //
       
   442     // Store current string to the buffer
       
   443     //
       
   444     aDestBuf->Des().Append(aString);
       
   445     return err;
       
   446     }
       
   447 
       
   448 
       
   449