--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ClientResolver/Resolver/src/CSIPFeatureSet.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,357 @@
+// Copyright (c) 2006-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:
+// Name : CSIPFeatureSet.cpp
+// Part of : SIP Client Resolver
+// Version : 1.0
+//
+
+
+
+#include "CSIPFeatureSet.h"
+#include "CSIPBooleanFeatureTag.h"
+#include "CSIPNumericFeatureTag.h"
+#include "CSIPStringFeatureTag.h"
+#include "CSIPTokenFeatureTag.h"
+#include "sipacceptcontactheader.h"
+#include "TTagValueListParser.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+
+_LIT8(KTrue, "TRUE");
+_LIT8(KFalse, "FALSE");
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet* CSIPFeatureSet::NewL()
+ {
+ CSIPFeatureSet* self = CSIPFeatureSet::NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet* CSIPFeatureSet::NewLC()
+ {
+ CSIPFeatureSet* self = new(ELeave)CSIPFeatureSet;
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet* CSIPFeatureSet::NewL(
+ const CSIPAcceptContactHeader& aAcceptContactHeader)
+ {
+ CSIPFeatureSet* self = CSIPFeatureSet::NewLC(aAcceptContactHeader);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::NewLC
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet* CSIPFeatureSet::NewLC(
+ const CSIPAcceptContactHeader& aAcceptContactHeader)
+ {
+ CSIPFeatureSet* self = new(ELeave)CSIPFeatureSet;
+ CleanupStack::PushL(self);
+ self->ConstructL(aAcceptContactHeader);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::CSIPFeatureSet
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet::CSIPFeatureSet()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::ConstructL(
+ const CSIPAcceptContactHeader& aAcceptContactHeader)
+ {
+ AddFeaturesL(aAcceptContactHeader);
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::~CSIPFeatureSet
+// -----------------------------------------------------------------------------
+//
+CSIPFeatureSet::~CSIPFeatureSet()
+ {
+ iFeatureTags.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::AddFeaturesL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::AddFeaturesL(
+ const CSIPAcceptContactHeader& aAcceptContactHeader)
+ {
+ TInt paramCount = aAcceptContactHeader.ParamCount();
+ for(TInt i = 0; i < paramCount; i++)
+ {
+ RStringF name;
+ User::LeaveIfError(aAcceptContactHeader.Param(i,name));
+ CleanupClosePushL(name);
+ if (IsFeatureParamName(name))
+ {
+ RStringF value = aAcceptContactHeader.ParamValue(name);
+ AddFeatureTagsL(name,value.DesC());
+ }
+ CleanupStack::PopAndDestroy(1); // name
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::Require
+// -----------------------------------------------------------------------------
+//
+TBool CSIPFeatureSet::Require() const
+ {
+ return iRequire;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::CalculateScore
+// -----------------------------------------------------------------------------
+//
+TInt CSIPFeatureSet::CalculateScore(const CSIPFeatureSet& aFeatureSet) const
+ {
+ TInt score = 0;
+ for(TInt i = 0; i < aFeatureSet.iFeatureTags.Count(); i++)
+ {
+ const CSIPFeatureTag* otherTag = aFeatureSet.iFeatureTags[i];
+ for(TInt j = 0; j < iFeatureTags.Count(); j++)
+ {
+ const CSIPFeatureTag* myTag = iFeatureTags[j];
+ if (myTag->Match(*otherTag))
+ {
+ score++;
+ }
+ }
+ }
+ if (aFeatureSet.Require() && score < aFeatureSet.iFeatureTags.Count())
+ {
+ // All feature tags should match if require-tag is present
+ score = 0;
+ }
+ return score;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::AddFeatureTagsL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::AddFeatureTagsL(
+ RStringF aName,
+ const TDesC8& aValue)
+ {
+ if (aValue.Length() > 0)
+ {
+ TPtrC8 value;
+ RemoveQuotesL(aValue,value);
+ if (value[0] == '<')
+ {
+ CSIPFeatureTag* fTag = CSIPStringFeatureTag::NewLC(aName,value);
+ iFeatureTags.AppendL(fTag);
+ CleanupStack::Pop(fTag);
+ }
+ else
+ {
+ TTagValueListParser parser;
+ parser.Parse(value);
+ while (!parser.Eos())
+ {
+ TPtrC8 segment;
+ User::LeaveIfError(parser.GetNext(segment));
+ AddFeatureTagL(aName,segment);
+ }
+ }
+ }
+ else
+ {
+ AddBooleanFeatureTagL(aName,EFalse,ETrue);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::AddFeatureTagL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::AddFeatureTagL(
+ RStringF aName,
+ const TDesC8& aValue)
+ {
+ TBool negation = EFalse;
+ TLex8 lex(aValue);
+ TChar chr = lex.Get();
+ if (chr == '!')
+ {
+ negation = ETrue;
+ chr = lex.Get();
+ }
+ if (chr == '#')
+ {
+ CSIPFeatureTag* fTag =
+ CSIPNumericFeatureTag::NewLC(aName,negation,lex.Remainder());
+ iFeatureTags.AppendL(fTag);
+ CleanupStack::Pop(fTag);
+ }
+ else
+ {
+ lex.UnGet();
+ TPtrC8 value(lex.Remainder());
+ if (value.CompareF(KTrue) == 0 ||
+ value.CompareF(KFalse) == 0 ||
+ value.Length() == 0)
+ {
+ TBool boolVal = !(value.CompareF(KFalse) == 0);
+ AddBooleanFeatureTagL(aName,negation,boolVal);
+ }
+ else
+ {
+ CSIPFeatureTag* fTag =
+ CSIPTokenFeatureTag::NewLC(aName,negation,value);
+ iFeatureTags.AppendL(fTag);
+ CleanupStack::Pop(fTag);
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::AddBooleanFeatureTagL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::AddBooleanFeatureTagL(
+ RStringF aName,
+ TBool aNegation,
+ TBool aValue)
+ {
+ if (aName == SIPStrings::StringF(SipStrConsts::ERequire))
+ {
+ iRequire = ETrue;
+ }
+ else if (aName == SIPStrings::StringF(SipStrConsts::EExplicit))
+ {
+ // explicit-parameter not handled.
+ // It must not be added to feature set
+ }
+ else
+ {
+ CSIPFeatureTag* fTag =
+ CSIPBooleanFeatureTag::NewLC(aName,aNegation,aValue);
+ iFeatureTags.AppendL(fTag);
+ CleanupStack::Pop(fTag);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::RemoveQuotesL
+// -----------------------------------------------------------------------------
+//
+void CSIPFeatureSet::RemoveQuotesL(
+ const TDesC8& aValue,
+ TPtrC8& aWithoutQuotes) const
+ {
+ __ASSERT_ALWAYS(aValue.Length() > 0, User::Leave(KErrCorrupt));
+ TLex8 lex(aValue);
+ lex.SkipSpace();
+ TPtrC8 remainder(lex.Remainder());
+ if (StartsAndEndsWithQuotes(remainder))
+ {
+ lex.Get(); // Skip the opening quote
+ remainder.Set(lex.Remainder());
+ aWithoutQuotes.Set(remainder.Left(remainder.Length()-1));
+ }
+ else
+ {
+ aWithoutQuotes.Set(aValue);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::StartsAndEndsWithQuotes
+// -----------------------------------------------------------------------------
+//
+TBool CSIPFeatureSet::StartsAndEndsWithQuotes(const TDesC8& aValue) const
+ {
+ // trim and check quotes
+ TLex8 lex(aValue);
+ lex.SkipSpace();
+ TPtrC8 trimmedVal(lex.Remainder());
+ const TInt KTwoQuotesLength = 2;
+ if (trimmedVal.Length() < KTwoQuotesLength)
+ {
+ return EFalse;
+ }
+ if (trimmedVal.Locate('"') != 0)
+ {
+ return EFalse;
+ }
+ if (trimmedVal.LocateReverse('"') != trimmedVal.Length()-1)
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPFeatureSet::IsFeatureParamName
+// -----------------------------------------------------------------------------
+//
+TBool CSIPFeatureSet::IsFeatureParamName(RStringF aName) const
+ {
+ if (aName == SIPStrings::StringF(SipStrConsts::EAudio) ||
+ aName == SIPStrings::StringF(SipStrConsts::EAutomata) ||
+ aName == SIPStrings::StringF(SipStrConsts::EClass) ||
+ aName == SIPStrings::StringF(SipStrConsts::EDuplex) ||
+ aName == SIPStrings::StringF(SipStrConsts::EData) ||
+ aName == SIPStrings::StringF(SipStrConsts::EControl) ||
+ aName == SIPStrings::StringF(SipStrConsts::EMobility) ||
+ aName == SIPStrings::StringF(SipStrConsts::EDescription) ||
+ aName == SIPStrings::StringF(SipStrConsts::EEvents) ||
+ aName == SIPStrings::StringF(SipStrConsts::EPriority) ||
+ aName == SIPStrings::StringF(SipStrConsts::EMethods) ||
+ aName == SIPStrings::StringF(SipStrConsts::ESchemes) ||
+ aName == SIPStrings::StringF(SipStrConsts::EApplication) ||
+ aName == SIPStrings::StringF(SipStrConsts::EVideo) ||
+ aName == SIPStrings::StringF(SipStrConsts::ELanguage) ||
+ aName == SIPStrings::StringF(SipStrConsts::EType) ||
+ aName == SIPStrings::StringF(SipStrConsts::EIsfocus) ||
+ aName == SIPStrings::StringF(SipStrConsts::EActor) ||
+ aName == SIPStrings::StringF(SipStrConsts::EText) ||
+ aName == SIPStrings::StringF(SipStrConsts::EExtensions) ||
+ aName == SIPStrings::StringF(SipStrConsts::ERequire) ||
+ aName == SIPStrings::StringF(SipStrConsts::EExplicit))
+ {
+ return ETrue;
+ }
+ TLex8 lex(aName.DesC());
+ lex.SkipSpace();
+ return (lex.Peek() == '+');
+ }