realtimenetprots/sipfw/SIP/Codec/src/CSIPMessage.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSIPMessage.cpp
       
    15 // Part of       : SIP Codec
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "sipmessage.h"
       
    23 #include "CSIPContentLengthHeader.h"
       
    24 #include "sipcodecerr.h"
       
    25 #include "SIPSyntaxCheck.h"
       
    26 #include "SIPHeaderLookup.h"
       
    27 #include "sipfromheader.h"
       
    28 #include "siptoheader.h"
       
    29 #include "sipcallidheader.h"
       
    30 #include "sipcseqheader.h"
       
    31 #include "sipstrings.h"
       
    32 #include "sipstrconsts.h"
       
    33 #include "_sipcodecdefs.h"
       
    34 
       
    35 _LIT8 (KCRLF, "\r\n");
       
    36 _LIT8 (KCRLFCRLF, "\r\n\r\n");
       
    37 _LIT8 (KComma, ",");
       
    38 const TInt KSIPHeaderOffset = _FOFF(CSIPHeaderBase,iLink);
       
    39 
       
    40 // -----------------------------------------------------------------------------
       
    41 // CSIPMessage::CSIPMessage
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 CSIPMessage::CSIPMessage()
       
    45  : iAnnouncedContentLengthSet (EFalse)
       
    46 	{
       
    47 	}
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // CSIPMessage::ConstructL
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 void CSIPMessage::ConstructL()
       
    54 	{
       
    55 	SIPHeaderLookup::OpenL();
       
    56 	iContent = HBufC8::NewL(0);
       
    57 	iSIPVersion = SIPStrings::StringF(SipStrConsts::EDefaultProtocolVersion);
       
    58 	}
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CSIPMessage::~CSIPMessage
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 EXPORT_C CSIPMessage::~CSIPMessage()
       
    65 	{
       
    66 	iSIPVersion.Close();
       
    67 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
    68 		{
       
    69 		TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[i]);
       
    70 		while (iter)
       
    71 			{
       
    72 			CSIPHeaderBase* header = iter++;
       
    73 			iSIPHeaderListArray[i].Remove (*header);
       
    74 			delete header;
       
    75 			}
       
    76 		}
       
    77 	iSIPHeaderListArray.Close();
       
    78 	// NEVER ResetAndDestroy because the array contains copies of the
       
    79 	// pointers in iSIPHeaderListArray (causes double-deletion).
       
    80 	iTmpAllHeaders.Close();
       
    81 	delete iContent;
       
    82 	SIPHeaderLookup::Close();
       
    83 	}
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CSIPMessage::AddHeaderL
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 EXPORT_C void CSIPMessage::AddHeaderL (CSIPHeaderBase* aSIPHeader)
       
    90 	{
       
    91 	__ASSERT_ALWAYS (aSIPHeader != 0, User::Leave(KErrArgument));
       
    92 
       
    93 	__ASSERT_ALWAYS (!(aSIPHeader->IsExtensionHeader() &&
       
    94 	                   SIPHeaderLookup::IsSupported(aSIPHeader->Name())),
       
    95 					   User::Leave(KErrSipCodecNotAllowed));
       
    96 
       
    97 	// Never add the Content-Length header. Instead store its value.
       
    98 	if (IsContentLengthHeader(*aSIPHeader))
       
    99 		{
       
   100 		if (iAnnouncedContentLengthSet) 
       
   101 			{
       
   102 			User::Leave(KErrAlreadyExists);
       
   103 			}
       
   104 		iAnnouncedContentLengthSet = ETrue;
       
   105 		iAnnouncedContentLength = 
       
   106 			(static_cast<CSIPContentLengthHeader*>(aSIPHeader))->Value();
       
   107 		delete aSIPHeader;
       
   108 		return;
       
   109 		}
       
   110 	TInt index = FindHeaderListIndex (*aSIPHeader);
       
   111 	if (index == KErrNotFound) // Insert as the head of a new header list.
       
   112 		{
       
   113 		TSglQue<CSIPHeaderBase> headerList(KSIPHeaderOffset);
       
   114 		headerList.AddLast (*aSIPHeader);
       
   115 		InsertL (headerList);
       
   116 		}
       
   117 	else // Try to add to existing header list
       
   118 		{
       
   119 		if (!aSIPHeader->MoreThanOneAllowed()) 
       
   120             {
       
   121             User::Leave(KErrAlreadyExists);
       
   122             }
       
   123 		iSIPHeaderListArray[index].AddLast(*aSIPHeader);
       
   124 		}
       
   125 	}
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // CSIPMessage::AddHeaderL
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 EXPORT_C void CSIPMessage::AddHeaderL (const CSIPHeaderBase& aSIPHeader)
       
   132     {
       
   133     CSIPHeaderBase* header = aSIPHeader.CloneL();
       
   134     CleanupStack::PushL(header);
       
   135     AddHeaderL(header);
       
   136     CleanupStack::Pop(header);
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CSIPMessage::ReplaceHeaderL
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 EXPORT_C void CSIPMessage::ReplaceHeaderL (CSIPHeaderBase* aOldSIPHeader,
       
   144                                            CSIPHeaderBase* aNewSIPHeader)
       
   145     {
       
   146     __ASSERT_ALWAYS (aOldSIPHeader != 0, User::Leave(KErrArgument));
       
   147     __ASSERT_ALWAYS (aNewSIPHeader != 0, User::Leave(KErrArgument));
       
   148     
       
   149     RStringF oldHeaderName = aOldSIPHeader->Name();
       
   150     __ASSERT_ALWAYS (oldHeaderName == aNewSIPHeader->Name(),
       
   151                      User::Leave(KErrArgument));
       
   152 
       
   153     TInt headerListIndex = FindHeaderListIndex(*aOldSIPHeader);
       
   154     __ASSERT_ALWAYS (headerListIndex >= 0, User::Leave(KErrNotFound));
       
   155 
       
   156     TBool found = EFalse;
       
   157 	TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[headerListIndex]);
       
   158 	while (iter && !found)
       
   159 		{
       
   160 		CSIPHeaderBase* header = iter++;
       
   161 		if (header == aOldSIPHeader)
       
   162 			{
       
   163 			iSIPHeaderListArray[headerListIndex].Remove(*header);
       
   164             delete aOldSIPHeader;
       
   165             iSIPHeaderListArray[headerListIndex].AddLast(*aNewSIPHeader);
       
   166             found = ETrue;
       
   167 			}
       
   168 		}
       
   169     __ASSERT_ALWAYS (found, User::Leave(KErrNotFound));
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CSIPMessage::ReplaceHeadersL
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 EXPORT_C void 
       
   177 CSIPMessage::ReplaceHeadersL (RPointerArray<CSIPHeaderBase>& aNewHeaders)
       
   178     {
       
   179     __ASSERT_ALWAYS (aNewHeaders.Count() > 0, User::Leave(KErrArgument));
       
   180     __ASSERT_ALWAYS (aNewHeaders[0] != 0, User::Leave(KErrArgument));
       
   181     
       
   182     RStringF name = aNewHeaders[0]->Name();
       
   183     for (TInt i=1; i < aNewHeaders.Count(); i++)
       
   184         {
       
   185         __ASSERT_ALWAYS (aNewHeaders[i] != 0, User::Leave(KErrArgument));
       
   186         __ASSERT_ALWAYS (name == aNewHeaders[i]->Name(),
       
   187                          User::Leave(KErrArgument));
       
   188         }
       
   189 
       
   190     TInt headerListIndex = FindHeaderListIndex (name);
       
   191     __ASSERT_ALWAYS (headerListIndex >= 0, User::Leave(KErrArgument));
       
   192 
       
   193     // Remove old headers
       
   194     TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[headerListIndex]);
       
   195 	while (iter)
       
   196 		{
       
   197 		CSIPHeaderBase* header = iter++;
       
   198 		delete header;
       
   199 		}
       
   200     iSIPHeaderListArray[headerListIndex].Reset();
       
   201 
       
   202     // Add new headers
       
   203     for (TInt j=0; j < aNewHeaders.Count(); j++)
       
   204         {
       
   205         iSIPHeaderListArray[headerListIndex].AddLast(*aNewHeaders[j]);
       
   206         }
       
   207     aNewHeaders.Reset();
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CSIPMessage::HasHeader
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 EXPORT_C TBool CSIPMessage::HasHeader (RStringF aName) const
       
   215 	{
       
   216 	return (FindHeaderListIndex(aName) >= 0);
       
   217 	}
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CSIPMessage::HeaderCount
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 EXPORT_C TInt CSIPMessage::HeaderCount (RStringF aName)
       
   224 	{
       
   225 	TInt index = FindHeaderListIndex (aName);
       
   226 	if (index < 0) 
       
   227         {
       
   228         return 0;
       
   229         }
       
   230 	TInt headerCount=0;
       
   231 	TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[index]);
       
   232 	while (iter++) 
       
   233         {
       
   234         headerCount++;
       
   235         }
       
   236 	return headerCount;
       
   237 	}
       
   238 
       
   239 // -----------------------------------------------------------------------------
       
   240 // CSIPMessage::Headers
       
   241 // -----------------------------------------------------------------------------
       
   242 //
       
   243 EXPORT_C TSglQueIter<CSIPHeaderBase> CSIPMessage::Headers (RStringF aName)
       
   244 	{
       
   245 	TInt index = FindHeaderListIndex (aName);
       
   246 	if (index == KErrNotFound)
       
   247 		{
       
   248 		// Return and iterator initialized to an empty list
       
   249 		TSglQue<CSIPHeaderBase> emptyList(KSIPHeaderOffset);
       
   250 		return TSglQueIter<CSIPHeaderBase>(emptyList);
       
   251 		}
       
   252 	return TSglQueIter<CSIPHeaderBase>(iSIPHeaderListArray[index]);
       
   253 	}
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CSIPMessage::Header
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 EXPORT_C CSIPHeaderBase* CSIPMessage::Header (RStringF aName, TInt aIndex)
       
   260 	{
       
   261 	TInt headerListIndex = FindHeaderListIndex (aName);
       
   262 	if (headerListIndex < 0) 
       
   263         {
       
   264         return 0;
       
   265         }
       
   266 	TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[headerListIndex]);
       
   267 	TInt positionInList=0;
       
   268 	while (iter != 0 && positionInList <= aIndex)
       
   269 		{
       
   270         CSIPHeaderBase* header = iter++;
       
   271 		if (positionInList == aIndex) 
       
   272             {
       
   273             return header;
       
   274             }
       
   275 		++positionInList;
       
   276 		}
       
   277 	return 0;
       
   278 	}
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CSIPMessage::RemoveHeader
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 EXPORT_C TInt CSIPMessage::RemoveHeader (const CSIPHeaderBase* aSIPHeader)
       
   285 	{
       
   286     if (aSIPHeader == 0)
       
   287         {
       
   288         return KErrNotFound;
       
   289         }
       
   290     TInt headerListIndex = FindHeaderListIndex (*aSIPHeader);
       
   291     if (headerListIndex < 0) 
       
   292         {
       
   293         return KErrNotFound;
       
   294         }
       
   295 	TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[headerListIndex]);
       
   296 	while (iter)
       
   297 		{
       
   298 		CSIPHeaderBase* header = iter++;
       
   299 		if (header == aSIPHeader)
       
   300 			{
       
   301 			iSIPHeaderListArray[headerListIndex].Remove (*header);
       
   302 			if (iSIPHeaderListArray[headerListIndex].IsEmpty())
       
   303 				{
       
   304 				iSIPHeaderListArray.Remove(headerListIndex);
       
   305 				}
       
   306 			return KErrNone;
       
   307 			}
       
   308 		}
       
   309 	return KErrNotFound;
       
   310 	}
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CSIPMessage::DeleteHeaders
       
   314 // -----------------------------------------------------------------------------
       
   315 //
       
   316 EXPORT_C TInt CSIPMessage::DeleteHeaders (RStringF aName)
       
   317     {
       
   318     TInt headerListIndex = FindHeaderListIndex (aName);
       
   319     if (headerListIndex < 0) 
       
   320         {
       
   321         return KErrNotFound;
       
   322         }
       
   323     TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[headerListIndex]);
       
   324 	while (iter)
       
   325 		{
       
   326 		CSIPHeaderBase* header = iter++;
       
   327 		iSIPHeaderListArray[headerListIndex].Remove(*header);
       
   328 		delete header;
       
   329 		}
       
   330     iSIPHeaderListArray.Remove(headerListIndex);
       
   331     return KErrNone;
       
   332     }
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // CSIPMessage::AllHeadersL
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 EXPORT_C const RPointerArray<CSIPHeaderBase>& CSIPMessage::AllHeadersL ()
       
   339 	{
       
   340 	iTmpAllHeaders.Reset();
       
   341 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
   342 		{
       
   343 		TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[i]);
       
   344 		while (iter)
       
   345 			{
       
   346 			CSIPHeaderBase* header = iter++;
       
   347 			User::LeaveIfError(iTmpAllHeaders.Append(header));
       
   348 			}
       
   349 		}
       
   350 	return iTmpAllHeaders;
       
   351 	}
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CSIPMessage::From
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 EXPORT_C CSIPFromHeader* CSIPMessage::From ()
       
   358     {
       
   359     CSIPHeaderBase* from = 
       
   360     	Header(SIPStrings::StringF(SipStrConsts::EFromHeader),0);
       
   361     return static_cast<CSIPFromHeader*>(from);
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CSIPMessage::To
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 EXPORT_C CSIPToHeader* CSIPMessage::To ()
       
   369     {
       
   370     CSIPHeaderBase* to = 
       
   371     	Header(SIPStrings::StringF(SipStrConsts::EToHeader),0);
       
   372     return static_cast<CSIPToHeader*>(to);
       
   373     }
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // CSIPMessage::CallID
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 EXPORT_C CSIPCallIDHeader* CSIPMessage::CallID ()
       
   380     {
       
   381     CSIPHeaderBase* callid = 
       
   382     	Header(SIPStrings::StringF(SipStrConsts::ECallIDHeader),0);
       
   383     return static_cast<CSIPCallIDHeader*>(callid);
       
   384     }
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // CSIPMessage::CSeq
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 EXPORT_C CSIPCSeqHeader* CSIPMessage::CSeq ()
       
   391     {
       
   392     CSIPHeaderBase* cseq = 
       
   393     	Header(SIPStrings::StringF(SipStrConsts::ECSeqHeader),0);
       
   394     return static_cast<CSIPCSeqHeader*>(cseq);
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CSIPMessage::SIPVersion
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 EXPORT_C RStringF CSIPMessage::SIPVersion() const
       
   402 	{
       
   403 	return iSIPVersion;
       
   404 	}
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CSIPMessage::SetContent
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 EXPORT_C void CSIPMessage::SetContent (HBufC8* aContent)
       
   411 	{
       
   412 	delete iContent;
       
   413 	iContent = aContent;
       
   414 	}
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // CSIPMessage::Content
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 EXPORT_C const TDesC8& CSIPMessage::Content () const
       
   421 	{
       
   422 	return *iContent;
       
   423 	}
       
   424 
       
   425 // -----------------------------------------------------------------------------
       
   426 // CSIPMessage::TakeContentOwnershipL
       
   427 // -----------------------------------------------------------------------------
       
   428 //
       
   429 EXPORT_C HBufC8* CSIPMessage::TakeContentOwnershipL ()
       
   430     {
       
   431     HBufC8* tmp = iContent;
       
   432     iContent = HBufC8::NewL(0);
       
   433     return tmp;
       
   434     }
       
   435 
       
   436 // -----------------------------------------------------------------------------
       
   437 // CSIPMessage::HasAnnouncedContentLength
       
   438 // -----------------------------------------------------------------------------
       
   439 //
       
   440 EXPORT_C TBool CSIPMessage::HasAnnouncedContentLength() const
       
   441 	{
       
   442 	return iAnnouncedContentLengthSet;
       
   443 	}
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 // CSIPMessage::AnnouncedContentLength
       
   447 // -----------------------------------------------------------------------------
       
   448 //
       
   449 EXPORT_C TUint CSIPMessage::AnnouncedContentLength() const
       
   450 	{
       
   451 	return iAnnouncedContentLength;
       
   452 	}
       
   453 
       
   454 // -----------------------------------------------------------------------------
       
   455 // CSIPMessage::EncodedHeaderPartLengthL
       
   456 // -----------------------------------------------------------------------------
       
   457 //
       
   458 EXPORT_C TInt CSIPMessage::EncodedHeaderPartLengthL ()
       
   459     {
       
   460     TInt encodedLength = 0;
       
   461     GetEncodedFirstLineSizeL(encodedLength);
       
   462     encodedLength += KCRLF().Length();
       
   463     // Calculate encoded header lengths
       
   464 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
   465 		{
       
   466 		TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[i]);
       
   467         TInt headerCountInList=0;
       
   468 		while (iter)
       
   469 			{
       
   470 			CSIPHeaderBase* header = iter++;
       
   471             HBufC8* headerAsText = 0;
       
   472             if (++headerCountInList == 1 || header->IsExtensionHeader())
       
   473                 {
       
   474 			    headerAsText = header->ToTextL();
       
   475                 }
       
   476             else
       
   477                 {
       
   478                 headerAsText = header->ToTextValueL();
       
   479                 }
       
   480             encodedLength += headerAsText->Length();
       
   481             delete headerAsText; headerAsText = 0;
       
   482             if (!iter || header->IsExtensionHeader())
       
   483                 {
       
   484                 encodedLength += KCRLF().Length();
       
   485                 }
       
   486             else // non-extension headers are encoded as a comma separated list
       
   487                 {
       
   488                 encodedLength += KComma().Length();
       
   489                 }
       
   490 			}
       
   491 		}
       
   492 	TInt encodedContentLengthHeaderSize = 0;
       
   493 	GetEncodedContentLengthHeaderSizeL(encodedContentLengthHeaderSize);
       
   494     encodedLength += encodedContentLengthHeaderSize;
       
   495     encodedLength += KCRLFCRLF().Length(); // CRLF CRLF ending the header part
       
   496     return encodedLength;
       
   497     }
       
   498 
       
   499 // -----------------------------------------------------------------------------
       
   500 // CSIPMessage::ToTextHeaderPartL
       
   501 // -----------------------------------------------------------------------------
       
   502 //
       
   503 EXPORT_C CBufBase* CSIPMessage::ToTextHeaderPartL ()
       
   504     {
       
   505     CBufBase* encodedHeaderPart = ToTextHeaderPartLC();
       
   506     CleanupStack::Pop(encodedHeaderPart);
       
   507     return encodedHeaderPart;
       
   508     }
       
   509 
       
   510 // -----------------------------------------------------------------------------
       
   511 // CSIPMessage::ToTextHeaderPartLC
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 EXPORT_C CBufBase* CSIPMessage::ToTextHeaderPartLC ()
       
   515     {
       
   516     const TInt KResultBufExpandSize = 100;
       
   517     CBufFlat* encodedHeaderPart = CBufFlat::NewL(KResultBufExpandSize);
       
   518     CleanupStack::PushL(encodedHeaderPart);
       
   519 	HBufC8* firstLine = ToTextFirstLineLC ();    
       
   520     encodedHeaderPart->InsertL (0,*firstLine);
       
   521     TInt encodedLength = firstLine->Length();
       
   522     CleanupStack::PopAndDestroy(firstLine);
       
   523     encodedHeaderPart->InsertL (encodedLength,KCRLF);
       
   524     encodedLength += KCRLF().Length();
       
   525 
       
   526     // Add headers
       
   527 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
   528 		{
       
   529 		TSglQueIter<CSIPHeaderBase> iter(iSIPHeaderListArray[i]);
       
   530         TInt headerCountInList=0;
       
   531 		while (iter)
       
   532 			{
       
   533 			CSIPHeaderBase* header = iter++;
       
   534             HBufC8* headerAsText = NULL;
       
   535             if (++headerCountInList == 1 || !header->EncodeMultipleToOneLine())
       
   536                 {
       
   537 			    headerAsText = header->ToTextLC();
       
   538                 }
       
   539             else
       
   540                 {
       
   541                 headerAsText = header->ToTextValueLC();
       
   542                 }
       
   543             encodedHeaderPart->InsertL (encodedLength,*headerAsText);
       
   544             encodedLength += headerAsText->Length();
       
   545             CleanupStack::PopAndDestroy(headerAsText);
       
   546             if (!iter || !header->EncodeMultipleToOneLine())
       
   547                 {
       
   548                 encodedHeaderPart->InsertL (encodedLength,KCRLF);
       
   549                 encodedLength += KCRLF().Length();
       
   550                 }
       
   551             else 
       
   552                 {
       
   553                 encodedHeaderPart->InsertL (encodedLength,KComma);
       
   554                 encodedLength += KComma().Length();
       
   555                 }
       
   556 			}
       
   557 		}
       
   558 
       
   559     // Add Content-Length header
       
   560 	HBufC8* contentLengthHeaderAsText = ToTextContentLengthLC ();
       
   561     encodedHeaderPart->InsertL (encodedLength,*contentLengthHeaderAsText);
       
   562     encodedLength += contentLengthHeaderAsText->Length();
       
   563     CleanupStack::PopAndDestroy(contentLengthHeaderAsText);
       
   564 
       
   565     // Add CRLF CRLF ending the header part
       
   566     encodedHeaderPart->InsertL (encodedLength,KCRLFCRLF);
       
   567     encodedLength += KCRLFCRLF().Length();
       
   568 
       
   569     return encodedHeaderPart;
       
   570     }
       
   571 
       
   572 // -----------------------------------------------------------------------------
       
   573 // CSIPMessage::ToTextL
       
   574 // -----------------------------------------------------------------------------
       
   575 //
       
   576 EXPORT_C CBufBase* CSIPMessage::ToTextL ()
       
   577 	{
       
   578     CBufBase* encodedMessage = ToTextLC();
       
   579     CleanupStack::Pop(encodedMessage);
       
   580     return encodedMessage;
       
   581     }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // CSIPMessage::ToTextLC
       
   585 // -----------------------------------------------------------------------------
       
   586 //
       
   587 EXPORT_C CBufBase* CSIPMessage::ToTextLC ()
       
   588 	{
       
   589     CBufBase* encodedMessage = ToTextHeaderPartLC();
       
   590     TInt length = encodedMessage->Ptr(0).Length();
       
   591     encodedMessage->InsertL (length,*iContent);
       
   592 	return encodedMessage;
       
   593 	}
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CSIPMessage::ExternalizeHeadersL
       
   597 // -----------------------------------------------------------------------------
       
   598 //
       
   599 EXPORT_C void CSIPMessage::ExternalizeHeadersL (RWriteStream& aWriteStream)
       
   600 	{
       
   601 	const RPointerArray<CSIPHeaderBase>& headers = AllHeadersL();
       
   602     const CSIPHeaderBase* header = 0;
       
   603 	for (TInt i=0; i < headers.Count(); i++)
       
   604 		{
       
   605 		header = headers[i];
       
   606 		if (SIPHeaderLookup::IsAPIHeader(header->Name()) ||
       
   607 		    header->IsExtensionHeader())
       
   608 			{
       
   609 			aWriteStream.WriteUint8L(1); // more headers in the stream flag
       
   610 			header->ExternalizeL(aWriteStream);
       
   611 			}
       
   612 		}
       
   613 	aWriteStream.WriteUint8L(0); // no more headers in the stream flag
       
   614 	}
       
   615 
       
   616 // -----------------------------------------------------------------------------
       
   617 // CSIPMessage::InternalizeHeadersL
       
   618 // -----------------------------------------------------------------------------
       
   619 //
       
   620 EXPORT_C void CSIPMessage::InternalizeHeadersL (RReadStream& aReadStream)
       
   621 	{
       
   622 	TUint8 moreHeaders = aReadStream.ReadUint8L();
       
   623     CSIPHeaderBase* header = 0;
       
   624 	while (moreHeaders)
       
   625 		{
       
   626 		RStringF headerName = ReadFromStreamL(aReadStream);
       
   627 		CleanupClosePushL(headerName);
       
   628 		header = SIPHeaderLookup::InternalizeL(headerName,aReadStream);
       
   629 		CleanupStack::PopAndDestroy(1); // headerName
       
   630 		if (header != 0)
       
   631 			{
       
   632 			CleanupStack::PushL(header);
       
   633 			AddHeaderL(header);
       
   634 			CleanupStack::Pop(header);
       
   635 			}
       
   636 		moreHeaders = aReadStream.ReadUint8L();
       
   637 		}
       
   638 	}
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 // CSIPMessage::ReadFromStreamL
       
   642 // -----------------------------------------------------------------------------
       
   643 //
       
   644 RStringF CSIPMessage::ReadFromStreamL (RReadStream& aReadStream) const
       
   645 	{
       
   646 	TUint32 bufLength = aReadStream.ReadUint32L();
       
   647 	HBufC8* buf = HBufC8::NewLC (bufLength);
       
   648 	TPtr8 bufPtr(buf->Des());	
       
   649 	if (bufLength > 0)
       
   650 		{
       
   651 		aReadStream.ReadL (bufPtr,bufLength);
       
   652 		}
       
   653 	RStringF str = SIPStrings::Pool().OpenFStringL(bufPtr);
       
   654 	CleanupStack::PopAndDestroy(buf);	
       
   655 	return str;
       
   656 	}
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CSIPMessage::SetSIPVersionL
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 void CSIPMessage::SetSIPVersionL (const TDesC8& aSIPVersion)
       
   663 	{
       
   664 	__ASSERT_ALWAYS (SIPSyntaxCheck::SIPVersion(aSIPVersion),
       
   665 	                 User::Leave(KErrSipCodecSIPVersion));
       
   666 
       
   667 	HBufC8* tmp = aSIPVersion.AllocLC();
       
   668 	tmp->Des().UpperCase();
       
   669 	RStringF tmpString = SIPStrings::Pool().OpenFStringL(*tmp);
       
   670 	CleanupStack::PopAndDestroy(tmp);		
       
   671 	iSIPVersion.Close();
       
   672 	iSIPVersion = tmpString;
       
   673 	}
       
   674 
       
   675 // -----------------------------------------------------------------------------
       
   676 // CSIPMessage::IsContentLengthHeader
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 TBool CSIPMessage::IsContentLengthHeader(const CSIPHeaderBase& aHeader) const
       
   680 	{
       
   681 	if (aHeader.Name() == 
       
   682 	    SIPStrings::StringF(SipStrConsts::EContentLengthHeader) ||
       
   683 		aHeader.CompactName() ==
       
   684 		SIPStrings::StringF(SipStrConsts::EContentLengthHeaderCompact))
       
   685 		{
       
   686 		return ETrue;	
       
   687 		}
       
   688 	return EFalse;
       
   689 	}
       
   690 
       
   691 // -----------------------------------------------------------------------------
       
   692 // CSIPMessage::FindHeaderListIndex
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 TInt CSIPMessage::FindHeaderListIndex (RStringF aName) const
       
   696 	{
       
   697 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
   698 		{
       
   699 		if (!iSIPHeaderListArray[i].IsEmpty())
       
   700 			{
       
   701 			CSIPHeaderBase* header = iSIPHeaderListArray[i].First();
       
   702 			if (header != 0)
       
   703 				{
       
   704 				if (header->Name() == aName ||
       
   705 					(header->HasCompactName() && 
       
   706 					 header->CompactName() == aName))
       
   707 					{
       
   708 					return i;
       
   709 					}
       
   710 				}
       
   711 			}
       
   712 		}
       
   713 	return KErrNotFound;
       
   714 	}
       
   715 
       
   716 // -----------------------------------------------------------------------------
       
   717 // CSIPMessage::FindHeaderListIndex
       
   718 // -----------------------------------------------------------------------------
       
   719 //
       
   720 TInt CSIPMessage::FindHeaderListIndex (const CSIPHeaderBase& aHeader) const
       
   721 	{
       
   722 	for (TInt i=0; i < iSIPHeaderListArray.Count(); i++)
       
   723 		{
       
   724 		if (!iSIPHeaderListArray[i].IsEmpty())
       
   725 			{
       
   726 			CSIPHeaderBase* header = iSIPHeaderListArray[i].First();
       
   727 			if (header != 0)
       
   728 				{
       
   729 				if (header->Name() == aHeader.Name() ||
       
   730 					(header->HasCompactName() && aHeader.HasCompactName() &&
       
   731 					 header->CompactName() == aHeader.CompactName()))
       
   732 					{
       
   733 					return i;
       
   734 					}
       
   735 				}
       
   736 			}
       
   737 		}
       
   738 	return KErrNotFound;
       
   739 	}
       
   740 
       
   741 // -----------------------------------------------------------------------------
       
   742 // CSIPMessage::InsertL
       
   743 // -----------------------------------------------------------------------------
       
   744 //
       
   745 void CSIPMessage::InsertL (TSglQue<CSIPHeaderBase>& aHeaderList)
       
   746 	{
       
   747 	TLinearOrder<TSglQue<CSIPHeaderBase> > order(&HeaderOrder);
       
   748 	TInt err=iSIPHeaderListArray.InsertInOrderAllowRepeats(aHeaderList,order);
       
   749 	User::LeaveIfError (err);
       
   750 	}
       
   751 
       
   752 // -----------------------------------------------------------------------------
       
   753 // CSIPMessage::HeaderOrder
       
   754 // -----------------------------------------------------------------------------
       
   755 //
       
   756 TInt CSIPMessage::HeaderOrder (const TSglQue<CSIPHeaderBase>& aFirstList,
       
   757 							   const TSglQue<CSIPHeaderBase>& aSecondList)
       
   758 	{
       
   759 	if (aFirstList.IsEmpty() && aSecondList.IsEmpty()) 
       
   760         {
       
   761         return 0;
       
   762         }
       
   763 	if (aFirstList.IsEmpty()) 
       
   764         {
       
   765         return 1;
       
   766         }
       
   767 	if (aSecondList.IsEmpty()) 
       
   768         {
       
   769         return -1;
       
   770         }
       
   771 
       
   772 	CSIPHeaderBase* firstHeader = aFirstList.First();
       
   773 	CSIPHeaderBase* secondHeader = aSecondList.First();
       
   774 
       
   775 	if (firstHeader->PreferredPlaceInMessage() <
       
   776 		secondHeader->PreferredPlaceInMessage()) 
       
   777         {
       
   778         return -1;
       
   779         }
       
   780 
       
   781 	if (firstHeader->PreferredPlaceInMessage() >
       
   782 		secondHeader->PreferredPlaceInMessage()) 
       
   783         {
       
   784         return 1;
       
   785         }
       
   786 	
       
   787 	return 0;
       
   788 	}
       
   789 
       
   790 // -----------------------------------------------------------------------------
       
   791 // CSIPMessage::GetEncodedFirstLineSizeL
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 void CSIPMessage::GetEncodedFirstLineSizeL(TInt& aSize) const
       
   795     {
       
   796 	HBufC8* firstLine = ToTextFirstLineLC ();   
       
   797     aSize = firstLine->Length();
       
   798     CleanupStack::PopAndDestroy(firstLine);
       
   799     }
       
   800 
       
   801 // -----------------------------------------------------------------------------
       
   802 // CSIPMessage::EncodedContentLengthHeaderSizeL
       
   803 // -----------------------------------------------------------------------------
       
   804 //
       
   805 void CSIPMessage::GetEncodedContentLengthHeaderSizeL(TInt& aSize) const
       
   806     {
       
   807     HBufC8* headerAsText = ToTextContentLengthLC();
       
   808     aSize = headerAsText->Length();
       
   809     CleanupStack::PopAndDestroy(headerAsText);
       
   810     }
       
   811 
       
   812 // -----------------------------------------------------------------------------
       
   813 // CSIPMessage::ToTextContentLengthLC
       
   814 // -----------------------------------------------------------------------------
       
   815 //
       
   816 HBufC8* CSIPMessage::ToTextContentLengthLC () const
       
   817 	{
       
   818 	CSIPContentLengthHeader* contentLengthHeader 
       
   819 		= new(ELeave)CSIPContentLengthHeader;
       
   820 	CleanupStack::PushL (contentLengthHeader);
       
   821 	if (iAnnouncedContentLengthSet)
       
   822 		{	
       
   823 		contentLengthHeader->SetValue(iAnnouncedContentLength);
       
   824 		}
       
   825 	else
       
   826 		{
       
   827 		contentLengthHeader->SetValue(iContent->Length());
       
   828 		}
       
   829 	HBufC8* headerAsText = contentLengthHeader->ToTextL();
       
   830 	CleanupStack::PopAndDestroy(contentLengthHeader);
       
   831 	CleanupStack::PushL(headerAsText);
       
   832 	return headerAsText;
       
   833 	}