|
1 // Copyright (c) 1998-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 <e32base.h> |
|
17 #include <e32math.h> |
|
18 #include <txtrich.h> |
|
19 #include <bautils.h> |
|
20 #include <miut_err.h> |
|
21 |
|
22 #include "IMUTDLL.H" |
|
23 #include "IMCVSEND.H" |
|
24 |
|
25 #include <miuthdr.h> |
|
26 #include <miutpars.h> |
|
27 |
|
28 #include <imcm.rsg> |
|
29 #include <barsread.h> // TResourceReader |
|
30 |
|
31 #include <cmsvattachment.h> |
|
32 #include <mmsvattachmentmanager.h> |
|
33 #include <cmsvplainbodytext.h> |
|
34 |
|
35 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
36 #include "miut_errconsts.h" |
|
37 #include "timrfc822datefield.h" |
|
38 #include "cimconvertheader.h" |
|
39 #endif |
|
40 |
|
41 |
|
42 #define SENDLOG(x) \ |
|
43 if (iLogFileExists) \ |
|
44 iLogFile.Write(x); |
|
45 |
|
46 |
|
47 #define SENDLOG2(x,y) \ |
|
48 if (iLogFileExists) \ |
|
49 { \ |
|
50 iLogFile.Write(x); \ |
|
51 iLogFile.Write(y); \ |
|
52 } |
|
53 |
|
54 _LIT(KLogFilePath, "c:\\logs\\mailtext\\"); |
|
55 _LIT(KLogFileName, "out.txt"); |
|
56 _LIT8(KNewLogHeader, "\r\n------ New Send Session ------\r\n"); |
|
57 _LIT8(KSent, "Sent : "); |
|
58 _LIT8(KSetBody, "Body length = %d\r\n"); |
|
59 |
|
60 const TInt KArrayGranularity = 3; |
|
61 const TInt KChunkSize = 1024; |
|
62 |
|
63 |
|
64 //********************************************************************************* |
|
65 // Class CImSendMessage Functions |
|
66 //********************************************************************************* |
|
67 |
|
68 //--------------------------------------------------------------------------------- |
|
69 EXPORT_C CImSendMessage* CImSendMessage::NewLC(CMsvServerEntry& aServerEntry) |
|
70 //--------------------------------------------------------------------------------- |
|
71 { |
|
72 CImSendMessage* self = new (ELeave) CImSendMessage(aServerEntry); |
|
73 CleanupStack::PushL( self ); |
|
74 self->ConstructL(); |
|
75 return self; |
|
76 } |
|
77 |
|
78 //--------------------------------------------------------------------------------- |
|
79 EXPORT_C CImSendMessage* CImSendMessage::NewL(CMsvServerEntry& aServerEntry) |
|
80 //--------------------------------------------------------------------------------- |
|
81 { |
|
82 CImSendMessage* self = CImSendMessage::NewLC(aServerEntry); |
|
83 CleanupStack::Pop( ); |
|
84 return self; |
|
85 } |
|
86 |
|
87 //--------------------------------------------------------------------------------- |
|
88 CImSendMessage::CImSendMessage(CMsvServerEntry& aServerEntry) : iServerEntry(aServerEntry) |
|
89 //--------------------------------------------------------------------------------- |
|
90 { |
|
91 } |
|
92 |
|
93 |
|
94 //--------------------------------------------------------------------------------- |
|
95 void CImSendMessage::ConstructL() |
|
96 //--------------------------------------------------------------------------------- |
|
97 { |
|
98 // logfile stuff |
|
99 TInt ret=0; |
|
100 TParse logFileName; |
|
101 logFileName.Set(KLogFileName, &KLogFilePath, NULL); |
|
102 TFileName filename(logFileName.FullName()); |
|
103 ret=iLogFile.Replace(iServerEntry.FileSession(), filename, EFileShareExclusive|EFileWrite ); |
|
104 iLogFileExists = (ret==KErrNone); |
|
105 SENDLOG( KNewLogHeader ) |
|
106 |
|
107 } |
|
108 |
|
109 //--------------------------------------------------------------------------------- |
|
110 EXPORT_C void CImSendMessage::InitialiseL(TMsvId aMessageId, TImSendMethod aSendMethod, |
|
111 const TTime aTimeDate, const TDesC& aDomainName, |
|
112 TUint aCharset, const TImSMTPSendCopyToSelf aCopyToSelf) |
|
113 //--------------------------------------------------------------------------------- |
|
114 { |
|
115 TImEmailTransformingInfo info; |
|
116 info.SetToDefault(aSendMethod); // Sets defaults |
|
117 info.SetHeaderAndBodyCharset(aCharset) ; // Sets charset for header/body |
|
118 |
|
119 InitialiseL(aMessageId, aTimeDate, aDomainName, info, aCopyToSelf); |
|
120 } |
|
121 |
|
122 |
|
123 //--------------------------------------------------------------------------------- |
|
124 EXPORT_C void CImSendMessage::InitialiseL(TMsvId aMessageId, const TTime aTimeDate, |
|
125 const TDesC& aDomainName, const TImEmailTransformingInfo& aInfo, |
|
126 const TImSMTPSendCopyToSelf aCopyToSelf) |
|
127 //--------------------------------------------------------------------------------- |
|
128 { |
|
129 User::LeaveIfError(iServerEntry.SetEntry(aMessageId)); |
|
130 __ASSERT_ALWAYS(iServerEntry.Entry().iType==KUidMsvMessageEntry, gPanic(KPanicEntryIsNotMessage)); |
|
131 |
|
132 SetSendMethodL(aInfo.SendMethod()); |
|
133 iSendEmail->InitialiseL(aTimeDate, aDomainName, aCopyToSelf, aInfo); |
|
134 Reset(); |
|
135 |
|
136 } |
|
137 |
|
138 //--------------------------------------------------------------------------------- |
|
139 EXPORT_C void CImSendMessage::Reset() |
|
140 //--------------------------------------------------------------------------------- |
|
141 { |
|
142 iSendEmail->Reset(); |
|
143 } |
|
144 |
|
145 |
|
146 // Creates the required email sending object, either Mime or non MIME. |
|
147 //--------------------------------------------------------------------------------- |
|
148 void CImSendMessage::SetSendMethodL(TImSendMethod aSendMethod) |
|
149 //--------------------------------------------------------------------------------- |
|
150 { |
|
151 switch (aSendMethod) |
|
152 { |
|
153 case ESendAsSimpleEmail: |
|
154 iSendEmail = CImSendPlainEmail::NewL(iServerEntry); |
|
155 break; |
|
156 case ESendAsMimeEmail: |
|
157 iSendEmail = CImSendMimeEmail::NewL(iServerEntry); |
|
158 break; |
|
159 default: |
|
160 gPanic(KPanicUnknownSendingMethod); |
|
161 } |
|
162 } |
|
163 |
|
164 |
|
165 //--------------------------------------------------------------------------------- |
|
166 EXPORT_C TInt CImSendMessage::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
167 //--------------------------------------------------------------------------------- |
|
168 { |
|
169 // Format the next line of output into rOutputLine. |
|
170 // If the output line contains more characters than the size of the source data cosumed |
|
171 // in preparing it, then the difference is passed back in aPaddingCount. |
|
172 |
|
173 TInt localPaddingCount=0; |
|
174 |
|
175 rOutputLine.Zero(); |
|
176 TInt ret = iSendEmail->NextLineL( rOutputLine, localPaddingCount ); |
|
177 |
|
178 AddCRLFAtEndOfLine(rOutputLine, localPaddingCount); |
|
179 |
|
180 SENDLOG(KSent); |
|
181 SENDLOG(rOutputLine); |
|
182 |
|
183 rPaddingCount = localPaddingCount; |
|
184 return ret; |
|
185 } |
|
186 |
|
187 |
|
188 //--------------------------------------------------------------------------------- |
|
189 EXPORT_C CImSendMessage::~CImSendMessage( ) |
|
190 //--------------------------------------------------------------------------------- |
|
191 { |
|
192 if (iLogFileExists) |
|
193 iLogFile.Close(); |
|
194 delete iSendEmail; |
|
195 } |
|
196 |
|
197 //--------------------------------------------------------------------------------- |
|
198 EXPORT_C TInt CImSendMessage::HeaderSize() |
|
199 //--------------------------------------------------------------------------------- |
|
200 { |
|
201 TInt size = iSendEmail->HeaderSize(); |
|
202 iSendEmail->Reset(); |
|
203 return size; |
|
204 } |
|
205 |
|
206 |
|
207 //--------------------------------------------------------------------------------- |
|
208 EXPORT_C TInt CImSendMessage::BodySizeL() |
|
209 //--------------------------------------------------------------------------------- |
|
210 { |
|
211 return iSendEmail->BodySizeL(); |
|
212 } |
|
213 |
|
214 |
|
215 //********************************************************************************* |
|
216 // Class CImSendEmail Functions |
|
217 //********************************************************************************* |
|
218 |
|
219 //--------------------------------------------------------------------------------- |
|
220 CImSendEmail::CImSendEmail(CMsvServerEntry& aServerEntry) : |
|
221 iServerEntry(aServerEntry), iDomainName(TPtrC()) |
|
222 //--------------------------------------------------------------------------------- |
|
223 { |
|
224 } |
|
225 |
|
226 |
|
227 //--------------------------------------------------------------------------------- |
|
228 CImSendEmail::~CImSendEmail( ) |
|
229 //--------------------------------------------------------------------------------- |
|
230 { |
|
231 delete iCharConv; |
|
232 delete iCharacterConverter; |
|
233 delete iHeaderConverter; |
|
234 |
|
235 delete iSendFile; |
|
236 delete iEmailTraverser; |
|
237 |
|
238 delete iRfc822Header; |
|
239 delete iSendRichText; |
|
240 } |
|
241 |
|
242 //--------------------------------------------------------------------------------- |
|
243 void CImSendEmail::ConstructL() |
|
244 //--------------------------------------------------------------------------------- |
|
245 { |
|
246 iCharacterConverter = CCnvCharacterSetConverter::NewL(); |
|
247 iCharConv = CImConvertCharconv::NewL(*iCharacterConverter, iServerEntry.FileSession()); |
|
248 |
|
249 iSendFile = CImSendFile::NewL(iServerEntry.FileSession(), *iCharConv); |
|
250 |
|
251 iEmailTraverser = CImEmailTraverser::NewL(iServerEntry); |
|
252 |
|
253 iHeaderConverter = CImConvertHeader::NewL(*iCharConv); |
|
254 iRfc822Header = CImSendRfc822Header::NewL(iServerEntry.FileSession(), *iHeaderConverter); |
|
255 iSendRichText = CImSendRichText::NewL(*iCharConv); |
|
256 } |
|
257 |
|
258 //--------------------------------------------------------------------------------- |
|
259 void CImSendEmail::InitialiseL( const TTime aTimeDate, const TDesC& aDomainName, |
|
260 const TImSMTPSendCopyToSelf aCopyToSelf, |
|
261 const TImEmailTransformingInfo& aTransformingInfo) |
|
262 //--------------------------------------------------------------------------------- |
|
263 { |
|
264 // get a list of all attachments |
|
265 iDomainName.Set(aDomainName); |
|
266 iDefaultTransformingInfo=aTransformingInfo; |
|
267 iTimeDate=aTimeDate; |
|
268 |
|
269 iRfc822Header->InitialiseL(iTimeDate, iDomainName, iServerEntry, |
|
270 iServerEntry.Entry().Priority(), aCopyToSelf, iDefaultTransformingInfo); |
|
271 |
|
272 iEmailTraverser->InitialiseL( iServerEntry.Entry().Id() ); |
|
273 |
|
274 } |
|
275 |
|
276 |
|
277 //--------------------------------------------------------------------------------- |
|
278 TBool CImSendEmail::InitBodyObjectL(TMsvEntry& rEntry) |
|
279 //--------------------------------------------------------------------------------- |
|
280 { |
|
281 return ( rEntry.iType==KUidMsvEmailTextEntry |
|
282 && iSendRichText->InitialiseL( iServerEntry, |
|
283 Encoder(EEncodingTypeNone), EEncodingTypeNone, |
|
284 iRfc822Header->TransformingInfo().BodyTextCharset()) ); |
|
285 } |
|
286 |
|
287 |
|
288 // calculates & returns the total size of the header info, including the RFC822 tags, |
|
289 // comma & space separation, the CRLFs and the blank line after the header itself |
|
290 |
|
291 //--------------------------------------------------------------------------------- |
|
292 TInt CImSendEmail::HeaderSize() |
|
293 //--------------------------------------------------------------------------------- |
|
294 { |
|
295 return iRfc822Header->Size(); |
|
296 } |
|
297 |
|
298 // Sum of body parts and file attachments. |
|
299 //--------------------------------------------------------------------------------- |
|
300 TInt CImSendEmail::BodySizeL() |
|
301 //--------------------------------------------------------------------------------- |
|
302 { |
|
303 TMsvEntry entry; |
|
304 TInt size=0; |
|
305 TBool isEndOfEmail=EFalse; |
|
306 |
|
307 entry = iEmailTraverser->ThisEntry(); |
|
308 do { |
|
309 if (InitBodyObjectL(entry)) |
|
310 size += iSendRichText->Size(); |
|
311 else if (InitAttachmentObjectL(entry)) |
|
312 size += iSendFile->Size(); |
|
313 |
|
314 if ( iEmailTraverser->DownLevelL() ) |
|
315 entry = iEmailTraverser->ThisEntry(); |
|
316 else |
|
317 while ( !iEmailTraverser->NextEntryL(entry) ) |
|
318 { |
|
319 if ( !iEmailTraverser->UpLevelL() || iEmailTraverser->IsBaseLevel() ) |
|
320 { |
|
321 // end of traversal, reached message entry. |
|
322 isEndOfEmail=ETrue; |
|
323 break; |
|
324 } |
|
325 } |
|
326 |
|
327 } while (!isEndOfEmail); |
|
328 |
|
329 return size; |
|
330 } |
|
331 |
|
332 //--------------------------------------------------------------------------------- |
|
333 void CImSendEmail::Reset() |
|
334 //--------------------------------------------------------------------------------- |
|
335 { |
|
336 if(iRfc822Header) |
|
337 { |
|
338 iRfc822Header->Reset(); |
|
339 } |
|
340 iState = 0; |
|
341 } |
|
342 |
|
343 //--------------------------------------------------------------------------------- |
|
344 TImFileCodec& CImSendEmail::Encoder(TImEncodingType aType) |
|
345 //--------------------------------------------------------------------------------- |
|
346 { |
|
347 switch (aType) |
|
348 { |
|
349 case EEncodingTypeUU: |
|
350 iUUEncoder.Initialise(); |
|
351 return iUUEncoder; |
|
352 case EEncodingTypeBASE64: |
|
353 iB64Encoder.Initialise(); |
|
354 return iB64Encoder; |
|
355 case EEncodingTypeQP: |
|
356 return iQPEncoder; |
|
357 case EEncodingTypeNone: |
|
358 return iNULLEncoder; |
|
359 default: |
|
360 __ASSERT_DEBUG( ETrue, gPanic(KPanicInvalidEncodingType) ); |
|
361 return iNULLEncoder; |
|
362 } |
|
363 } |
|
364 |
|
365 |
|
366 //--------------------------------------------------------------------------------- |
|
367 TBool CImSendEmail::InitAttachmentObjectL(TMsvEntry& rEntry) |
|
368 //--------------------------------------------------------------------------------- |
|
369 { |
|
370 if ( !(rEntry.iType==KUidMsvAttachmentEntry || rEntry.iType==KUidMsvEmailHtmlEntry) ) |
|
371 return EFalse; |
|
372 |
|
373 iSendFile->InitialiseL(iServerEntry, Encoder(iRfc822Header->TransformingInfo().AttachmentEncoding())); |
|
374 return ETrue; |
|
375 } |
|
376 |
|
377 |
|
378 |
|
379 //********************************************************************************* |
|
380 // Class CImEmailTraverser Functions |
|
381 //********************************************************************************* |
|
382 |
|
383 |
|
384 //--------------------------------------------------------------------------------- |
|
385 CImEmailTraverser* CImEmailTraverser::NewL( CMsvServerEntry& aServerEntry) |
|
386 //--------------------------------------------------------------------------------- |
|
387 { |
|
388 CImEmailTraverser* self = new (ELeave) CImEmailTraverser( aServerEntry ); |
|
389 CleanupStack::PushL( self ); |
|
390 self->ConstructL(); |
|
391 CleanupStack::Pop( ); |
|
392 return self; |
|
393 } |
|
394 |
|
395 //--------------------------------------------------------------------------------- |
|
396 CImEmailTraverser::CImEmailTraverser( CMsvServerEntry& aServerEntry ) : |
|
397 iServerEntry(aServerEntry), iCurrentEntryList(KArrayGranularity) |
|
398 //--------------------------------------------------------------------------------- |
|
399 { |
|
400 iBaseId = iServerEntry.Entry().Id(); |
|
401 } |
|
402 |
|
403 //--------------------------------------------------------------------------------- |
|
404 void CImEmailTraverser::ConstructL() |
|
405 //--------------------------------------------------------------------------------- |
|
406 { |
|
407 iSelectionList = new (ELeave) CArrayFixFlat<CMsvEntrySelection*>(KArrayGranularity); |
|
408 } |
|
409 |
|
410 //--------------------------------------------------------------------------------- |
|
411 CImEmailTraverser::~CImEmailTraverser() |
|
412 //--------------------------------------------------------------------------------- |
|
413 { |
|
414 Reset(); |
|
415 delete iSelectionList; |
|
416 } |
|
417 |
|
418 |
|
419 //--------------------------------------------------------------------------------- |
|
420 void CImEmailTraverser::Reset() |
|
421 //--------------------------------------------------------------------------------- |
|
422 { |
|
423 while (DeleteCurrentList()) |
|
424 ; |
|
425 } |
|
426 |
|
427 //--------------------------------------------------------------------------------- |
|
428 void CImEmailTraverser::InitialiseL( TMsvId aId) |
|
429 //--------------------------------------------------------------------------------- |
|
430 { |
|
431 iBaseId = aId; |
|
432 User::LeaveIfError(iServerEntry.SetEntry(iBaseId)); |
|
433 Reset(); |
|
434 } |
|
435 |
|
436 |
|
437 //--------------------------------------------------------------------------------- |
|
438 TBool CImEmailTraverser::DownLevelL() |
|
439 //--------------------------------------------------------------------------------- |
|
440 { |
|
441 TMsvSelectionOrdering ordering(KMsvNoGrouping,EMsvSortById,ETrue); |
|
442 iServerEntry.SetSort(ordering); |
|
443 CMsvEntrySelection* children = new(ELeave) CMsvEntrySelection; |
|
444 CleanupStack::PushL(children); |
|
445 User::LeaveIfError(iServerEntry.GetChildren(*children)); |
|
446 |
|
447 if (children->Count()) |
|
448 { |
|
449 AddList(*children); |
|
450 CleanupStack::Pop(children); |
|
451 User::LeaveIfError(iServerEntry.SetEntry( CurrentList()[0])); |
|
452 return ETrue; |
|
453 } |
|
454 |
|
455 CleanupStack::PopAndDestroy(children); |
|
456 return EFalse; |
|
457 } |
|
458 |
|
459 //--------------------------------------------------------------------------------- |
|
460 TBool CImEmailTraverser::UpLevelL() |
|
461 //--------------------------------------------------------------------------------- |
|
462 { |
|
463 if (!DeleteCurrentList()) |
|
464 return EFalse; |
|
465 |
|
466 if (!LevelExists()) |
|
467 User::LeaveIfError( iServerEntry.SetEntry(iBaseId) ); |
|
468 else |
|
469 User::LeaveIfError( iServerEntry.SetEntry( CurrentList()[CurrentEntry()]) ); |
|
470 return ETrue; |
|
471 } |
|
472 |
|
473 //--------------------------------------------------------------------------------- |
|
474 TBool CImEmailTraverser::NextEntryL(TMsvEntry& rEntry) |
|
475 //--------------------------------------------------------------------------------- |
|
476 { |
|
477 if (IsBaseLevel()) |
|
478 return EFalse; |
|
479 |
|
480 iCurrentEntryList[0] += 1; |
|
481 if ( CurrentEntry()>=CurrentList().Count() ) |
|
482 return EFalse; // last entry on this level. |
|
483 |
|
484 if (!LevelExists()) |
|
485 User::LeaveIfError( iServerEntry.SetEntry(iBaseId) ); |
|
486 else |
|
487 User::LeaveIfError( iServerEntry.SetEntry( CurrentList()[CurrentEntry()]) ); |
|
488 |
|
489 rEntry = ThisEntry(); |
|
490 return ETrue; |
|
491 } |
|
492 |
|
493 |
|
494 //********************************************************************************* |
|
495 // Class CImSendPlainEmail Functions |
|
496 //********************************************************************************* |
|
497 |
|
498 //--------------------------------------------------------------------------------- |
|
499 CImSendPlainEmail* CImSendPlainEmail::NewLC(CMsvServerEntry& aServerEntry) |
|
500 //--------------------------------------------------------------------------------- |
|
501 { |
|
502 CImSendPlainEmail* self = new (ELeave) CImSendPlainEmail(aServerEntry); |
|
503 CleanupStack::PushL( self ); |
|
504 self->ConstructL(); |
|
505 return self; |
|
506 } |
|
507 |
|
508 //--------------------------------------------------------------------------------- |
|
509 CImSendPlainEmail* CImSendPlainEmail::NewL(CMsvServerEntry& aServerEntry) |
|
510 //--------------------------------------------------------------------------------- |
|
511 { |
|
512 CImSendPlainEmail* self = CImSendPlainEmail::NewLC(aServerEntry); |
|
513 CleanupStack::Pop( ); |
|
514 return self; |
|
515 } |
|
516 |
|
517 //--------------------------------------------------------------------------------- |
|
518 CImSendPlainEmail::CImSendPlainEmail(CMsvServerEntry& aServerEntry) : CImSendEmail(aServerEntry) |
|
519 //--------------------------------------------------------------------------------- |
|
520 { |
|
521 } |
|
522 |
|
523 // Sending header followed by body and attachment parts, in the order in which they are |
|
524 // arranged in the TMsventry structure. |
|
525 //--------------------------------------------------------------------------------- |
|
526 TInt CImSendPlainEmail::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
527 //--------------------------------------------------------------------------------- |
|
528 { |
|
529 __ASSERT_DEBUG( iRfc822Header!=NULL, gPanic(KPanicNoRfc822Header) ); |
|
530 __ASSERT_DEBUG( iSendRichText!=NULL, gPanic(KPanicNoRichText) ); |
|
531 |
|
532 TInt advance = 0; |
|
533 TInt length = 0; |
|
534 TInt localPaddingCount=0; |
|
535 |
|
536 rOutputLine.Zero(); |
|
537 do |
|
538 { |
|
539 switch (iState) |
|
540 { |
|
541 case ERfc822Header: |
|
542 advance = iRfc822Header->NextLineL(rOutputLine, rPaddingCount); |
|
543 if (advance) |
|
544 AppendCRLF(rOutputLine, localPaddingCount); |
|
545 break; |
|
546 case EBody: |
|
547 advance = iSendRichText->NextLineL(rOutputLine, rPaddingCount); |
|
548 break; |
|
549 case EAttachmentFile: |
|
550 advance = iSendFile->NextLineL(rOutputLine, rPaddingCount); |
|
551 break; |
|
552 } |
|
553 |
|
554 length = rOutputLine.Length(); |
|
555 if ( !length || advance ) |
|
556 { |
|
557 if ( iState==EBody ) |
|
558 AppendCRLF(rOutputLine, localPaddingCount); |
|
559 while (!ChangeStateL()) |
|
560 ; |
|
561 } |
|
562 |
|
563 } while ( !length && iState != KImCvFinished); |
|
564 |
|
565 rPaddingCount = localPaddingCount; |
|
566 return (iState==KImCvFinished ? KImCvFinished : KErrNone); |
|
567 } |
|
568 |
|
569 |
|
570 //--------------------------------------------------------------------------------- |
|
571 TBool CImSendPlainEmail::ChangeStateL() |
|
572 //--------------------------------------------------------------------------------- |
|
573 { |
|
574 TMsvEmailEntry entry = iEmailTraverser->ThisEntry(); |
|
575 |
|
576 if ( iEmailTraverser->DownLevelL() ) |
|
577 entry = iEmailTraverser->ThisEntry(); |
|
578 else |
|
579 while ( !iEmailTraverser->NextEntryL(entry) ) |
|
580 { |
|
581 if ( !iEmailTraverser->UpLevelL() || iEmailTraverser->IsBaseLevel() ) |
|
582 { |
|
583 iState=KImCvFinished; |
|
584 return ETrue; |
|
585 } |
|
586 } |
|
587 |
|
588 // Is this entry an attachment entry? |
|
589 if (InitBodyObjectL(entry)) |
|
590 iState=EBody; |
|
591 else if (InitAttachmentObjectL(entry)) |
|
592 iState=EAttachmentFile; |
|
593 else |
|
594 return EFalse; |
|
595 |
|
596 return ETrue; |
|
597 } |
|
598 |
|
599 |
|
600 //********************************************************************************* |
|
601 // Class CImSendMimeEmail Functions |
|
602 //********************************************************************************* |
|
603 |
|
604 //--------------------------------------------------------------------------------- |
|
605 CImSendMimeEmail* CImSendMimeEmail::NewLC(CMsvServerEntry& aServerEntry ) |
|
606 //--------------------------------------------------------------------------------- |
|
607 { |
|
608 CImSendMimeEmail* self = new (ELeave) CImSendMimeEmail(aServerEntry); |
|
609 CleanupStack::PushL( self ); |
|
610 self->ConstructL(); |
|
611 return self; |
|
612 } |
|
613 |
|
614 //--------------------------------------------------------------------------------- |
|
615 CImSendMimeEmail* CImSendMimeEmail::NewL(CMsvServerEntry& aServerEntry ) |
|
616 //--------------------------------------------------------------------------------- |
|
617 { |
|
618 CImSendMimeEmail* self = CImSendMimeEmail::NewLC(aServerEntry); |
|
619 CleanupStack::Pop( ); |
|
620 return self; |
|
621 } |
|
622 |
|
623 //--------------------------------------------------------------------------------- |
|
624 CImSendMimeEmail::CImSendMimeEmail(CMsvServerEntry& aServerEntry ) : CImSendEmail(aServerEntry) |
|
625 //--------------------------------------------------------------------------------- |
|
626 { |
|
627 } |
|
628 |
|
629 //--------------------------------------------------------------------------------- |
|
630 CImSendMimeEmail::~CImSendMimeEmail() |
|
631 //--------------------------------------------------------------------------------- |
|
632 { |
|
633 Reset(); |
|
634 delete iSendMimeHeader; |
|
635 delete iBoundaryArray; |
|
636 delete iMimeHeader; |
|
637 } |
|
638 |
|
639 //--------------------------------------------------------------------------------- |
|
640 void CImSendMimeEmail::ConstructL() |
|
641 //--------------------------------------------------------------------------------- |
|
642 { |
|
643 TTime theTime; |
|
644 theTime.UniversalTime(); // Gets the current universal time to use as a random number seed |
|
645 iRandSeed = theTime.Int64(); |
|
646 |
|
647 iBoundaryArray = new (ELeave) CDesC8ArrayFlat(KArrayGranularity); |
|
648 CImSendEmail::ConstructL(); |
|
649 } |
|
650 |
|
651 //--------------------------------------------------------------------------------- |
|
652 void CImSendMimeEmail::Reset() |
|
653 //--------------------------------------------------------------------------------- |
|
654 { |
|
655 iTextDisplayed=EFalse; |
|
656 iBoundaryArray->Reset(); |
|
657 CImSendEmail::Reset(); |
|
658 } |
|
659 |
|
660 |
|
661 // Sending a MIME message consisting of a header, main MIME header followed by one or more |
|
662 // MIME parts. If more than one, the parts are seperated by a boundary string. |
|
663 |
|
664 //--------------------------------------------------------------------------------- |
|
665 TInt CImSendMimeEmail::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
666 //--------------------------------------------------------------------------------- |
|
667 { |
|
668 __ASSERT_DEBUG( iRfc822Header!=NULL, gPanic(KPanicNoRfc822Header) ); |
|
669 __ASSERT_DEBUG( iSendRichText!=NULL, gPanic(KPanicNoRichText) ); |
|
670 |
|
671 TInt advance = 0; |
|
672 TInt length = 0; |
|
673 TBool addBlankLine=EFalse; |
|
674 |
|
675 rOutputLine.Zero(); |
|
676 do |
|
677 { |
|
678 addBlankLine=EFalse; |
|
679 switch (iState) |
|
680 { |
|
681 case ERfc822Header: |
|
682 advance = iRfc822Header->NextLineL( rOutputLine, rPaddingCount ); |
|
683 break; |
|
684 case EMimeMainHeader: |
|
685 advance = iSendMimeHeader->NextLine( rOutputLine, rPaddingCount ); |
|
686 break; |
|
687 case EMimeText: |
|
688 if ( iBoundaryArray->Count() && !iTextDisplayed ) |
|
689 { |
|
690 rOutputLine.Append(KImcvMimeText); |
|
691 rPaddingCount=rOutputLine.Length(); |
|
692 AppendCRLF(rOutputLine, rPaddingCount); |
|
693 addBlankLine=ETrue; |
|
694 iTextDisplayed=ETrue; |
|
695 } |
|
696 advance=1; |
|
697 break; |
|
698 case EBoundary: |
|
699 if ( iBoundaryArray->Count() ) |
|
700 { |
|
701 SendBoundaryLine( rOutputLine, rPaddingCount ); |
|
702 AppendCRLF(rOutputLine, rPaddingCount); |
|
703 } |
|
704 advance = 1; |
|
705 break; |
|
706 case EMimePartHeader: |
|
707 advance = iSendMimeHeader->NextLine( rOutputLine, rPaddingCount ); |
|
708 break; |
|
709 case EBody: |
|
710 advance = iSendRichText->NextLineL(rOutputLine, rPaddingCount); |
|
711 break; |
|
712 case EAttachmentFile: |
|
713 advance = iSendFile->NextLineL(rOutputLine, rPaddingCount); |
|
714 break; |
|
715 case EEndBoundary: |
|
716 if ( iBoundaryArray->Count() ) |
|
717 { |
|
718 SendBoundaryLine( rOutputLine, rPaddingCount ); |
|
719 rOutputLine.Append(KImcvMimeBoundaryStartEnd); |
|
720 DeleteBoundary(); |
|
721 rPaddingCount=rOutputLine.Length(); |
|
722 } |
|
723 advance = 1; |
|
724 break; |
|
725 case ELineAfterEndBoundary: |
|
726 AppendCRLF(rOutputLine, rPaddingCount); |
|
727 advance = 1; |
|
728 break; |
|
729 } |
|
730 |
|
731 length = rOutputLine.Length(); |
|
732 |
|
733 if ( !length || advance ) |
|
734 ChangeStateL(); |
|
735 |
|
736 if (addBlankLine) |
|
737 AppendCRLF(rOutputLine, rPaddingCount); |
|
738 |
|
739 } while ( !length && iState != KImCvFinished); |
|
740 |
|
741 return (iState==KImCvFinished ? KImCvFinished : KErrNone); |
|
742 } |
|
743 |
|
744 |
|
745 //--------------------------------------------------------------------------------- |
|
746 TBool CImSendMimeEmail::ChangeStateL() |
|
747 //--------------------------------------------------------------------------------- |
|
748 { |
|
749 TInt ret=ETrue; |
|
750 TMsvEmailEntry entry = iEmailTraverser->ThisEntry(); |
|
751 TImEmailFolderType folderType; |
|
752 |
|
753 switch (iState) |
|
754 { |
|
755 case ERfc822Header: |
|
756 InitSendMimeHeaderL(entry, EMainMimeHeader); |
|
757 iState=EMimeMainHeader; |
|
758 break; |
|
759 case EMimeMainHeader: |
|
760 iState=EMimeText; |
|
761 break; |
|
762 case EMimeText: |
|
763 if ( !CheckForMultipartEmailL(entry, folderType) ) |
|
764 { |
|
765 // NOT a multipart email. |
|
766 // Get next entry and see what else it could be.. |
|
767 GetNextEntryL(entry); |
|
768 |
|
769 if (iState!=EBoundary) |
|
770 break; // Simple MIME message, only one part. |
|
771 |
|
772 if ( InitBodyObjectL(entry) ) |
|
773 iState=EBody; // Rich text |
|
774 else if ( iEmbeddedEmail ) |
|
775 // An embeddef RFC822 message, change state to RGC822 header |
|
776 InitEmbeddedEmailL(); |
|
777 else if ( InitAttachmentObjectL(entry) ) |
|
778 iState=EAttachmentFile; // Attachment part |
|
779 else |
|
780 GetNextEntryL(entry); |
|
781 } |
|
782 else |
|
783 { |
|
784 // A Multipart message, get next entry to see what first part is. |
|
785 GetNextEntryL(entry); |
|
786 |
|
787 // An multipart inside a multipart. |
|
788 if ( iState==EBoundary && entry.iType==KUidMsvFolderEntry ) |
|
789 GetNextEntryL(entry); |
|
790 } |
|
791 break; |
|
792 case EBoundary: |
|
793 iEmbeddedEmail = CheckForEmbeddedEmailL(entry); |
|
794 InitSendMimeHeaderL(entry, EPartMimeHeader); |
|
795 iState=EMimePartHeader; |
|
796 break; |
|
797 case EMimePartHeader: |
|
798 if ( entry.iType==KUidMsvFolderEntry ) |
|
799 GetNextEntryL(entry); |
|
800 else if ( InitBodyObjectL(entry) ) |
|
801 iState=EBody; |
|
802 else if ( iEmbeddedEmail ) |
|
803 InitEmbeddedEmailL(); |
|
804 else if ( InitAttachmentObjectL(entry) ) |
|
805 iState=EAttachmentFile; |
|
806 else |
|
807 GetNextEntryL(entry); |
|
808 break; |
|
809 case EBody: |
|
810 case EAttachmentFile: |
|
811 GetNextEntryL(entry); |
|
812 break; |
|
813 case EEndBoundary: |
|
814 iState=ELineAfterEndBoundary; |
|
815 break; |
|
816 case ELineAfterEndBoundary: |
|
817 GetNextEntryL(entry); |
|
818 break; |
|
819 } // end Switch |
|
820 |
|
821 return ret; |
|
822 } |
|
823 |
|
824 |
|
825 // If mimeheader in store, crates relevant mimeHeader object. |
|
826 //--------------------------------------------------------------------------------- |
|
827 TBool CImSendMimeEmail::CreateMimeHeaderL() |
|
828 //--------------------------------------------------------------------------------- |
|
829 { |
|
830 TBool restored=EFalse; |
|
831 delete iMimeHeader; |
|
832 iMimeHeader=NULL; |
|
833 iMimeHeader = CImMimeHeader::NewL(); |
|
834 |
|
835 if (iServerEntry.HasStoreL()) |
|
836 { |
|
837 CMsvStore* entryStore = iServerEntry.ReadStoreL(); |
|
838 CleanupStack::PushL(entryStore); |
|
839 if( entryStore->IsPresentL(KUidMsgFileMimeHeader) ) |
|
840 { |
|
841 iMimeHeader->RestoreL(*entryStore); |
|
842 restored=ETrue; |
|
843 } |
|
844 else |
|
845 /* The MIME header store does not exist, but MIME header info will be |
|
846 * sent with this email, so the Sent message should reflect this. |
|
847 * So we create a KUidMsgFileMimeHeader in the store */ |
|
848 { |
|
849 // open store for edit |
|
850 CleanupStack::PopAndDestroy(entryStore); |
|
851 entryStore = NULL; |
|
852 entryStore = iServerEntry.EditStoreL(); |
|
853 CleanupStack::PushL(entryStore); |
|
854 |
|
855 // store the MIMEheader |
|
856 iMimeHeader->StoreL(*entryStore); |
|
857 entryStore->CommitL(); |
|
858 } |
|
859 |
|
860 CleanupStack::PopAndDestroy(entryStore); |
|
861 } |
|
862 return restored; |
|
863 } |
|
864 |
|
865 //--------------------------------------------------------------------------------- |
|
866 void CImSendMimeEmail::InitMimeHeaderL( TMsvEntry& aEntry, TPtrC8& rBoundary, TPtrC& rFilename) |
|
867 //--------------------------------------------------------------------------------- |
|
868 { |
|
869 TBool multipart=EFalse; |
|
870 |
|
871 TImEmailFolderType folderType; |
|
872 if (!iEmbeddedEmail && CheckForMultipartEmailL(aEntry, folderType)) |
|
873 { |
|
874 //iMimeHeader->Reset(); |
|
875 iMimeHeader->SetContentTypeL(KImcvMultipart); |
|
876 switch(folderType) |
|
877 { |
|
878 case EFolderTypeRelated: |
|
879 iMimeHeader->SetContentSubTypeL(KImcvRelated); |
|
880 break; |
|
881 case EFolderTypeMixed: |
|
882 iMimeHeader->SetContentSubTypeL(KImcvMixed); |
|
883 break; |
|
884 case EFolderTypeParallel: |
|
885 iMimeHeader->SetContentSubTypeL(KImcvParallel); |
|
886 break; |
|
887 case EFolderTypeAlternative: |
|
888 iMimeHeader->SetContentSubTypeL(KImcvAlternative); |
|
889 break; |
|
890 case EFolderTypeDigest: |
|
891 iMimeHeader->SetContentSubTypeL(KImcvDigest); |
|
892 break; |
|
893 default: |
|
894 // Should really default to mixed rather than unknown. |
|
895 iMimeHeader->SetContentSubTypeL(KImcvMixed); |
|
896 } |
|
897 multipart=ETrue; |
|
898 } |
|
899 |
|
900 rBoundary.Set(SetBoundaryL(multipart)); |
|
901 |
|
902 //Storing header information(ContentType and SubContentType) for e-mail with attachment |
|
903 if ((aEntry.Attachment()) && (iMimeHeader->ContentType().Length() == 0) && (iServerEntry.HasStoreL())) |
|
904 { |
|
905 CMsvStore* store = iServerEntry.ReadStoreL(); |
|
906 CleanupStack::PushL(store); |
|
907 MMsvAttachmentManager& manager=store->AttachmentManagerL(); |
|
908 if(manager.AttachmentCount()) |
|
909 { |
|
910 CMsvAttachment* attachment = manager.GetAttachmentInfoL(0); |
|
911 CleanupStack::PushL(attachment); |
|
912 TInt length = attachment->MimeType().Length(); |
|
913 TInt location = attachment->MimeType().Locate('/'); |
|
914 if ((length > 0) && (location != KErrNotFound)) |
|
915 { |
|
916 iMimeHeader->SetContentTypeL(attachment->MimeType().Left(location++)); |
|
917 iMimeHeader->SetContentSubTypeL(attachment->MimeType().Right((length-location))); |
|
918 } |
|
919 CleanupStack::PopAndDestroy(attachment); |
|
920 } |
|
921 CleanupStack::PopAndDestroy(store); |
|
922 } |
|
923 |
|
924 if(InitAttachmentObjectL(aEntry)) |
|
925 rFilename.Set(static_cast<TPtrC>(iSendFile->Filename())); |
|
926 else |
|
927 rFilename.Set(KNullDesC); |
|
928 } |
|
929 |
|
930 //--------------------------------------------------------------------------------- |
|
931 void CImSendMimeEmail::InitSendMimeHeaderL( TMsvEntry& aEntry, TMimeHeaderType aMimeHeaderType ) |
|
932 //--------------------------------------------------------------------------------- |
|
933 { |
|
934 // When we are dealing with the main Mime header and we don't have a |
|
935 // multipart we want to check if the entry is a text entry and if it |
|
936 // has a Mime header in its store: this means we are probably dealing |
|
937 // with a scheduling message (i.e.meeting invite). In this case we take |
|
938 // the Mime header from the text entry. |
|
939 |
|
940 TImEmailFolderType folderType; |
|
941 TBool found = EFalse; |
|
942 |
|
943 if ( (aMimeHeaderType==EMainMimeHeader) && !CheckForMultipartEmailL(aEntry, folderType) ) |
|
944 { |
|
945 if ( Down(aEntry) ) |
|
946 { |
|
947 if ( aEntry.iType==KUidMsvEmailTextEntry ) |
|
948 { |
|
949 if ( CreateMimeHeaderL() ) |
|
950 { |
|
951 found = ETrue; |
|
952 } |
|
953 } |
|
954 |
|
955 // We move back to the previous entry |
|
956 iEmailTraverser->UpLevelL(); |
|
957 aEntry = iEmailTraverser->ThisEntry(); |
|
958 } |
|
959 } |
|
960 |
|
961 // We read the Mimeheader stream if we haven't done it already |
|
962 if ( !found ) |
|
963 { |
|
964 CreateMimeHeaderL(); |
|
965 } |
|
966 |
|
967 TPtrC8 boundary; |
|
968 TPtrC filename; |
|
969 |
|
970 InitMimeHeaderL(aEntry, boundary, filename); |
|
971 |
|
972 delete iSendMimeHeader; |
|
973 iSendMimeHeader = NULL; |
|
974 iSendMimeHeader = CImSendMimeHeader::NewL(*iHeaderConverter, aMimeHeaderType); |
|
975 if (( aEntry.iType == KUidMsvMessageEntry ) |
|
976 && ( !iEmailTraverser->IsBaseLevel() ) |
|
977 && ( aMimeHeaderType == EPartMimeHeader )) |
|
978 { |
|
979 iSendMimeHeader->InitialiseL( *iMimeHeader, filename, boundary,iEmbeddedEmail, |
|
980 aEntry, iRfc822Header->TransformingInfo(), ETrue); |
|
981 } |
|
982 else |
|
983 { |
|
984 iSendMimeHeader->InitialiseL( *iMimeHeader, filename, boundary,iEmbeddedEmail, |
|
985 aEntry, iRfc822Header->TransformingInfo()); |
|
986 } |
|
987 |
|
988 } |
|
989 |
|
990 |
|
991 //--------------------------------------------------------------------------------- |
|
992 void CImSendMimeEmail::InitEmbeddedEmailL() |
|
993 //--------------------------------------------------------------------------------- |
|
994 { |
|
995 iRfc822Header->InitialiseL(iServerEntry.Entry().iDate, iDomainName, iServerEntry, |
|
996 iServerEntry.Entry().Priority(), ESendNoCopy, iDefaultTransformingInfo); |
|
997 |
|
998 iState=ERfc822Header; |
|
999 iEmbeddedEmail=0; |
|
1000 } |
|
1001 |
|
1002 //--------------------------------------------------------------------------------- |
|
1003 void CImSendMimeEmail::CreateBoundaryL() |
|
1004 //--------------------------------------------------------------------------------- |
|
1005 { |
|
1006 TBuf8<57> validBoundaryBuffer(KBasicAsciiChars); |
|
1007 TBuf8<KBoundaryStringLength> boundaryString; |
|
1008 TUint result = 0; |
|
1009 |
|
1010 boundaryString.Append(KImcvEpoc32); |
|
1011 boundaryString.Append(KImcvHyphen); |
|
1012 |
|
1013 while( boundaryString.Length()<KBoundaryStringLength ) |
|
1014 { |
|
1015 result=(Math::Rand(iRandSeed)); |
|
1016 // gets the mod of Rand() which is a number between 0 to KMaxTInt |
|
1017 result%=57; |
|
1018 boundaryString.AppendFormat(KPrintChar, validBoundaryBuffer[result]); |
|
1019 result=0; |
|
1020 } |
|
1021 |
|
1022 iBoundaryArray->InsertL(0, boundaryString); |
|
1023 } |
|
1024 |
|
1025 //--------------------------------------------------------------------------------- |
|
1026 void CImSendMimeEmail::DeleteBoundary() |
|
1027 //--------------------------------------------------------------------------------- |
|
1028 { |
|
1029 if (iBoundaryArray->Count()) |
|
1030 iBoundaryArray->Delete(0); |
|
1031 } |
|
1032 |
|
1033 //--------------------------------------------------------------------------------- |
|
1034 TInt CImSendMimeEmail::HeaderSize() |
|
1035 //--------------------------------------------------------------------------------- |
|
1036 { |
|
1037 TInt size = CImSendEmail::HeaderSize(); |
|
1038 |
|
1039 TMsvId id = iServerEntry.Entry().Id(); |
|
1040 iEmailTraverser->SetBaseEntry(); |
|
1041 |
|
1042 TMsvEntry aId; |
|
1043 |
|
1044 // DEF023106. Can't let Leaves pass into public non-leave function, so Trap. |
|
1045 TRAPD(initialiseError, InitSendMimeHeaderL(aId, EMainMimeHeader)); |
|
1046 |
|
1047 if (initialiseError != KErrNone) |
|
1048 { |
|
1049 // DEF023106. Return double the rfc822 header size on Leave. |
|
1050 size += size; |
|
1051 } |
|
1052 else |
|
1053 { |
|
1054 size += iSendMimeHeader->Size(); |
|
1055 } |
|
1056 |
|
1057 iServerEntry.SetEntry(id); |
|
1058 return size; |
|
1059 } |
|
1060 |
|
1061 |
|
1062 //--------------------------------------------------------------------------------- |
|
1063 TBool CImSendMimeEmail::InitBodyObjectL(TMsvEntry& rEntry) |
|
1064 //--------------------------------------------------------------------------------- |
|
1065 { |
|
1066 TImEncodingType type=iRfc822Header->TransformingInfo().BodyTextEncoding(); |
|
1067 |
|
1068 return ( rEntry.iType==KUidMsvEmailTextEntry |
|
1069 && iSendRichText->InitialiseL( iServerEntry, |
|
1070 Encoder(type), type, |
|
1071 iSendMimeHeader->CharsetUid()) ); |
|
1072 } |
|
1073 |
|
1074 |
|
1075 //********************************************************************************* |
|
1076 // Class CImSendRfc822Header Functions |
|
1077 //********************************************************************************* |
|
1078 |
|
1079 //--------------------------------------------------------------------------------- |
|
1080 CImSendRfc822Header* CImSendRfc822Header::NewLC( RFs& anFs, CImConvertHeader& aConverter ) |
|
1081 //--------------------------------------------------------------------------------- |
|
1082 { |
|
1083 CImSendRfc822Header* self = new (ELeave) CImSendRfc822Header(anFs, aConverter); |
|
1084 CleanupStack::PushL( self ); |
|
1085 self->ConstructL(); |
|
1086 return self; |
|
1087 } |
|
1088 |
|
1089 //--------------------------------------------------------------------------------- |
|
1090 CImSendRfc822Header* CImSendRfc822Header::NewL( RFs& anFs, CImConvertHeader& aConverter ) |
|
1091 //--------------------------------------------------------------------------------- |
|
1092 { |
|
1093 CImSendRfc822Header* self = CImSendRfc822Header::NewLC(anFs, aConverter); |
|
1094 CleanupStack::Pop( ); |
|
1095 return self; |
|
1096 } |
|
1097 |
|
1098 //--------------------------------------------------------------------------------- |
|
1099 CImSendRfc822Header::CImSendRfc822Header( RFs& anFs, CImConvertHeader& aConverter ) |
|
1100 : iFs(anFs), iHeaderConverter(aConverter) |
|
1101 //--------------------------------------------------------------------------------- |
|
1102 { |
|
1103 } |
|
1104 |
|
1105 //--------------------------------------------------------------------------------- |
|
1106 CImSendRfc822Header::~CImSendRfc822Header() |
|
1107 //--------------------------------------------------------------------------------- |
|
1108 { |
|
1109 delete iHeader; |
|
1110 delete iDomainName; |
|
1111 |
|
1112 delete iOutputBuffer; |
|
1113 delete iProductName; |
|
1114 delete iImcvUtils; |
|
1115 delete iPriorityFields; |
|
1116 delete iImportanceFields; |
|
1117 delete iReceiptFields; |
|
1118 } |
|
1119 |
|
1120 //--------------------------------------------------------------------------------- |
|
1121 void CImSendRfc822Header::ConstructL() |
|
1122 //--------------------------------------------------------------------------------- |
|
1123 { |
|
1124 RResourceFile resFile; |
|
1125 OpenResourceFileL(resFile,iFs); // leaves if file not found |
|
1126 |
|
1127 // make sure the resource file will be closed if anything goes wrong |
|
1128 TCleanupItem close( CloseResourceFile, &resFile ); |
|
1129 CleanupStack::PushL( close ); |
|
1130 HBufC8* buf = resFile.AllocReadLC( PRODUCT_NAME ); |
|
1131 |
|
1132 TResourceReader reader; |
|
1133 reader.SetBuffer(buf); |
|
1134 iProductName = reader.ReadTPtrC().AllocL(); |
|
1135 CleanupStack::PopAndDestroy(2); // close , buf |
|
1136 resFile.Close(); |
|
1137 |
|
1138 } |
|
1139 |
|
1140 //--------------------------------------------------------------------------------- |
|
1141 TBool CImSendRfc822Header::InitialiseL( const TTime aTimeDate , const TDesC& aDomainName, |
|
1142 CMsvServerEntry& aServerEntry,const TMsvPriority aPriority, |
|
1143 const TImSMTPSendCopyToSelf aCopyToSelf, |
|
1144 TImEmailTransformingInfo& aInfo) |
|
1145 //--------------------------------------------------------------------------------- |
|
1146 { |
|
1147 Reset(); |
|
1148 iTimeDate = aTimeDate; |
|
1149 |
|
1150 delete iDomainName; |
|
1151 iDomainName=NULL; |
|
1152 iDomainName=aDomainName.AllocL(); |
|
1153 |
|
1154 delete iHeader; |
|
1155 iHeader=NULL; |
|
1156 iHeader = CImHeader::NewLC(); |
|
1157 CleanupStack::Pop(); // header |
|
1158 |
|
1159 delete iImcvUtils; |
|
1160 iImcvUtils=NULL; |
|
1161 iImcvUtils=CImcvUtils::NewL(); |
|
1162 |
|
1163 delete iPriorityFields; |
|
1164 iPriorityFields=NULL; |
|
1165 delete iImportanceFields; |
|
1166 iImportanceFields=NULL; |
|
1167 delete iReceiptFields; |
|
1168 iReceiptFields=NULL; |
|
1169 |
|
1170 iPriorityFields=new (ELeave)CDesC8ArrayFlat(KArrayAllocationNumber); |
|
1171 iImcvUtils->SendPriorityFieldsL(*iPriorityFields); |
|
1172 |
|
1173 iImportanceFields=new (ELeave)CDesC8ArrayFlat(KArrayAllocationNumber); |
|
1174 iImcvUtils->SendImportanceFieldsL(*iImportanceFields); |
|
1175 |
|
1176 TMsvEmailEntry entry = aServerEntry.Entry(); |
|
1177 if (entry.Receipt()) |
|
1178 { |
|
1179 iReceiptFields = new (ELeave)CDesC8ArrayFlat(KArrayAllocationNumber); |
|
1180 iImcvUtils->SendReturnReceiptFieldsL(*iReceiptFields); |
|
1181 } |
|
1182 iPriority = aPriority; |
|
1183 |
|
1184 TBool validEmailMsg=EFalse; |
|
1185 if (aServerEntry.HasStoreL()) |
|
1186 { |
|
1187 CMsvStore* store = aServerEntry.ReadStoreL(); |
|
1188 CleanupStack::PushL(store); |
|
1189 |
|
1190 if (store->IsPresentL( KUidMsgFileTransformingInfo)) |
|
1191 aInfo.RestoreL(*store); |
|
1192 |
|
1193 // Must have an rfc822 header. |
|
1194 if (store->IsPresentL( KUidMsgFileIMailHeader) ) |
|
1195 { |
|
1196 iHeader->RestoreL(*store); |
|
1197 validEmailMsg=ETrue; |
|
1198 } |
|
1199 |
|
1200 CleanupStack::PopAndDestroy(store); |
|
1201 } |
|
1202 |
|
1203 iTransformingInfo=aInfo; |
|
1204 if(aInfo.HeaderCharset() == 0) |
|
1205 aInfo.SetHeaderCharset(iHeaderConverter.CharConv().DefaultCharset()); |
|
1206 |
|
1207 iHeaderCharset=aInfo.HeaderCharset(); |
|
1208 iHeaderEncoding=aInfo.HeaderEncoding(); |
|
1209 |
|
1210 iCopyToSelf=aCopyToSelf; |
|
1211 |
|
1212 return validEmailMsg; |
|
1213 } |
|
1214 |
|
1215 //--------------------------------------------------------------------------------- |
|
1216 void CImSendRfc822Header::HandleSpecialCharacters(TPtr8& aAddressPtr) |
|
1217 //--------------------------------------------------------------------------------- |
|
1218 { |
|
1219 // Single address passed in. Make sure the address is of the format |
|
1220 // "quoted name" <name@domain> |
|
1221 // quoted, name <name@domain> |
|
1222 // quoted "name" <name@domain> |
|
1223 // name <name@domain> |
|
1224 // quoted "name <name@domain> |
|
1225 // Comments are not supported. |
|
1226 // Remove any leading and trailing white space. |
|
1227 aAddressPtr.Trim(); |
|
1228 |
|
1229 // If the address isn't the correct format. |
|
1230 if (aAddressPtr[aAddressPtr.Length() - 1] != '>') |
|
1231 return; |
|
1232 |
|
1233 TInt leftChevron = aAddressPtr.LocateReverse(TChar('<')); |
|
1234 if (leftChevron == KErrNotFound) |
|
1235 return; |
|
1236 |
|
1237 //If the address has allias |
|
1238 if(leftChevron > 0) |
|
1239 { |
|
1240 |
|
1241 TInt firstDQuote = aAddressPtr.Locate(TChar('"')); |
|
1242 TInt lastDQuote = aAddressPtr.Left(leftChevron).LocateReverse(TChar('"')); |
|
1243 TInt aliasLastChar = leftChevron-1; |
|
1244 |
|
1245 //If alias has ',' in between |
|
1246 if(aAddressPtr.Left(leftChevron).LocateReverse(TChar(',')) != KErrNotFound) |
|
1247 { |
|
1248 //get the last character of alias |
|
1249 for (TInt index = aliasLastChar ; aAddressPtr[index] == ' ' ; --index ) |
|
1250 { |
|
1251 aliasLastChar--; |
|
1252 } |
|
1253 //if alias not with in quotes then add quotes |
|
1254 if ( firstDQuote != 0 || lastDQuote != aliasLastChar) |
|
1255 { |
|
1256 aAddressPtr.Insert(0,KImcvQuoteString); |
|
1257 firstDQuote = 0; |
|
1258 //because alias length has been increased by one character |
|
1259 aliasLastChar+=1; |
|
1260 aAddressPtr.Insert(aliasLastChar+1 , KImcvQuoteString); |
|
1261 lastDQuote = aliasLastChar+1; |
|
1262 } |
|
1263 } |
|
1264 if (lastDQuote == KErrNotFound || lastDQuote == firstDQuote) |
|
1265 return; |
|
1266 |
|
1267 //add KBackslash before all spacial characters in alias |
|
1268 _LIT8(KBackslash,"\\"); |
|
1269 for (TInt index = lastDQuote - 1; index > firstDQuote; --index) |
|
1270 { |
|
1271 if (IsSpecialCharacter(aAddressPtr[index])) |
|
1272 { |
|
1273 // Character inserted before the current character. |
|
1274 aAddressPtr.Insert(index, KBackslash); |
|
1275 } |
|
1276 } |
|
1277 } |
|
1278 } |
|
1279 |
|
1280 //--------------------------------------------------------------------------------- |
|
1281 TBool CImSendRfc822Header::IsSpecialCharacter(const TUint aChar) |
|
1282 //--------------------------------------------------------------------------------- |
|
1283 { |
|
1284 return (aChar == '(' || aChar == ')' || aChar == '<' || aChar == '>' || aChar == '@' |
|
1285 || aChar == '"' || aChar == ';' || aChar == ':' || aChar == '/' || aChar == ']' |
|
1286 || aChar == '['); |
|
1287 } |
|
1288 |
|
1289 //--------------------------------------------------------------------------------- |
|
1290 void CImSendRfc822Header::Reset() |
|
1291 //--------------------------------------------------------------------------------- |
|
1292 { |
|
1293 iState = 0; |
|
1294 } |
|
1295 |
|
1296 //--------------------------------------------------------------------------------- |
|
1297 TInt CImSendRfc822Header::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
1298 //--------------------------------------------------------------------------------- |
|
1299 { |
|
1300 // Format the next line of output into rOutputLine. |
|
1301 // If the output line contains more characters than the size of the source data consumed |
|
1302 // in preparing it, then the difference is passed back in aPaddingCount. |
|
1303 |
|
1304 __ASSERT_DEBUG( iHeader!=NULL, gPanic(KPanicNoRfc822Header) ); |
|
1305 |
|
1306 TInt advance = 0; |
|
1307 TInt length = 0; |
|
1308 TInt localPaddingCount=0; |
|
1309 |
|
1310 rOutputLine.Zero(); |
|
1311 do |
|
1312 { |
|
1313 switch (iState) |
|
1314 { |
|
1315 case EFrom: // top of header, generate 'From' |
|
1316 advance = FromL( rOutputLine ); // returns 1 if we've finished the field, 0 otherwise |
|
1317 break; |
|
1318 case EReplyTo: // generate 'Reply-To' |
|
1319 advance = ReplyToL( rOutputLine ); |
|
1320 break; |
|
1321 case ETo: // generate 'To' |
|
1322 advance = ToL( rOutputLine ); |
|
1323 break; |
|
1324 case ECc: // generate 'Cc' |
|
1325 advance = CcL( rOutputLine ); |
|
1326 break; |
|
1327 case EBcc: // generate 'Bcc' |
|
1328 advance = BccL( rOutputLine ); |
|
1329 break; |
|
1330 case ESubject: // generate 'Subject' |
|
1331 advance = SubjectL( rOutputLine ); |
|
1332 break; |
|
1333 case EDate: // generate date |
|
1334 rOutputLine = KImcvDatePrompt; |
|
1335 iRfc822Date.SetDate( iTimeDate, rOutputLine ); |
|
1336 advance = 1; |
|
1337 break; |
|
1338 case EReturnReceiptTo: |
|
1339 if (iReceiptFields) |
|
1340 advance = ReturnReceiptsL( rOutputLine ); |
|
1341 break; |
|
1342 case EPriority: |
|
1343 advance = PriorityL(rOutputLine ); |
|
1344 break; |
|
1345 case EImportance: |
|
1346 advance = ImportanceL(rOutputLine ); |
|
1347 break; |
|
1348 case EMessageID: // iDomainName should be called somewhere before this is called! |
|
1349 // (use SetDomainNameL(aDomainName)) |
|
1350 SetMessageIdL(); |
|
1351 advance = MessageIdL(rOutputLine); |
|
1352 break; |
|
1353 case EXMailer: // quick advert for ourselves |
|
1354 advance = XMailerL( rOutputLine ); |
|
1355 break; |
|
1356 } |
|
1357 |
|
1358 length = rOutputLine.Length(); |
|
1359 if (!length || advance) |
|
1360 iState ++; |
|
1361 |
|
1362 } while ( !length && (iState < EEndOfRfc822Header) ); |
|
1363 |
|
1364 if ( !IsLineCRLF( rOutputLine ) ) |
|
1365 // only write something if there is any data! |
|
1366 AppendCRLF(rOutputLine, localPaddingCount); |
|
1367 |
|
1368 rPaddingCount = localPaddingCount; |
|
1369 return (iState>=EEndOfRfc822Header ? KImCvAdvance : KErrNone); |
|
1370 } |
|
1371 |
|
1372 // Pass in 16 bit descriptor, encode before outputting |
|
1373 |
|
1374 //--------------------------------------------------------------------------------- |
|
1375 void CImSendRfc822Header::PrepareBufferL( const TPtrC8& aPrompt, const TDesC& aData) |
|
1376 //--------------------------------------------------------------------------------- |
|
1377 { |
|
1378 HBufC8* buf = HBufC8::NewL(aData.Length()); |
|
1379 RBuf8 bufPtr(buf); |
|
1380 bufPtr.CleanupClosePushL(); |
|
1381 EncodeHeaderFieldL(aData, bufPtr, 0); |
|
1382 PrepareBufferL(aPrompt,bufPtr); |
|
1383 CleanupStack::PopAndDestroy(&bufPtr); |
|
1384 |
|
1385 } |
|
1386 |
|
1387 // data is 8 bit, no encoding. |
|
1388 |
|
1389 //--------------------------------------------------------------------------------- |
|
1390 void CImSendRfc822Header::PrepareBufferL( const TPtrC8& aPrompt, const TDesC8& aData) |
|
1391 //--------------------------------------------------------------------------------- |
|
1392 { |
|
1393 if (iOutputBuffer) |
|
1394 return; |
|
1395 |
|
1396 iOutputBuffer = HBufC8::NewL( aPrompt.Length() + aData.Length() + 1 ); |
|
1397 *iOutputBuffer = aPrompt; |
|
1398 |
|
1399 // need to buffer up some output |
|
1400 iOutputBuffer->Des().Append( KImcvSpace ); |
|
1401 iOutputBuffer->Des().Append( aData ); |
|
1402 ipOutputBuffer = iOutputBuffer->Ptr(); |
|
1403 } |
|
1404 |
|
1405 |
|
1406 //--------------------------------------------------------------------------------- |
|
1407 void CImSendRfc822Header::AddCopyToSelfL(TImSMTPSendCopyToSelf aCopyToSelf, CDesCArray& aList) |
|
1408 //--------------------------------------------------------------------------------- |
|
1409 { |
|
1410 if (iCopyToSelf==aCopyToSelf) |
|
1411 { |
|
1412 if ( iHeader->ReceiptAddress().Length() ) |
|
1413 aList.AppendL(iHeader->ReceiptAddress()); |
|
1414 else if ( iHeader->ReplyTo().Length() ) |
|
1415 aList.AppendL(iHeader->ReplyTo()); |
|
1416 } |
|
1417 } |
|
1418 |
|
1419 |
|
1420 //--------------------------------------------------------------------------------- |
|
1421 TInt CImSendRfc822Header::DoRecipientsL( TDes8& rOutputLine, const TPtrC8& aPrompt, |
|
1422 CDesCArray& aList) |
|
1423 //--------------------------------------------------------------------------------- |
|
1424 { |
|
1425 if (iOutputBuffer) |
|
1426 return SendOutput(rOutputLine); |
|
1427 |
|
1428 // first call into this function, so build the output buffer |
|
1429 // first establish the length (this is faster than guessing & having to re-allocate) |
|
1430 TInt32 totalLength = aPrompt.Length()+1; |
|
1431 TInt i=aList.Count(); // loop counter |
|
1432 while (i--) |
|
1433 // allow 2 chars for comma-separation |
|
1434 totalLength += aList[i].Length() + 2; |
|
1435 |
|
1436 iOutputBuffer = HBufC8::NewL( totalLength ); |
|
1437 // now build the combined list |
|
1438 TInt count=aList.Count(); |
|
1439 for ( i=0; i<count; i++ ) |
|
1440 { |
|
1441 if (!i) // first recipient in list needs to be preceeded by the field identifier |
|
1442 { |
|
1443 *iOutputBuffer = aPrompt; |
|
1444 iOutputBuffer->Des().Append( KImcvSpace ); |
|
1445 } |
|
1446 else // subsequent ones need comma-separation |
|
1447 iOutputBuffer->Des().Append( KImcvCommaSpace ); |
|
1448 // ...and of course the data |
|
1449 HBufC8* buf = HBufC8::NewL((aList[i]).Length()); |
|
1450 RBuf8 bufPtr(buf); |
|
1451 bufPtr.CleanupClosePushL(); |
|
1452 |
|
1453 EncodeHeaderFieldL(aList[i] , bufPtr, i); |
|
1454 |
|
1455 HBufC8* addrBuffer = HBufC8::NewLC(bufPtr.Length() * 2); |
|
1456 TPtr8 addrPtr(addrBuffer->Des()); |
|
1457 addrPtr.Copy(bufPtr); |
|
1458 HandleSpecialCharacters(addrPtr); |
|
1459 |
|
1460 // May have to increase size of iOutputBuf |
|
1461 if (iOutputBuffer->Des().MaxLength() < iOutputBuffer->Des().Length() + addrPtr.Length() + 2) |
|
1462 iOutputBuffer = iOutputBuffer->ReAllocL( iOutputBuffer->Des().MaxLength() + addrPtr.Length()); |
|
1463 iOutputBuffer->Des().Append( addrPtr); |
|
1464 bufPtr.Close(); |
|
1465 CleanupStack::PopAndDestroy(2, &bufPtr); // addrBuffer, buf |
|
1466 |
|
1467 } // for (...) |
|
1468 ipOutputBuffer = iOutputBuffer->Ptr(); |
|
1469 return SendOutput( rOutputLine ); |
|
1470 } |
|
1471 |
|
1472 void CImSendRfc822Header::PackRemainingData( TDes8& rOutputLine, TPtrC8& aBuf ) |
|
1473 { |
|
1474 |
|
1475 if (iAddSpaceToNewLine) |
|
1476 { |
|
1477 // wrapped lines start with a space to indicate their wrappiness. |
|
1478 rOutputLine = KImcvSpace; |
|
1479 rOutputLine.Append( aBuf.Ptr(), aBuf.Length() ); |
|
1480 // we can add this extra byte since MKaxIMailLineLength allows for it |
|
1481 rOutputLine.SetLength( aBuf.Length() + 1 ); |
|
1482 } |
|
1483 else |
|
1484 { |
|
1485 rOutputLine = aBuf; |
|
1486 } |
|
1487 } |
|
1488 |
|
1489 |
|
1490 //--------------------------------------------------------------------------------- |
|
1491 TInt CImSendRfc822Header::SendOutput( TDes8& rOutputLine ) |
|
1492 //--------------------------------------------------------------------------------- |
|
1493 { |
|
1494 // we have buffered output - first check whether we can bung the rest out on one line. |
|
1495 // the size of the remaining data is the whole length less the distance we've already got through |
|
1496 |
|
1497 TInt offset = (ipOutputBuffer-iOutputBuffer->Ptr()); |
|
1498 |
|
1499 TInt dataRemaining = iOutputBuffer->Length() - offset; |
|
1500 if ( dataRemaining < KMaxIMailHeaderWriteLineLength ) |
|
1501 { |
|
1502 // copy this into the line-output buffer |
|
1503 if ( !offset ) |
|
1504 { |
|
1505 // this is the first line for this field since we're still pointing at the start of the buffer |
|
1506 rOutputLine = *iOutputBuffer; |
|
1507 } |
|
1508 else |
|
1509 { |
|
1510 TPtrC8 data( ipOutputBuffer, dataRemaining ); |
|
1511 PackRemainingData( rOutputLine, data); |
|
1512 } |
|
1513 |
|
1514 delete iOutputBuffer; |
|
1515 iOutputBuffer = NULL; |
|
1516 ipOutputBuffer = NULL; |
|
1517 iAddSpaceToNewLine = EFalse; |
|
1518 // we can now advance to the next field |
|
1519 return 1; |
|
1520 } |
|
1521 else // we need to send out the data in line-long segments |
|
1522 { |
|
1523 // only the first line gets the whole length, cos subsequent ones are prepended with a space. |
|
1524 TInt lineLength = (offset ? KMaxIMailHeaderWriteLineLength : KMaxIMailHeaderWriteLineLength-1 ); |
|
1525 |
|
1526 TInt pos = 0; |
|
1527 TInt left = 0; |
|
1528 TInt right = 0; |
|
1529 TBool splitAddress = EFalse; |
|
1530 iAddSpaceToNewLine = EFalse; |
|
1531 |
|
1532 // if currently handling subject field, then do not attempt to parse for email addresses. |
|
1533 // This causes encoded words to be split accross line breaks, resulting in garbled text. |
|
1534 if (FieldIsEmailAddress()) |
|
1535 { |
|
1536 TPtrC8 addrData(ipOutputBuffer, dataRemaining); |
|
1537 while ( ValidEmailAddress( addrData, pos, left, right) ) |
|
1538 { |
|
1539 if (left+pos < lineLength) |
|
1540 { |
|
1541 if (right+pos >= lineLength) |
|
1542 { |
|
1543 // Current Email address won't fit into line |
|
1544 splitAddress = ETrue; |
|
1545 iAddSpaceToNewLine = ETrue; |
|
1546 |
|
1547 if (right - left < lineLength) |
|
1548 { |
|
1549 // Break line just before Email address |
|
1550 lineLength = left+pos; |
|
1551 break; |
|
1552 } |
|
1553 } |
|
1554 } |
|
1555 else |
|
1556 { |
|
1557 //length of alias is less than KMaxIMailHeaderWriteLineLength |
|
1558 if(left+pos < KMaxIMailHeaderLineLength) |
|
1559 { |
|
1560 splitAddress = ETrue; |
|
1561 iAddSpaceToNewLine = ETrue; |
|
1562 // Break line just before Email address |
|
1563 lineLength = left+pos; |
|
1564 } |
|
1565 else |
|
1566 { |
|
1567 User::Leave(KErrSmtpBufferOverFlow); |
|
1568 } |
|
1569 break; |
|
1570 } |
|
1571 if (right+pos > lineLength) |
|
1572 { |
|
1573 //length of email address is less than KMaxIMailHeaderWriteLineLength |
|
1574 if(right+pos < KMaxIMailHeaderLineLength) |
|
1575 { |
|
1576 splitAddress = ETrue; |
|
1577 iAddSpaceToNewLine = ETrue; |
|
1578 // Break line just before Email address |
|
1579 lineLength = right+pos; |
|
1580 } |
|
1581 else |
|
1582 { |
|
1583 User::Leave(KErrSmtpBufferOverFlow); |
|
1584 } |
|
1585 break; |
|
1586 } |
|
1587 // Move pos to end of Email address |
|
1588 pos += right; |
|
1589 } |
|
1590 } |
|
1591 |
|
1592 if ( !splitAddress ) |
|
1593 { |
|
1594 TPtrC8 encData(ipOutputBuffer, dataRemaining); |
|
1595 while ( iHeaderConverter.FindEncodedWord(encData, pos, left, right) ) |
|
1596 { |
|
1597 if (left+pos < lineLength) |
|
1598 { |
|
1599 // Second part of condition checks for too long encoded-words |
|
1600 if ((right+pos >= lineLength) && (right - left < lineLength)) |
|
1601 { |
|
1602 // Break line just before encoded word |
|
1603 lineLength = left+pos; |
|
1604 iAddSpaceToNewLine = ETrue; |
|
1605 break; |
|
1606 } |
|
1607 } |
|
1608 else if (right+pos > lineLength) |
|
1609 break; |
|
1610 // Move pos to end of the encoded word |
|
1611 pos += right; |
|
1612 } |
|
1613 } |
|
1614 |
|
1615 |
|
1616 if ( !FieldIsEmailAddress() && !iAddSpaceToNewLine ) |
|
1617 { |
|
1618 // We have a subject field and no wrapping set at an Encoded Word |
|
1619 _LIT(KInvalidDataSize, "Data Remaining, not suitable for more than a line"); |
|
1620 __ASSERT_DEBUG( dataRemaining >= KMaxIMailHeaderWriteLineLength, User::Panic(KInvalidDataSize, 1 )); |
|
1621 |
|
1622 // Find space from a resonable length onwards in ascending order |
|
1623 TInt minLineLength = KMaxIMailHeaderWriteLineLength/2; |
|
1624 TPtrC8 buf(ipOutputBuffer+minLineLength, KMaxIMailHeaderWriteLineLength); |
|
1625 lineLength = buf.Locate(' '); |
|
1626 |
|
1627 if ( lineLength != KErrNotFound ) |
|
1628 { |
|
1629 // We have found a space |
|
1630 lineLength += minLineLength; |
|
1631 // only the first line gets the whole length, cos subsequent ones are prepended with a space. |
|
1632 TInt maxLineLength = (offset ? KMaxIMailHeaderWriteLineLength : KMaxIMailHeaderWriteLineLength-1 ); |
|
1633 if (left+pos < maxLineLength) |
|
1634 { |
|
1635 // Second part of condition checks for too long encoded-words |
|
1636 if ((right+pos >= maxLineLength) && pos>0) |
|
1637 { |
|
1638 rOutputLine = KImcvSpace; |
|
1639 } |
|
1640 } |
|
1641 rOutputLine.Append( ipOutputBuffer, lineLength ); |
|
1642 ipOutputBuffer += lineLength; |
|
1643 } |
|
1644 else |
|
1645 { |
|
1646 // Line length limit is 1000 chars per line including CRLF (RFC2822, Section 2.1.1) |
|
1647 // 1000 chars including "Field name: "+"Field body"+CRLF (here "Resent-Message-ID: " is largest field) |
|
1648 if (dataRemaining > KSmtpMaxBufferExcludingCRLF) |
|
1649 User::Leave(KErrSmtpBufferOverFlow); |
|
1650 |
|
1651 // No space found, so send the full remaining buffer as it is |
|
1652 rOutputLine.Append( ipOutputBuffer, dataRemaining ); |
|
1653 delete iOutputBuffer; |
|
1654 iOutputBuffer = NULL; |
|
1655 ipOutputBuffer = NULL; |
|
1656 return 1; |
|
1657 } |
|
1658 |
|
1659 return 0; |
|
1660 } |
|
1661 // create a descriptor for the next line-length of characters |
|
1662 TPtrC8 data( ipOutputBuffer, lineLength ); |
|
1663 |
|
1664 if ( !offset ) |
|
1665 { |
|
1666 // this is the first line for this field |
|
1667 rOutputLine = data; |
|
1668 } |
|
1669 else |
|
1670 { |
|
1671 PackRemainingData( rOutputLine, data ); |
|
1672 } |
|
1673 // advance the data pointer to the next line-length of data |
|
1674 ipOutputBuffer += lineLength; |
|
1675 |
|
1676 // prevent ourselves advancing to the next field |
|
1677 return 0; |
|
1678 } |
|
1679 } |
|
1680 |
|
1681 // Assumption: |
|
1682 // data string coming in has already been formatted. |
|
1683 // address1@dd.com, address2@dd.com, addreass3@dd |
|
1684 // |
|
1685 //--------------------------------------------------------------------------------- |
|
1686 TBool CImSendRfc822Header::ValidEmailAddress(const TPtrC8& aData, const TInt aPos, |
|
1687 TInt& rStart, TInt& rEnd) |
|
1688 //--------------------------------------------------------------------------------- |
|
1689 { |
|
1690 TBool found = EFalse; |
|
1691 |
|
1692 TPtrC8 data = aData.Mid(aPos); |
|
1693 TInt len = data.Length(); |
|
1694 if (len < 3) |
|
1695 return found; |
|
1696 //Assuming that alias does not contain '@' |
|
1697 TInt at = data.Locate(KImcvAt); |
|
1698 if ( at!=KErrNotFound ) |
|
1699 { |
|
1700 found = ETrue; |
|
1701 |
|
1702 TPtrC8 findEnd(data.Right(len-at)); |
|
1703 TPtrC8 findStart(data.Left(at)); |
|
1704 |
|
1705 rEnd = findEnd.Locate(KImcvComma); |
|
1706 rStart = findStart.LocateReverse(KImcvSpaceChar); |
|
1707 } |
|
1708 |
|
1709 rEnd = (rEnd==KErrNotFound) ? data.Length() : rEnd+at; |
|
1710 |
|
1711 if (rStart==KErrNotFound) |
|
1712 rStart = 0; |
|
1713 |
|
1714 return found; |
|
1715 } |
|
1716 |
|
1717 //--------------------------------------------------------------------------------- |
|
1718 void CImSendRfc822Header::SetMessageIdL() |
|
1719 //--------------------------------------------------------------------------------- |
|
1720 { |
|
1721 TInt domainNameLength= iDomainName && iDomainName->Length() ? iDomainName->Length():0; |
|
1722 |
|
1723 // list of Valid Characters |
|
1724 TBuf8<52> validCharacterBuffer(KValidCharacters); |
|
1725 TBuf8<20> randomString; |
|
1726 HBufC8* messageId = HBufC8::NewL(domainNameLength+24); |
|
1727 CleanupStack::PushL(messageId); |
|
1728 |
|
1729 TPtr8 ptr(messageId->Des()); |
|
1730 TUint result = 0; |
|
1731 TInt64 randSeed; |
|
1732 TTime theTime; |
|
1733 |
|
1734 theTime.UniversalTime(); |
|
1735 // Gets the current universal time to use as a random number seed |
|
1736 randSeed = theTime.Int64(); |
|
1737 |
|
1738 while(randomString.Length()<20) |
|
1739 { |
|
1740 result= (Math::Rand(randSeed)%10)*10; |
|
1741 result+= Math::Rand(randSeed)%10; |
|
1742 result%=52; |
|
1743 randomString.AppendFormat(KImcvCharacterFormat, validCharacterBuffer[result]); |
|
1744 result=0; |
|
1745 } |
|
1746 |
|
1747 ptr.Append(KImcvLeftChevron); |
|
1748 ptr.Append(randomString.Left(12)); |
|
1749 ptr.Append(KImcvFullStop); |
|
1750 ptr.Append(randomString.Right(8)); |
|
1751 if (domainNameLength) |
|
1752 { |
|
1753 ptr.Append(KImcvAt); |
|
1754 ptr.Append(iDomainName->Des()); |
|
1755 } |
|
1756 ptr.Append(KImcvRightChevron); |
|
1757 iHeader->SetImMsgIdL(messageId->Des()); |
|
1758 |
|
1759 CleanupStack::PopAndDestroy(messageId); |
|
1760 } |
|
1761 |
|
1762 |
|
1763 //--------------------------------------------------------------------------------- |
|
1764 TInt CImSendRfc822Header::PriorityL(TDes8& rOutputLine) |
|
1765 //--------------------------------------------------------------------------------- |
|
1766 { |
|
1767 if (iPriority==EMsvMediumPriority) |
|
1768 return 0; |
|
1769 if (iPriority==EMsvHighPriority) |
|
1770 PrepareBufferL((*iPriorityFields)[0], KImPrioritySendHigh); |
|
1771 else if (iPriority==EMsvLowPriority) |
|
1772 PrepareBufferL((*iPriorityFields)[0], KImPrioritySendLow); |
|
1773 iPriorityFields->Delete(0); |
|
1774 SendOutput( rOutputLine ); |
|
1775 |
|
1776 return (iPriorityFields->Count()) ? 0:1; // Return 1 if array is empty |
|
1777 } |
|
1778 |
|
1779 //--------------------------------------------------------------------------------- |
|
1780 TInt CImSendRfc822Header::ImportanceL(TDes8& rOutputLine) |
|
1781 //--------------------------------------------------------------------------------- |
|
1782 { |
|
1783 // Although importance means priority, it is a different field and |
|
1784 // had a different format. When we send the importance field we send |
|
1785 // it based on the priority of the e-mail hense the usage of iPriority |
|
1786 |
|
1787 if (iPriority==EMsvMediumPriority) |
|
1788 return 0; |
|
1789 if (iPriority==EMsvHighPriority) |
|
1790 PrepareBufferL((*iImportanceFields)[0], KImImportanceSendHigh); |
|
1791 else if (iPriority==EMsvLowPriority) |
|
1792 PrepareBufferL((*iImportanceFields)[0], KImImportanceSendLow); |
|
1793 iImportanceFields->Delete(0); |
|
1794 SendOutput( rOutputLine ); |
|
1795 |
|
1796 return (iImportanceFields->Count()) ? 0:1; // Return 1 if array is empty |
|
1797 } |
|
1798 |
|
1799 // calculates & returns the total size of the header info, including the RFC822 tags, |
|
1800 // comma & space separation, the CRLFs and the blank line after the header itself |
|
1801 |
|
1802 //--------------------------------------------------------------------------------- |
|
1803 TInt CImSendRfc822Header::Size() const |
|
1804 //--------------------------------------------------------------------------------- |
|
1805 { |
|
1806 __ASSERT_DEBUG( iHeader!=NULL, gPanic(KPanicNoRfc822Header) ); |
|
1807 |
|
1808 TInt size = iHeader->DataSize(); |
|
1809 |
|
1810 size+= KImcvFromPrompt().Length() + 3; |
|
1811 if (iHeader->ReplyTo(). |
|
1812 Length()>0) //test for existence of replyTo field |
|
1813 { |
|
1814 size+= KImcvReplyToPrompt().Length() + 3; |
|
1815 } |
|
1816 size+= KImcvSubjectPrompt().Length() + 3; |
|
1817 size+= KImcvDateStringLength + KImcvDatePrompt().Length() + 2; |
|
1818 size+= KImcvXMailer().Length() + iProductName->Length() + 2; |
|
1819 |
|
1820 |
|
1821 if (iHeader->ToRecipients().Length()) |
|
1822 size+= KImcvToPrompt().Length()+3 |
|
1823 + iHeader->ToRecipients().Count()*2; |
|
1824 |
|
1825 if (iHeader->CcRecipients().Length()) |
|
1826 size+= KImcvCcPrompt().Length()+3 |
|
1827 + iHeader->CcRecipients().Count()*2; |
|
1828 |
|
1829 if (iHeader->BccRecipients().Length()) |
|
1830 size+= KImcvBccPrompt().Length()+3 |
|
1831 + iHeader->BccRecipients().Count()*2; |
|
1832 |
|
1833 if (iHeader->ReceiptAddress().Length()) |
|
1834 // for now there will always be one return receipt field in send. In future if we implement more than one |
|
1835 //field then the size should include other fields. |
|
1836 size+= KImcvMsgDispositionTo().Length()+3 |
|
1837 + iHeader->ReceiptAddress().Length()+2; |
|
1838 return size; |
|
1839 } |
|
1840 |
|
1841 |
|
1842 //--------------------------------------------------------------------------------- |
|
1843 TUint CImSendRfc822Header::HeaderCharset() const |
|
1844 //--------------------------------------------------------------------------------- |
|
1845 { |
|
1846 return iHeader->Charset(); |
|
1847 } |
|
1848 |
|
1849 //--------------------------------------------------------------------------------- |
|
1850 void CImSendRfc822Header::EncodeHeaderFieldL(const TDesC& aBufIn, RBuf8& rBufOut, const TInt aArrayVal) |
|
1851 //--------------------------------------------------------------------------------- |
|
1852 { |
|
1853 CArrayFix<TImHeaderEncodingInfo>* infoArray = &(iHeader->EncodingInfo()); |
|
1854 TImHeaderEncodingInfo::TEncodingType type; |
|
1855 switch (iHeaderEncoding) |
|
1856 { |
|
1857 case EEncodingTypeQP: |
|
1858 type=TImHeaderEncodingInfo::EQP; |
|
1859 break; |
|
1860 case EEncodingTypeBASE64: |
|
1861 type=TImHeaderEncodingInfo::EBase64; |
|
1862 break; |
|
1863 case EEncodingTypeUU: |
|
1864 type=TImHeaderEncodingInfo::EUU; |
|
1865 break; |
|
1866 case EEncodingTypeNone: |
|
1867 type=TImHeaderEncodingInfo::ENoEncoding; |
|
1868 break; |
|
1869 default: |
|
1870 __ASSERT_DEBUG( ETrue, gPanic(KPanicInvalidEncodingType) ); |
|
1871 type=TImHeaderEncodingInfo::ENoEncoding; |
|
1872 } |
|
1873 |
|
1874 if (iTransformingInfo.SendMethod() == ESendAsSimpleEmail) |
|
1875 { |
|
1876 // Don't encode, just convert |
|
1877 iHeaderConverter.ConvertHeaderFieldL(aBufIn, rBufOut, FieldIsEmailAddress()); |
|
1878 } |
|
1879 else if (iHeaderCharset && iHeaderCharset!=KUidMsvCharsetNone) |
|
1880 { |
|
1881 iHeaderConverter.EncodeHeaderFieldL(aBufIn, rBufOut, iHeaderCharset, type, FieldIsEmailAddress()); |
|
1882 } |
|
1883 else if (infoArray->Count()) |
|
1884 { |
|
1885 // Use encoding information stored from incoming message. |
|
1886 iHeaderConverter.EncodeHeaderFieldL(aBufIn, rBufOut, infoArray, iState, aArrayVal); |
|
1887 } |
|
1888 else |
|
1889 { |
|
1890 // Dont encode |
|
1891 rBufOut.Copy(aBufIn); |
|
1892 } |
|
1893 } |
|
1894 |
|
1895 //********************************************************************************* |
|
1896 // Class CImSendMimeHeader Functions |
|
1897 //********************************************************************************* |
|
1898 |
|
1899 //--------------------------------------------------------------------------------- |
|
1900 CImSendMimeHeader* CImSendMimeHeader::NewLC(CImConvertHeader& aConverter, TMimeHeaderType aType) |
|
1901 //--------------------------------------------------------------------------------- |
|
1902 { |
|
1903 CImSendMimeHeader* self = new (ELeave) CImSendMimeHeader(aConverter, aType); |
|
1904 CleanupStack::PushL( self ); |
|
1905 return self; |
|
1906 } |
|
1907 |
|
1908 //--------------------------------------------------------------------------------- |
|
1909 CImSendMimeHeader* CImSendMimeHeader::NewL(CImConvertHeader& aConverter, TMimeHeaderType aType) |
|
1910 //--------------------------------------------------------------------------------- |
|
1911 { |
|
1912 CImSendMimeHeader* self = CImSendMimeHeader::NewLC(aConverter, aType); |
|
1913 CleanupStack::Pop(); |
|
1914 return self; |
|
1915 } |
|
1916 |
|
1917 //--------------------------------------------------------------------------------- |
|
1918 CImSendMimeHeader::CImSendMimeHeader(CImConvertHeader& aConverter, TMimeHeaderType aType) : |
|
1919 iConverter(aConverter), iBoundaryString(TPtrC8()), iMimeHeaderType(aType) |
|
1920 //--------------------------------------------------------------------------------- |
|
1921 { |
|
1922 } |
|
1923 |
|
1924 //--------------------------------------------------------------------------------- |
|
1925 CImSendMimeHeader::~CImSendMimeHeader() |
|
1926 //--------------------------------------------------------------------------------- |
|
1927 { |
|
1928 delete iCharsetString; |
|
1929 } |
|
1930 |
|
1931 //--------------------------------------------------------------------------------- |
|
1932 void CImSendMimeHeader::InitialiseL( CImMimeHeader& aMimeHeader, const TPtrC aFilename, |
|
1933 const TPtrC8& aBoundary, const TBool aEmbedded, |
|
1934 const TMsvEntry& aEntry, const TImEmailTransformingInfo& aInfo, |
|
1935 TBool aEmbeddedEmail) |
|
1936 //--------------------------------------------------------------------------------- |
|
1937 { |
|
1938 iMimeHeader=&aMimeHeader; |
|
1939 iBoundaryString.Set(aBoundary); |
|
1940 iFilename = aFilename; |
|
1941 iHeaderState=0; |
|
1942 iDealingWithAnEmbeddedEmail = aEmbeddedEmail; |
|
1943 iEntry=aEntry; |
|
1944 |
|
1945 TPtrC8 contentType = iMimeHeader->ContentType(); |
|
1946 iIsMultipart = (contentType.Length() && contentType==KImcvMultipart) ? ETrue:EFalse; |
|
1947 |
|
1948 // Set the EncodingType of whatever MIME part it is. |
|
1949 if (aEmbedded) |
|
1950 { |
|
1951 // Deals with the case of a message/rfc22 which is 7 bit. |
|
1952 iEncodingType=EEncodingTypeNone; |
|
1953 } |
|
1954 else if (aEntry.iType==KUidMsvMessageEntry && iMimeHeader->ContentType()!=KImcvMultipart) |
|
1955 { |
|
1956 // Special case: for non multipart HTML message. |
|
1957 if ( ((TMsvEmailEntry)aEntry).MHTMLEmail() ) |
|
1958 { |
|
1959 if ( aEntry.Attachment()) |
|
1960 { |
|
1961 iEncodingType=aInfo.AttachmentEncoding(); |
|
1962 SetCharsetUidL(aInfo.HeaderCharset()); |
|
1963 } |
|
1964 else |
|
1965 { |
|
1966 iEncodingType=aInfo.HTMLEncoding(); |
|
1967 SetCharsetUidL(aInfo.HTMLCharset()); |
|
1968 } |
|
1969 } |
|
1970 else if (contentType.CompareF(KImcvApplication)==0) |
|
1971 { |
|
1972 // So we know it is binary.. |
|
1973 iEncodingType=aInfo.AttachmentEncoding(); |
|
1974 SetCharsetUidL(aInfo.HeaderCharset()); |
|
1975 } |
|
1976 else |
|
1977 { |
|
1978 iEncodingType=aInfo.BodyTextEncoding(); |
|
1979 SetCharsetUidL(aInfo.BodyTextCharset()); |
|
1980 } |
|
1981 } |
|
1982 else |
|
1983 { |
|
1984 if (aEntry.iType == KUidMsvAttachmentEntry) |
|
1985 { |
|
1986 iEncodingType=aInfo.AttachmentEncoding(); |
|
1987 SetCharsetUidL(aInfo.HeaderCharset()); |
|
1988 } |
|
1989 else if (aEntry.iType == KUidMsvEmailHtmlEntry) |
|
1990 { |
|
1991 iEncodingType=aInfo.HTMLEncoding(); |
|
1992 SetCharsetUidL(aInfo.HTMLCharset()); |
|
1993 } |
|
1994 else |
|
1995 { |
|
1996 iEncodingType=aInfo.BodyTextEncoding(); |
|
1997 SetCharsetUidL(aInfo.BodyTextCharset()); |
|
1998 } |
|
1999 } |
|
2000 |
|
2001 TUint mimeCharset = iMimeHeader->MimeCharset(); |
|
2002 if (mimeCharset) |
|
2003 SetCharsetUidL(mimeCharset); // Ovverriding the info value passed in. |
|
2004 |
|
2005 if (aEmbedded) |
|
2006 { |
|
2007 iMimeHeader->SetContentTypeL(KImcvMessage); |
|
2008 iMimeHeader->SetContentSubTypeL(KImcvRfc822); |
|
2009 } |
|
2010 |
|
2011 if (iDealingWithAnEmbeddedEmail) |
|
2012 { |
|
2013 CImSendFile::EmbeddedEmailFilename(this->iEntry, this->iFilename); |
|
2014 } |
|
2015 |
|
2016 } |
|
2017 |
|
2018 //--------------------------------------------------------------------------------- |
|
2019 TInt CImSendMimeHeader::NextLine( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2020 //--------------------------------------------------------------------------------- |
|
2021 { |
|
2022 TInt advance = 0; |
|
2023 rOutputLine.Zero(); |
|
2024 |
|
2025 switch (iHeaderState) |
|
2026 { |
|
2027 case EMimeVersion: // Main only |
|
2028 if (iMimeHeaderType==EMainMimeHeader) |
|
2029 { |
|
2030 advance = MimeVersion(rOutputLine); |
|
2031 break; |
|
2032 } |
|
2033 advance++; // else continue.. |
|
2034 case EContentLanguage: // Main only |
|
2035 if (iMimeHeaderType==EMainMimeHeader) |
|
2036 { |
|
2037 advance = ContentLanguage( rOutputLine ); |
|
2038 break; |
|
2039 } |
|
2040 advance++; // else continue.. |
|
2041 case EDescription: // Part only |
|
2042 advance++; |
|
2043 if ( Description(rOutputLine) ) |
|
2044 break; |
|
2045 // else continue on to.. |
|
2046 case EContentType: |
|
2047 advance++; |
|
2048 if ( ContentType(rOutputLine) ) |
|
2049 break; |
|
2050 // else continue.. |
|
2051 case EBoundaryString: |
|
2052 if( iBoundaryString.Length() ) |
|
2053 { |
|
2054 advance = Boundary(rOutputLine); |
|
2055 break; |
|
2056 } |
|
2057 advance++; // else continue.. |
|
2058 case EDisposition: |
|
2059 if (iIsMultipart && !iDealingWithAnEmbeddedEmail) |
|
2060 advance++; |
|
2061 else if (Disposition(rOutputLine, advance)) |
|
2062 break; |
|
2063 // else continue.. |
|
2064 case ETransferEncoding: |
|
2065 advance++; |
|
2066 if ( !iIsMultipart && TransferEncoding(rOutputLine) ) |
|
2067 break; |
|
2068 // else continue.. |
|
2069 case ECRLF: |
|
2070 advance += AddCRLF(rOutputLine); |
|
2071 break; |
|
2072 default: |
|
2073 __ASSERT_DEBUG( ETrue, gPanic(EPanicInvalidHeaderState) ); |
|
2074 } |
|
2075 |
|
2076 iHeaderState += advance; |
|
2077 rPaddingCount = rOutputLine.Length(); |
|
2078 return (iHeaderState >= EEndOfMimeHeader ? KImAttFinished : KErrNone); |
|
2079 } |
|
2080 |
|
2081 |
|
2082 //--------------------------------------------------------------------------------- |
|
2083 void CImSendMimeHeader::AppendFilenameL( TDes8& rOutputLine ) const |
|
2084 //--------------------------------------------------------------------------------- |
|
2085 { |
|
2086 HBufC8* buf = HBufC8::NewL( iFilename.Length() ); |
|
2087 RBuf8 bufPtr(buf); |
|
2088 CleanupClosePushL(bufPtr); |
|
2089 iConverter.EncodeHeaderFieldL( iFilename, bufPtr, iCharsetUid, KDefaultSendingHeaderEncoding, EFalse); |
|
2090 rOutputLine.Append(KImcvEqualsQuote); |
|
2091 rOutputLine.Append( bufPtr ); |
|
2092 rOutputLine.Append(KImcvQuoteString); |
|
2093 CleanupStack::PopAndDestroy(&bufPtr); |
|
2094 } |
|
2095 |
|
2096 //--------------------------------------------------------------------------------- |
|
2097 void CImSendMimeHeader::SetCharsetUidL(const TUint aId) |
|
2098 //--------------------------------------------------------------------------------- |
|
2099 { |
|
2100 delete iCharsetString; |
|
2101 iCharsetString=NULL; |
|
2102 |
|
2103 iCharsetUid=aId; |
|
2104 |
|
2105 if (iCharsetUid==KUidMsvCharsetNone) |
|
2106 // Unknown charset, set string to original |
|
2107 iCharsetString = (iMimeHeader->GetContentTypeValue(KImcvCharset)).AllocL(); |
|
2108 else |
|
2109 { |
|
2110 if (!iCharsetUid) |
|
2111 iCharsetUid=iConverter.CharConv().DefaultCharset(); |
|
2112 |
|
2113 iCharsetString = iConverter.CharConv().GetMimeCharsetTextStringL(iCharsetUid); |
|
2114 } |
|
2115 } |
|
2116 |
|
2117 //--------------------------------------------------------------------------------- |
|
2118 TPtrC8 CImSendMimeHeader::GetCharsetString() const |
|
2119 //--------------------------------------------------------------------------------- |
|
2120 { |
|
2121 return *iCharsetString; |
|
2122 } |
|
2123 |
|
2124 |
|
2125 // Only calculates main header size |
|
2126 //--------------------------------------------------------------------------------- |
|
2127 TInt CImSendMimeHeader::Size() const |
|
2128 //--------------------------------------------------------------------------------- |
|
2129 { |
|
2130 TInt size=0; |
|
2131 |
|
2132 // MIME VERSION |
|
2133 size+=KImcvMimePrompt().Length() + |
|
2134 KImcvSpMimeVersion().Length() + 2; |
|
2135 |
|
2136 // CONTENT LANGUAGE |
|
2137 size+=KImcvContentLanguage().Length() + |
|
2138 KImcvDefaultLanguage().Length() + 2; |
|
2139 |
|
2140 // CONTENT TYPE |
|
2141 TPtrC8 contentType = iMimeHeader->ContentType(); |
|
2142 if (contentType.Length()!=0) |
|
2143 { |
|
2144 size += KImcvContentType().Length() + |
|
2145 contentType.Length() + 2; |
|
2146 |
|
2147 TPtrC8 contentSubType = iMimeHeader->ContentSubType(); |
|
2148 if ( contentSubType.Length() ) |
|
2149 { |
|
2150 size += KImcvForwardSlash().Length() + contentSubType.Length() + 2; |
|
2151 } |
|
2152 |
|
2153 if ( contentType.CompareF(KImcvText)==0 ) |
|
2154 { |
|
2155 size += 3 ; // space, =, semi colon |
|
2156 size += KImcvCharset().Length() + (GetCharsetString()).Length() + 2; |
|
2157 } |
|
2158 } |
|
2159 |
|
2160 // BOUNDARY |
|
2161 size+= CImSendMimeEmail::KBoundaryStringLength + GetCharsetString().Length() + 2; |
|
2162 |
|
2163 // TRANSFER ENCODING |
|
2164 TPtrC8 encodingType = EncodingType(); |
|
2165 if (encodingType.Length()) |
|
2166 size+= KImcvContentTransferEncoding().Length() + encodingType.Length() + 2; |
|
2167 |
|
2168 // CRLF |
|
2169 size+= 2; |
|
2170 |
|
2171 return size; |
|
2172 } |
|
2173 |
|
2174 |
|
2175 //********************************************************************************* |
|
2176 // Class CImSendRichText Functions |
|
2177 //********************************************************************************* |
|
2178 |
|
2179 //--------------------------------------------------------------------------------- |
|
2180 CImSendRichText* CImSendRichText::NewLC(CImConvertCharconv& aConv) |
|
2181 //--------------------------------------------------------------------------------- |
|
2182 { |
|
2183 CImSendRichText* self = new (ELeave) CImSendRichText(aConv); |
|
2184 CleanupStack::PushL( self ); |
|
2185 return self; |
|
2186 } |
|
2187 |
|
2188 //--------------------------------------------------------------------------------- |
|
2189 CImSendRichText* CImSendRichText::NewL(CImConvertCharconv& aConv) |
|
2190 //--------------------------------------------------------------------------------- |
|
2191 { |
|
2192 CImSendRichText* self = CImSendRichText::NewLC(aConv); |
|
2193 CleanupStack::Pop(); |
|
2194 return self; |
|
2195 } |
|
2196 |
|
2197 //--------------------------------------------------------------------------------- |
|
2198 CImSendRichText::CImSendRichText(CImConvertCharconv& aConv) : iConverter(aConv) |
|
2199 //--------------------------------------------------------------------------------- |
|
2200 { |
|
2201 } |
|
2202 |
|
2203 |
|
2204 //--------------------------------------------------------------------------------- |
|
2205 CImSendRichText::~CImSendRichText() |
|
2206 //--------------------------------------------------------------------------------- |
|
2207 { |
|
2208 delete iLeftOver; |
|
2209 delete iPlainBodyText; |
|
2210 iCurrentChunk.Close(); |
|
2211 } |
|
2212 |
|
2213 //--------------------------------------------------------------------------------- |
|
2214 TBool CImSendRichText::InitialiseL( CMsvServerEntry& aServerEntry, TImCodec& anEncoder, |
|
2215 TImEncodingType aType, TUint aCharset) |
|
2216 //--------------------------------------------------------------------------------- |
|
2217 { |
|
2218 TBool ret = 0; |
|
2219 iPos = 0; |
|
2220 delete iPlainBodyText; |
|
2221 iPlainBodyText = NULL; |
|
2222 iIsNewChunk = ETrue; |
|
2223 |
|
2224 iCurrentChunk.Close(); |
|
2225 iCurrentChunk.Create(KChunkSize); |
|
2226 |
|
2227 if (aServerEntry.HasStoreL()) |
|
2228 { |
|
2229 CMsvStore* store = aServerEntry.ReadStoreL(); |
|
2230 CleanupStack::PushL(store); |
|
2231 |
|
2232 ret = store->HasBodyTextL(); |
|
2233 if (ret) |
|
2234 { |
|
2235 // Initialize the plainbodytext message store for reading the bodytext. |
|
2236 iPlainBodyText = store->InitialisePlainBodyTextForReadL(KChunkSize); |
|
2237 iBodySize = iPlainBodyText->Size(); // Size() returns in no of bytes and the data is 16 bit formatted. |
|
2238 } |
|
2239 |
|
2240 CleanupStack::PopAndDestroy(store); |
|
2241 } |
|
2242 |
|
2243 if (aCharset ==KCharacterSetIdentifierIso88591 || aCharset== KCharacterSetIdentifierAscii) |
|
2244 { |
|
2245 aCharset=KCharacterSetIdentifierCodePage1252; |
|
2246 } |
|
2247 |
|
2248 iPreparedToConvert= iConverter.PrepareToConvertToFromOurCharsetL(aCharset); |
|
2249 |
|
2250 iBodyEncoding = aType; |
|
2251 iEncoder=&anEncoder; |
|
2252 |
|
2253 return ret; |
|
2254 } |
|
2255 |
|
2256 |
|
2257 |
|
2258 //--------------------------------------------------------------------------------- |
|
2259 TInt CImSendRichText::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2260 //--------------------------------------------------------------------------------- |
|
2261 { |
|
2262 __ASSERT_DEBUG( iPlainBodyText != NULL, gPanic(KPanicNoRichText) ); |
|
2263 |
|
2264 TInt noMoreChars= 0; |
|
2265 |
|
2266 switch (iBodyEncoding) |
|
2267 { |
|
2268 case EEncodingTypeQP: |
|
2269 noMoreChars = EncodeQPNextLineL(rOutputLine, rPaddingCount); |
|
2270 break; |
|
2271 case EEncodingTypeUU: |
|
2272 case EEncodingTypeBASE64: |
|
2273 noMoreChars = EncodeNextLineL(rOutputLine, rPaddingCount); |
|
2274 break; |
|
2275 case EEncodingTypeNone: |
|
2276 default: |
|
2277 NoEncodeNextLineL(rOutputLine, rPaddingCount); |
|
2278 } |
|
2279 |
|
2280 return noMoreChars; |
|
2281 } |
|
2282 |
|
2283 /** |
|
2284 Extract line from the chunk restored from Message Store |
|
2285 @param rOutputLine The output line to be sent. |
|
2286 @return void. |
|
2287 */ |
|
2288 void CImSendRichText::ExtractLineFromChunkL(TDes16& aOutputLine) |
|
2289 { |
|
2290 // Check if there is enough data in the chunk to extract a line from it. |
|
2291 if((iPos + iMaxLength) > iCurrentChunk.Length()) |
|
2292 { |
|
2293 iIsNewChunk = ETrue; |
|
2294 } |
|
2295 |
|
2296 // Restore the newchunk from the messagestore. |
|
2297 if(iIsNewChunk) |
|
2298 { |
|
2299 iIsNewChunk = EFalse; |
|
2300 |
|
2301 // Rearrange the remaining data from current chunk. |
|
2302 iCurrentChunk.Delete(0, iPos); |
|
2303 TInt currentChunkLength = iCurrentChunk.Length(); |
|
2304 |
|
2305 // Resize iCurrentChunk as per data left for send operation. |
|
2306 iCurrentChunk.ReAlloc(KChunkSize + currentChunkLength); |
|
2307 iCurrentChunk.SetMax(); |
|
2308 |
|
2309 TPtr16 restoredChunkPtr = iCurrentChunk.MidTPtr(currentChunkLength); |
|
2310 |
|
2311 // Restore the chunk from Message Store. |
|
2312 iPlainBodyText->NextChunkL(restoredChunkPtr); |
|
2313 // if NextChunkL did not return a full size chunk, then need to update the size of iCurrentChunk |
|
2314 if(restoredChunkPtr.Length() != KChunkSize) |
|
2315 { |
|
2316 iCurrentChunk.SetLength(currentChunkLength + restoredChunkPtr.Length()); |
|
2317 } |
|
2318 iPos = 0; |
|
2319 } |
|
2320 |
|
2321 // Check whether chunk length is not greater than (iPos+iMaxlength). |
|
2322 if( (iPos + iMaxLength) >= iCurrentChunk.Length() ) |
|
2323 { |
|
2324 aOutputLine.Copy(iCurrentChunk.MidTPtr(iPos)); |
|
2325 } |
|
2326 else |
|
2327 { |
|
2328 aOutputLine.Copy(iCurrentChunk.MidTPtr(iPos, iMaxLength)); |
|
2329 } |
|
2330 } |
|
2331 |
|
2332 |
|
2333 // Convert character set of line |
|
2334 //--------------------------------------------------------------------------------- |
|
2335 TInt CImSendRichText::ConvertNextLineL( const TDesC& aInput, TDes8& rOutput) |
|
2336 //--------------------------------------------------------------------------------- |
|
2337 { |
|
2338 TInt unconvertedChars=0; |
|
2339 TInt pos=0; |
|
2340 if (iPreparedToConvert) |
|
2341 iConverter.ConvertFromOurCharsetL(aInput, rOutput, unconvertedChars, pos); |
|
2342 else |
|
2343 rOutput.Copy(aInput); |
|
2344 |
|
2345 return pos; |
|
2346 } |
|
2347 |
|
2348 //--------------------------------------------------------------------------------- |
|
2349 TInt CImSendRichText::NoEncodeNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2350 //--------------------------------------------------------------------------------- |
|
2351 { |
|
2352 rOutputLine.Zero(); |
|
2353 |
|
2354 // grab a few characters from the buffer |
|
2355 // (making sure this is more than we will ever need for the current line). |
|
2356 |
|
2357 TBuf<2*KMaxIMailBodyLineLength> source; |
|
2358 |
|
2359 iMaxLength = iPos+2*KMaxIMailBodyLineLength > iBodySize ? |
|
2360 iBodySize-iPos : 2*KMaxIMailBodyLineLength; |
|
2361 |
|
2362 // Extract line from chunk restored from store. |
|
2363 ExtractLineFromChunkL(source); |
|
2364 HBufC* output = HBufC::NewLC(rOutputLine.MaxLength()); |
|
2365 |
|
2366 TPtr outPtr(output->Des()); |
|
2367 TInt ret = RemoveControlCharacters( source, outPtr, rPaddingCount ); |
|
2368 |
|
2369 ConvertNextLineL( outPtr, rOutputLine); |
|
2370 |
|
2371 CleanupStack::PopAndDestroy(output); |
|
2372 return ret; |
|
2373 } |
|
2374 |
|
2375 |
|
2376 //--------------------------------------------------------------------------------- |
|
2377 TInt CImSendRichText::RemoveControlCharacters( const TDesC& aInputLine, TDes& rOutputLine, TInt& rPaddingCount ) |
|
2378 //--------------------------------------------------------------------------------- |
|
2379 { |
|
2380 TInt written=0; // number of characters written to the current line |
|
2381 |
|
2382 TLex lexSource(aInputLine); |
|
2383 TDes& ptr = rOutputLine; |
|
2384 |
|
2385 while ( (written<KMaxIMailBodyLineLength) && !lexSource.Eos() ) |
|
2386 { |
|
2387 // first check whether we're at a line break |
|
2388 if ( IsEOL(lexSource.Peek()) ) |
|
2389 { |
|
2390 Append( ptr, (TDesC8&) KImcvCRLF); |
|
2391 written+=2; |
|
2392 |
|
2393 // we just added an extra character |
|
2394 rPaddingCount+=1; |
|
2395 lexSource.Inc(); |
|
2396 break; |
|
2397 } |
|
2398 else if ( SmartBreak(written, lexSource.Remainder()) ) |
|
2399 { |
|
2400 ptr.Append( lexSource.Peek() ); |
|
2401 Append( ptr, (TDesC8&) KImcvCRLF); |
|
2402 written+=3; |
|
2403 rPaddingCount+=2; |
|
2404 lexSource.Inc(); |
|
2405 break; |
|
2406 } |
|
2407 else if ( written >= KMaxIMailBodyLineLength-1 ) |
|
2408 // make sure we don't exceed 76 chars per line of encoded text (must allow for CRLF) |
|
2409 { |
|
2410 Append( ptr, (TDesC8&) KImcvCRLF); |
|
2411 written+=2; |
|
2412 rPaddingCount+=2; |
|
2413 } |
|
2414 // check whether we have a whacky control character from CEditableText |
|
2415 else if ( lexSource.Peek()<KImcvSP ) |
|
2416 { |
|
2417 TUint8 replacement = ReplacementChar( lexSource.Peek() ); |
|
2418 if (replacement) // potentially ditch the character altogther |
|
2419 { |
|
2420 ptr.Append( replacement ); |
|
2421 written++; |
|
2422 } |
|
2423 else |
|
2424 rPaddingCount-=1; |
|
2425 } |
|
2426 else |
|
2427 { |
|
2428 ptr.Append( lexSource.Peek() ); |
|
2429 written++; |
|
2430 } |
|
2431 |
|
2432 // advance to next source character |
|
2433 lexSource.Inc(); |
|
2434 |
|
2435 } // while |
|
2436 |
|
2437 iPos += written - rPaddingCount; |
|
2438 rPaddingCount = rPaddingCount >=0 ? rPaddingCount : 0; |
|
2439 |
|
2440 // set up the output parameter & return value |
|
2441 return (iPos >= iBodySize ? 1 : 0); |
|
2442 } |
|
2443 |
|
2444 //--------------------------------------------------------------------------------- |
|
2445 TInt CImSendRichText::EncodeNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2446 //--------------------------------------------------------------------------------- |
|
2447 { |
|
2448 rOutputLine.Zero(); |
|
2449 TInt sourceLength=0; |
|
2450 |
|
2451 HBufC8* output = HBufC8::NewLC(rOutputLine.MaxLength()); |
|
2452 TPtr8 outPtr(output->Des()); |
|
2453 |
|
2454 TBuf<KMaxIMailBodyLineLength+1> source; |
|
2455 |
|
2456 iMaxLength = iPos+KMaxIMailBodyLineLength > iBodySize ? |
|
2457 iBodySize-iPos : KMaxIMailBodyLineLength; |
|
2458 |
|
2459 TInt leftOverLength= (iLeftOver) ? (*iLeftOver).Length() : 0 ; |
|
2460 if (leftOverLength < KDecodeLineLength && iPos<iBodySize ) |
|
2461 { |
|
2462 // Extract line from chunk restored from store. |
|
2463 ExtractLineFromChunkL(source); |
|
2464 sourceLength=source.Length(); |
|
2465 |
|
2466 // Character conversion |
|
2467 ConvertNextLineL( source, outPtr ); |
|
2468 |
|
2469 ConvertLineBreaks(source, ETrue); |
|
2470 } |
|
2471 |
|
2472 if (iLeftOver) |
|
2473 { |
|
2474 outPtr.Insert(0, *iLeftOver); |
|
2475 delete iLeftOver; |
|
2476 iLeftOver=NULL; |
|
2477 } |
|
2478 |
|
2479 TInt rem = outPtr.Length() - KDecodeLineLength; |
|
2480 if (rem>0) |
|
2481 { |
|
2482 iLeftOver=(outPtr.Right(rem)).AllocL(); |
|
2483 outPtr.SetLength(KDecodeLineLength); |
|
2484 } |
|
2485 |
|
2486 if (outPtr.Length()) |
|
2487 iEncoder->Encode(outPtr, rOutputLine); |
|
2488 |
|
2489 if (source.Length()) // some text has bee extracted from the rich text store |
|
2490 iPos +=sourceLength; |
|
2491 |
|
2492 CleanupStack::PopAndDestroy(output); |
|
2493 |
|
2494 rPaddingCount=rOutputLine.Length(); |
|
2495 |
|
2496 // set up the output parameter & return value |
|
2497 return iLeftOver ? 0 : (iPos >= iBodySize ? 1 : 0); |
|
2498 } |
|
2499 |
|
2500 |
|
2501 //--------------------------------------------------------------------------------- |
|
2502 TInt CImSendRichText::EncodeQPNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2503 //--------------------------------------------------------------------------------- |
|
2504 { |
|
2505 rOutputLine.Zero(); |
|
2506 iUseRichText=ETrue; |
|
2507 TInt sourceUsed=0; |
|
2508 TInt crlfPadding=0; |
|
2509 TBool unicodeChars=EFalse; |
|
2510 TInt originalSource=0; |
|
2511 |
|
2512 HBufC8* output = HBufC8::NewLC(rOutputLine.MaxLength()); |
|
2513 TPtr8 outPtr(output->Des()); |
|
2514 |
|
2515 TBuf<KMaxIMailBodyLineLength+1> source; |
|
2516 |
|
2517 iMaxLength = iPos+KMaxIMailBodyLineLength > iBodySize ? |
|
2518 iBodySize-iPos : KMaxIMailBodyLineLength; |
|
2519 |
|
2520 TInt leftOverLength= (iLeftOver) ? (*iLeftOver).Length() : 0 ; |
|
2521 if (leftOverLength < KMaxIMailBodyLineLength && iPos<iBodySize ) |
|
2522 { |
|
2523 // Extract line from chunk restored from store. |
|
2524 ExtractLineFromChunkL(source); |
|
2525 crlfPadding=ConvertLineBreaks(source, ETrue); |
|
2526 originalSource=source.Length()-crlfPadding; |
|
2527 |
|
2528 // Character conversion |
|
2529 ConvertNextLineL( source, outPtr ); |
|
2530 |
|
2531 unicodeChars = (outPtr.Length() > source.Length()) ? ETrue:EFalse; |
|
2532 } |
|
2533 |
|
2534 if (iLeftOver) |
|
2535 outPtr.Insert(0, *iLeftOver); |
|
2536 |
|
2537 // QP encode line |
|
2538 ((TImCodecQP*) iEncoder)->AddPlainChar(KImcvPlainRichText); |
|
2539 |
|
2540 |
|
2541 TInt written = iEncoder->Encode(outPtr, rOutputLine); |
|
2542 TInt leftover = outPtr.Length() - written; |
|
2543 |
|
2544 if (iLeftOver) |
|
2545 { |
|
2546 TInt rem = leftOverLength - written; |
|
2547 if (rem>0) |
|
2548 { |
|
2549 // Not all of the leftOver buffer was used. |
|
2550 iLeftOver->Des().Copy((*iLeftOver).Right(rem)); |
|
2551 sourceUsed=0; |
|
2552 } |
|
2553 else |
|
2554 { |
|
2555 delete iLeftOver; |
|
2556 iLeftOver=NULL; |
|
2557 if(leftover) |
|
2558 sourceUsed=rem*(-1); |
|
2559 else |
|
2560 sourceUsed=originalSource; |
|
2561 } |
|
2562 } |
|
2563 else if (leftover) |
|
2564 sourceUsed=written; |
|
2565 else |
|
2566 sourceUsed=originalSource; |
|
2567 |
|
2568 if (unicodeChars && !iLeftOver && leftover>0) |
|
2569 { |
|
2570 iLeftOver=(outPtr.Right(leftover)).AllocL(); |
|
2571 iPos += originalSource; |
|
2572 } |
|
2573 else if (source.Length()) // some text has bee extracted from the rich text store |
|
2574 iPos +=sourceUsed; |
|
2575 |
|
2576 CleanupStack::PopAndDestroy(output); |
|
2577 |
|
2578 rPaddingCount=rOutputLine.Length(); |
|
2579 |
|
2580 // set up the output parameter & return value |
|
2581 return iLeftOver ? 0 : (iPos >= iBodySize ? 1 : 0); |
|
2582 } |
|
2583 |
|
2584 |
|
2585 |
|
2586 //--------------------------------------------------------------------------------- |
|
2587 TBool CImSendRichText::SmartBreak( TInt aWritten, const TUint8* aSource, TInt aMaxLength ) |
|
2588 //--------------------------------------------------------------------------------- |
|
2589 { |
|
2590 // Check whether the current char is breakable. |
|
2591 |
|
2592 TBool ret = EFalse; |
|
2593 TUint8 ch = *aSource; |
|
2594 |
|
2595 if ( IsBreakable(ch) ) |
|
2596 { |
|
2597 // Scan ahead looking for the next breakable char |
|
2598 |
|
2599 const TUint8* lookAhead = aSource+1; |
|
2600 TBool found = EFalse; |
|
2601 while ( !found && lookAhead-aSource <= aMaxLength ) |
|
2602 { |
|
2603 found = IsBreakable(*lookAhead); |
|
2604 if (!found) |
|
2605 lookAhead++; |
|
2606 } |
|
2607 |
|
2608 // There's another breakable char before the end of the text - we need to break now |
|
2609 // if it's too far away and only if the non-breakable text fits on an output line. |
|
2610 |
|
2611 ret = (aWritten+(lookAhead-aSource) >= KMaxIMailBodyLineLength |
|
2612 && (lookAhead-aSource) < KMaxIMailBodyLineLength); |
|
2613 } |
|
2614 |
|
2615 return ret; |
|
2616 } |
|
2617 |
|
2618 |
|
2619 //--------------------------------------------------------------------------------- |
|
2620 TBool CImSendRichText::SmartBreak( TInt aWritten, const TDesC& aSource ) |
|
2621 //--------------------------------------------------------------------------------- |
|
2622 { |
|
2623 TBool ret = EFalse; |
|
2624 TLex source( aSource ); |
|
2625 |
|
2626 // only check for whether we should break if the current char is breakable |
|
2627 if ( IsBreakable(source.Peek()) ) |
|
2628 { |
|
2629 // scan ahead looking for the next breakable char |
|
2630 source.Inc(); |
|
2631 TBool found = EFalse; |
|
2632 TInt encodingOffset=(IsPlain(source.Peek()) ? 0 : 2); |
|
2633 while ( !found && !source.Eos() ) |
|
2634 { |
|
2635 found = IsBreakable(source.Peek()); |
|
2636 if (!found) |
|
2637 { |
|
2638 encodingOffset+=(IsPlain(source.Peek()) ? 0 : 2); |
|
2639 source.Inc(); |
|
2640 } |
|
2641 } |
|
2642 // there's another breakable char before the end of the text |
|
2643 // - we need to break now if it's too far away |
|
2644 // but only if the non-breakable text fits on a line itself. |
|
2645 |
|
2646 ret = ((aWritten+source.Offset()+encodingOffset) > KMaxIMailBodyLineLength-4); |
|
2647 } |
|
2648 |
|
2649 return ret; |
|
2650 } |
|
2651 |
|
2652 //********************************************************************************* |
|
2653 // Class CImSendFile Functions |
|
2654 //********************************************************************************* |
|
2655 |
|
2656 //--------------------------------------------------------------------------------- |
|
2657 CImSendFile* CImSendFile::NewLC(RFs& anFs, CImConvertCharconv& aCharConv) |
|
2658 //--------------------------------------------------------------------------------- |
|
2659 { |
|
2660 CImSendFile* self = new (ELeave) CImSendFile(anFs, aCharConv); |
|
2661 CleanupStack::PushL( self ); |
|
2662 self->ConstructL(); |
|
2663 return self; |
|
2664 } |
|
2665 |
|
2666 //--------------------------------------------------------------------------------- |
|
2667 CImSendFile* CImSendFile::NewL(RFs& anFs, CImConvertCharconv& aCharConv) |
|
2668 //--------------------------------------------------------------------------------- |
|
2669 { |
|
2670 CImSendFile* self = CImSendFile::NewLC(anFs, aCharConv); |
|
2671 CleanupStack::Pop(); |
|
2672 return self; |
|
2673 } |
|
2674 |
|
2675 /** |
|
2676 Intended Usage : Second phase of two-phase construction method. Does any |
|
2677 allocations required to fully construct the object. |
|
2678 @since 7.0s |
|
2679 @leave KErrNoMemory. |
|
2680 @pre First phase of construction is complete |
|
2681 @post The object is fully constructed and initialised. |
|
2682 */ |
|
2683 //--------------------------------------------------------------------------------- |
|
2684 void CImSendFile::ConstructL() |
|
2685 //--------------------------------------------------------------------------------- |
|
2686 { |
|
2687 iAttachmentFile = new(ELeave) TImAttachmentFile(CONST_CAST(RFs&,iFs)); |
|
2688 } |
|
2689 |
|
2690 //--------------------------------------------------------------------------------- |
|
2691 CImSendFile::CImSendFile(RFs& anFs, CImConvertCharconv& aCharConv) |
|
2692 :iFs(anFs), iConverter(aCharConv), iAttachmentFile(NULL) |
|
2693 //--------------------------------------------------------------------------------- |
|
2694 { |
|
2695 } |
|
2696 |
|
2697 //--------------------------------------------------------------------------------- |
|
2698 void CImSendFile::InitialiseL( CMsvServerEntry& aServerEntry, TImFileCodec& anEncoder) |
|
2699 //--------------------------------------------------------------------------------- |
|
2700 { |
|
2701 iEncoder = &anEncoder; |
|
2702 iAttachmentState=ENextFile; |
|
2703 Filename(aServerEntry, iAttachmentInfo); |
|
2704 } |
|
2705 |
|
2706 //--------------------------------------------------------------------------------- |
|
2707 CImSendFile::~CImSendFile() |
|
2708 //--------------------------------------------------------------------------------- |
|
2709 { |
|
2710 delete iAttachmentFile; |
|
2711 } |
|
2712 |
|
2713 //--------------------------------------------------------------------------------- |
|
2714 TInt CImSendFile::NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ) |
|
2715 //--------------------------------------------------------------------------------- |
|
2716 { |
|
2717 rOutputLine.Zero(); |
|
2718 |
|
2719 do |
|
2720 { |
|
2721 switch(iAttachmentState) |
|
2722 { |
|
2723 case ENextFile: |
|
2724 iAttachmentState=EPrefixLines; |
|
2725 break; |
|
2726 case EPrefixLines: |
|
2727 if (iEncoder->PrefixNextLineL(rOutputLine, iAttachmentInfo.iName, rPaddingCount)==KImAttFinished) |
|
2728 iAttachmentState=EEncodeFile; |
|
2729 break; |
|
2730 case EEncodeFile: |
|
2731 if (iAttachmentFile->ReadFile( iSourceLine, KDecodeLineLength)) |
|
2732 { |
|
2733 iAttachmentState=EPostfixLines; |
|
2734 } |
|
2735 else if (iSourceLine.Length()!=0) |
|
2736 { |
|
2737 iEncoder->Encode(iSourceLine, rOutputLine); |
|
2738 rPaddingCount=rOutputLine.Length()-(iSourceLine.Length()); |
|
2739 } |
|
2740 else |
|
2741 { |
|
2742 iAttachmentState=EPostfixLines; |
|
2743 } |
|
2744 break; |
|
2745 case EPostfixLines: |
|
2746 if (iEncoder->PostfixNextLine(rOutputLine, rPaddingCount)==KImAttFinished) |
|
2747 iAttachmentState=EEndOfAttachments; |
|
2748 break; |
|
2749 case EEndOfAttachments: |
|
2750 iAttachmentFile->CloseFile(); |
|
2751 iAttachmentState=ECloseDelimiter; |
|
2752 break; |
|
2753 case ECloseDelimiter: |
|
2754 // Dependent on encoding type |
|
2755 iAttachmentState=ECRLFLine; |
|
2756 break; |
|
2757 case ECRLFLine: |
|
2758 AddCRLF(rOutputLine, rPaddingCount); |
|
2759 rPaddingCount=rOutputLine.Length(); |
|
2760 iAttachmentState=EEnd; |
|
2761 break; |
|
2762 } |
|
2763 |
|
2764 } while(!rOutputLine.Length()); |
|
2765 |
|
2766 return (iAttachmentState==EEnd ? KImAttFinished : KErrNone); |
|
2767 } |
|
2768 |
|
2769 //--------------------------------------------------------------------------------- |
|
2770 const TFileName& CImSendFile::Filename() const |
|
2771 //--------------------------------------------------------------------------------- |
|
2772 { |
|
2773 return iAttachmentInfo.iName; |
|
2774 } |
|
2775 |
|
2776 TFileName& CImSendFile::Filename(CMsvServerEntry& aEntry, SAttachmentInfo& aInfo) |
|
2777 { |
|
2778 TMsvEntry entry = aEntry.Entry(); |
|
2779 aInfo.iSize=entry.iSize; |
|
2780 |
|
2781 CMsvStore* store = aEntry.ReadStoreL(); |
|
2782 CleanupStack::PushL(store); |
|
2783 MMsvAttachmentManager& manager=store->AttachmentManagerL(); |
|
2784 if(manager.AttachmentCount()) |
|
2785 { |
|
2786 CMsvAttachment* attachment = manager.GetAttachmentInfoL(0); |
|
2787 CleanupStack::PushL(attachment); |
|
2788 TParsePtrC parse(attachment->FilePath()); |
|
2789 aInfo.iPath=parse.DriveAndPath(); |
|
2790 aInfo.iName=parse.NameAndExt(); |
|
2791 iAttachmentFile->CloseFile(); |
|
2792 RFile file=manager.GetAttachmentFileL(0); |
|
2793 iAttachmentFile->SetFileHandle(file,TImAttachmentFile::EImFileRead); |
|
2794 CleanupStack::PopAndDestroy(attachment); |
|
2795 } |
|
2796 CleanupStack::PopAndDestroy(store); |
|
2797 return aInfo.iName; |
|
2798 } |
|
2799 |
|
2800 //--------------------------------------------------------------------------------- |
|
2801 void CImSendFile::EmbeddedEmailFilename(TMsvEntry& aEntry, TFileName& aFileName) |
|
2802 //--------------------------------------------------------------------------------- |
|
2803 { |
|
2804 if (aEntry.iDescription.Length()) |
|
2805 { |
|
2806 aFileName = aEntry.iDescription; |
|
2807 if ( (aFileName.MaxLength() - aFileName.Length()) >= KImcvEmbeddedEmailFilenameExtension().Length() ) |
|
2808 { |
|
2809 aFileName.Insert(aFileName.Length(), KImcvEmbeddedEmailFilenameExtension); |
|
2810 } |
|
2811 else |
|
2812 { |
|
2813 aFileName = KImcvEmbeddedEmailDefaultFilename; |
|
2814 aFileName.Insert(aFileName.Length(), KImcvEmbeddedEmailFilenameExtension); |
|
2815 } |
|
2816 } |
|
2817 } |
|
2818 |
|
2819 |
|
2820 |
|
2821 |
|
2822 //********************************************************************************* |
|
2823 // Class CImCalculateMsgSize Functions |
|
2824 //********************************************************************************* |
|
2825 |
|
2826 //--------------------------------------------------------------------------------- |
|
2827 EXPORT_C CImCalculateMsgSize* CImCalculateMsgSize::NewL(RFs &anFs,CMsvServerEntry& aServerEntry) |
|
2828 //--------------------------------------------------------------------------------- |
|
2829 { |
|
2830 CImCalculateMsgSize* self=new (ELeave) CImCalculateMsgSize(anFs, aServerEntry); |
|
2831 CleanupStack::PushL(self); |
|
2832 self->ConstructL(); |
|
2833 CleanupStack::Pop(); |
|
2834 return self; |
|
2835 } |
|
2836 |
|
2837 |
|
2838 //--------------------------------------------------------------------------------- |
|
2839 CImCalculateMsgSize::CImCalculateMsgSize(RFs &anFs,CMsvServerEntry& aServerEntry) |
|
2840 : CMsgActive(EPriorityStandard), iFs(anFs),iServerEntry(aServerEntry) |
|
2841 //--------------------------------------------------------------------------------- |
|
2842 { |
|
2843 } |
|
2844 |
|
2845 |
|
2846 //--------------------------------------------------------------------------------- |
|
2847 void CImCalculateMsgSize::ConstructL() |
|
2848 //--------------------------------------------------------------------------------- |
|
2849 { |
|
2850 CActiveScheduler::Add(this); |
|
2851 } |
|
2852 |
|
2853 //--------------------------------------------------------------------------------- |
|
2854 EXPORT_C CImCalculateMsgSize::~CImCalculateMsgSize() |
|
2855 //--------------------------------------------------------------------------------- |
|
2856 { |
|
2857 Cancel(); |
|
2858 Reset(); |
|
2859 } |
|
2860 |
|
2861 |
|
2862 //--------------------------------------------------------------------------------- |
|
2863 EXPORT_C void CImCalculateMsgSize::StartL(TRequestStatus& aStatus,TMsvId aMsvId, |
|
2864 TImSendMethod aAlgorithm, TTime& aTimeDate, const TDesC& aDomainName, |
|
2865 const TUint aCharset) |
|
2866 //--------------------------------------------------------------------------------- |
|
2867 { |
|
2868 Reset(); |
|
2869 //initialise |
|
2870 iMailString.Zero(); |
|
2871 iFinished=KErrNone; |
|
2872 iSize=0; |
|
2873 // |
|
2874 iSendMsg=CImSendMessage::NewL(iServerEntry); |
|
2875 iSendMsg->InitialiseL(aMsvId, aAlgorithm, aTimeDate, aDomainName, aCharset, ESendNoCopy); |
|
2876 // |
|
2877 #if defined (_DEBUG) |
|
2878 TBuf<25> KFileName=_L("c:\\mailtest\\imcv\\size.txt"); |
|
2879 TInt err=iFile.Open(iFs, KFileName, EFileStreamText|EFileWrite|EFileShareAny); |
|
2880 if (err==KErrNotFound) // file does not exist - create it |
|
2881 { |
|
2882 err = iFile.Create(iFs, KFileName, EFileStreamText|EFileWrite|EFileShareAny); |
|
2883 } |
|
2884 if (err == KErrNone) |
|
2885 { |
|
2886 iFileOpen=ETrue; |
|
2887 } |
|
2888 #endif |
|
2889 Queue(aStatus); |
|
2890 TRequestStatus* status=&iStatus; |
|
2891 User::RequestComplete(status,0); |
|
2892 SetActive(); |
|
2893 } |
|
2894 |
|
2895 |
|
2896 //--------------------------------------------------------------------------------- |
|
2897 void CImCalculateMsgSize::Reset() |
|
2898 //--------------------------------------------------------------------------------- |
|
2899 { |
|
2900 delete iSendMsg; |
|
2901 iSendMsg=NULL; |
|
2902 #if defined (_DEBUG) |
|
2903 if (iFileOpen) |
|
2904 { |
|
2905 iFile.Close(); |
|
2906 iFileOpen=EFalse; |
|
2907 } |
|
2908 #endif |
|
2909 } |
|
2910 |
|
2911 //--------------------------------------------------------------------------------- |
|
2912 void CImCalculateMsgSize::DoRunL() |
|
2913 //--------------------------------------------------------------------------------- |
|
2914 { |
|
2915 if (iStatus.Int()!=KErrNone || iFinished==KImCvFinished) |
|
2916 return; |
|
2917 TInt count=0; |
|
2918 iFinished=iSendMsg->NextLineL(iMailString,count); |
|
2919 iSize+=iMailString.Length(); |
|
2920 #if defined (_DEBUG) |
|
2921 if (iFileOpen) |
|
2922 { |
|
2923 iFile.Write(iMailString); |
|
2924 } |
|
2925 #endif |
|
2926 SetActive(); |
|
2927 TRequestStatus* status=&iStatus; |
|
2928 User::RequestComplete(status,0); |
|
2929 } |
|
2930 |
|
2931 |
|
2932 //--------------------------------------------------------------------------------- |
|
2933 void CImCalculateMsgSize::DoCancel() |
|
2934 //--------------------------------------------------------------------------------- |
|
2935 { |
|
2936 CMsgActive::DoCancel(); |
|
2937 } |
|
2938 |