|
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 } |