|
1 /* |
|
2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 // INCLUDE FILES |
|
26 #include <http.h> |
|
27 |
|
28 #include "senmultiparttxnstate.h" |
|
29 #include "senhttpchannel.h" |
|
30 #include "sendebug.h" |
|
31 #include "senlogger.h" |
|
32 |
|
33 |
|
34 // =========================== MEMBER FUNCTIONS =============================== |
|
35 |
|
36 // ---------------------------------------------------------------------------- |
|
37 // CSenMultiPartTxnState::CSenMultiPartTxnState |
|
38 // C++ default constructor can NOT contain any code, that |
|
39 // might leave. |
|
40 // ---------------------------------------------------------------------------- |
|
41 // |
|
42 CSenMultiPartTxnState::CSenMultiPartTxnState(MSenResponseObserver& aObserver) |
|
43 : CSenTxnState(aObserver), |
|
44 iRootCid(NULL), |
|
45 iMimeBoundaryOut(NULL), |
|
46 iMimeBoundaryIn(NULL), |
|
47 iMimeBoundaryEndIn(NULL), |
|
48 iPartDataOut(1), |
|
49 iLastPartOut(EFalse), |
|
50 iPartDataIn(1), |
|
51 iLastPartIn(EFalse), |
|
52 iCurPart(EFalse), |
|
53 iBinaryDataEnd(ETrue), |
|
54 iChecked(EFalse), |
|
55 iBinaryDataPart(NULL), |
|
56 iBinaryDataParts(NULL), |
|
57 iBinaryDataRest(NULL), |
|
58 iFirst(ETrue) |
|
59 { |
|
60 } |
|
61 |
|
62 |
|
63 |
|
64 CSenMultiPartTxnState::~CSenMultiPartTxnState() |
|
65 { |
|
66 iMessage = NULL; |
|
67 iBinaryDataList.Close(); |
|
68 iRootCid.Close(); |
|
69 iMimeBoundaryOut.Close(); |
|
70 iMimeBoundaryIn.Close(); |
|
71 iMimeBoundaryEndIn.Close(); |
|
72 iCurrentPart.Close(); |
|
73 iSoapAction.Close(); |
|
74 iXopEnvelopeResponse.Close(); |
|
75 iBlobHeader.Close(); |
|
76 |
|
77 for(TUint i(0); i < iFileNames.Count(); ++i) // iFileNames.Count() equals iCids.Count() |
|
78 { |
|
79 iFileNames[i].Close(); |
|
80 iCids[i].Close(); |
|
81 } |
|
82 iFileNames.Close(); |
|
83 iCids.Close(); |
|
84 } |
|
85 |
|
86 |
|
87 |
|
88 // --------------------------------------------------------------------- |
|
89 // calculates number of parts in BLOB (every part = 10KB) |
|
90 // and how many bytes there are in the last part |
|
91 //---------------------------------------------------------------------- |
|
92 // |
|
93 void CSenMultiPartTxnState::SizeBinaryData(TUint aIndex) |
|
94 { |
|
95 TUint size = iBinaryDataList[aIndex].Size(); |
|
96 iBinaryDataParts = size/KTenKBytes; |
|
97 iBinaryDataRest = size%KTenKBytes; |
|
98 if (iBinaryDataParts > 0) |
|
99 { |
|
100 iBinaryDataEnd = EFalse; |
|
101 } |
|
102 } |
|
103 |
|
104 // --------------------------------------------------------------------- |
|
105 // creates header for Blob in Request |
|
106 // --------------------------------------------------------------------- |
|
107 // |
|
108 void CSenMultiPartTxnState::BlobHeaderL() |
|
109 { |
|
110 // iCurrentPart == header, binary part |
|
111 RBuf8 boundaryStart; |
|
112 boundaryStart.CleanupClosePushL(); |
|
113 SenMultiPartUtils::BoundaryLineStartL(iMimeBoundaryOut, boundaryStart); |
|
114 |
|
115 TUint index = (iPartDataOut - 3)/2; |
|
116 |
|
117 RBuf8 headerBinaryData; |
|
118 headerBinaryData.CleanupClosePushL(); |
|
119 SenMultiPartUtils::HeaderBinaryDataL(index, iBinaryDataList, headerBinaryData); |
|
120 |
|
121 iCurrentPart.ReAllocL(2*KNewLine().Length()+boundaryStart.Length()+headerBinaryData.Length()); |
|
122 iCurrentPart.Append(KNewLine); |
|
123 iCurrentPart.Append(KNewLine); |
|
124 iCurrentPart.Append(boundaryStart); |
|
125 iCurrentPart.Append(headerBinaryData); |
|
126 CleanupStack::PopAndDestroy(&headerBinaryData); |
|
127 CleanupStack::PopAndDestroy(&boundaryStart); |
|
128 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::GetNextDataPart - aDataPart (header, binary part):"))); |
|
129 iCurPart = ETrue; |
|
130 } |
|
131 |
|
132 // --------------------------------------------------------------------- |
|
133 // for case if Blob is kept in a file |
|
134 // this function passes Blob from a file part by part (every part = 10KB) |
|
135 // in Request |
|
136 // --------------------------------------------------------------------- |
|
137 // |
|
138 void CSenMultiPartTxnState::FileContainerL(TUint aIndex) |
|
139 { |
|
140 if (!iChecked) |
|
141 { |
|
142 SizeBinaryData(aIndex); |
|
143 iChecked = ETrue; |
|
144 } |
|
145 if (iBinaryDataPart < iBinaryDataParts) |
|
146 { |
|
147 SenMultiPartUtils::FileDataPartL(iBinaryDataPart, aIndex, iBinaryDataList, iCurrentPart); |
|
148 } |
|
149 else if (iBinaryDataRest != 0) |
|
150 { |
|
151 SenMultiPartUtils::FileDataRestL(iBinaryDataParts, iBinaryDataRest, aIndex, iBinaryDataList, iCurrentPart); |
|
152 iBinaryDataEnd = ETrue; |
|
153 } |
|
154 iCurPart = ETrue; |
|
155 } |
|
156 |
|
157 // --------------------------------------------------------------------- |
|
158 // creates the last part (MimeBoundaryEnd) in Request |
|
159 // --------------------------------------------------------------------- |
|
160 // |
|
161 void CSenMultiPartTxnState::XopEndL() |
|
162 { |
|
163 // iCurrentPart == XOP end |
|
164 SenMultiPartUtils::BoundaryLineEndL(iMimeBoundaryOut, iCurrentPart); |
|
165 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::GetNextDataPart - aDataPart (boundary end):"))); |
|
166 iCurPart = ETrue; |
|
167 iLastPartOut = ETrue; |
|
168 } |
|
169 |
|
170 // ---------------------------------------------------------------------------- |
|
171 // CSenMultiPartTxnState::GetNextDataPart |
|
172 // Implementation of the pure virtual method from MHTTPDataSupplier |
|
173 // ---------------------------------------------------------------------------- |
|
174 // |
|
175 TBool CSenMultiPartTxnState::GetNextDataPart(TPtrC8& aDataPart) |
|
176 { |
|
177 TBool lastPart(EFalse); |
|
178 TRAP_IGNORE(lastPart = GetNextDataPartL(aDataPart)); |
|
179 return lastPart; |
|
180 } |
|
181 |
|
182 // ---------------------------------------------------------------------------- |
|
183 // CSenMultiPartTxnState::ReleaseData |
|
184 // Implementation of the pure virtual method from MHTTPDataSupplier |
|
185 // ---------------------------------------------------------------------------- |
|
186 // |
|
187 void CSenMultiPartTxnState::ReleaseData() |
|
188 { |
|
189 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::ReleaseData"))); |
|
190 iCurPart = EFalse; |
|
191 iCurrentPart.Close(); |
|
192 if (!iLastPartOut) |
|
193 { |
|
194 // Notify HTTP of more data available immediately |
|
195 TRAP_IGNORE(Transaction().NotifyNewRequestBodyPartL()); |
|
196 if (iBinaryDataEnd) |
|
197 { |
|
198 iPartDataOut++; |
|
199 iChecked = EFalse; |
|
200 iBinaryDataPart = 0; |
|
201 } |
|
202 else |
|
203 { |
|
204 ++iBinaryDataPart; |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 // ---------------------------------------------------------------------------- |
|
210 // CSenMultiPartTxnState::OverallDataSize |
|
211 // Implementation of the pure virtual method from MHTTPDataSupplier |
|
212 // ---------------------------------------------------------------------------- |
|
213 // |
|
214 TInt CSenMultiPartTxnState::OverallDataSize() |
|
215 { |
|
216 return KErrNotFound; |
|
217 } |
|
218 |
|
219 |
|
220 // ---------------------------------------------------------------------------- |
|
221 // CSenMultiPartTxnState::Reset |
|
222 // Implementation of the pure virtual method from MHTTPDataSupplier |
|
223 // ---------------------------------------------------------------------------- |
|
224 // |
|
225 TInt CSenMultiPartTxnState::Reset() |
|
226 { |
|
227 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::Reset"))); |
|
228 return KErrNone; |
|
229 } |
|
230 |
|
231 // --------------------------------------------------------------------------- |
|
232 // parses Response from server (MultiPart message) and extracts MimeBoundary part |
|
233 // and MimeBoundaryEnd part |
|
234 // --------------------------------------------------------------------------- |
|
235 // |
|
236 void CSenMultiPartTxnState::MimeBoundaryInL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1) |
|
237 { |
|
238 _LIT8(KDDash,"--"); |
|
239 aOffset = aDataPartPtr.Find(KDDash); //CodeScannerWarnings |
|
240 if (aOffset == KErrNotFound) |
|
241 { |
|
242 User::Panic(KMultiPartResponseBodyInvalidPanicText, SenMultiPartUtils::EMultiPartResponseBodyInvalid); |
|
243 } |
|
244 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset)); |
|
245 aOffset = aDataPartPtr.Find(_L8("\r\n")); |
|
246 |
|
247 iMimeBoundaryIn.ReAllocL(aOffset); |
|
248 iMimeBoundaryIn.Copy(aDataPartPtr.Left(aOffset)); |
|
249 |
|
250 iMimeBoundaryEndIn.ReAllocL(aOffset+2); |
|
251 iMimeBoundaryEndIn.Append(iMimeBoundaryIn); |
|
252 iMimeBoundaryEndIn.Append(KDDash); |
|
253 |
|
254 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-2)); |
|
255 |
|
256 aOffset = aDataPartPtr.Find(_L8("\r\n\r\n")); |
|
257 aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn); |
|
258 if (aOffset1 != KErrNotFound) |
|
259 { |
|
260 iLastPartIn = ETrue; |
|
261 } |
|
262 if (aOffset != KErrNotFound) |
|
263 { |
|
264 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-4)); |
|
265 iPartDataIn++; |
|
266 } |
|
267 } |
|
268 |
|
269 // --------------------------------------------------------------------------- |
|
270 // parses Response from server (MultiPart message) and extracts XopEnvelope part |
|
271 // --------------------------------------------------------------------------- |
|
272 // |
|
273 void CSenMultiPartTxnState::XopEnvelopeResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1) |
|
274 { |
|
275 aOffset = aDataPartPtr.Find(iMimeBoundaryIn); |
|
276 aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn); |
|
277 if (aOffset1 != KErrNotFound) |
|
278 { |
|
279 iLastPartIn = ETrue; |
|
280 } |
|
281 if (aOffset == KErrNotFound) |
|
282 { |
|
283 iXopEnvelopeResponse.ReAllocL(iXopEnvelopeResponse.Length()+aDataPartPtr.Length()); |
|
284 iXopEnvelopeResponse.Append(aDataPartPtr); |
|
285 } |
|
286 else |
|
287 { |
|
288 iXopEnvelopeResponse.ReAllocL(iXopEnvelopeResponse.Length()+aOffset-4); |
|
289 iXopEnvelopeResponse.Append(aDataPartPtr.Left(aOffset-4)); |
|
290 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset)); |
|
291 iPartDataIn++; |
|
292 iObserver->FileProgress(iId, ETrue, ETrue, |
|
293 iXopEnvelopeResponse, iXopEnvelopeResponse.Length()); |
|
294 } |
|
295 } |
|
296 |
|
297 // --------------------------------------------------------------------------- |
|
298 // parses Response from server (MultiPart message) and extracts header of Blob part |
|
299 // --------------------------------------------------------------------------- |
|
300 // |
|
301 void CSenMultiPartTxnState::BlobHeaderResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1) |
|
302 { |
|
303 aOffset = aDataPartPtr.Find(_L8("\r\n\r\n")); |
|
304 aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn); |
|
305 |
|
306 if (aOffset1 != KErrNotFound) |
|
307 { |
|
308 iLastPartIn = ETrue; |
|
309 } |
|
310 if (aOffset == KErrNotFound) |
|
311 { |
|
312 iBlobHeader.ReAllocL(iBlobHeader.Length()+aDataPartPtr.Length()); |
|
313 iBlobHeader.Append(aDataPartPtr); |
|
314 } |
|
315 else |
|
316 { |
|
317 iBlobHeader.ReAllocL(iBlobHeader.Length()+aOffset); |
|
318 iBlobHeader.Append(aDataPartPtr.Left(aOffset)); |
|
319 |
|
320 // extract cids |
|
321 SenMultiPartUtils::CidL(iBlobHeader, iCids); |
|
322 |
|
323 iBlobHeader.Close(); |
|
324 |
|
325 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-4)); |
|
326 iPartDataIn++; |
|
327 } |
|
328 } |
|
329 |
|
330 // --------------------------------------------------------------------------- |
|
331 // parses Response from server (MultiPart message) and extracts Blob part |
|
332 // puts it in the file |
|
333 // --------------------------------------------------------------------------- |
|
334 // |
|
335 void CSenMultiPartTxnState::BlobResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1) |
|
336 { |
|
337 TInt size(0); |
|
338 aOffset = aDataPartPtr.Find(iMimeBoundaryIn); |
|
339 aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn); |
|
340 if (aOffset1 != KErrNotFound) |
|
341 { |
|
342 iLastPartIn = ETrue; |
|
343 } |
|
344 TUint index = (iPartDataIn-4)/2; |
|
345 |
|
346 if (aOffset == KErrNotFound) |
|
347 { |
|
348 size = SenMultiPartUtils::SetFileL(index, iFirst, aDataPartPtr, iFileNames); |
|
349 iFirst = EFalse; |
|
350 } |
|
351 else |
|
352 { |
|
353 TPtrC8 blobPartPtr; |
|
354 blobPartPtr.Set(aDataPartPtr.Left(aOffset-4)); |
|
355 size = SenMultiPartUtils::SetFileL(index, iFirst, blobPartPtr, iFileNames); |
|
356 aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset)); |
|
357 iFirst = ETrue; |
|
358 iPartDataIn++; |
|
359 } |
|
360 iObserver->FileProgress(iId, ETrue, EFalse, iCids[index], size); |
|
361 } |
|
362 |
|
363 // --------------------------------------------------------------------------- |
|
364 // parses Response from server (MultiPart message) |
|
365 // --------------------------------------------------------------------------- |
|
366 // |
|
367 void CSenMultiPartTxnState::ParseMultiPartResponseL(TDesC8& aDataPart) |
|
368 { |
|
369 TPtrC8 dataPartPtr; |
|
370 dataPartPtr.Set(aDataPart); |
|
371 |
|
372 TInt offset(0); |
|
373 TInt offset1(-1); |
|
374 if (!iLastPartIn) |
|
375 { |
|
376 while ((dataPartPtr.Length()) && (offset != offset1)) |
|
377 { |
|
378 if (iPartDataIn == 1) |
|
379 { |
|
380 MimeBoundaryInL(dataPartPtr, offset, offset1); |
|
381 } |
|
382 else if (iPartDataIn == 2) |
|
383 { |
|
384 XopEnvelopeResponseL(dataPartPtr, offset, offset1); |
|
385 } |
|
386 else if ((iPartDataIn > 2) && (iPartDataIn%2 != 0)) |
|
387 { |
|
388 BlobHeaderResponseL(dataPartPtr, offset, offset1); |
|
389 } |
|
390 else if ((iPartDataIn > 2) && (iPartDataIn%2 == 0)) |
|
391 { |
|
392 BlobResponseL(dataPartPtr, offset, offset1); |
|
393 } |
|
394 } |
|
395 } |
|
396 } |
|
397 |
|
398 // ----------------------------------------------------------------------------- |
|
399 // added HttpTransportProperties about Cids of Blobs and File namess, |
|
400 // where Blobs are kept |
|
401 // and passes transport properties and XopEnvelope to an observer |
|
402 //------------------------------------------------------------------------------ |
|
403 // |
|
404 void CSenMultiPartTxnState::ResponseReceivedL(const SenMultiPartUtils::TMultiPartContentType& aMultiPartContentType) |
|
405 { |
|
406 TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenMultiPartTxnState(%d)::ResponseReceivedL"), iId)); |
|
407 TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"iXopEnvelopeResponse:"); |
|
408 TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,(iXopEnvelopeResponse)); |
|
409 |
|
410 |
|
411 if(iXopEnvelopeResponse.Length()) |
|
412 { |
|
413 CSenHttpTransportProperties* pHttpProperties = CSenHttpTransportProperties::NewLC(); |
|
414 |
|
415 pHttpProperties->SetDownloadFolderL(KDownloadFolder); |
|
416 for (TUint i=0; i < iCids.Count(); ++i) |
|
417 { |
|
418 pHttpProperties->SetFileAttachmentL(iCids[i], iFileNames[i]); |
|
419 } |
|
420 HBufC8* pResponse = iXopEnvelopeResponse.AllocL(); |
|
421 // delete allocated body |
|
422 iXopEnvelopeResponse.Close(); |
|
423 iObserver->ResponseReceivedL(iId, &aMultiPartContentType, pResponse, pHttpProperties); |
|
424 CleanupStack::PopAndDestroy(pHttpProperties); |
|
425 } |
|
426 else |
|
427 { |
|
428 TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"Fatal: NULL response received in MultiPartTxnState!"); |
|
429 // delete allocated body |
|
430 iXopEnvelopeResponse.Close(); |
|
431 } |
|
432 |
|
433 } |
|
434 // --------------------------------------------------------------------- |
|
435 // creates header for SoapEnvelope in Request |
|
436 // --------------------------------------------------------------------- |
|
437 // |
|
438 void CSenMultiPartTxnState::MessageHeaderL() |
|
439 { |
|
440 RBuf8 boundaryStart; |
|
441 boundaryStart.CleanupClosePushL(); |
|
442 |
|
443 // Note: BoundaryLineStart re-allocates (and first de-allocates) boundaryStart |
|
444 SenMultiPartUtils::BoundaryLineStartL(iMimeBoundaryOut, boundaryStart); |
|
445 |
|
446 RBuf8 headerRoot; |
|
447 headerRoot.CleanupClosePushL(); |
|
448 |
|
449 // Note: HeaderRootL re-allocates (and first de-allocates) iRootCid |
|
450 SenMultiPartUtils::HeaderRootL(iMessage, iRootCid, headerRoot); |
|
451 |
|
452 // iCurrentPart == header root: |
|
453 iCurrentPart.ReAllocL(boundaryStart.Length()+headerRoot.Length()); |
|
454 iCurrentPart.Append(boundaryStart); |
|
455 iCurrentPart.Append(headerRoot); |
|
456 CleanupStack::PopAndDestroy(&headerRoot); |
|
457 CleanupStack::PopAndDestroy(&boundaryStart); |
|
458 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::MessageHeaderL"))); |
|
459 iCurPart = ETrue; |
|
460 } |
|
461 |
|
462 // --------------------------------------------------------------------- |
|
463 // creates SoapEnvelope in Request |
|
464 // --------------------------------------------------------------------- |
|
465 // |
|
466 void CSenMultiPartTxnState::MessageL() |
|
467 { |
|
468 } |
|
469 |
|
470 |
|
471 // ---------------------------------------------------------------------------- |
|
472 // creates Request for MultiPart message in MultiPart format |
|
473 // should be used to send MultiPart message through HTTP Channel |
|
474 // ---------------------------------------------------------------------------- |
|
475 // |
|
476 TBool CSenMultiPartTxnState::GetNextDataPartL(TPtrC8& aDataPart) |
|
477 { |
|
478 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMtomTxnState::GetNextDataPart"))); |
|
479 |
|
480 if(!HasRequestBody()) |
|
481 { |
|
482 iLastPartOut = ETrue; |
|
483 iPartDataOut = 0; |
|
484 } |
|
485 else |
|
486 { |
|
487 if(!iCurPart) // Note: this is zero only when new part is requested |
|
488 { |
|
489 if ((iPartDataOut == 1) && (iPartDataOut < iCountDataParts)) |
|
490 { |
|
491 MessageHeaderL(); // First part of MultiPart message = header of SoapEnvelope |
|
492 } |
|
493 else if ((iPartDataOut == 2) && (iPartDataOut < iCountDataParts)) |
|
494 { |
|
495 MessageL(); // Second part of MultiPart message = SoapEnvelope |
|
496 } |
|
497 else if ((iPartDataOut > 2) && (iPartDataOut%2 != 0) && (iPartDataOut < iCountDataParts)) |
|
498 { |
|
499 BlobHeaderL(); // Third and then all odd parts = headers of Blobs |
|
500 } |
|
501 else if ((iPartDataOut > 2) && (iPartDataOut%2 == 0) && (iPartDataOut < iCountDataParts)) |
|
502 { |
|
503 TUint index = (iPartDataOut - 4)/2; |
|
504 |
|
505 switch (iBinaryDataList[index].NodeType()) // Fourth and then all even parts = Blobs |
|
506 { |
|
507 case TXmlEngNode::EChunkContainer: // blob is kept in Chunk |
|
508 { |
|
509 TInt offset = iBinaryDataList[index].AsChunkContainer().ChunkOffset(); |
|
510 aDataPart.Set(iBinaryDataList[index].AsChunkContainer().Chunk().Base()+offset,iBinaryDataList[index].Size()); |
|
511 TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,aDataPart); |
|
512 iBinaryDataEnd = ETrue; |
|
513 return iLastPartOut; |
|
514 } |
|
515 |
|
516 case TXmlEngNode::EFileContainer: // blob is kept in File |
|
517 { |
|
518 FileContainerL(index); |
|
519 break; |
|
520 } |
|
521 |
|
522 case TXmlEngNode::EBinaryContainer: // blob is kept as binary data |
|
523 { |
|
524 aDataPart.Set(iBinaryDataList[index].AsBinaryContainer().Contents()); |
|
525 return iLastPartOut; |
|
526 } |
|
527 |
|
528 default: |
|
529 { |
|
530 User::Panic(KMultiPartBlobContainerTypeInvalidPanicText, |
|
531 SenMultiPartUtils::EMultiPartBlobContainerTypeInvalid); } |
|
532 } |
|
533 |
|
534 TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMtomTxnState::GetNextDataPart - aDataPart (binary data)"))); |
|
535 if (iBinaryDataPart) |
|
536 { |
|
537 iObserver->FileProgress(iId, EFalse, EFalse, |
|
538 iBinaryDataList[index].Cid(), iBinaryDataPart*KTenKBytes); |
|
539 } |
|
540 } |
|
541 else if (iPartDataOut == iCountDataParts) |
|
542 { |
|
543 TUint index = (iPartDataOut - 4)/2; |
|
544 XopEndL(); // The last part of MultiPart message = MimeBoundaryEnd |
|
545 if ((iPartDataOut > 2) && (iPartDataOut%2 == 0)) |
|
546 { |
|
547 iObserver->FileProgress(iId, EFalse, EFalse, |
|
548 iBinaryDataList[index].Cid(), iBinaryDataList[index].Size()); |
|
549 } |
|
550 |
|
551 } |
|
552 } // on first call, allocate the current part |
|
553 aDataPart.Set(iCurrentPart); // .. otherwise, just re-use it |
|
554 TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,aDataPart); |
|
555 } |
|
556 return iLastPartOut; |
|
557 } |
|
558 |
|
559 // End of File |