diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/ClientResolver/Resolver/src/CSIPFeatureSet.cpp --- /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() == '+'); + }