diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Codec/src/CSIPAddress.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Codec/src/CSIPAddress.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,612 @@ +// Copyright (c) 2004-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 : CSIPAddress.cpp +// Part of : SIP Codec +// Version : SIP/4.0 +// + + + + +#include "sipaddress.h" +#include "sipuri.h" +#include "sipcodecerr.h" +#include "SIPSyntaxCheck.h" +#include "uricontainer.h" +#include "_sipcodecdefs.h" + + +_LIT8 (KLaQuot, "<"); +_LIT8 (KRaQuot, ">"); + +// ---------------------------------------------------------------------------- +// CSIPAddress::DecodeL +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::DecodeL (const TDesC8& aValue) + { + __ASSERT_ALWAYS (aValue.Length() > 0, + User::Leave (KErrSipCodecSIPAddress)); + + TLex8 lex(aValue); + lex.SkipSpace(); + if (lex.Peek() == 0) + { + User::Leave (KErrSipCodecSIPAddress); + } + TPtrC8 value(lex.Remainder()); + + CSIPAddress* sipAddress = new(ELeave)CSIPAddress; + CleanupStack::PushL(sipAddress); + sipAddress->ConstructL(); + TInt doubleQuotePos = value.Locate ('"'); + if (doubleQuotePos == 0) // has display-name as quoted string and URI + { + const TInt KMinQuotedStrLength = 2; + TInt quotedStrLen = sipAddress->QuotedStringLength(value); + if (quotedStrLen < KMinQuotedStrLength || + quotedStrLen == value.Length()) + { + User::Leave (KErrSipCodecSIPAddress); + } + sipAddress->SetDisplayNameL (value.Left(quotedStrLen)); + sipAddress->ParseURIInAngleBracketsL (value.Mid(quotedStrLen)); + } + else if (doubleQuotePos < 0) + { + TInt openingAngleBracketPos = value.Locate('<'); + if (openingAngleBracketPos < 0) // has only URI + { + sipAddress->ParseURIL (value); + } + else if (openingAngleBracketPos == 0) // has only URI in angle brackets + { + sipAddress->ParseURIInAngleBracketsL (value); + } + else // has both display-name and URI + { + TPtrC8 displayName (value.Left(openingAngleBracketPos)); + sipAddress->SetDisplayNameL (displayName); + value.Set(value.Mid(openingAngleBracketPos)); + sipAddress->ParseURIInAngleBracketsL (value); + } + } + else + { + User::Leave (KErrSipCodecSIPAddress); + } + CleanupStack::Pop(sipAddress); + return sipAddress; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewL +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::NewL (CUri8* aUri8) + { + CSIPAddress* self = CSIPAddress::NewLC (aUri8); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewLC +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::NewLC (CUri8* aUri8) + { + CSIPAddress* self = new(ELeave)CSIPAddress; + CleanupStack::PushL(self); + self->ConstructL(aUri8); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewL +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* +CSIPAddress::NewL (const TDesC8& aDisplayName, CUri8* aUri8) + { + CSIPAddress* self = CSIPAddress::NewLC (aDisplayName, aUri8); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewLC +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* +CSIPAddress::NewLC (const TDesC8& aDisplayName, CUri8* aUri8) + { + CSIPAddress* self = new(ELeave)CSIPAddress; + CleanupStack::PushL(self); + self->ConstructL(aDisplayName, aUri8); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewL +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::NewL (const CSIPAddress& aSIPAddress) + { + CSIPAddress* self = CSIPAddress::NewLC (aSIPAddress); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewLC +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::NewLC (const CSIPAddress& aSIPAddress) + { + CSIPAddress* self = new(ELeave)CSIPAddress; + CleanupStack::PushL(self); + self->ConstructL(aSIPAddress); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::NewLC +// ---------------------------------------------------------------------------- +// +CSIPAddress* CSIPAddress::NewLC(CURIContainer* aURI) + { + CSIPAddress* self = new(ELeave)CSIPAddress; + CleanupStack::PushL(self); + self->ConstructL(aURI); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::CSIPAddress +// ---------------------------------------------------------------------------- +// +CSIPAddress::CSIPAddress() + { + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ConstructL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ConstructL () + { + iDisplayName = KNullDesC8().AllocL(); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ConstructL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ConstructL (CUri8* aUri) + { + iDisplayName = KNullDesC8().AllocL(); + SetUri8L (aUri); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ConstructL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ConstructL (const TDesC8& aDisplayName, CUri8* aUri) + { + SetDisplayNameL (aDisplayName); + SetUri8L (aUri); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ConstructL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ConstructL (const CSIPAddress& aSIPAddress) + { + __ASSERT_ALWAYS (aSIPAddress.iURI != 0, User::Leave(KErrArgument)); + + if (aSIPAddress.HasDisplayName()) + { + SetDisplayNameL(aSIPAddress.DisplayName()); + } + else + { + iDisplayName = KNullDesC8().AllocL(); + } + if(aSIPAddress.URI().IsSIPURI()) + { + HBufC8* value = aSIPAddress.iURI->SIPURI()->ToTextL(); + CleanupStack::PushL(value); + TPtrC8 valuePtr(value->Des()); + iURI = CURIContainer::DecodeL(valuePtr); + CleanupStack::PopAndDestroy(value); + } + else + { + iURI = CURIContainer::DecodeL(aSIPAddress.iURI->Uri8()->Uri().UriDes()); + } + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ConstructL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ConstructL (CURIContainer* aURI) + { + __ASSERT_ALWAYS (aURI != 0, User::Leave(KErrArgument)); + + iDisplayName = KNullDesC8().AllocL(); + iURI = aURI; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::~CSIPAddress +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress::~CSIPAddress() + { + delete iDisplayName; + delete iURI; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::operator== +// ---------------------------------------------------------------------------- +// +EXPORT_C TBool CSIPAddress::operator==(const CSIPAddress& aSIPAddress) const + { + if (aSIPAddress.HasDisplayName() != HasDisplayName()) + { + return EFalse; + } + + if (aSIPAddress.HasDisplayName()) + { + // In quoted strings the case sensitivity matters. + if (aSIPAddress.DisplayName().Locate('"') == 0) + { + if (aSIPAddress.DisplayName().Compare(*iDisplayName) != 0) + { + return EFalse; + } + } + else + { + if (aSIPAddress.DisplayName().CompareF(*iDisplayName) != 0) + { + return EFalse; + } + } + } + + return (*(aSIPAddress.iURI) == *iURI); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::DisplayName +// ---------------------------------------------------------------------------- +// +EXPORT_C const TDesC8& CSIPAddress::DisplayName() const + { + return *iDisplayName; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::SetDisplayNameL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CSIPAddress::SetDisplayNameL(const TDesC8& aDisplayName) + { + HBufC8* tmp = aDisplayName.AllocLC(); + tmp->Des().Trim(); + __ASSERT_ALWAYS (CheckDisplayName(*tmp), + User::Leave(KErrSipCodecDisplayName)); + CleanupStack::Pop(tmp); + delete iDisplayName; + iDisplayName = tmp; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::URI +// ---------------------------------------------------------------------------- +// +EXPORT_C const CURIContainer& CSIPAddress::URI() const + { + return *iURI; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::URI +// ---------------------------------------------------------------------------- +// +EXPORT_C CURIContainer& CSIPAddress::URI() + { + return *iURI; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::Uri8 +// ---------------------------------------------------------------------------- +// +EXPORT_C const CUri8& CSIPAddress::Uri8() const + { + return *(iURI->Uri8()); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::SetURIL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CSIPAddress::SetUri8L (CUri8* aUri8) + { + __ASSERT_ALWAYS(aUri8 != 0, User::Leave(KErrArgument)); + + CURIContainer* tmp = CURIContainer::DecodeL(aUri8->Uri().UriDes()); + delete aUri8; + delete iURI; + iURI = 0; + iURI = tmp; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ToTextLC +// ---------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CSIPAddress::ToTextLC(TBool aUseAngleBrackets) const + { + TUint encodedLength = 0; + if (HasDisplayName()) + { + encodedLength += iDisplayName->Length() + 1; // SP + } + HBufC8* encodedURI = iURI->ToTextL(); + CleanupStack::PushL (encodedURI); + encodedLength += encodedURI->Length(); + + TBool uriContainsSeparators = ContainsSeparators(*encodedURI); + + if (HasDisplayName() || uriContainsSeparators || aUseAngleBrackets) + { + encodedLength += KLaQuot().Length(); + encodedLength += KRaQuot().Length(); + } + + HBufC8* encodedSIPAddress = HBufC8::NewL (encodedLength); + TPtr8 encodedPtr = encodedSIPAddress->Des(); + + if (HasDisplayName()) + { + encodedPtr.Append(*iDisplayName); + encodedPtr.Append(' '); // SP + } + + if (HasDisplayName() || uriContainsSeparators || aUseAngleBrackets) + { + encodedPtr.Append(KLaQuot); + } + + encodedPtr.Append(*encodedURI); + + if (HasDisplayName() || uriContainsSeparators || aUseAngleBrackets) + { + encodedPtr.Append(KRaQuot); + } + + CleanupStack::PopAndDestroy(encodedURI); + CleanupStack::PushL (encodedSIPAddress); + return encodedSIPAddress; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::InternalizeL +// ---------------------------------------------------------------------------- +// +EXPORT_C CSIPAddress* CSIPAddress::InternalizeL(RReadStream& aReadStream) + { + CSIPAddress* self = new(ELeave)CSIPAddress; + CleanupStack::PushL(self); + self->DoInternalizeL(aReadStream); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ExternalizeL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CSIPAddress::ExternalizeL (RWriteStream& aWriteStream) + { + iURI->ExternalizeL(aWriteStream); + + if (HasDisplayName()) + { + aWriteStream.WriteUint8L(1); + aWriteStream.WriteUint32L (iDisplayName->Length()); + aWriteStream.WriteL (*iDisplayName, iDisplayName->Length()); + } + else + { + aWriteStream.WriteUint8L(0); + } + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::DoInternalizeL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::DoInternalizeL (RReadStream& aReadStream) + { + iURI = CURIContainer::InternalizeL(aReadStream); + + if (aReadStream.ReadUint8L() == 1) // has display name + { + TUint32 displayNameLength = aReadStream.ReadUint32L(); + iDisplayName = HBufC8::NewL (displayNameLength); + TPtr8 displayName(iDisplayName->Des()); + aReadStream.ReadL (displayName,displayNameLength); + } + else + { + iDisplayName = KNullDesC8().AllocL(); + } + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::QuotedStringLength +// ---------------------------------------------------------------------------- +// +TInt CSIPAddress::QuotedStringLength (const TDesC8& aValue) + { + if (aValue.Length() == 0) + { + return KErrNotFound; + } + TLex8 lex(aValue); + if (lex.Get() != '"') + { + return KErrNotFound; + } + TUint chrCount = 1; + TChar currChr = lex.Get(); + TBool endOfQuotedStringFound = EFalse; + TBool previousWasBackSlash = EFalse; + while (currChr != 0 && !endOfQuotedStringFound) + { + if (currChr == '\\') + { + // Backslash can be used to quote another backslash + previousWasBackSlash = !previousWasBackSlash; + } + else + { + if (currChr == '"' && !previousWasBackSlash) + { + endOfQuotedStringFound = ETrue; + } + previousWasBackSlash = EFalse; + } + chrCount++; + currChr = lex.Get(); + } + if (!endOfQuotedStringFound) + { + return KErrNotFound; + } + return chrCount; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::CheckDisplayName +// ---------------------------------------------------------------------------- +// +TBool CSIPAddress::CheckDisplayName (const TDesC8& aValue) + { + if (aValue.Length() == 0) return EFalse; + TLex8 lex(aValue); + lex.SkipSpace(); + if (lex.Peek() == '"') // quoted-string + { + return SIPSyntaxCheck::QuotedString(aValue); + } + else // *(token LWS) + { + TPtrC8 token(lex.NextToken()); + while (token.Length() > 0) + { + if (!SIPSyntaxCheck::Token(token)) + { + return EFalse; + } + token.Set(lex.NextToken()); + } + } + return ETrue; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ParseURIInAngleBracketsL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ParseURIInAngleBracketsL (const TDesC8& aValue) + { + __ASSERT_ALWAYS (aValue.Length() > 0, + User::Leave (KErrSipCodecSIPAddress)); + + HBufC8* trimmedValue = aValue.AllocLC(); + TPtr8 trimmedValuePtr(trimmedValue->Des()); + trimmedValuePtr.Trim(); + + TInt openingAngleBracketPos = trimmedValuePtr.Locate('<'); + if (openingAngleBracketPos != 0) + { + User::Leave (KErrSipCodecSIPAddress); + } + + TInt closingAngleBracketPos = trimmedValuePtr.LocateReverse('>'); + if (closingAngleBracketPos < 0 || + closingAngleBracketPos != trimmedValuePtr.Length()-1) + { + User::Leave (KErrSipCodecSIPAddress); + } + + const TInt KURIStartPos = 1; + const TInt KURIEndPos = trimmedValuePtr.Length()-2; + ParseURIL (trimmedValuePtr.Mid(KURIStartPos,KURIEndPos)); + + CleanupStack::PopAndDestroy(trimmedValue); + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ParseURIL +// ---------------------------------------------------------------------------- +// +void CSIPAddress::ParseURIL (const TDesC8& aValue) + { + __ASSERT_ALWAYS (aValue.Length() > 0, + User::Leave (KErrSipCodecURI)); + + CURIContainer* uri = CURIContainer::DecodeL (aValue); + delete iURI; + iURI = uri; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::ContainsSeparators +// ---------------------------------------------------------------------------- +// +TBool CSIPAddress::ContainsSeparators(const TDesC8& aValue) const + { + TLex8 lex(aValue); + TChar chr = lex.Get(); + while (chr) + { + if (chr == ',' || chr == '?' || chr == ';') + { + return ETrue; + } + chr = lex.Get(); + } + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CSIPAddress::HasDisplayName +// ---------------------------------------------------------------------------- +// +TBool CSIPAddress::HasDisplayName() const + { + return (DisplayName().Length() > 0); + }