--- /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();
+ }
+