|
1 // Copyright (c) 2002-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 // |
|
15 |
|
16 #include "cmessagecomposerdriver.h" |
|
17 |
|
18 #include "mdriverobserver.h" |
|
19 #include "cbodydatasupplier.h" |
|
20 |
|
21 CMessageComposerDriver* CMessageComposerDriver::NewL(MDriverObserver& aObserver) |
|
22 { |
|
23 CMessageComposerDriver* self = new(ELeave) CMessageComposerDriver(aObserver); |
|
24 CleanupStack::PushL(self); |
|
25 self->ConstructL(); |
|
26 CleanupStack::Pop(self); |
|
27 return self; |
|
28 } |
|
29 |
|
30 CMessageComposerDriver::~CMessageComposerDriver() |
|
31 { |
|
32 iHeaders.Close(); |
|
33 iTrailers.Close(); |
|
34 iMessageComposer.Close(); |
|
35 delete iBodyData; |
|
36 } |
|
37 |
|
38 CMessageComposerDriver::CMessageComposerDriver(MDriverObserver& aObserver) |
|
39 : CActive(CActive::EPriorityStandard), iObserver(aObserver) |
|
40 { |
|
41 CActiveScheduler::Add(this); |
|
42 } |
|
43 |
|
44 void CMessageComposerDriver::ConstructL() |
|
45 { |
|
46 iMessageComposer.OpenL(*this); |
|
47 } |
|
48 |
|
49 void CMessageComposerDriver::SetMessageData(const TDesC8& aMessageData) |
|
50 { |
|
51 iMessageData.Set(aMessageData); |
|
52 } |
|
53 |
|
54 void CMessageComposerDriver::SetStartLine(const TDesC8& aToken1, const TDesC8& aToken2, const TDesC8& aToken3) |
|
55 { |
|
56 iStartLine1.Set(aToken1); |
|
57 iStartLine2.Set(aToken2); |
|
58 iStartLine3.Set(aToken3); |
|
59 } |
|
60 |
|
61 void CMessageComposerDriver::SetHeaderL(const TDesC8& aFieldName, const TDesC8& aFieldValue) |
|
62 { |
|
63 User::LeaveIfError(iHeaders.Append(THeaderField(aFieldName, aFieldValue))); |
|
64 } |
|
65 |
|
66 void CMessageComposerDriver::SetBodyDataL(const TDesC8& aBodyPart) |
|
67 { |
|
68 if( iBodyData == NULL ) |
|
69 iBodyData = CBodyDataSupplier::NewL(*this); |
|
70 |
|
71 iBodyData->AddBodyPartL(aBodyPart); |
|
72 } |
|
73 |
|
74 void CMessageComposerDriver::SetBodySize(TInt aSize) |
|
75 { |
|
76 __ASSERT_DEBUG( iBodyData, User::Invariant() ); |
|
77 |
|
78 iBodyData->SetBodySize(aSize); |
|
79 } |
|
80 |
|
81 void CMessageComposerDriver::SetTrailerL(const TDesC8& aFieldName, const TDesC8& aFieldValue) |
|
82 { |
|
83 User::LeaveIfError(iTrailers.Append(THeaderField(aFieldName, aFieldValue))); |
|
84 } |
|
85 |
|
86 void CMessageComposerDriver::Start(TInt aExpectedError, TBool aTestReset) |
|
87 { |
|
88 iExpectedError = aExpectedError; |
|
89 iDoReset = aTestReset; |
|
90 |
|
91 // Inform the observer that the test has started |
|
92 iObserver.NotifyStart(); |
|
93 |
|
94 // Set the reset state to initial state - PendingStartLine. |
|
95 iResetState = EPendingStartLine; |
|
96 |
|
97 // Self-complete to kick-off the test. |
|
98 CompleteSelf(); |
|
99 } |
|
100 |
|
101 void CMessageComposerDriver::CompleteSelf() |
|
102 { |
|
103 TRequestStatus* pStat = &iStatus; |
|
104 User::RequestComplete(pStat, KErrNone); |
|
105 SetActive(); |
|
106 } |
|
107 |
|
108 void CMessageComposerDriver::DoReset() |
|
109 { |
|
110 // Reset the composer and update the reset state. |
|
111 iMessageComposer.Reset(); |
|
112 iResetState = iState; |
|
113 |
|
114 iObserver.Log(_L("RESET - starting test again!!")); |
|
115 |
|
116 // Reset the data supplier |
|
117 if( iBodyData != NULL ) |
|
118 iBodyData->ResetSupplier(); |
|
119 |
|
120 if( iState == EPendingNextHeader ) |
|
121 iResetIndex = iHeaderIndex; |
|
122 else if( iState == EPendingNextTrailer ) |
|
123 iResetIndex = iTrailerIndex; |
|
124 else if( iState == EPendingHasBody ) |
|
125 iChunkIndex = 0; |
|
126 |
|
127 // Start the test over... |
|
128 CompleteSelf(); |
|
129 } |
|
130 |
|
131 /* |
|
132 * Methods from CActive |
|
133 */ |
|
134 |
|
135 void CMessageComposerDriver::RunL() |
|
136 { |
|
137 // Reset the indexes |
|
138 iHeaderIndex = 0; |
|
139 iTrailerIndex = 0; |
|
140 |
|
141 // Set the reset flags |
|
142 iReset = EFalse; |
|
143 iMessageChunk = 0; |
|
144 iChunkCount = 0; |
|
145 |
|
146 // Reset the expected data.. |
|
147 iExpectedData.Set(iMessageData); |
|
148 |
|
149 // Start the composer... |
|
150 iMessageComposer.MessageInfoAvailable(); |
|
151 |
|
152 // Move to PendingStartLine state... |
|
153 iState = EPendingStartLine; |
|
154 } |
|
155 |
|
156 void CMessageComposerDriver::DoCancel() |
|
157 { |
|
158 // Do nothing... |
|
159 } |
|
160 |
|
161 TInt CMessageComposerDriver::RunError(TInt aError) |
|
162 { |
|
163 // Inform the observer of the error |
|
164 iObserver.NotifyError(aError); |
|
165 |
|
166 return KErrNone; |
|
167 } |
|
168 |
|
169 /* |
|
170 * Methods from MHttpMessageComposerObserver |
|
171 */ |
|
172 |
|
173 void CMessageComposerDriver::StartLineL(TPtrC8& aToken1, TPtrC8& aToken2, TPtrC8& aToken3) |
|
174 { |
|
175 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
176 |
|
177 iObserver.Log(_L("StartLineL received")); |
|
178 |
|
179 // Was StartLineL expected? |
|
180 if( iState != EPendingStartLine || iReset ) |
|
181 { |
|
182 // Not expecting start-line. Test has failed - notify the observer. |
|
183 iObserver.Log(_L("FAIL - not expecting StartLineL request")); |
|
184 iObserver.NotifyError(KErrNotFound); |
|
185 iTestFailed = ETrue; |
|
186 } |
|
187 else |
|
188 { |
|
189 // Should a reset occur here? |
|
190 if( iDoReset && iResetState == iState ) |
|
191 iReset = ETrue; |
|
192 |
|
193 // Set the tokens... |
|
194 aToken1.Set(iStartLine1); |
|
195 aToken2.Set(iStartLine2); |
|
196 aToken3.Set(iStartLine3); |
|
197 |
|
198 // Set the next state... |
|
199 iState = EPendingNextHeader; |
|
200 // We no longer compose line by line. We compose startline & headers (6) at one go. |
|
201 // We cannot reset here |
|
202 iReset = EFalse; |
|
203 if( iReset ) |
|
204 DoReset(); |
|
205 } |
|
206 } |
|
207 |
|
208 TInt CMessageComposerDriver::NextHeaderL(TPtrC8& aHeaderName, TPtrC8& aHeaderValue) |
|
209 { |
|
210 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
211 |
|
212 iObserver.Log(_L("NextHeaderL received")); |
|
213 |
|
214 // Was NextHeaderL expected? |
|
215 TInt error = ( iHeaderIndex < iHeaders.Count() ) ? KErrNone : KErrNotFound; |
|
216 if( iState != EPendingNextHeader || iReset ) |
|
217 { |
|
218 // Not expecting NextHeader. Test has failed - reset the composer and |
|
219 // notify the observer. |
|
220 iObserver.Log(_L("FAIL - not expecting NextHeaderL request")); |
|
221 iObserver.NotifyError(KErrNotFound); |
|
222 iTestFailed = ETrue; |
|
223 } |
|
224 else |
|
225 { |
|
226 // Should a reset occur here? |
|
227 if( iDoReset && (iResetState == iState && iResetIndex == iHeaderIndex) ) |
|
228 iReset = ETrue; |
|
229 |
|
230 // Are there any headers left to give? |
|
231 if( iHeaderIndex < iHeaders.Count() ) |
|
232 { |
|
233 // Give the current header info... |
|
234 THeaderField header = iHeaders[iHeaderIndex]; |
|
235 |
|
236 aHeaderName.Set(header.iName); |
|
237 aHeaderValue.Set(header.iValue); |
|
238 |
|
239 // Loop to next header... |
|
240 ++iHeaderIndex; |
|
241 } |
|
242 else |
|
243 { |
|
244 // No more headers - change state |
|
245 iState = EPendingHasBody; |
|
246 } |
|
247 |
|
248 if( iReset ) |
|
249 DoReset(); |
|
250 } |
|
251 // Return KErrNotFound if this is the last header. |
|
252 return error; |
|
253 } |
|
254 |
|
255 MHTTPDataSupplier* CMessageComposerDriver::HasBodyL() |
|
256 { |
|
257 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
258 |
|
259 iObserver.Log(_L("HasBodyL received")); |
|
260 |
|
261 // Was start-line expected? |
|
262 if( iState != EPendingHasBody ) |
|
263 { |
|
264 // Not expecting HasBodyL. Test has failed - notify the observer. |
|
265 iObserver.Log(_L("FAIL - not expecting HasBodyL request")); |
|
266 iObserver.NotifyError(KErrNotFound); |
|
267 iTestFailed = ETrue; |
|
268 } |
|
269 else |
|
270 { |
|
271 // Should a reset occur here? |
|
272 // if( iDoReset && iResetState == iState ) |
|
273 // iReset = ETrue; |
|
274 |
|
275 // Set the next state... |
|
276 if( iBodyData != NULL && iBodyData->IsChunked() ) |
|
277 { |
|
278 // Have got a chunked body - expect NextTrailersL... |
|
279 iState = EPendingNextTrailer; |
|
280 } |
|
281 else |
|
282 { |
|
283 // Either no body or non-encoded body - expect MessageComplete |
|
284 iState = EPendingMessageComplete; |
|
285 } |
|
286 |
|
287 // if( iReset ) |
|
288 // DoReset(); |
|
289 } |
|
290 return iBodyData; |
|
291 } |
|
292 |
|
293 TInt CMessageComposerDriver::NextTrailerL(TPtrC8& aHeaderName, TPtrC8& aHeaderValue) |
|
294 { |
|
295 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
296 |
|
297 iObserver.Log(_L("NextTrailerL received")); |
|
298 |
|
299 // Was NextTrailerL expected? |
|
300 TInt error = ( iTrailerIndex < iTrailers.Count() ) ? KErrNone : KErrNotFound; |
|
301 if( iState != EPendingNextTrailer || iReset ) |
|
302 { |
|
303 // Not expecting NextHeader. Test has failed - notify the observer. |
|
304 iObserver.Log(_L("FAIL - not expecting NextTrailerL request")); |
|
305 iObserver.NotifyError(KErrNotFound); |
|
306 iTestFailed = ETrue; |
|
307 } |
|
308 else |
|
309 { |
|
310 // Should a reset occur here? |
|
311 if( iDoReset && (iResetState == iState && iResetIndex == iTrailerIndex) ) |
|
312 iReset = ETrue; |
|
313 |
|
314 // Are there any headers left to give? |
|
315 if( iTrailerIndex < iTrailers.Count() ) |
|
316 { |
|
317 // Give the current header info... |
|
318 THeaderField header = iTrailers[iTrailerIndex]; |
|
319 |
|
320 aHeaderName.Set(header.iName); |
|
321 aHeaderValue.Set(header.iValue); |
|
322 |
|
323 // Loop to next header... |
|
324 ++iTrailerIndex; |
|
325 } |
|
326 else |
|
327 { |
|
328 // No more trailers - change state |
|
329 iState = EPendingMessageComplete; |
|
330 } |
|
331 |
|
332 if( iReset ) |
|
333 DoReset(); |
|
334 } |
|
335 // Return KErrNotFound if this is the last header. |
|
336 return error; |
|
337 } |
|
338 |
|
339 void CMessageComposerDriver::MessageComplete() |
|
340 { |
|
341 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
342 |
|
343 // Log the message complete event |
|
344 iObserver.Log(_L("Message Complete received")); |
|
345 |
|
346 // Was this expected? |
|
347 if( iState != EPendingMessageComplete || iReset ) |
|
348 { |
|
349 // Not expecting message complete. Test has failed - notify the observer |
|
350 iObserver.Log(_L("FAIL - not expecting message complete")); |
|
351 iObserver.NotifyError(KErrNotFound); |
|
352 iTestFailed = ETrue; |
|
353 } |
|
354 else |
|
355 { |
|
356 // Has all the data been received? |
|
357 if( iExpectedData.Length() == 0 ) |
|
358 { |
|
359 // Should a reset occur here? |
|
360 if( iDoReset && iResetState == iState ) |
|
361 iReset = ETrue; |
|
362 |
|
363 iState = EDone; |
|
364 |
|
365 if( iReset ) |
|
366 DoReset(); |
|
367 else |
|
368 {// Test done... |
|
369 iObserver.NotifyComplete(); |
|
370 } |
|
371 } |
|
372 else |
|
373 { |
|
374 // Oh dear, not all data has been received - test failed. |
|
375 iObserver.Log(_L("FAIL - all message data not received")); |
|
376 iObserver.NotifyError(KErrNotFound); |
|
377 iTestFailed = ETrue; |
|
378 } |
|
379 } |
|
380 } |
|
381 |
|
382 void CMessageComposerDriver::MessageDataReadyL() |
|
383 { |
|
384 __ASSERT_DEBUG( iTestFailed == EFalse, User::Invariant() ); |
|
385 |
|
386 if( iReset ) |
|
387 { |
|
388 // The composer has been reset - should not be receiving this. |
|
389 // Test has failed - notify the observer. |
|
390 iObserver.Log(_L("FAIL - not expecting MessageDataReady")); |
|
391 iObserver.NotifyError(KErrNotFound); |
|
392 iTestFailed = ETrue; |
|
393 } |
|
394 else |
|
395 { |
|
396 // Get data from the composer |
|
397 TPtrC8 data; |
|
398 iMessageComposer.GetMessageData(data); |
|
399 |
|
400 // Dump the message data... |
|
401 iObserver.Log(_L("Message data received")); |
|
402 iObserver.Dump(data); |
|
403 |
|
404 // Check to see if it matches the expected data. |
|
405 TBool match = EFalse; |
|
406 if( data.Length() <= iExpectedData.Length() ) |
|
407 { |
|
408 // Is the content the same |
|
409 if( data.Compare(iExpectedData.Left(data.Length())) == 0 ) |
|
410 { |
|
411 // Data is the same - update the expected data |
|
412 iExpectedData.Set(iExpectedData.Mid(data.Length())); |
|
413 match = ETrue; |
|
414 } |
|
415 } |
|
416 if( match ) |
|
417 { |
|
418 if( iDoReset && iMessageIndex == iMessageChunk ) |
|
419 { |
|
420 // Reset the composer and update the chunk index |
|
421 iMessageComposer.Reset(); |
|
422 ++iMessageIndex; |
|
423 |
|
424 iObserver.Log(_L("RESET - starting test again!!")); |
|
425 |
|
426 // Reset the data supplier |
|
427 if( iBodyData != NULL ) |
|
428 iBodyData->ResetSupplier(); |
|
429 |
|
430 // Start the test over... |
|
431 CompleteSelf(); |
|
432 } |
|
433 else |
|
434 { |
|
435 // Inc the message chunk count |
|
436 ++iMessageChunk; |
|
437 |
|
438 // Release the message data... |
|
439 iMessageComposer.ReleaseMessageData(); |
|
440 } |
|
441 } |
|
442 else |
|
443 { |
|
444 // The data does not match. Test has failed - notify the observer. |
|
445 iObserver.Log(_L("FAIL - received incorrect data")); |
|
446 iObserver.NotifyError(KErrNotFound); |
|
447 iTestFailed = ETrue; |
|
448 } |
|
449 } |
|
450 } |
|
451 |
|
452 TInt CMessageComposerDriver::HandleComposeError(TInt aError) |
|
453 { |
|
454 // Is an error expected? |
|
455 if( iExpectedError == aError ) |
|
456 { |
|
457 TBuf<64> comment; |
|
458 comment.Format(_L("Received expected error : %d"), aError); |
|
459 iObserver.Log(comment); |
|
460 |
|
461 // Yep - test done... |
|
462 iObserver.NotifyComplete(); |
|
463 } |
|
464 else |
|
465 { |
|
466 // Inform the observer of the error |
|
467 iObserver.NotifyError(aError); |
|
468 } |
|
469 return KErrNone; |
|
470 } |
|
471 |
|
472 void CMessageComposerDriver::Reserved_MHttpMessageComposerObserver() |
|
473 { |
|
474 User::Invariant(); |
|
475 } |
|
476 |
|
477 /* |
|
478 * Methods from MBodyDataSupplierObserver |
|
479 */ |
|
480 |
|
481 void CMessageComposerDriver::NotifyMoreData() |
|
482 { |
|
483 if( iDoReset && iChunkIndex == iChunkCount ) |
|
484 { |
|
485 // Reset the composer and update the chunk index |
|
486 iMessageComposer.Reset(); |
|
487 ++iChunkIndex; |
|
488 |
|
489 iObserver.Log(_L("RESET - starting test again!!")); |
|
490 |
|
491 // Reset the data supplier |
|
492 if( iBodyData != NULL ) |
|
493 iBodyData->ResetSupplier(); |
|
494 |
|
495 // Start the test over... |
|
496 CompleteSelf(); |
|
497 } |
|
498 else |
|
499 { |
|
500 // Inc the chunk count and notify the composer of more data |
|
501 ++iChunkCount; |
|
502 iMessageComposer.MessageInfoAvailable(); |
|
503 } |
|
504 } |