realtimenetprots/sipfw/SIP/Codec/src/CSIPHostPort.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Codec/src/CSIPHostPort.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,338 @@
+// 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          : CSIPHostPort.cpp
+// Part of       : SIP Codec
+// Version       : SIP/4.0 
+//
+
+
+
+
+#include "siphostport.h"
+#include "sipcodecerr.h"
+#include "SIPSyntaxCheck.h"
+#include "_sipcodecdefs.h"
+
+_LIT8(KPortFormat, "%u");
+
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::DecodeL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPHostPort* CSIPHostPort::DecodeL (const TDesC8& aValue)
+	{
+	__ASSERT_ALWAYS (aValue.Length() > 0, User::Leave(KErrSipCodecHostPort));
+
+	CSIPHostPort* hostPort = new(ELeave)CSIPHostPort;
+    CleanupStack::PushL (hostPort);
+
+	if (aValue.Locate('[') == 0) // seems to be an IPv6 address
+		{
+		TInt hostEndPos = aValue.Locate(']');
+		if (hostEndPos > 1)
+			{
+			hostPort->SetHostL (aValue.Mid(1,hostEndPos-1));
+			if (hostEndPos < aValue.Length()-1) // seems to have a port
+				{
+				TLex8 lex(aValue.Mid(hostEndPos+1));
+				lex.SkipSpace();
+				TPtrC8 portAsText(lex.Remainder());
+				if (portAsText.Length() > 0)
+					{
+					TInt colonPos = portAsText.Locate (':');
+					if (colonPos != 0) User::Leave(KErrSipCodecPort);
+					hostPort->SetPort (ParsePortL(portAsText.Mid(1)));
+					}
+				}
+			}
+		else
+			{
+			User::Leave(KErrSipCodecHostPort);
+			}
+	    __ASSERT_ALWAYS (hostPort->HostType() == ESIPIpv6, 
+	                     User::Leave(KErrSipCodecHostPort));
+		}
+	else // seems to be an IPv4 address or a host name 
+		{
+		TInt colonPos = aValue.Locate(':');
+		if (colonPos == 0 || colonPos == aValue.Length()-1)
+			{
+			User::Leave(KErrSipCodecPort);
+			}
+		if (colonPos > 0) // has port
+			{
+			hostPort->SetPort (ParsePortL (aValue.Mid(colonPos+1)));
+			hostPort->SetHostL (aValue.Left(colonPos));
+			}
+		else // has only host part
+			{
+			hostPort->SetHostL (aValue);
+			}
+		}
+	CleanupStack::Pop(hostPort);
+    
+	return hostPort;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPHostPort* CSIPHostPort::NewL (const CSIPHostPort& aHostPort)
+	{
+	CSIPHostPort* self = CSIPHostPort::NewLC (aHostPort);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPHostPort* CSIPHostPort::NewLC (const CSIPHostPort& aHostPort)
+	{
+	CSIPHostPort* self = new(ELeave)CSIPHostPort;
+	CleanupStack::PushL(self);
+	self->ConstructL (aHostPort);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::CSIPHostPort
+// -----------------------------------------------------------------------------
+//
+CSIPHostPort::CSIPHostPort()
+ : iHostType (ESIPNoHost),
+   iHasPort (EFalse)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPHostPort::ConstructL ()
+	{
+	iHost = HBufC8::NewL(0);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPHostPort::ConstructL (const CSIPHostPort& aHostPort)
+	{
+	iHost = aHostPort.iHost->AllocL();
+	iHostType = aHostPort.iHostType;
+	iHasPort = aHostPort.iHasPort;
+	iPort = aHostPort.iPort;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::~CSIPHostPort
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPHostPort::~CSIPHostPort()
+	{
+	delete iHost;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::SetHostL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPHostPort::SetHostL (const TDesC8& aHost)
+	{
+	HBufC8* tmp = aHost.AllocLC();
+	tmp->Des().Trim();
+	if (tmp->Length() == 0) 
+        {
+        User::Leave(KErrSipCodecHost);
+        }
+
+	TType hostType;
+	TInt err = SIPSyntaxCheck::HostType(*tmp,hostType);
+	if (err != KErrNone) 
+        {
+        User::Leave (err);
+        }
+
+	CleanupStack::Pop(tmp);
+
+	delete iHost;
+	iHost = tmp;
+	iHostType = hostType;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::HostType
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPHostPort::TType CSIPHostPort::HostType () const
+	{
+	return iHostType;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::Host
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSIPHostPort::Host () const
+	{
+	return *iHost;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::HasPort
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPHostPort::HasPort() const
+	{
+	return iHasPort;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::Port
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TUint CSIPHostPort::Port() const
+	{
+	if (iHasPort) 
+        {
+        return iPort;
+        }
+	return 0;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::SetPort
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPHostPort::SetPort (TUint aPort)
+	{
+	iPort = aPort;
+	iHasPort = ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::DeletePort
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CSIPHostPort::DeletePort ()
+	{
+	if (!iHasPort) 
+        {
+        return KErrNotFound;
+        }
+	iPort = 0;
+	iHasPort = EFalse;
+	return KErrNone;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::operator==
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPHostPort::operator==(const CSIPHostPort& aHostPort) const
+	{
+	if (iHostType != aHostPort.iHostType) 
+        {
+        return EFalse;
+        }
+	if (iHost->CompareF(*(aHostPort.iHost)) != 0) 
+        {
+        return EFalse;
+        }
+	if (iHasPort != aHostPort.iHasPort) 
+        {
+        return EFalse;
+        }
+	if (iHasPort)
+		{
+		if (iPort != aHostPort.iPort) 
+            {
+            return EFalse;
+            }
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::ToTextLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSIPHostPort::ToTextLC () const
+	{
+	TUint encodedLength = iHost->Length();
+	if (iHostType == ESIPIpv6)
+	    {
+	    const TInt KBracketsLength = 2; // []
+	    encodedLength += KBracketsLength;
+	    }
+	
+	const TInt KMaxPortAsText = 40;
+	TBuf8<KMaxPortAsText> portAsText;
+	if (iHasPort)
+		{
+		portAsText.Format(KPortFormat, iPort);
+		encodedLength += 1 + portAsText.Length(); // COLON + port
+		}
+	
+	HBufC8* encodedHostPort = HBufC8::NewLC(encodedLength);
+	TPtr8 encodedHostPortPtr = encodedHostPort->Des();
+	if (iHostType == ESIPIpv6)
+		{
+		encodedHostPortPtr.Append('[');
+		encodedHostPortPtr.Append(*iHost);
+		encodedHostPortPtr.Append(']');
+		}
+	else
+		{
+		encodedHostPortPtr.Append(*iHost);
+		}
+
+	if (iHasPort)
+		{
+		encodedHostPortPtr.Append(':');
+		encodedHostPortPtr.Append(portAsText);
+		}
+	return encodedHostPort;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPHostPort::ParsePortL
+// -----------------------------------------------------------------------------
+//
+TUint CSIPHostPort::ParsePortL (const TDesC8& aValue)
+	{
+	TLex8 lex(aValue);
+	lex.SkipSpace();
+	TPtrC8 remainder(lex.Remainder());
+    if (remainder.Length() == 0) 
+        {
+        User::Leave(KErrSipCodecPort);
+        }
+	TUint parsedValue=0;
+	if (lex.Val(parsedValue) != KErrNone) 
+        {
+        User::Leave (KErrSipCodecPort);
+        }
+    lex.SkipSpace();
+	if (lex.Remainder().Length() != 0) 
+        {
+        User::Leave (KErrSipCodecPort);
+        }
+	return parsedValue;
+	}