vpnengine/eventviewer/src/eventformater.cpp
changeset 0 33413c0669b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/eventviewer/src/eventformater.cpp	Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,449 @@
+/*
+* Copyright (c) 2003 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: Event formatting services.
+*
+*/
+
+
+#include "eventviewer2.h"
+
+#define KEventBufferSizeIncrement  1000
+#define KConvTypeU    1
+#define KConvTypeN    2
+#define KConvTypeA    3
+
+
+///////////////////////////////////////////////////////////////////
+//  HBufC* aDestBuf = FormatEvent(TInt aDescrCount, TDesc8 aDescrList,
+//  aEventString)
+//
+//  This function formats an event string loaded from the localisation
+//  file by replacing the conversion specification elements with the data
+//  description parameters available in a log event read from the 
+//  log file.
+//
+//  -- aDestBuf = the result of formatting. The caller have to release
+//     the buffer
+//  -- aDescrCount = number of data description elements (lth/data
+//     pairs) in aDescrList.
+//  -- aDescrList  = LTH, LTH, ... , Data , Data, ...
+//  -- aEventString = text containing 0 - 20 conversion specification
+//     elements. The format of conversion specification elements is
+//     as follows: %N %U or %iN %iU, where % starts a specification,
+//     N is numeric data, U is Unicode data, i is an optional sequence
+//     number of description used with this specification (1,2,3...).
+//
+///////////////////////////////////////////////////////////////////
+HBufC* CEventViewer::FormatEvent(TInt   aDescrCount,
+                                 const TDesC8& aDescrList,
+                                 const TDesC&  aEventString)
+    {
+    TInt  err;
+    TInt  beginOffset;
+    TInt  convSpecOffset;
+    TInt  continueToLoop;
+    TInt  descrNumber;
+    TInt  currDescrNumber;
+    TUint32 convType;
+    TUint32 seqNumber;
+    HBufC*  descrBuf = 0;
+    
+    // Allocate a buffer for the result data. This buffer will
+    // contain the modified event string. The buffer may be extended
+    // during the operation.
+
+    iResultBuf = HBufC::New( KEventBufferSizeIncrement);
+    if (iResultBuf == 0)
+        {
+        return iResultBuf;
+        }
+    //
+    // Prepare to process an event string 
+    //
+    beginOffset = 0;
+    err         = KErrNone;
+    continueToLoop = ETrue;
+    currDescrNumber = 0;
+    //
+    // Loop here until all conversion specifications of an event string
+    // have been processed
+    //
+    while (continueToLoop)
+        {
+
+    //  
+    // Locate a conversion specification element (It begins with '%'
+    //
+
+        convSpecOffset = aEventString.Mid(beginOffset).Locate('%');
+
+    //
+    // If no prefix (%) found, copy the last or the only part
+    // of text to buffer
+    //
+
+        if (convSpecOffset == KErrNotFound)
+            {
+            TInt lth = aEventString.Length();
+            if (lth > beginOffset)
+                {
+                TPtrC tempPtr = aEventString.Mid(beginOffset, lth - beginOffset);
+                err = BufferAppend(iResultBuf,
+                                   tempPtr);
+                }
+            continueToLoop = EFalse;
+            continue;
+            }
+        
+    //  
+    // Copy the part preceding the conv spec to the destination buffer
+    //
+        TPtrC tempPtr = aEventString.Mid(beginOffset, convSpecOffset);
+        err = BufferAppend(iResultBuf,
+                           tempPtr);
+        if (err != KErrNone)
+            {
+            continueToLoop = EFalse;
+            continue;
+            }
+
+    //  
+    // Analyse the conversion specification element
+    //
+        beginOffset += convSpecOffset + 1;
+        err = AnalyseConvSpec(
+                                 aEventString,
+                                 beginOffset,
+                                 convType,
+                                 seqNumber);
+        if (err != KErrNone)
+            {
+            continueToLoop = EFalse;
+            continue;
+            }
+
+    //
+    // Define the seq number of the descriptor element
+    //
+    
+        if (seqNumber == 0) {
+            currDescrNumber++,                 // no number in conv spec element
+            descrNumber = currDescrNumber;
+            }
+        else
+            {
+            descrNumber = seqNumber;   // number available in conv spec element
+            }
+
+    //
+    // Find descritptor from the descriptor list and return the data
+    //
+        descrBuf = 0;
+        descrBuf = GetDescriptorData (
+                                   aDescrCount,
+                                   aDescrList,
+                                   convType,
+                                   descrNumber);
+        if (descrBuf == 0) 
+            {
+            continue;
+            }
+    //
+    // Store the data got from the descriptor list to the
+    // destination  buffer
+    //
+
+        err = BufferAppend(iResultBuf,
+                           descrBuf->Des());
+        if (err != KErrNone)
+            {
+            continueToLoop = EFalse;
+            continue;
+            }
+        delete descrBuf;
+        descrBuf = 0;
+        beginOffset++;
+        }
+    //
+    // While loop completed
+    //
+    delete descrBuf;
+    return iResultBuf;
+    }
+///////////////////////////////////////////////////////////////////
+//  GetDescriptorData - Searches the requested descriptor and
+//  returns the data.
+//
+//  -- returns: converted data in heap buffer. Caller must delete the
+//     buffer. Null if no descriptor returned.   
+//
+//  -- aDescrCount defines the number of LTH/DATA pairs 
+//
+//  --aDescrList has the following format:
+//     LTH LTH ... DATA DATA ..., where
+//     --  LTH is TUint32 length of corresponding DATA
+//     --  DATA is either 32-bit integer or 8-bit byte strings.
+//
+//  --aConvType has value KConvTypeN (integer to desimal conversion
+//    needed) or KConvTypeU (Unicode data)
+//    or KConvTypeA (8-bits data)
+//
+//  -- aDescrNumber is the sequence number of LTH/DATA pair (1, 2..)
+//
+//
+///////////////////////////////////////////////////////////////////
+HBufC* CEventViewer::GetDescriptorData (
+                                  TUint32 aDescrCount,
+                                  const TDesC8&  aDescrList,
+                                  TUint32 aConvType,
+                                  TUint32 aDescrNumber)
+
+    {
+    HBufC* descrDataBuf = 0;
+    TBuf8<4> lthBuf;
+    TUint lth = 0;;
+
+    //
+    // Check that descriptor number is valid
+    //
+    if (aDescrNumber > aDescrCount ||  aDescrNumber == 0)
+        {
+        return descrDataBuf;      // return Null
+        }
+
+    TInt dataOffset = 0;
+    TInt lthOffset  = 0;
+    TUint32 currDescrNumber = 1;
+
+    //
+    // Search the requested LTH/DATA pair 
+    //
+    TInt fillerLth = 0;
+    while (currDescrNumber <= aDescrNumber)
+        {
+        lthBuf.Copy(&aDescrList[lthOffset],4);   // Copy lth to 4 byte buffer
+        lth = *(TInt*) (lthBuf.Ptr());
+        dataOffset += 4;
+        fillerLth = 0;
+        if (currDescrNumber < aDescrNumber)
+            {
+            dataOffset += lth;
+            if (lth % 4 != 0)
+                {
+                fillerLth = 4 - (lth % 4);
+                }
+            dataOffset += fillerLth;         // Remainder is filler count in data
+            }
+        lthOffset += 4;
+        currDescrNumber++;
+        }
+    dataOffset += 4 * (aDescrCount - (currDescrNumber - 1)); // rest of lth fields
+    
+    // 
+    // Convert integer to character string
+    //
+
+    if (aConvType == KConvTypeN)
+        {
+        TInt intValue;
+        if (lth != 4)
+            {
+            return descrDataBuf;      // return 0, because wrong size for integer
+            }
+        descrDataBuf = HBufC::New(16);
+        if (descrDataBuf !=0)
+            {
+            TPtr descrDataPtr(descrDataBuf->Des());
+            TPtrC8 ptr8 = aDescrList.Mid(dataOffset, 4);
+            intValue = *(TInt*) (ptr8.Ptr());
+            descrDataPtr.Num(intValue);
+            }
+        return descrDataBuf;
+        }
+    else if (aConvType == KConvTypeA)
+
+    //
+    // ConvType == A, convert 8-bit string to unicode   
+    //  
+        {
+        descrDataBuf = HBufC::New(lth);
+        if (descrDataBuf == 0)
+            {
+            return descrDataBuf;
+            }
+        TPtr descrDataPtr(descrDataBuf->Des());
+        TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth);
+        descrDataPtr.Copy(ptr8);
+        return descrDataBuf;
+        }
+    else
+
+    //
+    // ConvType == U, unicode string, only copy data
+    //  
+        {
+        descrDataBuf = HBufC::New(lth/2);
+        if (descrDataBuf == 0)
+            {
+            return descrDataBuf;
+            }
+        TPtr descrDataPtr(descrDataBuf->Des());
+        TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth);
+        TPtrC ptr16(reinterpret_cast<const TUint16*>(ptr8.Ptr()), ptr8.Length() / 2);;
+        descrDataPtr.Copy(ptr16);
+        return descrDataBuf;
+        }
+    }
+        
+///////////////////////////////////////////////////////////////////
+//  AnalyseConvSpec - Analyse Conversion Specification string
+//  The format of string is as follows:
+//  %U or %N or %A or %sU or %sN or %sA where:
+//  --  % is prefix
+//  --  U means Unicode (16-bits) data
+//  --  A means 8-bits data
+//  --  N means numeric data
+//  --  s means 1 or 2 character sequence number    
+///////////////////////////////////////////////////////////////////
+TInt CEventViewer::AnalyseConvSpec(
+                               const TDesC&    aSourceBuf,
+                               TInt&     aOffset,         // input/output
+                               TUint32&  aConvType,       // U or N
+                               TUint32&  aSeqNumber)
+    {
+    TInt currOffset = aOffset;
+    TUint32 seqNumber = 0;
+    TUint32 convType;
+    TInt   sourceDataLeft = aSourceBuf.Length() -  aOffset;
+    TBuf<2> seqNumberBuf;
+
+    // One byte data should exist
+    
+    if (sourceDataLeft < 1)
+        {
+        return KErrNotFound;
+        }
+
+    // Check if 1 or 2 byte long sequence number follows. Value
+    // should be 1 - 20.
+    
+    if (aSourceBuf[currOffset] >= '0' && 
+          aSourceBuf[currOffset] <= '9')
+        {
+        seqNumberBuf.Copy(&aSourceBuf[currOffset], 1);
+        currOffset++;
+        sourceDataLeft--; 
+        
+        if (aSourceBuf[currOffset] >= '0' && 
+            aSourceBuf[currOffset] <= '9')
+            {
+            seqNumberBuf.Append(&aSourceBuf[currOffset], 1);
+            currOffset++;
+            sourceDataLeft--;
+            }
+        TLex seqNumberLex(seqNumberBuf);
+        seqNumberLex.Val(seqNumber, EDecimal);
+        if (seqNumber == 0 || seqNumber > 20)
+            {
+            return KErrNotFound;
+            }
+        }
+
+    // One byte data should exist
+
+    if (sourceDataLeft < 1)
+        {
+        return KErrNotFound;
+        }
+
+    // Check if the conversion type is U
+
+
+    if (aSourceBuf[currOffset] == 'U' || 
+         aSourceBuf[currOffset] == 'u')
+        {
+        convType = KConvTypeU;
+        } 
+
+    // Check if the conversion type is N
+
+    else if
+        (aSourceBuf[currOffset] == 'N' || 
+          aSourceBuf[currOffset] == 'n')
+        {
+        convType = KConvTypeN;
+        }
+    
+    // Check if the conversion type is A
+
+    else if
+        (aSourceBuf[currOffset] == 'A' || 
+          aSourceBuf[currOffset] == 'a')
+        {
+        convType = KConvTypeA;
+        }
+    else
+        {
+        return KErrNotFound;
+        }
+    
+    // Return parameters to caller
+
+    aConvType   = convType;
+    aOffset     = currOffset;
+    aSeqNumber  = seqNumber;
+    return KErrNone;
+    }
+
+
+
+///////////////////////////////////////////////////////////////
+// BufferAppend()
+// This function appends a buffer by storing a new string.
+// If the buffer does not have space enough, the function extends
+// the buffer.
+//
+///////////////////////////////////////////////////////////////
+TInt CEventViewer::BufferAppend(HBufC*& aDestBuf,
+                                const TDesC& aString)
+    {
+    TInt err = KErrNone;
+    // Make sure that we have enough space for the new text
+
+    TInt spaceLeft = aDestBuf->Des().MaxLength() - aDestBuf->Des().Length();
+    if (aString.Length() > spaceLeft)
+        {
+    // Allocate enough space for the new string + some additional
+    // free space so that allocations are not too frequent
+
+        TInt newMaxLength = aDestBuf->Des().MaxLength() + aString.Length() + KEventBufferSizeIncrement;
+        HBufC* tempBuf = aDestBuf->ReAlloc(newMaxLength);
+        if (tempBuf != NULL)
+            {
+            aDestBuf = tempBuf;
+            }
+        else
+            {
+            err = KErrNoMemory;
+            }
+        }
+    //
+    // Store current string to the buffer
+    //
+    aDestBuf->Des().Append(aString);
+    return err;
+    }
+
+
+