realtimenetprots/sipfw/SIP/Codec/src/CSIPAddress.cpp
changeset 0 307788aac0a8
--- /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);
+	}