|
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 : TTCPMsgContentStart.cpp |
|
15 // Part of : ConnectionMgr |
|
16 // Implementation |
|
17 // Version : SIP/4.0 |
|
18 // |
|
19 |
|
20 |
|
21 |
|
22 #include "TTCPMsgContentStart.h" |
|
23 #include "sipmessage.h" |
|
24 #include "SipAssert.h" |
|
25 #include "MMsgAssemblerContext.h" |
|
26 #include "MSigCompController.h" |
|
27 #include "CSIPMsgAssembler.h" |
|
28 |
|
29 |
|
30 // ---------------------------------------------------------------------------- |
|
31 // TTCPMsgContentStart::DataReceivedL |
|
32 // ---------------------------------------------------------------------------- |
|
33 // |
|
34 void TTCPMsgContentStart::DataReceivedL( TPtr8 aData, TUint& aNextLength ) |
|
35 { |
|
36 CSIPMessage* message = iMsgAssembler.Message(); |
|
37 |
|
38 // panic if message == 0 in debug mode. leaves in release mode. |
|
39 __SIP_ASSERT_LEAVE( message, KErrGeneral ); |
|
40 // panic if there is no content length in debug mode. |
|
41 // leaves in release mode. |
|
42 __SIP_ASSERT_LEAVE( message->HasAnnouncedContentLength(), |
|
43 KErrGeneral ); |
|
44 |
|
45 TUint contentLen = message->AnnouncedContentLength(); |
|
46 |
|
47 // panic if content length <= 0 in debug mode. |
|
48 // leaves in release mode. |
|
49 __SIP_ASSERT_LEAVE( contentLen > 0, KErrGeneral ); |
|
50 |
|
51 // if message contains already some content, received data is complementing |
|
52 // it. this kind of situation might occur when sigcomp splits too big sip |
|
53 // message to pieces |
|
54 if ( message->Content().Length() > 0 ) |
|
55 { |
|
56 iMsgAssembler.MsgBuffer().InsertL( iMsgAssembler.MsgBuffer().Size(), |
|
57 message->Content() ); |
|
58 iMsgAssembler.MsgBuffer().Compress(); |
|
59 |
|
60 // remove old uncomplete content |
|
61 HBufC8* uncompletedContent = message->TakeContentOwnershipL(); |
|
62 delete uncompletedContent; |
|
63 } |
|
64 |
|
65 if ( iMsgAssembler.SigComp().IsSupported() && |
|
66 iMsgAssembler.IsSigComp() && |
|
67 HandleComplementingSigCompDataL( aData, aNextLength, contentLen ) ) |
|
68 { |
|
69 return; |
|
70 } |
|
71 |
|
72 if ( iMsgAssembler.MsgBuffer().Size() > 0 ) |
|
73 { |
|
74 // insert received data to msg buffer. |
|
75 iMsgAssembler.MsgBuffer().InsertL( |
|
76 iMsgAssembler.MsgBuffer().Size(), aData ); |
|
77 iMsgAssembler.MsgBuffer().Compress(); |
|
78 // delete the content of received data |
|
79 aData.Delete( 0, aData.Length() ); |
|
80 |
|
81 TPtr8 bufPtr = iMsgAssembler.MsgBuffer().Ptr( 0 ); |
|
82 |
|
83 // check if the msg buffer contains the whole content, if so |
|
84 // copy the msg buffer to new data buffer, clean the msg buffer |
|
85 // and enter to msg content end state. |
|
86 if ( contentLen <= static_cast< TUint >( bufPtr.Length() ) ) |
|
87 { |
|
88 HBufC8* newData = HBufC8::NewLC( bufPtr.Length() ); |
|
89 // copy the msg buffer data new data |
|
90 TPtr8 newDataPtr = newData->Des(); |
|
91 // delete the content of received data |
|
92 aData.Delete( 0, aData.Length() ); |
|
93 newDataPtr.Append(iMsgAssembler.MsgBuffer().Ptr(0)); |
|
94 // clean the msg buffer |
|
95 iMsgAssembler.MsgBuffer().Reset(); |
|
96 iMsgAssembler.MsgBuffer().Compress(); |
|
97 |
|
98 iMsgAssembler.ChangeState( MMsgAssemblerContext::EMsgContentEnd ); |
|
99 iMsgAssembler.CurrentState().DataReceivedL( newDataPtr, |
|
100 aNextLength ); |
|
101 CleanupStack::PopAndDestroy( newData ); |
|
102 } |
|
103 // if the msg buffer contains not enough content, ask the next |
|
104 // length to be received. |
|
105 else |
|
106 { |
|
107 aNextLength = contentLen - aData.Length(); |
|
108 } |
|
109 } |
|
110 else if ( contentLen <= static_cast< TUint >( aData.Length() ) ) |
|
111 { |
|
112 iMsgAssembler.ChangeState(MMsgAssemblerContext::EMsgContentEnd); |
|
113 iMsgAssembler.CurrentState().DataReceivedL( aData, aNextLength ); |
|
114 } |
|
115 else |
|
116 { |
|
117 iMsgAssembler.MsgBuffer().InsertL( |
|
118 iMsgAssembler.MsgBuffer().Size(), aData ); |
|
119 iMsgAssembler.MsgBuffer().Compress(); |
|
120 aNextLength = contentLen - aData.Length(); |
|
121 } |
|
122 } |
|
123 |
|
124 // ---------------------------------------------------------------------------- |
|
125 // TTCPMsgContentStart::HandleComplementingSigCompDataL |
|
126 // ---------------------------------------------------------------------------- |
|
127 // |
|
128 TBool TTCPMsgContentStart::HandleComplementingSigCompDataL( |
|
129 TPtr8 aData, |
|
130 TUint& aNextLength, |
|
131 TInt aAnnouncedContentLen ) |
|
132 { |
|
133 // If still receiving compressed data, current contents have to be |
|
134 // stored until we come back from comp states, in sigcomp point of |
|
135 // view message can be complete but it ain't necessary complete |
|
136 // in sip point of view. All data in aData or msgbuffer are not |
|
137 // necessarily decompressed - these have to be taken with us when |
|
138 // going back to decompression states |
|
139 |
|
140 TInt unconsumedBytes( iMsgAssembler.UnConsumedBytes() ); |
|
141 |
|
142 TPtr8 msgBufPtr( iMsgAssembler.MsgBuffer().Ptr( 0 ) ); |
|
143 HBufC8* content = NULL; |
|
144 |
|
145 TInt decompressedDataLen = aData.Length() - unconsumedBytes; |
|
146 |
|
147 __SIP_ASSERT_LEAVE( decompressedDataLen > 0, KErrGeneral ); |
|
148 |
|
149 TInt msgBufLen( msgBufPtr.Length() ); |
|
150 TInt decompressedLen( msgBufLen + decompressedDataLen ); |
|
151 if ( aAnnouncedContentLen <= decompressedLen ) |
|
152 { |
|
153 // Enough decompressed content data |
|
154 return EFalse; |
|
155 } |
|
156 |
|
157 // Store decompressed data to message content |
|
158 if ( msgBufLen > 0 ) |
|
159 { |
|
160 content = HBufC8::NewL( decompressedLen ); |
|
161 TPtr8 contentPtr( content->Des() ); |
|
162 contentPtr.Copy( msgBufPtr ); |
|
163 contentPtr.Append( aData.Left( decompressedDataLen ) ); |
|
164 } |
|
165 else |
|
166 { |
|
167 content = aData.Left( decompressedDataLen ).AllocL(); |
|
168 } |
|
169 |
|
170 // Remove decompressed data which was stored to content |
|
171 aData.Delete( 0, decompressedDataLen ); |
|
172 |
|
173 // Clean msgbuffer |
|
174 iMsgAssembler.MsgBuffer().Reset(); |
|
175 iMsgAssembler.MsgBuffer().Compress(); |
|
176 |
|
177 iMsgAssembler.SetUnConsumedBytes( 0 ); |
|
178 |
|
179 CSIPMessage* message = iMsgAssembler.Message(); |
|
180 message->SetContent( content ); // ownership is transferred |
|
181 content = NULL; |
|
182 |
|
183 aNextLength = CSIPMsgAssembler::EMsgBufferSize; |
|
184 |
|
185 iMsgAssembler.ChangeState( MMsgAssemblerContext::ECompMsgStart ); |
|
186 iMsgAssembler.CurrentState().DataReceivedL( aData, aNextLength ); |
|
187 |
|
188 return ETrue; |
|
189 } |
|
190 |
|
191 // End of File |