realtimenetprots/sipfw/ClientResolver/Resolver/src/CSIPFeatureSet.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSIPFeatureSet.cpp
       
    15 // Part of       : SIP Client Resolver
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "CSIPFeatureSet.h"
       
    22 #include "CSIPBooleanFeatureTag.h"
       
    23 #include "CSIPNumericFeatureTag.h"
       
    24 #include "CSIPStringFeatureTag.h"
       
    25 #include "CSIPTokenFeatureTag.h"
       
    26 #include "sipacceptcontactheader.h"
       
    27 #include "TTagValueListParser.h"
       
    28 #include "sipstrings.h"
       
    29 #include "sipstrconsts.h"
       
    30 
       
    31 _LIT8(KTrue, "TRUE");
       
    32 _LIT8(KFalse, "FALSE");
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // CSIPFeatureSet::NewL
       
    36 // -----------------------------------------------------------------------------
       
    37 //
       
    38 CSIPFeatureSet* CSIPFeatureSet::NewL()
       
    39 	{
       
    40 	CSIPFeatureSet* self = CSIPFeatureSet::NewLC();
       
    41 	CleanupStack::Pop(self);
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CSIPFeatureSet::NewLC
       
    47 // -----------------------------------------------------------------------------
       
    48 //
       
    49 CSIPFeatureSet* CSIPFeatureSet::NewLC()
       
    50 	{
       
    51 	CSIPFeatureSet* self = new(ELeave)CSIPFeatureSet;
       
    52 	CleanupStack::PushL(self);
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CSIPFeatureSet::NewL
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CSIPFeatureSet* CSIPFeatureSet::NewL(
       
    61     const CSIPAcceptContactHeader& aAcceptContactHeader)
       
    62 	{
       
    63 	CSIPFeatureSet* self = CSIPFeatureSet::NewLC(aAcceptContactHeader);
       
    64 	CleanupStack::Pop(self);
       
    65 	return self;
       
    66 	}
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CSIPFeatureSet::NewLC
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 CSIPFeatureSet* CSIPFeatureSet::NewLC(
       
    73     const CSIPAcceptContactHeader& aAcceptContactHeader)
       
    74 	{
       
    75 	CSIPFeatureSet* self = new(ELeave)CSIPFeatureSet;
       
    76 	CleanupStack::PushL(self);
       
    77 	self->ConstructL(aAcceptContactHeader);
       
    78 	return self;
       
    79 	}
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CSIPFeatureSet::CSIPFeatureSet
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 CSIPFeatureSet::CSIPFeatureSet()
       
    86 	{
       
    87 	}
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CSIPFeatureSet::ConstructL
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 void CSIPFeatureSet::ConstructL(
       
    94     const CSIPAcceptContactHeader& aAcceptContactHeader)
       
    95 	{
       
    96     AddFeaturesL(aAcceptContactHeader);
       
    97 	}
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CSIPFeatureSet::~CSIPFeatureSet
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 CSIPFeatureSet::~CSIPFeatureSet()
       
   104 	{
       
   105 	iFeatureTags.ResetAndDestroy();
       
   106 	}
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CSIPFeatureSet::AddFeaturesL
       
   110 // -----------------------------------------------------------------------------
       
   111 //
       
   112 void CSIPFeatureSet::AddFeaturesL(
       
   113     const CSIPAcceptContactHeader& aAcceptContactHeader)
       
   114     {
       
   115 	TInt paramCount = aAcceptContactHeader.ParamCount();
       
   116 	for(TInt i = 0; i < paramCount; i++)
       
   117 	    {
       
   118 	    RStringF name;
       
   119 	    User::LeaveIfError(aAcceptContactHeader.Param(i,name));
       
   120 	    CleanupClosePushL(name);
       
   121 	    if (IsFeatureParamName(name))
       
   122 	        {
       
   123     	    RStringF value = aAcceptContactHeader.ParamValue(name);
       
   124     	    AddFeatureTagsL(name,value.DesC());
       
   125 	        }
       
   126 	    CleanupStack::PopAndDestroy(1); // name
       
   127 	    }
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CSIPFeatureSet::Require
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 TBool CSIPFeatureSet::Require() const
       
   135 	{
       
   136 	return iRequire;
       
   137 	}
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CSIPFeatureSet::CalculateScore
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 TInt CSIPFeatureSet::CalculateScore(const CSIPFeatureSet& aFeatureSet) const
       
   144 	{
       
   145 	TInt score = 0;
       
   146 	for(TInt i = 0; i < aFeatureSet.iFeatureTags.Count(); i++)
       
   147 	    {
       
   148 	    const CSIPFeatureTag* otherTag = aFeatureSet.iFeatureTags[i];
       
   149         for(TInt j = 0; j < iFeatureTags.Count(); j++)
       
   150             {
       
   151             const CSIPFeatureTag* myTag = iFeatureTags[j];
       
   152             if (myTag->Match(*otherTag))
       
   153     	        {
       
   154     	        score++;
       
   155     	        }
       
   156     	    }
       
   157 	    }
       
   158 	if (aFeatureSet.Require() && score < aFeatureSet.iFeatureTags.Count())
       
   159 	    {
       
   160 	    // All feature tags should match if require-tag is present
       
   161 	    score = 0;
       
   162 	    }
       
   163 	return score;
       
   164 	}
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CSIPFeatureSet::AddFeatureTagsL
       
   168 // -----------------------------------------------------------------------------
       
   169 //	
       
   170 void CSIPFeatureSet::AddFeatureTagsL(
       
   171     RStringF aName,
       
   172     const TDesC8& aValue)
       
   173     {
       
   174     if (aValue.Length() > 0)
       
   175         {
       
   176         TPtrC8 value;
       
   177         RemoveQuotesL(aValue,value);
       
   178         if (value[0] == '<')
       
   179             {
       
   180             CSIPFeatureTag* fTag = CSIPStringFeatureTag::NewLC(aName,value);
       
   181             iFeatureTags.AppendL(fTag);
       
   182             CleanupStack::Pop(fTag);            
       
   183             }
       
   184         else
       
   185             {
       
   186             TTagValueListParser parser;
       
   187             parser.Parse(value);
       
   188             while (!parser.Eos())
       
   189                 {
       
   190                 TPtrC8 segment;
       
   191                 User::LeaveIfError(parser.GetNext(segment));
       
   192                 AddFeatureTagL(aName,segment);
       
   193                 }            
       
   194             }
       
   195         }
       
   196     else
       
   197         {
       
   198         AddBooleanFeatureTagL(aName,EFalse,ETrue);    
       
   199         }
       
   200     }
       
   201 
       
   202 // -----------------------------------------------------------------------------
       
   203 // CSIPFeatureSet::AddFeatureTagL
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 void CSIPFeatureSet::AddFeatureTagL(
       
   207     RStringF aName,
       
   208     const TDesC8& aValue)
       
   209     {
       
   210     TBool negation = EFalse;
       
   211     TLex8 lex(aValue);
       
   212     TChar chr = lex.Get();
       
   213     if (chr == '!')
       
   214         {
       
   215         negation = ETrue;
       
   216         chr = lex.Get();
       
   217         }
       
   218     if (chr == '#')
       
   219         {
       
   220         CSIPFeatureTag* fTag = 
       
   221             CSIPNumericFeatureTag::NewLC(aName,negation,lex.Remainder());
       
   222         iFeatureTags.AppendL(fTag);
       
   223         CleanupStack::Pop(fTag);
       
   224         }
       
   225     else
       
   226         {
       
   227         lex.UnGet();
       
   228         TPtrC8 value(lex.Remainder());
       
   229         if (value.CompareF(KTrue) == 0 || 
       
   230             value.CompareF(KFalse) == 0 ||
       
   231             value.Length() == 0)
       
   232             {
       
   233             TBool boolVal = !(value.CompareF(KFalse) == 0);
       
   234             AddBooleanFeatureTagL(aName,negation,boolVal);
       
   235             }
       
   236         else
       
   237             {
       
   238             CSIPFeatureTag* fTag = 
       
   239                 CSIPTokenFeatureTag::NewLC(aName,negation,value);
       
   240             iFeatureTags.AppendL(fTag);
       
   241             CleanupStack::Pop(fTag);            
       
   242             }
       
   243         }    
       
   244     }
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // CSIPFeatureSet::AddBooleanFeatureTagL
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CSIPFeatureSet::AddBooleanFeatureTagL(
       
   251     RStringF aName,
       
   252     TBool aNegation,
       
   253     TBool aValue)
       
   254     {
       
   255     if (aName == SIPStrings::StringF(SipStrConsts::ERequire))
       
   256         {
       
   257         iRequire = ETrue;
       
   258         }
       
   259     else if (aName == SIPStrings::StringF(SipStrConsts::EExplicit))
       
   260         {
       
   261         // explicit-parameter not handled. 
       
   262         // It must not be added to feature set
       
   263         }
       
   264     else
       
   265         {
       
   266         CSIPFeatureTag* fTag = 
       
   267             CSIPBooleanFeatureTag::NewLC(aName,aNegation,aValue);
       
   268         iFeatureTags.AppendL(fTag);
       
   269         CleanupStack::Pop(fTag);
       
   270         }   
       
   271     } 		
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CSIPFeatureSet::RemoveQuotesL
       
   275 // -----------------------------------------------------------------------------
       
   276 //    
       
   277 void CSIPFeatureSet::RemoveQuotesL(
       
   278     const TDesC8& aValue,
       
   279     TPtrC8& aWithoutQuotes) const
       
   280     {
       
   281     __ASSERT_ALWAYS(aValue.Length() > 0, User::Leave(KErrCorrupt));
       
   282     TLex8 lex(aValue);
       
   283     lex.SkipSpace();
       
   284     TPtrC8 remainder(lex.Remainder());
       
   285     if (StartsAndEndsWithQuotes(remainder))
       
   286         {
       
   287         lex.Get(); // Skip the opening quote
       
   288         remainder.Set(lex.Remainder());
       
   289         aWithoutQuotes.Set(remainder.Left(remainder.Length()-1));
       
   290         }
       
   291     else
       
   292         {
       
   293         aWithoutQuotes.Set(aValue);
       
   294         }
       
   295     }
       
   296 
       
   297 // -----------------------------------------------------------------------------
       
   298 // CSIPFeatureSet::StartsAndEndsWithQuotes
       
   299 // -----------------------------------------------------------------------------
       
   300 //
       
   301 TBool CSIPFeatureSet::StartsAndEndsWithQuotes(const TDesC8& aValue) const
       
   302     {
       
   303 	// trim and check quotes
       
   304 	TLex8 lex(aValue);
       
   305 	lex.SkipSpace();
       
   306 	TPtrC8 trimmedVal(lex.Remainder());
       
   307 	const TInt KTwoQuotesLength = 2;
       
   308 	if (trimmedVal.Length() < KTwoQuotesLength) 
       
   309 		{
       
   310 		return EFalse;
       
   311 		}
       
   312 	if (trimmedVal.Locate('"') != 0) 
       
   313 		{
       
   314 		return EFalse;
       
   315 		}
       
   316 	if (trimmedVal.LocateReverse('"') != trimmedVal.Length()-1) 
       
   317 		{
       
   318 		return EFalse;
       
   319 		}
       
   320 	return ETrue; 
       
   321     }
       
   322 
       
   323 // -----------------------------------------------------------------------------
       
   324 // CSIPFeatureSet::IsFeatureParamName
       
   325 // -----------------------------------------------------------------------------
       
   326 //
       
   327 TBool CSIPFeatureSet::IsFeatureParamName(RStringF aName) const
       
   328     {
       
   329     if (aName == SIPStrings::StringF(SipStrConsts::EAudio) ||
       
   330         aName == SIPStrings::StringF(SipStrConsts::EAutomata) ||
       
   331 		aName == SIPStrings::StringF(SipStrConsts::EClass) ||
       
   332 		aName == SIPStrings::StringF(SipStrConsts::EDuplex) ||
       
   333 		aName == SIPStrings::StringF(SipStrConsts::EData) ||
       
   334 		aName == SIPStrings::StringF(SipStrConsts::EControl) ||
       
   335 		aName == SIPStrings::StringF(SipStrConsts::EMobility) ||
       
   336 		aName == SIPStrings::StringF(SipStrConsts::EDescription) ||
       
   337 		aName == SIPStrings::StringF(SipStrConsts::EEvents) ||
       
   338 		aName == SIPStrings::StringF(SipStrConsts::EPriority) ||
       
   339 		aName == SIPStrings::StringF(SipStrConsts::EMethods) ||
       
   340 		aName == SIPStrings::StringF(SipStrConsts::ESchemes) ||
       
   341 		aName == SIPStrings::StringF(SipStrConsts::EApplication) ||
       
   342 		aName == SIPStrings::StringF(SipStrConsts::EVideo) ||
       
   343 		aName == SIPStrings::StringF(SipStrConsts::ELanguage) ||
       
   344 		aName == SIPStrings::StringF(SipStrConsts::EType) ||
       
   345 		aName == SIPStrings::StringF(SipStrConsts::EIsfocus) ||
       
   346 		aName == SIPStrings::StringF(SipStrConsts::EActor) ||
       
   347 		aName == SIPStrings::StringF(SipStrConsts::EText) ||
       
   348 		aName == SIPStrings::StringF(SipStrConsts::EExtensions) ||
       
   349 		aName == SIPStrings::StringF(SipStrConsts::ERequire) ||
       
   350 		aName == SIPStrings::StringF(SipStrConsts::EExplicit))
       
   351         {
       
   352         return ETrue;
       
   353         }
       
   354     TLex8 lex(aName.DesC());
       
   355     lex.SkipSpace();
       
   356     return (lex.Peek() == '+');
       
   357     }