realtimenetprots/sipfw/SIP/Client/src/CSIPMessageElements.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/Client/src/CSIPMessageElements.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,516 @@
+// Copyright (c) 2005-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          : CSIPMessageElements.cpp
+// Part of       : SIPClient
+// Version       : SIP/4.0 
+//
+
+
+
+
+#include "sipmessageelements.h"
+#include "sipheaderbase.h"
+#include "sipfromheader.h"
+#include "sipcontactheader.h"
+#include "siptoheader.h"
+#include "sipcseqheader.h"
+#include "sipcontenttypeheader.h"
+#include "sipextensionheader.h"
+#include "SIPHeaderLookup.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "_sipcodecdefs.h"
+
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageElements* CSIPMessageElements::NewL()
+	{
+    CSIPMessageElements* self = CSIPMessageElements::NewLC();
+    CleanupStack::Pop (self);
+    return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageElements* CSIPMessageElements::NewLC ()
+	{
+	CSIPMessageElements* self = new(ELeave)CSIPMessageElements;
+    CleanupStack::PushL (self);
+    self->ConstructL ();
+    return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::CSIPMessageElements
+// -----------------------------------------------------------------------------
+//
+CSIPMessageElements::CSIPMessageElements ()
+ : iHeaderLookupOpen(EFalse) 
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::ConstructL()
+	{
+	SIPHeaderLookup::OpenL();
+    iHeaderLookupOpen = ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::~CSIPMessageElements
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPMessageElements::~CSIPMessageElements () 
+	{
+    if (iHeaderLookupOpen)
+        {
+	    SIPHeaderLookup::Close();
+        }
+	delete iContent;
+	iUserHeaders.ResetAndDestroy();
+    delete iFromHeader;
+    delete iToHeader;
+    delete iCSeqHeader;
+    delete iContentTypeHeader;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::SetUserHeadersL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void 
+CSIPMessageElements::SetUserHeadersL (RPointerArray<CSIPHeaderBase>& aHeaders)
+	{
+    RPointerArray<CSIPHeaderBase> tmpHeaders;
+    CleanupClosePushL(tmpHeaders);
+	for (TInt i=0; i<aHeaders.Count(); i++)
+        {
+        CSIPHeaderBase* header = aHeaders[i];
+        CheckUserHeaderL(header);
+        tmpHeaders.AppendL(header);
+        }
+    CleanupStack::Pop(1); // tmpHeaders
+    iUserHeaders.ResetAndDestroy();
+    iUserHeaders = tmpHeaders;
+    aHeaders.Reset();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::UserHeaders
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const RPointerArray<CSIPHeaderBase>& 
+CSIPMessageElements::UserHeaders() const
+	{
+	return iUserHeaders;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::SetContentL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPMessageElements::SetContentL (HBufC8* aContent,
+                                                CSIPContentTypeHeader* aType)
+	{
+	__ASSERT_ALWAYS (aContent != 0, User::Leave(KErrArgument));
+	__ASSERT_ALWAYS (aType != 0, User::Leave(KErrArgument));
+
+    delete iContentTypeHeader;
+    iContentTypeHeader = aType;
+	delete iContent;
+	iContent = aContent;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::Content
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSIPMessageElements::Content () const
+    {
+    if (iContent)
+        {
+        return *iContent;
+        }
+    return KNullDesC8;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::Content
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CSIPContentTypeHeader* CSIPMessageElements::ContentType() const
+    {
+    return iContentTypeHeader;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::ExtractContent
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC8* CSIPMessageElements::ExtractContent ()
+    {
+    HBufC8* tmp = iContent;
+    iContent = 0;
+    delete iContentTypeHeader;
+    iContentTypeHeader = 0;
+    return tmp;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::InternalizeL
+// -----------------------------------------------------------------------------
+//
+CSIPMessageElements* CSIPMessageElements::InternalizeL(RReadStream& aReadStream)
+	{
+	CSIPMessageElements* self = CSIPMessageElements::NewLC();
+    self->DoInternalizeL(aReadStream);
+	CleanupStack::Pop(self);
+    return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::DoInternalizeL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::DoInternalizeL (RReadStream& aReadStream)
+	{
+	TUint8 moreHeaders = aReadStream.ReadUint8L();
+	while (moreHeaders)
+		{
+		TUint32 nameLength = aReadStream.ReadUint32L();
+		HBufC8* name = HBufC8::NewLC (nameLength);
+		TPtr8 namePtr(name->Des());
+		aReadStream.ReadL (namePtr,nameLength);
+		RStringF nameStr = SIPStrings::Pool().OpenFStringL(namePtr);
+		CleanupClosePushL(nameStr);
+		CSIPHeaderBase* header = 
+		    SIPHeaderLookup::InternalizeL(nameStr,aReadStream);
+		CleanupStack::PopAndDestroy(); // nameStr
+		CleanupStack::PopAndDestroy(name);
+		CleanupStack::PushL(header);
+		AddHeaderL(header);
+		CleanupStack::Pop(header);
+		moreHeaders = aReadStream.ReadUint8L();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::ExternalizeL
+// -----------------------------------------------------------------------------
+//
+void 
+CSIPMessageElements::ExternalizeL (RWriteStream& aWriteStream) const
+	{
+    if (iFromHeader)
+        {
+		aWriteStream.WriteUint8L(1); // more headers in the stream flag
+        iFromHeader->ExternalizeL(aWriteStream);
+        }
+    if (iToHeader)
+        {
+		aWriteStream.WriteUint8L(1); // more headers in the stream flag
+        iToHeader->ExternalizeL(aWriteStream);
+        }
+    if (iCSeqHeader)
+        {
+		aWriteStream.WriteUint8L(1); // more headers in the stream flag
+        iCSeqHeader->ExternalizeL(aWriteStream);
+        }
+    if (iContentTypeHeader)
+        {
+        aWriteStream.WriteUint8L(1); // more headers in the stream flag
+        iContentTypeHeader->ExternalizeL(aWriteStream);
+        }
+    ExternalizeUserHeadersL (aWriteStream);
+	aWriteStream.WriteUint8L(0); // no more headers in the stream flag
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::UserHeaderCount
+// -----------------------------------------------------------------------------
+//
+TInt CSIPMessageElements::UserHeaderCount (RStringF aName) const
+    {
+    TInt headerCount = 0;
+	for (TInt i=0; i < iUserHeaders.Count(); i++)
+		{
+        if (iUserHeaders[i]->Name() == aName)
+            {
+            headerCount++;
+            }
+		}
+    return headerCount;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::UserHeadersL
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CSIPHeaderBase> 
+CSIPMessageElements::UserHeadersL (RStringF aName) const
+    {
+    RPointerArray<CSIPHeaderBase> headers;
+    CleanupClosePushL(headers);
+	for (TInt i=0; i < iUserHeaders.Count(); i++)
+		{
+        if (iUserHeaders[i]->Name() == aName)
+            {
+            User::LeaveIfError(headers.Append(iUserHeaders[i]));
+            }
+		}
+    CleanupStack::Pop(1); // headers
+    return headers;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::RemoveHeaders
+// -----------------------------------------------------------------------------
+//
+TInt CSIPMessageElements::RemoveHeaders (RStringF aName)
+    {
+    TInt err = KErrNotFound;
+	for (TInt i=iUserHeaders.Count()-1; i>=0; i--)
+		{
+        if (iUserHeaders[i]->Name() == aName)
+            {
+            CSIPHeaderBase* header = iUserHeaders[i];
+            iUserHeaders.Remove(i);
+            delete header;
+            err = KErrNone;
+            }
+		}
+    return err;
+    }   
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::DetachUserHeader
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::DetachUserHeader (CSIPHeaderBase* aHeader)
+    {
+	for (TInt i=0; i < iUserHeaders.Count(); i++)
+		{
+        if (iUserHeaders[i] == aHeader)
+            {
+            iUserHeaders.Remove(i);
+            }
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::AddHeaderL 
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::AddHeaderL (CSIPHeaderBase* aHeader)
+	{
+	__ASSERT_ALWAYS (aHeader != 0, User::Leave(KErrArgument));
+	
+    if (aHeader->Name() == SIPStrings::StringF(SipStrConsts::EFromHeader))
+        {
+        delete iFromHeader;
+        iFromHeader = static_cast<CSIPFromHeader*>(aHeader);
+        }
+    else if (aHeader->Name() == SIPStrings::StringF(SipStrConsts::EToHeader))
+        {
+        delete iToHeader;
+        iToHeader = static_cast<CSIPToHeader*>(aHeader);
+        }
+    else if (aHeader->Name() == SIPStrings::StringF(SipStrConsts::ECSeqHeader))
+        {
+        delete iCSeqHeader;
+        iCSeqHeader = static_cast<CSIPCSeqHeader*>(aHeader);
+        }
+    else if (aHeader->Name() == 
+             SIPStrings::StringF(SipStrConsts::EContentTypeHeader))
+        {
+        delete iContentTypeHeader;
+        iContentTypeHeader = static_cast<CSIPContentTypeHeader*>(aHeader);
+        }
+    else
+        {
+        User::LeaveIfError(iUserHeaders.Append(aHeader));
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::SetToL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::SetToL (CSIPToHeader* aTo)
+    {
+    __ASSERT_ALWAYS (aTo != 0, User::Leave(KErrArgument));
+    __ASSERT_ALWAYS (!aTo->HasParam(SIPStrings::StringF(SipStrConsts::ETag)),
+                     User::Leave(KErrArgument));
+
+    delete iToHeader;
+    iToHeader = aTo;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::To
+// -----------------------------------------------------------------------------
+//
+const CSIPToHeader* CSIPMessageElements::To() const
+    {
+    return iToHeader;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::SetFromL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::SetFromL (CSIPFromHeader* aFrom)
+    {
+    __ASSERT_ALWAYS (aFrom != 0, User::Leave(KErrArgument));
+    __ASSERT_ALWAYS (!aFrom->HasParam(SIPStrings::StringF(SipStrConsts::ETag)),
+                     User::Leave(KErrArgument));
+
+    delete iFromHeader;
+    iFromHeader = aFrom;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::From
+// -----------------------------------------------------------------------------
+//
+const CSIPFromHeader* CSIPMessageElements::From() const
+    {
+    return iFromHeader;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::CSeq
+// -----------------------------------------------------------------------------
+//
+const CSIPCSeqHeader* CSIPMessageElements::CSeq() const
+    {
+    return iCSeqHeader;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::SetContent
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::SetContent (HBufC8* aContent)
+    {
+    delete iContent;
+    iContent = aContent;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::DetachContent
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::DetachContent ()
+    {
+    iContent = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::CheckUserHeaderL
+// -----------------------------------------------------------------------------
+//
+void CSIPMessageElements::CheckUserHeaderL (const CSIPHeaderBase* aHeader) const
+    {
+    __ASSERT_ALWAYS (aHeader != 0, User::Leave(KErrArgument));
+    // The SIP headers can be divided to two sets:
+    // Supported headers and extension headers.
+    // The supported headers can be further divided into two subsets:
+    // API headers and private headers. 
+    // Private headers cannot be set by the application.
+    RStringF name = aHeader->Name();
+    if (SIPHeaderLookup::IsAPIHeader(name))
+        {
+        if (name == SIPStrings::StringF(SipStrConsts::EFromHeader) ||
+            name == SIPStrings::StringF(SipStrConsts::EToHeader) ||
+            name == SIPStrings::StringF(SipStrConsts::ECSeqHeader) ||
+            name == SIPStrings::StringF(SipStrConsts::EContentTypeHeader))
+            {
+            User::Leave(KErrArgument);
+            }
+        }
+    else
+        {
+        if (SIPHeaderLookup::IsSupported(name)) // Private header
+            {
+            User::Leave(KErrArgument);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::ExternalizeUserHeadersL
+// -----------------------------------------------------------------------------
+//   
+void 
+CSIPMessageElements::ExternalizeUserHeadersL (RWriteStream& aWriteStream) const
+    {
+    CSIPHeaderBase* header = 0;
+	for (TInt i=0; i < iUserHeaders.Count(); i++)
+		{
+        header = iUserHeaders[i];
+        if (header->IsExtensionHeader())
+            {
+            ExternalizeL(static_cast<CSIPExtensionHeader*>(header),
+                         aWriteStream);
+            }
+        else
+            {
+            aWriteStream.WriteUint8L(1); // more headers in the stream
+            header->ExternalizeL(aWriteStream);
+            }
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPMessageElements::ExternalizeL
+// -----------------------------------------------------------------------------
+//  
+void CSIPMessageElements::ExternalizeL (const CSIPExtensionHeader* aHeader,
+                                        RWriteStream& aWriteStream) const
+    {
+    RPointerArray<CSIPHeaderBase> convertedHeaders;
+    CSIPHeaderBase* convertedHeader = 0;
+    if (SIPHeaderLookup::IsSupported(aHeader->Name()))
+        {
+        convertedHeaders = SIPHeaderLookup::CreateHeaderL(aHeader->Name(),
+                                                          aHeader->Value());
+        CSIPHeaderBase::PushLC(&convertedHeaders);
+        for (TInt i=0; i < convertedHeaders.Count(); i++)
+            {
+            convertedHeader = convertedHeaders[i];
+            if (convertedHeader->ExternalizeSupported())
+                {
+                aWriteStream.WriteUint8L(1); // more headers in the stream
+                convertedHeader->ExternalizeL(aWriteStream);
+                }
+            }
+        CleanupStack::PopAndDestroy(1); // convertedHeaders
+        }
+    else
+        {
+        aWriteStream.WriteUint8L(1); // more headers in the stream
+        aHeader->ExternalizeL(aWriteStream);
+        }
+    convertedHeaders.Close();
+    }
+