diff -r 000000000000 -r 4a5361db8937 logsui/logsengine/logssymbianos/src/logseventdataparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/logsui/logsengine/logssymbianos/src/logseventdataparser.cpp Tue May 04 12:39:37 2010 +0300 @@ -0,0 +1,204 @@ +/* +* Copyright (c) 2009 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 "logseventdataparser.h" +#include "logseventdata.h" +#include +#include +#include +#include "LogsApiConsts.h" + + +// Separator for gprs data (old legacy non-tagged format for sent and +// received grps data) +_LIT8(KDataSeparator,","); + +// ---------------------------------------------------------------------------- +// LogsEventDataParser::parse +// ---------------------------------------------------------------------------- +// +int LogsEventDataParser::parse( + const CLogEvent& source, LogsEventData& dest ) +{ + // For SMS'es part data is packed into data field (by sms stack), so in + // this case there is no need to try to parse S60 specific data from it. + bool readMessageParts = ( + source.EventType() == KLogShortMessageEventTypeUid || + source.EventType() == KLogsEngMmsEventTypeUid ); + const TDesC8& data = source.Data(); + + //All default values must already be set in case there is no data in the + //event's data field. + dest.mIsCNAP = false; + dest.mIsVT = false; + dest.mIsVoIP = false; + dest.mIsPoC = false; + dest.mIsEmerg = false; + dest.mMsgPartsNumber = 0; //Meaningful only for sms + dest.mServiceId = 0; + dest.mContactLocalId = 0; + dest.mDataSent = 0; + dest.mDataReceived = 0; + dest.mRemoteUrl.clear(); + dest.mLocalUrl.clear(); + + // 1. Msg parts are written in different format in data field. + if( readMessageParts ) { + setMsgPartsNumber( data, dest ); + } + // 2. else check if the sent & received data is in old format (this can be + // removed when creating log data field entries is similar to format of + // other data field entries (i.e is tagged)) + else if ( !checkNonTaggedData( data, dest ) ) { + // 3. Otherwise check if tagged data is available. + checkTaggedData( data, dest ); + } + return 0; +} + +// ---------------------------------------------------------------------------- +// LogsEventDataParser::setMsgPartsNumber +// Read msg parts. They are written in format of TLogSmsPduData in Data field +// ---------------------------------------------------------------------------- +// +void LogsEventDataParser::setMsgPartsNumber( const TDesC8 &data, LogsEventData& dest ) +{ + TPckgBuf packedData; + packedData.Copy( data.Ptr(), sizeof( TLogSmsPduData ) ); + dest.mMsgPartsNumber = packedData().iTotal; +} + +// ---------------------------------------------------------------------------- +// LogsEventDataParser::checkNonTaggedData +// ---------------------------------------------------------------------------- +// +bool LogsEventDataParser::checkNonTaggedData( const TDesC8 &data, LogsEventData& dest ) +{ + if( data.Length() < 1 ) { + return false; + } + + //At least 1 byte of data available. Check does it begin with number. + TInt v; + TPtrC8 ptr( data.Left(1) ); + TLex8 lex = ptr; + if( lex.Val( v ) != KErrNone ) { + //First byte does not contain number + return false; + } + + //Ok, data begins with number. Try to read a pair of comma separated numbers + TInt separatorOffset = data.Find( KDataSeparator ); + if( separatorOffset + 1 > data.Length() || separatorOffset < 0 ) { + //No separator found. + return false; + } + + ptr.Set( data.Left( separatorOffset ) ); + lex = ptr; + lex.Val( dest.mDataSent ); + + if( (separatorOffset + 1) < data.Length() ){ + // Parse rest + ptr.Set( data.Mid(separatorOffset + 1, data.Length() - separatorOffset - 1) ); + lex = ptr; + lex.Val( dest.mDataReceived ); + } + + return true; +} + +// ---------------------------------------------------------------------------- +// LogsEventDataParser::checkTaggedData +// ---------------------------------------------------------------------------- +// +void LogsEventDataParser::checkTaggedData( const TDesC8 &data, LogsEventData& dest ) +{ + TPtrC8 dataPtr( data ); + TInt dataLeft = dataPtr.Length(); + while( dataLeft > 0 ){ + TInt nextTokenStart = dataPtr.Find( KLogsDataFldNameDelimiter() ); + if ( nextTokenStart > dataPtr.Length() || nextTokenStart < 0 ) { + nextTokenStart = dataPtr.Length(); + } + + TPtrC8 nameValue = dataPtr.Left( nextTokenStart ); + TPtrC8 name; + TPtrC8 value; + + TInt delimiterStart = nameValue.Find( KLogsDataFldValueDelimiter() ); + if( delimiterStart > dataPtr.Length() || delimiterStart < 0 ){ + name.Set( nameValue ); + //No value. Initialised to null in above (TPtrC8 value) + } else { + name.Set( dataPtr.Left( delimiterStart ) ); + TInt length = nameValue.Length() - delimiterStart - 1; + value.Set( dataPtr.Mid( delimiterStart + 1, length) ); + } + + // Below a minor attempt to slightly speed up the string comparisons: + // If value already found, no need to compare same name anymore. + // Most likely there is VT, VOIP or POC tag in the beginning of data + // field if any tags. + if( !dest.mIsVT && name.Compare( KLogsDataFldTag_VT ) == 0 ){ + dest.mIsVT = true; + } else if( !dest.mIsCNAP && name.Compare( KLogsDataFldTag_CNAP ) == 0 ){ + dest.mIsCNAP = true; + } else if( !dest.mIsEmerg && name.Compare( KLogsDataFldTag_Emergency ) == 0 ){ + dest.mIsEmerg = true; + } else if( !dest.mIsPoC && name.Compare( KLogsDataFldTag_POC ) == 0 ){ + dest.mIsPoC = true; + } else if( !dest.mIsVoIP && name.Compare( KLogsDataFldTag_IP ) == 0 ){ + dest.mIsVoIP = true; + } else if( !dest.mServiceId && name.Compare( KLogsDataFldTag_ServiceId ) == 0 ) { + TLex8 lex( value ); + TUint32 temp( 0 ); + TInt err = lex.Val( temp , EDecimal ); + if ( KErrNone == err ) { + //if an error occurred we leave the service id unchanged + dest.mServiceId = temp; + } + } else if ( !dest.mContactLocalId && + name.Compare( KLogsDataFldTag_ContactLink ) == 0 ) { + HBufC8* contactLink = value.AllocLC(); + TLex8 lex( contactLink->Des() ); + TUint32 temp( 0 ); + TInt err = lex.Val( temp , EDecimal ); + if ( KErrNone == err ) { + dest.mContactLocalId = temp; + } + CleanupStack::PopAndDestroy(contactLink); + + } else if ( dest.mRemoteUrl.isEmpty() && name.Compare( KLogsDataFldTag_URL ) == 0 ) { + // VoIP strips unneeded stuff from uri before writing the log + // event to db (it removes '<' '>', "sip:", and everything after ';', + // see svpsslogcall.cpp) so no need to postprocess. + dest.mRemoteUrl = QString::fromUtf8( (char*)value.Ptr(), value.Length() ); + } else if ( dest.mLocalUrl.isEmpty() && name.Compare( KLogsDataFldTag_MA ) == 0 ) { + dest.mLocalUrl = QString::fromUtf8( (char*)value.Ptr(), value.Length() ); + } + + //Process remaining data + dataLeft = dataPtr.Length() - nextTokenStart - 1; + if ( dataLeft > 0 ) { + //Continue with remaining data on the right side of token + nameValue.Set( dataPtr.Right( dataLeft ) ); + dataPtr.Set( nameValue ); + } + } +}