diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Client/src/CSIPMessageElements.cpp --- /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& aHeaders) + { + RPointerArray tmpHeaders; + CleanupClosePushL(tmpHeaders); + for (TInt i=0; i& +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 +CSIPMessageElements::UserHeadersL (RStringF aName) const + { + RPointerArray 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(aHeader); + } + else if (aHeader->Name() == SIPStrings::StringF(SipStrConsts::EToHeader)) + { + delete iToHeader; + iToHeader = static_cast(aHeader); + } + else if (aHeader->Name() == SIPStrings::StringF(SipStrConsts::ECSeqHeader)) + { + delete iCSeqHeader; + iCSeqHeader = static_cast(aHeader); + } + else if (aHeader->Name() == + SIPStrings::StringF(SipStrConsts::EContentTypeHeader)) + { + delete iContentTypeHeader; + iContentTypeHeader = static_cast(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(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 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(); + } +