voipplugins/svtlogging/src/csvtsipuriparser.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:29:57 +0100
branchRCL_3
changeset 22 d38647835c2e
parent 0 a4daefaec16c
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2008 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 "csvtsipuriparser.h"
#include "svtphonenumbervalidator.h"

_LIT( KColon, ":");
_LIT( KAtSign, "@");
_LIT( KLeftElbow, "<" );
_LIT( KRightElbow, ">" );

// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------------------------
// CSvtSipUriParser::CSvtSipUriParser
// ---------------------------------------------------------------------------
//
CSvtSipUriParser::CSvtSipUriParser( TDomainPartClippingSetting aOptions )
    :
    iOptions( aOptions )
    {

    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ConstructL
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ConstructL( const TDesC& aSipUri )
    {
    ParseSipUriL( aSipUri );
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::NewL
// ---------------------------------------------------------------------------
//
CSvtSipUriParser* CSvtSipUriParser::NewL( const TDesC& aSipUri,
        TDomainPartClippingSetting aOptions )
    {
    CSvtSipUriParser* self = CSvtSipUriParser::NewLC( aSipUri, aOptions );
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::NewLC
// ---------------------------------------------------------------------------
//
CSvtSipUriParser* CSvtSipUriParser::NewLC( const TDesC& aSipUri,
        TDomainPartClippingSetting aOptions )
    {
    CSvtSipUriParser* self = new( ELeave ) CSvtSipUriParser( aOptions );
    CleanupStack::PushL( self );
    self->ConstructL( aSipUri );
    return self;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::~CSvtSipUriParser
// ---------------------------------------------------------------------------
//
CSvtSipUriParser::~CSvtSipUriParser()
    {
    iUserName.Close();
    iDomain.Close();
    iDisplayName.Close();
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::GetVoipAddress
// ---------------------------------------------------------------------------
//
TInt CSvtSipUriParser::GetVoipAddress( RBuf& aVoipAddress ) const
    {
    aVoipAddress = KNullDesC();
    
    if ( IsAnonymousUri( iUserName ) )
        {
        return KErrNone;
        }
    
    TInt result( KErrNone );
    TInt addressLength = AddressLength( iUserName, iDomain, iOptions );
    if ( aVoipAddress.MaxLength() < addressLength )
        {
        result = aVoipAddress.ReAlloc( addressLength );
        }
    
    if ( KErrNone == result )
        {
        aVoipAddress.Append( iUserName );
        
        if ( iUserName.Length() < addressLength )
            {
            // domain part clipping isn't used
            aVoipAddress.Append( KAtSign() );
            aVoipAddress.Append( iDomain );
            }
        }
    
    return result;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::GetPhoneNumber
// ---------------------------------------------------------------------------
//
TInt CSvtSipUriParser::GetPhoneNumber( RBuf& aPhoneNumber ) const
    {
    aPhoneNumber = KNullDesC();
    
    TInt result( KErrNone );
    if ( SvtPhoneNumberValidator::IsValidNumber( iUserName ) 
            && ( ENoClipping != iOptions ) )
        {
        if ( aPhoneNumber.MaxLength() < iUserName.Length() )
            {
            result = aPhoneNumber.ReAlloc( iUserName.Length() );
            }
        
        if ( KErrNone == result )
            {
            aPhoneNumber.Append( iUserName );
            }        
        }
    
    return result;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::GetDisplayName
// ---------------------------------------------------------------------------
//
TInt CSvtSipUriParser::GetDisplayName( RBuf& aDisplayName ) const
    {
    aDisplayName = KNullDesC();
    
    TInt result( KErrNone );
    if ( aDisplayName.MaxLength() < iDisplayName.Length() )
        {
        result = aDisplayName.ReAlloc( iDisplayName.Length() );
        }
    
    if ( KErrNone == result )
        {
        aDisplayName = iDisplayName;
        }
    
    return result;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ParseSipUriL
// Accepted URI forms are: [schema:]user@host[:port] and 
// displayname <[schema:]user@host[:port]>. URI parameters and headers are 
// ripped off in MCE & SVP.
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ParseSipUriL( const TDesC& aSipUri )
    {
    if ( IsAnonymousUri( aSipUri ) )
        {
        ParsePrivateAddress();
        }
    else
        {
        RBuf sipUri( aSipUri.AllocL() );
        CleanupClosePushL( sipUri );
        
        // remove trailing and leading white spaces from input uri
        sipUri.TrimAll();
        ParseDisplayNameL( sipUri );
        RemoveElbows( sipUri );
        ParseUserNameL( sipUri );
        ParseDomainL( sipUri );
        
        CleanupStack::PopAndDestroy( &sipUri );
        }
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ParseDisplayNameL
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ParseDisplayNameL( const TDesC& aSipUri )
    {
    iDisplayName.Close();
    
    TInt leftElbowIndex = aSipUri.Find( KLeftElbow );
    TInt rightElbowIndex = aSipUri.Find( KRightElbow );
    if ( ( 0 < leftElbowIndex ) && ( KErrNotFound != rightElbowIndex ) )
        {
        // display name is available
        iDisplayName.Assign( aSipUri.Left( leftElbowIndex ).AllocL() );
        
        // remove whitespace around display name
        iDisplayName.TrimAll();
        
        // remove quatation marks around display name
        _LIT( KQuatationMark, "\"");
        if ( iDisplayName.Length() && iDisplayName[0] == '"' )
            {
            iDisplayName.Delete( 0, KQuatationMark().Length() );
            }
        
        if ( iDisplayName.Length() 
                && iDisplayName[iDisplayName.Length() - 1] == '"')
            {
            iDisplayName.Delete( 
                iDisplayName.Length() - 1, KQuatationMark().Length() );
            }
        }
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::RemoveElbows
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::RemoveElbows( TDes& sipUri ) const
    {
    TInt leftElbowIndex = sipUri.Find( KLeftElbow );
    if ( KErrNotFound != leftElbowIndex )
        {
        sipUri.Delete( leftElbowIndex, KLeftElbow().Length() );
        }
    
    TInt rightElbowIndex = sipUri.Find( KRightElbow );
    if ( KErrNotFound != rightElbowIndex )
        {
        sipUri.Delete( rightElbowIndex, KRightElbow().Length() );
        }
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ParseUserNameL
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ParseUserNameL( const TDesC& aSipUri )
    {
    // If uri does not specify schema, user name starts from the beginning of
    // the uri. Otherwise additional calculations are done.
    TInt userNameStartInd = 0;
    TInt indexOfColon = aSipUri.Find( KColon() );
    if ( KErrNotFound != indexOfColon )
        {
        userNameStartInd = aSipUri.Find( KColon() ) + KColon().Length();
        __ASSERT_ALWAYS( KColon().Length() <= userNameStartInd, 
            User::Leave( KErrArgument ) );
        }
    
    TInt userNameEndInd = aSipUri.Find( KAtSign() ) - KAtSign().Length();
    __ASSERT_ALWAYS( 0 <= userNameEndInd, User::Leave( KErrArgument ) );
    
    TInt userNameLength = ( userNameEndInd - userNameStartInd ) + 1;
    __ASSERT_ALWAYS( 0 < userNameLength, User::Leave( KErrArgument ) );
    
    iUserName.Close();
    iUserName.Assign( aSipUri.Mid( userNameStartInd, userNameLength ).AllocL() );
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ParseDomainL
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ParseDomainL( const TDesC& aSipUri )
    {
    TInt hostNameStartInd = aSipUri.Find( KAtSign() ) + KAtSign().Length();
    __ASSERT_ALWAYS( KAtSign().Length() <= hostNameStartInd, 
        User::Leave( KErrArgument ) );
    
    TInt hostNameEndInd = aSipUri.Length() - 1;
    TInt hostNameLength = ( hostNameEndInd - hostNameStartInd ) + 1;
    __ASSERT_ALWAYS( 0 < hostNameLength, User::Leave( KErrArgument ) );
    
    iDomain.Close();
    iDomain.Assign( aSipUri.Mid( hostNameStartInd, hostNameLength ).AllocL() );
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::ParsePrivateAddress
// ---------------------------------------------------------------------------
//
void CSvtSipUriParser::ParsePrivateAddress()
    {
    iUserName.Close();
    iUserName = KNullDesC();
    
    iDomain.Close();
    iDomain = KNullDesC();
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::AddressLength
// ---------------------------------------------------------------------------
//
TInt CSvtSipUriParser::AddressLength( const TDesC& aUserName, 
        const TDesC& aDomain, TDomainPartClippingSetting aClipSetting ) const
    {
    TInt addressLength( 0 );
    TBool isPhoneNumber( SvtPhoneNumberValidator::IsValidNumber( aUserName ) );
    switch ( aClipSetting )
        {
        case ENoClipping:
            addressLength = 
            aUserName.Length() + KAtSign().Length() + aDomain.Length();
            break;
        
        case EClipDomainIfNumber:
            addressLength = isPhoneNumber 
                ? aUserName.Length() 
                : aUserName.Length() + KAtSign().Length() + aDomain.Length();
            break;
        
        case EClipDomain:
            addressLength = aUserName.Length();
            break;
        
        default:
            ASSERT( EFalse );
        }
    
    return addressLength;
    }


// ---------------------------------------------------------------------------
// CSvtSipUriParser::IsAnonymousUri
// ---------------------------------------------------------------------------
//
TBool CSvtSipUriParser::IsAnonymousUri( const TDesC& aCandidate ) const
    {
    if ( aCandidate.Length() == 0 )
        {
        return ETrue;
        }
    else
        {
        return EFalse;
        }
    }