voipplugins/svtmatching/src/svturiparser.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 27 Apr 2010 16:28:03 +0300
branchRCL_3
changeset 12 876a3df1f464
parent 9 bddb6d4447db
permissions -rw-r--r--
Revision: 201015 Kit: 201017

/*
* Copyright (c) 2008-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:  Settings handler class for svtmatching.
*
*/


#include "svturiparser.h"

// Valid characters for GSM call
_LIT( KPhoneValidChars, "0123456789*#+pwPW" );
// For parsing protocol prefix and domain part out of a VoIP call URI
_LIT( KSvtColon, ":" );
_LIT( KSvtAt, "@" );
// Indicates the start of sip uri.
const TUint KStartBracket = '<'; 
// Indicates the end of sip uri.
const TUint KEndBracket = '>'; 
const TUint KSpaceMark = ' ';
const TUint KQuotationMark = '"';


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

// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
CSvtUriParser::CSvtUriParser()
    {
    }

  
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
CSvtUriParser* CSvtUriParser::NewL()
    {
    CSvtUriParser* self = new ( ELeave ) CSvtUriParser;
    return self;
    }


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
CSvtUriParser::~CSvtUriParser()
    {

    }

// ---------------------------------------------------------------------------
// Parses sip uri by ignore domain part setting
// ---------------------------------------------------------------------------
//
void CSvtUriParser::ParseAddressL( 
        TInt aIgnoreDomain, 
        const TDesC& aOriginal, 
        RBuf& aParsedAddress ) const
    {
    switch ( aIgnoreDomain )
        {
        case 1:
        case 2:
            {
            HandleUserNamePartL( aIgnoreDomain, aOriginal, aParsedAddress );
            break;
            }
        case 0:
        default:
            {
            aParsedAddress.Close();
            aParsedAddress.CreateL( aOriginal );
            break;
            }
        
        }
    }

// ---------------------------------------------------------------------------
// Resolves display name from sip uri
// ---------------------------------------------------------------------------
//
TInt CSvtUriParser::DisplayNameFromUri( 
        const TDesC& aData, 
        RBuf& aDisplayname ) const
    {
    TInt result = KErrNotFound;

    TRAPD( err, DisplayNameFromUriL( aData, aDisplayname, result ) );
    if ( err )
        {
        result = err;
        }
    return result;
    }

// ---------------------------------------------------------------------------
// The inner logic for resolving display name from sip uri
// ---------------------------------------------------------------------------
//
void CSvtUriParser::DisplayNameFromUriL(
        const TDesC& aData,
        RBuf& aDisplayname,
        TInt& aResult ) const
    {
    aResult = KErrNotFound;
    
    TPtrC preResultStr( aData );
    aDisplayname.Close();
    
    HBufC* tempBuffer = preResultStr.AllocLC(); // CS:1
    tempBuffer->Des().TrimAll();
    
    if ( tempBuffer->Length() )
        {
        TPtrC resultStr( tempBuffer->Des() );

        // resolves potential SIP Display info and removes it from uri
        // also possible "<" and ">" character are removed around the SIP uri
        TInt uriStartIndex = resultStr.LocateReverse( KStartBracket );      
        TInt uriEndIndex = resultStr.LocateReverse( KEndBracket );       
        
        if ( KErrNotFound != uriStartIndex && KErrNotFound != uriEndIndex )
            {
            if ( uriStartIndex < uriEndIndex )
                {
                // brackets found so modify descriptor and save the display info
                
                // check if there is anything before "<" if there is use
                // it as displayname if match op fails.
                if ( uriStartIndex > 1 )
                    {        
                    TPtrC tempStr( resultStr.Left( uriStartIndex ) );          
                    // remove possible quotation marks from displayname
                    TInt index = tempStr.Locate( KQuotationMark );
                    if ( KErrNotFound != index )
                        {
                        // marks have to be removed
                        tempStr.Set( tempStr.Mid( ++index ) );    
                        if ( tempStr[tempStr.Length() - 1] == KQuotationMark )
                            {
                            tempStr.Set( tempStr.Left( tempStr.Length() - 1 ) );
                            }
                        }
                    aResult = aDisplayname.Create( tempStr );
                    }                      
                }
            else
                {
                // Start and end separators in wrong order: "xxxx>xxxx<xxx"
                aResult = KErrArgument;
                }
            }        
        else 
            {
            // it is also possible that displayname is included, in case there's
            // no brackets around the uri. So if there is something
            // inside quotationMarks it should be used as displayname
    
            // check if displayname is found
            TInt displayNameStart = resultStr.Locate( KQuotationMark );
            TInt displayNameEnd = resultStr.LocateReverse( KQuotationMark );
    
            if ( displayNameStart != KErrNotFound 
                && displayNameEnd != KErrNotFound 
                && displayNameStart < displayNameEnd )
                {
                // displayname is included
                // +1, to remove quotationMark from the start
                // -1, to remove quotationMark from the end
                aResult = aDisplayname.Create( resultStr.Mid( displayNameStart + 1,
                                       displayNameEnd - displayNameStart - 1 ) );
                }                                
            else
                {
                // check if there is spaces in the uri. If there is,
                // everything before it belongs to display name                
                TInt index = resultStr.LocateReverse( KSpaceMark );
                
                if ( KErrNotFound != index )            
                    {
                    // set displayname
                    aResult = aDisplayname.Create( resultStr.Left( index ) );
                    }            
                }
             }
        }
    else
        {
        // Invalid data length
        aResult = KErrArgument;
        }

    CleanupStack::PopAndDestroy( tempBuffer ); // CS:0
    }

