diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/Codec/src/CSIPMessage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/Codec/src/CSIPMessage.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,833 @@ +// 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 : CSIPMessage.cpp +// Part of : SIP Codec +// Version : SIP/4.0 +// + + + + +#include "sipmessage.h" +#include "CSIPContentLengthHeader.h" +#include "sipcodecerr.h" +#include "SIPSyntaxCheck.h" +#include "SIPHeaderLookup.h" +#include "sipfromheader.h" +#include "siptoheader.h" +#include "sipcallidheader.h" +#include "sipcseqheader.h" +#include "sipstrings.h" +#include "sipstrconsts.h" +#include "_sipcodecdefs.h" + +_LIT8 (KCRLF, "\r\n"); +_LIT8 (KCRLFCRLF, "\r\n\r\n"); +_LIT8 (KComma, ","); +const TInt KSIPHeaderOffset = _FOFF(CSIPHeaderBase,iLink); + +// ----------------------------------------------------------------------------- +// CSIPMessage::CSIPMessage +// ----------------------------------------------------------------------------- +// +CSIPMessage::CSIPMessage() + : iAnnouncedContentLengthSet (EFalse) + { + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ConstructL +// ----------------------------------------------------------------------------- +// +void CSIPMessage::ConstructL() + { + SIPHeaderLookup::OpenL(); + iContent = HBufC8::NewL(0); + iSIPVersion = SIPStrings::StringF(SipStrConsts::EDefaultProtocolVersion); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::~CSIPMessage +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPMessage::~CSIPMessage() + { + iSIPVersion.Close(); + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + TSglQueIter iter(iSIPHeaderListArray[i]); + while (iter) + { + CSIPHeaderBase* header = iter++; + iSIPHeaderListArray[i].Remove (*header); + delete header; + } + } + iSIPHeaderListArray.Close(); + // NEVER ResetAndDestroy because the array contains copies of the + // pointers in iSIPHeaderListArray (causes double-deletion). + iTmpAllHeaders.Close(); + delete iContent; + SIPHeaderLookup::Close(); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::AddHeaderL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::AddHeaderL (CSIPHeaderBase* aSIPHeader) + { + __ASSERT_ALWAYS (aSIPHeader != 0, User::Leave(KErrArgument)); + + __ASSERT_ALWAYS (!(aSIPHeader->IsExtensionHeader() && + SIPHeaderLookup::IsSupported(aSIPHeader->Name())), + User::Leave(KErrSipCodecNotAllowed)); + + // Never add the Content-Length header. Instead store its value. + if (IsContentLengthHeader(*aSIPHeader)) + { + if (iAnnouncedContentLengthSet) + { + User::Leave(KErrAlreadyExists); + } + iAnnouncedContentLengthSet = ETrue; + iAnnouncedContentLength = + (static_cast(aSIPHeader))->Value(); + delete aSIPHeader; + return; + } + TInt index = FindHeaderListIndex (*aSIPHeader); + if (index == KErrNotFound) // Insert as the head of a new header list. + { + TSglQue headerList(KSIPHeaderOffset); + headerList.AddLast (*aSIPHeader); + InsertL (headerList); + } + else // Try to add to existing header list + { + if (!aSIPHeader->MoreThanOneAllowed()) + { + User::Leave(KErrAlreadyExists); + } + iSIPHeaderListArray[index].AddLast(*aSIPHeader); + } + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::AddHeaderL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::AddHeaderL (const CSIPHeaderBase& aSIPHeader) + { + CSIPHeaderBase* header = aSIPHeader.CloneL(); + CleanupStack::PushL(header); + AddHeaderL(header); + CleanupStack::Pop(header); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ReplaceHeaderL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::ReplaceHeaderL (CSIPHeaderBase* aOldSIPHeader, + CSIPHeaderBase* aNewSIPHeader) + { + __ASSERT_ALWAYS (aOldSIPHeader != 0, User::Leave(KErrArgument)); + __ASSERT_ALWAYS (aNewSIPHeader != 0, User::Leave(KErrArgument)); + + RStringF oldHeaderName = aOldSIPHeader->Name(); + __ASSERT_ALWAYS (oldHeaderName == aNewSIPHeader->Name(), + User::Leave(KErrArgument)); + + TInt headerListIndex = FindHeaderListIndex(*aOldSIPHeader); + __ASSERT_ALWAYS (headerListIndex >= 0, User::Leave(KErrNotFound)); + + TBool found = EFalse; + TSglQueIter iter(iSIPHeaderListArray[headerListIndex]); + while (iter && !found) + { + CSIPHeaderBase* header = iter++; + if (header == aOldSIPHeader) + { + iSIPHeaderListArray[headerListIndex].Remove(*header); + delete aOldSIPHeader; + iSIPHeaderListArray[headerListIndex].AddLast(*aNewSIPHeader); + found = ETrue; + } + } + __ASSERT_ALWAYS (found, User::Leave(KErrNotFound)); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ReplaceHeadersL +// ----------------------------------------------------------------------------- +// +EXPORT_C void +CSIPMessage::ReplaceHeadersL (RPointerArray& aNewHeaders) + { + __ASSERT_ALWAYS (aNewHeaders.Count() > 0, User::Leave(KErrArgument)); + __ASSERT_ALWAYS (aNewHeaders[0] != 0, User::Leave(KErrArgument)); + + RStringF name = aNewHeaders[0]->Name(); + for (TInt i=1; i < aNewHeaders.Count(); i++) + { + __ASSERT_ALWAYS (aNewHeaders[i] != 0, User::Leave(KErrArgument)); + __ASSERT_ALWAYS (name == aNewHeaders[i]->Name(), + User::Leave(KErrArgument)); + } + + TInt headerListIndex = FindHeaderListIndex (name); + __ASSERT_ALWAYS (headerListIndex >= 0, User::Leave(KErrArgument)); + + // Remove old headers + TSglQueIter iter(iSIPHeaderListArray[headerListIndex]); + while (iter) + { + CSIPHeaderBase* header = iter++; + delete header; + } + iSIPHeaderListArray[headerListIndex].Reset(); + + // Add new headers + for (TInt j=0; j < aNewHeaders.Count(); j++) + { + iSIPHeaderListArray[headerListIndex].AddLast(*aNewHeaders[j]); + } + aNewHeaders.Reset(); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::HasHeader +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CSIPMessage::HasHeader (RStringF aName) const + { + return (FindHeaderListIndex(aName) >= 0); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::HeaderCount +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CSIPMessage::HeaderCount (RStringF aName) + { + TInt index = FindHeaderListIndex (aName); + if (index < 0) + { + return 0; + } + TInt headerCount=0; + TSglQueIter iter(iSIPHeaderListArray[index]); + while (iter++) + { + headerCount++; + } + return headerCount; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::Headers +// ----------------------------------------------------------------------------- +// +EXPORT_C TSglQueIter CSIPMessage::Headers (RStringF aName) + { + TInt index = FindHeaderListIndex (aName); + if (index == KErrNotFound) + { + // Return and iterator initialized to an empty list + TSglQue emptyList(KSIPHeaderOffset); + return TSglQueIter(emptyList); + } + return TSglQueIter(iSIPHeaderListArray[index]); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::Header +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPHeaderBase* CSIPMessage::Header (RStringF aName, TInt aIndex) + { + TInt headerListIndex = FindHeaderListIndex (aName); + if (headerListIndex < 0) + { + return 0; + } + TSglQueIter iter(iSIPHeaderListArray[headerListIndex]); + TInt positionInList=0; + while (iter != 0 && positionInList <= aIndex) + { + CSIPHeaderBase* header = iter++; + if (positionInList == aIndex) + { + return header; + } + ++positionInList; + } + return 0; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::RemoveHeader +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CSIPMessage::RemoveHeader (const CSIPHeaderBase* aSIPHeader) + { + if (aSIPHeader == 0) + { + return KErrNotFound; + } + TInt headerListIndex = FindHeaderListIndex (*aSIPHeader); + if (headerListIndex < 0) + { + return KErrNotFound; + } + TSglQueIter iter(iSIPHeaderListArray[headerListIndex]); + while (iter) + { + CSIPHeaderBase* header = iter++; + if (header == aSIPHeader) + { + iSIPHeaderListArray[headerListIndex].Remove (*header); + if (iSIPHeaderListArray[headerListIndex].IsEmpty()) + { + iSIPHeaderListArray.Remove(headerListIndex); + } + return KErrNone; + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::DeleteHeaders +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CSIPMessage::DeleteHeaders (RStringF aName) + { + TInt headerListIndex = FindHeaderListIndex (aName); + if (headerListIndex < 0) + { + return KErrNotFound; + } + TSglQueIter iter(iSIPHeaderListArray[headerListIndex]); + while (iter) + { + CSIPHeaderBase* header = iter++; + iSIPHeaderListArray[headerListIndex].Remove(*header); + delete header; + } + iSIPHeaderListArray.Remove(headerListIndex); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::AllHeadersL +// ----------------------------------------------------------------------------- +// +EXPORT_C const RPointerArray& CSIPMessage::AllHeadersL () + { + iTmpAllHeaders.Reset(); + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + TSglQueIter iter(iSIPHeaderListArray[i]); + while (iter) + { + CSIPHeaderBase* header = iter++; + User::LeaveIfError(iTmpAllHeaders.Append(header)); + } + } + return iTmpAllHeaders; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::From +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPFromHeader* CSIPMessage::From () + { + CSIPHeaderBase* from = + Header(SIPStrings::StringF(SipStrConsts::EFromHeader),0); + return static_cast(from); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::To +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPToHeader* CSIPMessage::To () + { + CSIPHeaderBase* to = + Header(SIPStrings::StringF(SipStrConsts::EToHeader),0); + return static_cast(to); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::CallID +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPCallIDHeader* CSIPMessage::CallID () + { + CSIPHeaderBase* callid = + Header(SIPStrings::StringF(SipStrConsts::ECallIDHeader),0); + return static_cast(callid); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::CSeq +// ----------------------------------------------------------------------------- +// +EXPORT_C CSIPCSeqHeader* CSIPMessage::CSeq () + { + CSIPHeaderBase* cseq = + Header(SIPStrings::StringF(SipStrConsts::ECSeqHeader),0); + return static_cast(cseq); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::SIPVersion +// ----------------------------------------------------------------------------- +// +EXPORT_C RStringF CSIPMessage::SIPVersion() const + { + return iSIPVersion; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::SetContent +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::SetContent (HBufC8* aContent) + { + delete iContent; + iContent = aContent; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::Content +// ----------------------------------------------------------------------------- +// +EXPORT_C const TDesC8& CSIPMessage::Content () const + { + return *iContent; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::TakeContentOwnershipL +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CSIPMessage::TakeContentOwnershipL () + { + HBufC8* tmp = iContent; + iContent = HBufC8::NewL(0); + return tmp; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::HasAnnouncedContentLength +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CSIPMessage::HasAnnouncedContentLength() const + { + return iAnnouncedContentLengthSet; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::AnnouncedContentLength +// ----------------------------------------------------------------------------- +// +EXPORT_C TUint CSIPMessage::AnnouncedContentLength() const + { + return iAnnouncedContentLength; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::EncodedHeaderPartLengthL +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CSIPMessage::EncodedHeaderPartLengthL () + { + TInt encodedLength = 0; + GetEncodedFirstLineSizeL(encodedLength); + encodedLength += KCRLF().Length(); + // Calculate encoded header lengths + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + TSglQueIter iter(iSIPHeaderListArray[i]); + TInt headerCountInList=0; + while (iter) + { + CSIPHeaderBase* header = iter++; + HBufC8* headerAsText = 0; + if (++headerCountInList == 1 || header->IsExtensionHeader()) + { + headerAsText = header->ToTextL(); + } + else + { + headerAsText = header->ToTextValueL(); + } + encodedLength += headerAsText->Length(); + delete headerAsText; headerAsText = 0; + if (!iter || header->IsExtensionHeader()) + { + encodedLength += KCRLF().Length(); + } + else // non-extension headers are encoded as a comma separated list + { + encodedLength += KComma().Length(); + } + } + } + TInt encodedContentLengthHeaderSize = 0; + GetEncodedContentLengthHeaderSizeL(encodedContentLengthHeaderSize); + encodedLength += encodedContentLengthHeaderSize; + encodedLength += KCRLFCRLF().Length(); // CRLF CRLF ending the header part + return encodedLength; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ToTextHeaderPartL +// ----------------------------------------------------------------------------- +// +EXPORT_C CBufBase* CSIPMessage::ToTextHeaderPartL () + { + CBufBase* encodedHeaderPart = ToTextHeaderPartLC(); + CleanupStack::Pop(encodedHeaderPart); + return encodedHeaderPart; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ToTextHeaderPartLC +// ----------------------------------------------------------------------------- +// +EXPORT_C CBufBase* CSIPMessage::ToTextHeaderPartLC () + { + const TInt KResultBufExpandSize = 100; + CBufFlat* encodedHeaderPart = CBufFlat::NewL(KResultBufExpandSize); + CleanupStack::PushL(encodedHeaderPart); + HBufC8* firstLine = ToTextFirstLineLC (); + encodedHeaderPart->InsertL (0,*firstLine); + TInt encodedLength = firstLine->Length(); + CleanupStack::PopAndDestroy(firstLine); + encodedHeaderPart->InsertL (encodedLength,KCRLF); + encodedLength += KCRLF().Length(); + + // Add headers + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + TSglQueIter iter(iSIPHeaderListArray[i]); + TInt headerCountInList=0; + while (iter) + { + CSIPHeaderBase* header = iter++; + HBufC8* headerAsText = NULL; + if (++headerCountInList == 1 || !header->EncodeMultipleToOneLine()) + { + headerAsText = header->ToTextLC(); + } + else + { + headerAsText = header->ToTextValueLC(); + } + encodedHeaderPart->InsertL (encodedLength,*headerAsText); + encodedLength += headerAsText->Length(); + CleanupStack::PopAndDestroy(headerAsText); + if (!iter || !header->EncodeMultipleToOneLine()) + { + encodedHeaderPart->InsertL (encodedLength,KCRLF); + encodedLength += KCRLF().Length(); + } + else + { + encodedHeaderPart->InsertL (encodedLength,KComma); + encodedLength += KComma().Length(); + } + } + } + + // Add Content-Length header + HBufC8* contentLengthHeaderAsText = ToTextContentLengthLC (); + encodedHeaderPart->InsertL (encodedLength,*contentLengthHeaderAsText); + encodedLength += contentLengthHeaderAsText->Length(); + CleanupStack::PopAndDestroy(contentLengthHeaderAsText); + + // Add CRLF CRLF ending the header part + encodedHeaderPart->InsertL (encodedLength,KCRLFCRLF); + encodedLength += KCRLFCRLF().Length(); + + return encodedHeaderPart; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ToTextL +// ----------------------------------------------------------------------------- +// +EXPORT_C CBufBase* CSIPMessage::ToTextL () + { + CBufBase* encodedMessage = ToTextLC(); + CleanupStack::Pop(encodedMessage); + return encodedMessage; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ToTextLC +// ----------------------------------------------------------------------------- +// +EXPORT_C CBufBase* CSIPMessage::ToTextLC () + { + CBufBase* encodedMessage = ToTextHeaderPartLC(); + TInt length = encodedMessage->Ptr(0).Length(); + encodedMessage->InsertL (length,*iContent); + return encodedMessage; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ExternalizeHeadersL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::ExternalizeHeadersL (RWriteStream& aWriteStream) + { + const RPointerArray& headers = AllHeadersL(); + const CSIPHeaderBase* header = 0; + for (TInt i=0; i < headers.Count(); i++) + { + header = headers[i]; + if (SIPHeaderLookup::IsAPIHeader(header->Name()) || + header->IsExtensionHeader()) + { + aWriteStream.WriteUint8L(1); // more headers in the stream flag + header->ExternalizeL(aWriteStream); + } + } + aWriteStream.WriteUint8L(0); // no more headers in the stream flag + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::InternalizeHeadersL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CSIPMessage::InternalizeHeadersL (RReadStream& aReadStream) + { + TUint8 moreHeaders = aReadStream.ReadUint8L(); + CSIPHeaderBase* header = 0; + while (moreHeaders) + { + RStringF headerName = ReadFromStreamL(aReadStream); + CleanupClosePushL(headerName); + header = SIPHeaderLookup::InternalizeL(headerName,aReadStream); + CleanupStack::PopAndDestroy(1); // headerName + if (header != 0) + { + CleanupStack::PushL(header); + AddHeaderL(header); + CleanupStack::Pop(header); + } + moreHeaders = aReadStream.ReadUint8L(); + } + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ReadFromStreamL +// ----------------------------------------------------------------------------- +// +RStringF CSIPMessage::ReadFromStreamL (RReadStream& aReadStream) const + { + TUint32 bufLength = aReadStream.ReadUint32L(); + HBufC8* buf = HBufC8::NewLC (bufLength); + TPtr8 bufPtr(buf->Des()); + if (bufLength > 0) + { + aReadStream.ReadL (bufPtr,bufLength); + } + RStringF str = SIPStrings::Pool().OpenFStringL(bufPtr); + CleanupStack::PopAndDestroy(buf); + return str; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::SetSIPVersionL +// ----------------------------------------------------------------------------- +// +void CSIPMessage::SetSIPVersionL (const TDesC8& aSIPVersion) + { + __ASSERT_ALWAYS (SIPSyntaxCheck::SIPVersion(aSIPVersion), + User::Leave(KErrSipCodecSIPVersion)); + + HBufC8* tmp = aSIPVersion.AllocLC(); + tmp->Des().UpperCase(); + RStringF tmpString = SIPStrings::Pool().OpenFStringL(*tmp); + CleanupStack::PopAndDestroy(tmp); + iSIPVersion.Close(); + iSIPVersion = tmpString; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::IsContentLengthHeader +// ----------------------------------------------------------------------------- +// +TBool CSIPMessage::IsContentLengthHeader(const CSIPHeaderBase& aHeader) const + { + if (aHeader.Name() == + SIPStrings::StringF(SipStrConsts::EContentLengthHeader) || + aHeader.CompactName() == + SIPStrings::StringF(SipStrConsts::EContentLengthHeaderCompact)) + { + return ETrue; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::FindHeaderListIndex +// ----------------------------------------------------------------------------- +// +TInt CSIPMessage::FindHeaderListIndex (RStringF aName) const + { + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + if (!iSIPHeaderListArray[i].IsEmpty()) + { + CSIPHeaderBase* header = iSIPHeaderListArray[i].First(); + if (header != 0) + { + if (header->Name() == aName || + (header->HasCompactName() && + header->CompactName() == aName)) + { + return i; + } + } + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::FindHeaderListIndex +// ----------------------------------------------------------------------------- +// +TInt CSIPMessage::FindHeaderListIndex (const CSIPHeaderBase& aHeader) const + { + for (TInt i=0; i < iSIPHeaderListArray.Count(); i++) + { + if (!iSIPHeaderListArray[i].IsEmpty()) + { + CSIPHeaderBase* header = iSIPHeaderListArray[i].First(); + if (header != 0) + { + if (header->Name() == aHeader.Name() || + (header->HasCompactName() && aHeader.HasCompactName() && + header->CompactName() == aHeader.CompactName())) + { + return i; + } + } + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::InsertL +// ----------------------------------------------------------------------------- +// +void CSIPMessage::InsertL (TSglQue& aHeaderList) + { + TLinearOrder > order(&HeaderOrder); + TInt err=iSIPHeaderListArray.InsertInOrderAllowRepeats(aHeaderList,order); + User::LeaveIfError (err); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::HeaderOrder +// ----------------------------------------------------------------------------- +// +TInt CSIPMessage::HeaderOrder (const TSglQue& aFirstList, + const TSglQue& aSecondList) + { + if (aFirstList.IsEmpty() && aSecondList.IsEmpty()) + { + return 0; + } + if (aFirstList.IsEmpty()) + { + return 1; + } + if (aSecondList.IsEmpty()) + { + return -1; + } + + CSIPHeaderBase* firstHeader = aFirstList.First(); + CSIPHeaderBase* secondHeader = aSecondList.First(); + + if (firstHeader->PreferredPlaceInMessage() < + secondHeader->PreferredPlaceInMessage()) + { + return -1; + } + + if (firstHeader->PreferredPlaceInMessage() > + secondHeader->PreferredPlaceInMessage()) + { + return 1; + } + + return 0; + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::GetEncodedFirstLineSizeL +// ----------------------------------------------------------------------------- +// +void CSIPMessage::GetEncodedFirstLineSizeL(TInt& aSize) const + { + HBufC8* firstLine = ToTextFirstLineLC (); + aSize = firstLine->Length(); + CleanupStack::PopAndDestroy(firstLine); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::EncodedContentLengthHeaderSizeL +// ----------------------------------------------------------------------------- +// +void CSIPMessage::GetEncodedContentLengthHeaderSizeL(TInt& aSize) const + { + HBufC8* headerAsText = ToTextContentLengthLC(); + aSize = headerAsText->Length(); + CleanupStack::PopAndDestroy(headerAsText); + } + +// ----------------------------------------------------------------------------- +// CSIPMessage::ToTextContentLengthLC +// ----------------------------------------------------------------------------- +// +HBufC8* CSIPMessage::ToTextContentLengthLC () const + { + CSIPContentLengthHeader* contentLengthHeader + = new(ELeave)CSIPContentLengthHeader; + CleanupStack::PushL (contentLengthHeader); + if (iAnnouncedContentLengthSet) + { + contentLengthHeader->SetValue(iAnnouncedContentLength); + } + else + { + contentLengthHeader->SetValue(iContent->Length()); + } + HBufC8* headerAsText = contentLengthHeader->ToTextL(); + CleanupStack::PopAndDestroy(contentLengthHeader); + CleanupStack::PushL(headerAsText); + return headerAsText; + }