// ---------------------------------------------------------------------------
// Check original address for spaces. 
// ---------------------------------------------------------------------------
//
void CSvtUriParser::CheckForSpacesL(
    const TDesC& aOriginal, 
    RBuf& aCheckedAddress ) const
    {
    aCheckedAddress.CreateL( aOriginal );
    
    TInt index( 0 );
    while ( index != KErrNotFound )
        {
        index = aCheckedAddress.Locate( KSpaceMark );
        
        // Remove space if itīs in begin or end of string
        if ( index == 0 || ( index == ( aCheckedAddress.Length() - 1 ) ) )
            {
            aCheckedAddress.Delete( index, 1 );
            }
        else
            {
            index = KErrNotFound;
            }
        }
    }

// ---------------------------------------------------------------------------
// Check is string valid for gsm call
// ---------------------------------------------------------------------------
//
TBool CSvtUriParser::IsValidGsmNumber( const TDesC& aOriginal ) const
    {
    TLex input( aOriginal );
    TPtrC valid( KPhoneValidChars );

    while ( valid.Locate( input.Peek() ) != KErrNotFound )
        {
        input.Inc();
        }
  
    return !input.Remainder().Length();
    }

// ---------------------------------------------------------------------------
// Gets username part from sip uri
// ---------------------------------------------------------------------------
//
TInt CSvtUriParser::GetUserNamePart( 
        const TDesC& aOriginal,
        TDes& aUserName ) const
    {
    if ( aOriginal.Length() > aUserName.MaxLength() )
        {
        return KErrArgument;
        }
    
    aUserName.Copy( aOriginal );
    
    // Parse protocol prefix and domain part out of a VoIP call URI
    TInt pos( aUserName.Find( KSvtColon ) );
    if ( pos > KErrNotFound )
        {
        aUserName.Delete( 0, pos+1 );
        }                
        
    pos = aUserName.Find( KSvtAt );
    if ( pos > KErrNotFound )
        {
        aUserName.Delete( pos, aUserName.Length() - pos );
        }
    
    if ( 0 == aUserName.Length() )
        {
        return KErrNotFound;
        }
    
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// Handles sip uri's username part for ignore domain part values 1 and 2
// ---------------------------------------------------------------------------
//
void CSvtUriParser::HandleUserNamePartL( 
        TInt aIgnoreDomain, 
        const TDesC& aOriginal, 
        RBuf& aParsedAddress ) const
    {
    if ( 0 == aOriginal.Length() )
        {
        User::Leave( KErrArgument );
        }
    
    HBufC* buf = HBufC::NewLC( aOriginal.Length() );
    TPtr des( buf->Des() );
    
    User::LeaveIfError( GetUserNamePart( aOriginal, des ) );
    
    aParsedAddress.Close();
    
    if ( ( 1 == aIgnoreDomain && IsValidGsmNumber( des ) ) ||
           2 == aIgnoreDomain )
        {
        // Set parsed address
        User::LeaveIfError( aParsedAddress.Create( des ) );
        }
    else
        {
        User::LeaveIfError( aParsedAddress.Create( aOriginal ) );
        }
        
    CleanupStack::PopAndDestroy( buf );
    }