summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/abstractmail.cpp15
-rw-r--r--noncore/net/mail/abstractmail.h3
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.cpp15
-rw-r--r--noncore/net/mail/libmailwrapper/abstractmail.h3
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.cpp40
-rw-r--r--noncore/net/mail/libmailwrapper/pop3wrapper.h7
-rw-r--r--noncore/net/mail/pop3wrapper.cpp40
-rw-r--r--noncore/net/mail/pop3wrapper.h7
8 files changed, 112 insertions, 18 deletions
diff --git a/noncore/net/mail/abstractmail.cpp b/noncore/net/mail/abstractmail.cpp
index 3d76c96..626b9aa 100644
--- a/noncore/net/mail/abstractmail.cpp
+++ b/noncore/net/mail/abstractmail.cpp
@@ -1,30 +1,32 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mailtypes.h" 4#include "mailtypes.h"
5 5
6#include <qstring.h> 6#include <qstring.h>
7#include <qfile.h>
8#include <qtextstream.h>
7#include <stdlib.h> 9#include <stdlib.h>
8#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
9 11
10AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 12AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
11{ 13{
12 return new IMAPwrapper(a); 14 return new IMAPwrapper(a);
13} 15}
14 16
15AbstractMail* AbstractMail::getWrapper(POP3account *a) 17AbstractMail* AbstractMail::getWrapper(POP3account *a)
16{ 18{
17 return new POP3wrapper(a); 19 return new POP3wrapper(a);
18} 20}
19 21
20encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 22encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
21{ 23{
22 qDebug("Decode string start"); 24 qDebug("Decode string start");
23 char*result_text; 25 char*result_text;
24 size_t index = 0; 26 size_t index = 0;
25 /* reset for recursive use! */ 27 /* reset for recursive use! */
26 size_t target_length = 0; 28 size_t target_length = 0;
27 result_text = 0; 29 result_text = 0;
28 int mimetype = MAILMIME_MECHANISM_7BIT; 30 int mimetype = MAILMIME_MECHANISM_7BIT;
29 if (enc.lower()=="quoted-printable") { 31 if (enc.lower()=="quoted-printable") {
30 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 32 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
@@ -45,24 +47,37 @@ encodedString* AbstractMail::decode_String(const encodedString*text,const QStrin
45 } 47 }
46 qDebug("Decode string finished"); 48 qDebug("Decode string finished");
47 return result; 49 return result;
48} 50}
49 51
50QString AbstractMail::convert_String(const char*text) 52QString AbstractMail::convert_String(const char*text)
51{ 53{
52 size_t index = 0; 54 size_t index = 0;
53 char*res = 0; 55 char*res = 0;
54 56
55 /* attention - doesn't work with arm systems! */ 57 /* attention - doesn't work with arm systems! */
56 int err = mailmime_encoded_phrase_parse("iso-8859-1", 58 int err = mailmime_encoded_phrase_parse("iso-8859-1",
57 text, strlen(text),&index, "iso-8859-1",&res); 59 text, strlen(text),&index, "iso-8859-1",&res);
58 if (err != MAILIMF_NO_ERROR) { 60 if (err != MAILIMF_NO_ERROR) {
59 if (res) free(res); 61 if (res) free(res);
60 return QString(text); 62 return QString(text);
61 } 63 }
62 if (res) { 64 if (res) {
63 QString result(res); 65 QString result(res);
64 free(res); 66 free(res);
65 return result; 67 return result;
66 } 68 }
67 return QString(text); 69 return QString(text);
68} 70}
71
72/* cp & paste from launcher */
73QString AbstractMail::gen_attachment_id()
74{
75 QFile file( "/proc/sys/kernel/random/uuid" );
76 if (!file.open(IO_ReadOnly ) )
77 return QString::null;
78
79 QTextStream stream(&file);
80
81 return "{" + stream.read().stripWhiteSpace() + "}";
82}
83
diff --git a/noncore/net/mail/abstractmail.h b/noncore/net/mail/abstractmail.h
index c16e9c0..8dd2e12 100644
--- a/noncore/net/mail/abstractmail.h
+++ b/noncore/net/mail/abstractmail.h
@@ -9,28 +9,31 @@ class RecBody;
9class RecPart; 9class RecPart;
10class IMAPwrapper; 10class IMAPwrapper;
11class POP3wrapper; 11class POP3wrapper;
12class Folder; 12class Folder;
13class encodedString; 13class encodedString;
14 14
15class AbstractMail:public QObject 15class AbstractMail:public QObject
16{ 16{
17 Q_OBJECT 17 Q_OBJECT
18public: 18public:
19 AbstractMail(){}; 19 AbstractMail(){};
20 virtual ~AbstractMail(){} 20 virtual ~AbstractMail(){}
21 virtual QList<Folder>* listFolders()=0; 21 virtual QList<Folder>* listFolders()=0;
22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; 22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0;
23 virtual RecBody fetchBody(const RecMail&mail)=0; 23 virtual RecBody fetchBody(const RecMail&mail)=0;
24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0; 24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0;
25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0; 25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0; 26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
27 27
28 virtual void deleteMail(const RecMail&mail)=0; 28 virtual void deleteMail(const RecMail&mail)=0;
29 virtual void answeredMail(const RecMail&mail)=0; 29 virtual void answeredMail(const RecMail&mail)=0;
30 30
31 static AbstractMail* getWrapper(IMAPaccount *a); 31 static AbstractMail* getWrapper(IMAPaccount *a);
32 static AbstractMail* getWrapper(POP3account *a); 32 static AbstractMail* getWrapper(POP3account *a);
33
34protected:
33 static encodedString*decode_String(const encodedString*text,const QString&enc); 35 static encodedString*decode_String(const encodedString*text,const QString&enc);
34 static QString convert_String(const char*text); 36 static QString convert_String(const char*text);
37 static QString gen_attachment_id();
35}; 38};
36#endif 39#endif
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.cpp b/noncore/net/mail/libmailwrapper/abstractmail.cpp
index 3d76c96..626b9aa 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.cpp
+++ b/noncore/net/mail/libmailwrapper/abstractmail.cpp
@@ -1,30 +1,32 @@
1#include "abstractmail.h" 1#include "abstractmail.h"
2#include "imapwrapper.h" 2#include "imapwrapper.h"
3#include "pop3wrapper.h" 3#include "pop3wrapper.h"
4#include "mailtypes.h" 4#include "mailtypes.h"
5 5
6#include <qstring.h> 6#include <qstring.h>
7#include <qfile.h>
8#include <qtextstream.h>
7#include <stdlib.h> 9#include <stdlib.h>
8#include <libetpan/mailmime_content.h> 10#include <libetpan/mailmime_content.h>
9 11
10AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) 12AbstractMail* AbstractMail::getWrapper(IMAPaccount *a)
11{ 13{
12 return new IMAPwrapper(a); 14 return new IMAPwrapper(a);
13} 15}
14 16
15AbstractMail* AbstractMail::getWrapper(POP3account *a) 17AbstractMail* AbstractMail::getWrapper(POP3account *a)
16{ 18{
17 return new POP3wrapper(a); 19 return new POP3wrapper(a);
18} 20}
19 21
20encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) 22encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc)
21{ 23{
22 qDebug("Decode string start"); 24 qDebug("Decode string start");
23 char*result_text; 25 char*result_text;
24 size_t index = 0; 26 size_t index = 0;
25 /* reset for recursive use! */ 27 /* reset for recursive use! */
26 size_t target_length = 0; 28 size_t target_length = 0;
27 result_text = 0; 29 result_text = 0;
28 int mimetype = MAILMIME_MECHANISM_7BIT; 30 int mimetype = MAILMIME_MECHANISM_7BIT;
29 if (enc.lower()=="quoted-printable") { 31 if (enc.lower()=="quoted-printable") {
30 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; 32 mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
@@ -45,24 +47,37 @@ encodedString* AbstractMail::decode_String(const encodedString*text,const QStrin
45 } 47 }
46 qDebug("Decode string finished"); 48 qDebug("Decode string finished");
47 return result; 49 return result;
48} 50}
49 51
50QString AbstractMail::convert_String(const char*text) 52QString AbstractMail::convert_String(const char*text)
51{ 53{
52 size_t index = 0; 54 size_t index = 0;
53 char*res = 0; 55 char*res = 0;
54 56
55 /* attention - doesn't work with arm systems! */ 57 /* attention - doesn't work with arm systems! */
56 int err = mailmime_encoded_phrase_parse("iso-8859-1", 58 int err = mailmime_encoded_phrase_parse("iso-8859-1",
57 text, strlen(text),&index, "iso-8859-1",&res); 59 text, strlen(text),&index, "iso-8859-1",&res);
58 if (err != MAILIMF_NO_ERROR) { 60 if (err != MAILIMF_NO_ERROR) {
59 if (res) free(res); 61 if (res) free(res);
60 return QString(text); 62 return QString(text);
61 } 63 }
62 if (res) { 64 if (res) {
63 QString result(res); 65 QString result(res);
64 free(res); 66 free(res);
65 return result; 67 return result;
66 } 68 }
67 return QString(text); 69 return QString(text);
68} 70}
71
72/* cp & paste from launcher */
73QString AbstractMail::gen_attachment_id()
74{
75 QFile file( "/proc/sys/kernel/random/uuid" );
76 if (!file.open(IO_ReadOnly ) )
77 return QString::null;
78
79 QTextStream stream(&file);
80
81 return "{" + stream.read().stripWhiteSpace() + "}";
82}
83
diff --git a/noncore/net/mail/libmailwrapper/abstractmail.h b/noncore/net/mail/libmailwrapper/abstractmail.h
index c16e9c0..8dd2e12 100644
--- a/noncore/net/mail/libmailwrapper/abstractmail.h
+++ b/noncore/net/mail/libmailwrapper/abstractmail.h
@@ -9,28 +9,31 @@ class RecBody;
9class RecPart; 9class RecPart;
10class IMAPwrapper; 10class IMAPwrapper;
11class POP3wrapper; 11class POP3wrapper;
12class Folder; 12class Folder;
13class encodedString; 13class encodedString;
14 14
15class AbstractMail:public QObject 15class AbstractMail:public QObject
16{ 16{
17 Q_OBJECT 17 Q_OBJECT
18public: 18public:
19 AbstractMail(){}; 19 AbstractMail(){};
20 virtual ~AbstractMail(){} 20 virtual ~AbstractMail(){}
21 virtual QList<Folder>* listFolders()=0; 21 virtual QList<Folder>* listFolders()=0;
22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0; 22 virtual void listMessages(const QString & mailbox,QList<RecMail>&target )=0;
23 virtual RecBody fetchBody(const RecMail&mail)=0; 23 virtual RecBody fetchBody(const RecMail&mail)=0;
24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0; 24 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part)=0;
25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0; 25 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part)=0;
26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0; 26 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part)=0;
27 27
28 virtual void deleteMail(const RecMail&mail)=0; 28 virtual void deleteMail(const RecMail&mail)=0;
29 virtual void answeredMail(const RecMail&mail)=0; 29 virtual void answeredMail(const RecMail&mail)=0;
30 30
31 static AbstractMail* getWrapper(IMAPaccount *a); 31 static AbstractMail* getWrapper(IMAPaccount *a);
32 static AbstractMail* getWrapper(POP3account *a); 32 static AbstractMail* getWrapper(POP3account *a);
33
34protected:
33 static encodedString*decode_String(const encodedString*text,const QString&enc); 35 static encodedString*decode_String(const encodedString*text,const QString&enc);
34 static QString convert_String(const char*text); 36 static QString convert_String(const char*text);
37 static QString gen_attachment_id();
35}; 38};
36#endif 39#endif
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
index 65cd4ba..d3447f4 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.cpp
@@ -1,77 +1,91 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include "pop3wrapper.h" 2#include "pop3wrapper.h"
3#include "mailtypes.h" 3#include "mailtypes.h"
4#include "logindialog.h" 4#include "logindialog.h"
5#include <libetpan/mailpop3.h> 5#include <libetpan/mailpop3.h>
6#include <libetpan/mailmime.h> 6#include <libetpan/mailmime.h>
7#include <libetpan/data_message_driver.h> 7#include <libetpan/data_message_driver.h>
8#include <qfile.h> 8#include <qfile.h>
9 9
10/* we don't fetch messages larger than 5 MB */ 10/* we don't fetch messages larger than 5 MB */
11#define HARD_MSG_SIZE_LIMIT 5242880 11#define HARD_MSG_SIZE_LIMIT 5242880
12 12
13POP3wrapper::POP3wrapper( POP3account *a ) 13POP3wrapper::POP3wrapper( POP3account *a )
14{ 14{
15 account = a; 15 account = a;
16 m_pop3 = NULL; 16 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 17 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 18 last_msg_id = 0;
19 bodyCache.clear();
19} 20}
20 21
21POP3wrapper::~POP3wrapper() 22POP3wrapper::~POP3wrapper()
22{ 23{
23 logout(); 24 logout();
24 QFile msg_cache(msgTempName); 25 QFile msg_cache(msgTempName);
25 if (msg_cache.exists()) { 26 if (msg_cache.exists()) {
26 msg_cache.remove(); 27 msg_cache.remove();
27 } 28 }
29 cleanUpCache();
30}
31
32void POP3wrapper::cleanUpCache()
33{
34 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
35 for (;it!=bodyCache.end();++it) {
36 encodedString*t = it.data();
37 //it.setValue(0);
38 if (t) delete t;
39 }
40 bodyCache.clear();
28} 41}
29 42
30void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 43void POP3wrapper::pop3_progress( size_t current, size_t maximum )
31{ 44{
32 //qDebug( "POP3: %i of %i", current, maximum ); 45 //qDebug( "POP3: %i of %i", current, maximum );
33} 46}
34 47
35RecBody POP3wrapper::fetchBody( const RecMail &mail ) 48RecBody POP3wrapper::fetchBody( const RecMail &mail )
36{ 49{
37 int err = MAILPOP3_NO_ERROR; 50 int err = MAILPOP3_NO_ERROR;
38 char *message; 51 char *message;
39 size_t length = 0; 52 size_t length = 0;
40 53
41 login(); 54 login();
42 if ( !m_pop3 ) { 55 if ( !m_pop3 ) {
43 return RecBody(); 56 return RecBody();
44 } 57 }
45 58
46 RecBody body; 59 RecBody body;
47 60
48 QFile msg_cache(msgTempName); 61 QFile msg_cache(msgTempName);
49 62
50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 63 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
51 qDebug("Message to large: %i",mail.Msgsize()); 64 qDebug("Message to large: %i",mail.Msgsize());
52 return body; 65 return body;
53 } 66 }
67 cleanUpCache();
54 if (mail.getNumber()!=last_msg_id) { 68 if (mail.getNumber()!=last_msg_id) {
55 if (msg_cache.exists()) { 69 if (msg_cache.exists()) {
56 msg_cache.remove(); 70 msg_cache.remove();
57 } 71 }
58 msg_cache.open(IO_ReadWrite|IO_Truncate); 72 msg_cache.open(IO_ReadWrite|IO_Truncate);
59 last_msg_id = mail.getNumber(); 73 last_msg_id = mail.getNumber();
60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 74 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
61 if ( err != MAILPOP3_NO_ERROR ) { 75 if ( err != MAILPOP3_NO_ERROR ) {
62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 76 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
63 last_msg_id = 0; 77 last_msg_id = 0;
64 return RecBody(); 78 return RecBody();
65 } 79 }
66 msg_cache.writeBlock(message,length); 80 msg_cache.writeBlock(message,length);
67 } else { 81 } else {
68 QString msg=""; 82 QString msg="";
69 msg_cache.open(IO_ReadOnly); 83 msg_cache.open(IO_ReadOnly);
70 message = new char[4096]; 84 message = new char[4096];
71 memset(message,0,4096); 85 memset(message,0,4096);
72 while (msg_cache.readBlock(message,4095)>0) { 86 while (msg_cache.readBlock(message,4095)>0) {
73 msg+=message; 87 msg+=message;
74 memset(message,0,4096); 88 memset(message,0,4096);
75 } 89 }
76 delete message; 90 delete message;
77 message = (char*)malloc(msg.length()+1*sizeof(char)); 91 message = (char*)malloc(msg.length()+1*sizeof(char));
@@ -384,110 +398,120 @@ void POP3wrapper::login()
384} 398}
385 399
386void POP3wrapper::logout() 400void POP3wrapper::logout()
387{ 401{
388 int err = MAILPOP3_NO_ERROR; 402 int err = MAILPOP3_NO_ERROR;
389 if ( m_pop3 == NULL ) return; 403 if ( m_pop3 == NULL ) return;
390 err = mailpop3_quit( m_pop3 ); 404 err = mailpop3_quit( m_pop3 );
391 mailpop3_free( m_pop3 ); 405 mailpop3_free( m_pop3 );
392 m_pop3 = NULL; 406 m_pop3 = NULL;
393} 407}
394 408
395 409
396QList<Folder>* POP3wrapper::listFolders() 410QList<Folder>* POP3wrapper::listFolders()
397{ 411{
398 /* TODO: integrate MH directories 412 /* TODO: integrate MH directories
399 but not before version 0.1 ;) 413 but not before version 0.1 ;)
400 */ 414 */
401 QList<Folder> * folders = new QList<Folder>(); 415 QList<Folder> * folders = new QList<Folder>();
402 folders->setAutoDelete( false ); 416 folders->setAutoDelete( false );
403 Folder*inb=new Folder("INBOX","/"); 417 Folder*inb=new Folder("INBOX","/");
404 folders->append(inb); 418 folders->append(inb);
405 return folders; 419 return folders;
406} 420}
407 421
408QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&) 422QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
409{ 423{
410 return ""; 424 encodedString*t = fetchDecodedPart(mail,part);
425 QString text=t->Content();
426 delete t;
427 return text;
411} 428}
412 429
413void POP3wrapper::deleteMail(const RecMail&mail) 430void POP3wrapper::deleteMail(const RecMail&mail)
414{ 431{
415 login(); 432 login();
416 if (!m_pop3) return; 433 if (!m_pop3) return;
417 int err = mailpop3_dele(m_pop3,mail.getNumber()); 434 int err = mailpop3_dele(m_pop3,mail.getNumber());
418 if (err != MAILPOP3_NO_ERROR) { 435 if (err != MAILPOP3_NO_ERROR) {
419 qDebug("error deleting mail"); 436 qDebug("error deleting mail");
420 } 437 }
421} 438}
422 439
423void POP3wrapper::answeredMail(const RecMail&) 440void POP3wrapper::answeredMail(const RecMail&)
424{ 441{
425} 442}
426 443
427encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) 444encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
428{ 445{
429 return new encodedString(); 446 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
447 if (it==bodyCache.end()) return new encodedString();
448 encodedString*t = decode_String(it.data(),part.Encoding());
449 return t;
430} 450}
431 451
432encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) 452encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
433{ 453{
434 return new encodedString(); 454 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
455 if (it==bodyCache.end()) return new encodedString();
456 encodedString*t = it.data();
457 return t;
435} 458}
436 459
437void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec) 460void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
438{ 461{
439 if (current_rec >= 10) { 462 if (current_rec >= 10) {
440 qDebug("too deep recursion!"); 463 qDebug("too deep recursion!");
441 } 464 }
442 if (!message || !mime) { 465 if (!message || !mime) {
443 return; 466 return;
444 } 467 }
445 int r; 468 int r;
446 char*data = 0; 469 char*data = 0;
447 size_t len; 470 size_t len;
448 clistiter * cur = 0; 471 clistiter * cur = 0;
449 int res; 472 int res;
450 QString b; 473 QString b;
451 RecPart part; 474 RecPart part;
452 475
453 switch (mime->mm_type) { 476 switch (mime->mm_type) {
454 case MAILMIME_SINGLE: 477 case MAILMIME_SINGLE:
455 r = mailmessage_fetch_section(message,mime,&data,&len); 478 r = mailmessage_fetch_section(message,mime,&data,&len);
456 part.setSize(len); 479 part.setSize(len);
457 fillSingleBody(part,message,mime); 480 fillSingleBody(part,message,mime);
458 if (part.Type()=="text" && target.Bodytext().isNull()) { 481 if (part.Type()=="text" && target.Bodytext().isNull()) {
459 encodedString*r = new encodedString(); 482 encodedString*r = new encodedString();
460 r->setContent(data,len); 483 r->setContent(data,len);
461 encodedString*res = decode_String(r,part.Encoding()); 484 encodedString*res = decode_String(r,part.Encoding());
462 b = QString(res->Content()); 485 b = QString(res->Content());
463 delete r; 486 delete r;
464 delete res; 487 delete res;
465 target.setBodytext(b); 488 target.setBodytext(b);
466 target.setDescription(part); 489 target.setDescription(part);
467 } else { 490 } else {
468 /* TODO: Add the content to a list and store it for later use */ 491 b = gen_attachment_id();
469 if (data) free(data); 492 part.setIdentifier(b);
493 bodyCache[b]=new encodedString(data,len);
470 target.addPart(part); 494 target.addPart(part);
471 } 495 }
472 break; 496 break;
473 case MAILMIME_MULTIPLE: 497 case MAILMIME_MULTIPLE:
474 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { 498 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
475 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1); 499 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
476 } 500 }
477 break; 501 break;
478 case MAILMIME_MESSAGE: 502 case MAILMIME_MESSAGE:
479 if (mime->mm_data.mm_message.mm_msg_mime != NULL) { 503 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
480 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1); 504 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
481 } 505 }
482 break; 506 break;
483 } 507 }
484} 508}
485 509
486QString POP3wrapper::getencoding(mailmime_mechanism*aEnc) 510QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
487{ 511{
488 QString enc="7bit"; 512 QString enc="7bit";
489 if (!aEnc) return enc; 513 if (!aEnc) return enc;
490 switch(aEnc->enc_type) { 514 switch(aEnc->enc_type) {
491 case MAILMIME_MECHANISM_7BIT: 515 case MAILMIME_MECHANISM_7BIT:
492 enc = "7bit"; 516 enc = "7bit";
493 break; 517 break;
diff --git a/noncore/net/mail/libmailwrapper/pop3wrapper.h b/noncore/net/mail/libmailwrapper/pop3wrapper.h
index b17928e..a31a145 100644
--- a/noncore/net/mail/libmailwrapper/pop3wrapper.h
+++ b/noncore/net/mail/libmailwrapper/pop3wrapper.h
@@ -1,58 +1,63 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include "mailwrapper.h" 4#include "mailwrapper.h"
5#include "abstractmail.h" 5#include "abstractmail.h"
6#include <qmap.h>
7#include <qstring.h>
6 8
7class RecMail; 9class RecMail;
8class RecBody; 10class RecBody;
9class encodedString; 11class encodedString;
10struct mailpop3; 12struct mailpop3;
11struct mailmessage; 13struct mailmessage;
12struct mailmime; 14struct mailmime;
13struct mailmime_mechanism; 15struct mailmime_mechanism;
14 16
15class POP3wrapper : public AbstractMail 17class POP3wrapper : public AbstractMail
16{ 18{
17 Q_OBJECT 19 Q_OBJECT
18 20
19public: 21public:
20 POP3wrapper( POP3account *a ); 22 POP3wrapper( POP3account *a );
21 virtual ~POP3wrapper(); 23 virtual ~POP3wrapper();
22 /* mailbox will be ignored */ 24 /* mailbox will be ignored */
23 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 25 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
24 virtual QList<Folder>* listFolders(); 26 virtual QList<Folder>* listFolders();
25 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 27 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
26 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 28 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
27 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 29 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
28 30
29 virtual void deleteMail(const RecMail&mail); 31 virtual void deleteMail(const RecMail&mail);
30 virtual void answeredMail(const RecMail&mail); 32 virtual void answeredMail(const RecMail&mail);
31 33
32 RecBody fetchBody( const RecMail &mail ); 34 RecBody fetchBody( const RecMail &mail );
33 static void pop3_progress( size_t current, size_t maximum ); 35 static void pop3_progress( size_t current, size_t maximum );
34 36
35protected: 37protected:
36 void login(); 38 void login();
37 void logout(); 39 void logout();
38 40
39 RecMail *parseHeader( const char *header ); 41 RecMail *parseHeader( const char *header );
40 RecBody parseMail( char *message ); 42 RecBody parseMail( char *message );
41 QString parseMailboxList( mailimf_mailbox_list *list ); 43 QString parseMailboxList( mailimf_mailbox_list *list );
42 QString parseMailbox( mailimf_mailbox *box ); 44 QString parseMailbox( mailimf_mailbox *box );
43 QString parseGroup( mailimf_group *group ); 45 QString parseGroup( mailimf_group *group );
44 QString parseAddressList( mailimf_address_list *list ); 46 QString parseAddressList( mailimf_address_list *list );
45 QString parseDateTime( mailimf_date_time *date ); 47 QString parseDateTime( mailimf_date_time *date );
46 48
47 static void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); 49 void cleanUpCache();
50
51 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
48 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); 52 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
49 static void fillParameters(RecPart&target,clist*parameters); 53 static void fillParameters(RecPart&target,clist*parameters);
50 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); 54 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
51 55
52 POP3account *account; 56 POP3account *account;
53 mailpop3 *m_pop3; 57 mailpop3 *m_pop3;
54 QString msgTempName; 58 QString msgTempName;
55 unsigned int last_msg_id; 59 unsigned int last_msg_id;
60 QMap<QString,encodedString*> bodyCache;
56}; 61};
57 62
58#endif 63#endif
diff --git a/noncore/net/mail/pop3wrapper.cpp b/noncore/net/mail/pop3wrapper.cpp
index 65cd4ba..d3447f4 100644
--- a/noncore/net/mail/pop3wrapper.cpp
+++ b/noncore/net/mail/pop3wrapper.cpp
@@ -1,77 +1,91 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include "pop3wrapper.h" 2#include "pop3wrapper.h"
3#include "mailtypes.h" 3#include "mailtypes.h"
4#include "logindialog.h" 4#include "logindialog.h"
5#include <libetpan/mailpop3.h> 5#include <libetpan/mailpop3.h>
6#include <libetpan/mailmime.h> 6#include <libetpan/mailmime.h>
7#include <libetpan/data_message_driver.h> 7#include <libetpan/data_message_driver.h>
8#include <qfile.h> 8#include <qfile.h>
9 9
10/* we don't fetch messages larger than 5 MB */ 10/* we don't fetch messages larger than 5 MB */
11#define HARD_MSG_SIZE_LIMIT 5242880 11#define HARD_MSG_SIZE_LIMIT 5242880
12 12
13POP3wrapper::POP3wrapper( POP3account *a ) 13POP3wrapper::POP3wrapper( POP3account *a )
14{ 14{
15 account = a; 15 account = a;
16 m_pop3 = NULL; 16 m_pop3 = NULL;
17 msgTempName = a->getFileName()+"_msg_cache"; 17 msgTempName = a->getFileName()+"_msg_cache";
18 last_msg_id = 0; 18 last_msg_id = 0;
19 bodyCache.clear();
19} 20}
20 21
21POP3wrapper::~POP3wrapper() 22POP3wrapper::~POP3wrapper()
22{ 23{
23 logout(); 24 logout();
24 QFile msg_cache(msgTempName); 25 QFile msg_cache(msgTempName);
25 if (msg_cache.exists()) { 26 if (msg_cache.exists()) {
26 msg_cache.remove(); 27 msg_cache.remove();
27 } 28 }
29 cleanUpCache();
30}
31
32void POP3wrapper::cleanUpCache()
33{
34 QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
35 for (;it!=bodyCache.end();++it) {
36 encodedString*t = it.data();
37 //it.setValue(0);
38 if (t) delete t;
39 }
40 bodyCache.clear();
28} 41}
29 42
30void POP3wrapper::pop3_progress( size_t current, size_t maximum ) 43void POP3wrapper::pop3_progress( size_t current, size_t maximum )
31{ 44{
32 //qDebug( "POP3: %i of %i", current, maximum ); 45 //qDebug( "POP3: %i of %i", current, maximum );
33} 46}
34 47
35RecBody POP3wrapper::fetchBody( const RecMail &mail ) 48RecBody POP3wrapper::fetchBody( const RecMail &mail )
36{ 49{
37 int err = MAILPOP3_NO_ERROR; 50 int err = MAILPOP3_NO_ERROR;
38 char *message; 51 char *message;
39 size_t length = 0; 52 size_t length = 0;
40 53
41 login(); 54 login();
42 if ( !m_pop3 ) { 55 if ( !m_pop3 ) {
43 return RecBody(); 56 return RecBody();
44 } 57 }
45 58
46 RecBody body; 59 RecBody body;
47 60
48 QFile msg_cache(msgTempName); 61 QFile msg_cache(msgTempName);
49 62
50 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) { 63 if (mail.Msgsize()>HARD_MSG_SIZE_LIMIT) {
51 qDebug("Message to large: %i",mail.Msgsize()); 64 qDebug("Message to large: %i",mail.Msgsize());
52 return body; 65 return body;
53 } 66 }
67 cleanUpCache();
54 if (mail.getNumber()!=last_msg_id) { 68 if (mail.getNumber()!=last_msg_id) {
55 if (msg_cache.exists()) { 69 if (msg_cache.exists()) {
56 msg_cache.remove(); 70 msg_cache.remove();
57 } 71 }
58 msg_cache.open(IO_ReadWrite|IO_Truncate); 72 msg_cache.open(IO_ReadWrite|IO_Truncate);
59 last_msg_id = mail.getNumber(); 73 last_msg_id = mail.getNumber();
60 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length ); 74 err = mailpop3_retr( m_pop3, mail.getNumber(), &message, &length );
61 if ( err != MAILPOP3_NO_ERROR ) { 75 if ( err != MAILPOP3_NO_ERROR ) {
62 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() ); 76 qDebug( "POP3: error retrieving body with index %i", mail.getNumber() );
63 last_msg_id = 0; 77 last_msg_id = 0;
64 return RecBody(); 78 return RecBody();
65 } 79 }
66 msg_cache.writeBlock(message,length); 80 msg_cache.writeBlock(message,length);
67 } else { 81 } else {
68 QString msg=""; 82 QString msg="";
69 msg_cache.open(IO_ReadOnly); 83 msg_cache.open(IO_ReadOnly);
70 message = new char[4096]; 84 message = new char[4096];
71 memset(message,0,4096); 85 memset(message,0,4096);
72 while (msg_cache.readBlock(message,4095)>0) { 86 while (msg_cache.readBlock(message,4095)>0) {
73 msg+=message; 87 msg+=message;
74 memset(message,0,4096); 88 memset(message,0,4096);
75 } 89 }
76 delete message; 90 delete message;
77 message = (char*)malloc(msg.length()+1*sizeof(char)); 91 message = (char*)malloc(msg.length()+1*sizeof(char));
@@ -384,110 +398,120 @@ void POP3wrapper::login()
384} 398}
385 399
386void POP3wrapper::logout() 400void POP3wrapper::logout()
387{ 401{
388 int err = MAILPOP3_NO_ERROR; 402 int err = MAILPOP3_NO_ERROR;
389 if ( m_pop3 == NULL ) return; 403 if ( m_pop3 == NULL ) return;
390 err = mailpop3_quit( m_pop3 ); 404 err = mailpop3_quit( m_pop3 );
391 mailpop3_free( m_pop3 ); 405 mailpop3_free( m_pop3 );
392 m_pop3 = NULL; 406 m_pop3 = NULL;
393} 407}
394 408
395 409
396QList<Folder>* POP3wrapper::listFolders() 410QList<Folder>* POP3wrapper::listFolders()
397{ 411{
398 /* TODO: integrate MH directories 412 /* TODO: integrate MH directories
399 but not before version 0.1 ;) 413 but not before version 0.1 ;)
400 */ 414 */
401 QList<Folder> * folders = new QList<Folder>(); 415 QList<Folder> * folders = new QList<Folder>();
402 folders->setAutoDelete( false ); 416 folders->setAutoDelete( false );
403 Folder*inb=new Folder("INBOX","/"); 417 Folder*inb=new Folder("INBOX","/");
404 folders->append(inb); 418 folders->append(inb);
405 return folders; 419 return folders;
406} 420}
407 421
408QString POP3wrapper::fetchTextPart(const RecMail&,const RecPart&) 422QString POP3wrapper::fetchTextPart(const RecMail&mail,const RecPart&part)
409{ 423{
410 return ""; 424 encodedString*t = fetchDecodedPart(mail,part);
425 QString text=t->Content();
426 delete t;
427 return text;
411} 428}
412 429
413void POP3wrapper::deleteMail(const RecMail&mail) 430void POP3wrapper::deleteMail(const RecMail&mail)
414{ 431{
415 login(); 432 login();
416 if (!m_pop3) return; 433 if (!m_pop3) return;
417 int err = mailpop3_dele(m_pop3,mail.getNumber()); 434 int err = mailpop3_dele(m_pop3,mail.getNumber());
418 if (err != MAILPOP3_NO_ERROR) { 435 if (err != MAILPOP3_NO_ERROR) {
419 qDebug("error deleting mail"); 436 qDebug("error deleting mail");
420 } 437 }
421} 438}
422 439
423void POP3wrapper::answeredMail(const RecMail&) 440void POP3wrapper::answeredMail(const RecMail&)
424{ 441{
425} 442}
426 443
427encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&) 444encodedString* POP3wrapper::fetchDecodedPart(const RecMail&,const RecPart&part)
428{ 445{
429 return new encodedString(); 446 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
447 if (it==bodyCache.end()) return new encodedString();
448 encodedString*t = decode_String(it.data(),part.Encoding());
449 return t;
430} 450}
431 451
432encodedString* POP3wrapper::fetchRawPart(const RecMail&,const RecPart&) 452encodedString* POP3wrapper::fetchRawPart(const RecMail&mail,const RecPart&part)
433{ 453{
434 return new encodedString(); 454 QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part.Identifier());
455 if (it==bodyCache.end()) return new encodedString();
456 encodedString*t = it.data();
457 return t;
435} 458}
436 459
437void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec) 460void POP3wrapper::traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rec)
438{ 461{
439 if (current_rec >= 10) { 462 if (current_rec >= 10) {
440 qDebug("too deep recursion!"); 463 qDebug("too deep recursion!");
441 } 464 }
442 if (!message || !mime) { 465 if (!message || !mime) {
443 return; 466 return;
444 } 467 }
445 int r; 468 int r;
446 char*data = 0; 469 char*data = 0;
447 size_t len; 470 size_t len;
448 clistiter * cur = 0; 471 clistiter * cur = 0;
449 int res; 472 int res;
450 QString b; 473 QString b;
451 RecPart part; 474 RecPart part;
452 475
453 switch (mime->mm_type) { 476 switch (mime->mm_type) {
454 case MAILMIME_SINGLE: 477 case MAILMIME_SINGLE:
455 r = mailmessage_fetch_section(message,mime,&data,&len); 478 r = mailmessage_fetch_section(message,mime,&data,&len);
456 part.setSize(len); 479 part.setSize(len);
457 fillSingleBody(part,message,mime); 480 fillSingleBody(part,message,mime);
458 if (part.Type()=="text" && target.Bodytext().isNull()) { 481 if (part.Type()=="text" && target.Bodytext().isNull()) {
459 encodedString*r = new encodedString(); 482 encodedString*r = new encodedString();
460 r->setContent(data,len); 483 r->setContent(data,len);
461 encodedString*res = decode_String(r,part.Encoding()); 484 encodedString*res = decode_String(r,part.Encoding());
462 b = QString(res->Content()); 485 b = QString(res->Content());
463 delete r; 486 delete r;
464 delete res; 487 delete res;
465 target.setBodytext(b); 488 target.setBodytext(b);
466 target.setDescription(part); 489 target.setDescription(part);
467 } else { 490 } else {
468 /* TODO: Add the content to a list and store it for later use */ 491 b = gen_attachment_id();
469 if (data) free(data); 492 part.setIdentifier(b);
493 bodyCache[b]=new encodedString(data,len);
470 target.addPart(part); 494 target.addPart(part);
471 } 495 }
472 break; 496 break;
473 case MAILMIME_MULTIPLE: 497 case MAILMIME_MULTIPLE:
474 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { 498 for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
475 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1); 499 traverseBody(target,message, (mailmime*)clist_content(cur),current_rec+1);
476 } 500 }
477 break; 501 break;
478 case MAILMIME_MESSAGE: 502 case MAILMIME_MESSAGE:
479 if (mime->mm_data.mm_message.mm_msg_mime != NULL) { 503 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
480 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1); 504 traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,current_rec+1);
481 } 505 }
482 break; 506 break;
483 } 507 }
484} 508}
485 509
486QString POP3wrapper::getencoding(mailmime_mechanism*aEnc) 510QString POP3wrapper::getencoding(mailmime_mechanism*aEnc)
487{ 511{
488 QString enc="7bit"; 512 QString enc="7bit";
489 if (!aEnc) return enc; 513 if (!aEnc) return enc;
490 switch(aEnc->enc_type) { 514 switch(aEnc->enc_type) {
491 case MAILMIME_MECHANISM_7BIT: 515 case MAILMIME_MECHANISM_7BIT:
492 enc = "7bit"; 516 enc = "7bit";
493 break; 517 break;
diff --git a/noncore/net/mail/pop3wrapper.h b/noncore/net/mail/pop3wrapper.h
index b17928e..a31a145 100644
--- a/noncore/net/mail/pop3wrapper.h
+++ b/noncore/net/mail/pop3wrapper.h
@@ -1,58 +1,63 @@
1#ifndef __POP3WRAPPER 1#ifndef __POP3WRAPPER
2#define __POP3WRAPPER 2#define __POP3WRAPPER
3 3
4#include "mailwrapper.h" 4#include "mailwrapper.h"
5#include "abstractmail.h" 5#include "abstractmail.h"
6#include <qmap.h>
7#include <qstring.h>
6 8
7class RecMail; 9class RecMail;
8class RecBody; 10class RecBody;
9class encodedString; 11class encodedString;
10struct mailpop3; 12struct mailpop3;
11struct mailmessage; 13struct mailmessage;
12struct mailmime; 14struct mailmime;
13struct mailmime_mechanism; 15struct mailmime_mechanism;
14 16
15class POP3wrapper : public AbstractMail 17class POP3wrapper : public AbstractMail
16{ 18{
17 Q_OBJECT 19 Q_OBJECT
18 20
19public: 21public:
20 POP3wrapper( POP3account *a ); 22 POP3wrapper( POP3account *a );
21 virtual ~POP3wrapper(); 23 virtual ~POP3wrapper();
22 /* mailbox will be ignored */ 24 /* mailbox will be ignored */
23 virtual void listMessages(const QString & mailbox, QList<RecMail> &target ); 25 virtual void listMessages(const QString & mailbox, QList<RecMail> &target );
24 virtual QList<Folder>* listFolders(); 26 virtual QList<Folder>* listFolders();
25 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part); 27 virtual QString fetchTextPart(const RecMail&mail,const RecPart&part);
26 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part); 28 virtual encodedString* fetchDecodedPart(const RecMail&mail,const RecPart&part);
27 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part); 29 virtual encodedString* fetchRawPart(const RecMail&mail,const RecPart&part);
28 30
29 virtual void deleteMail(const RecMail&mail); 31 virtual void deleteMail(const RecMail&mail);
30 virtual void answeredMail(const RecMail&mail); 32 virtual void answeredMail(const RecMail&mail);
31 33
32 RecBody fetchBody( const RecMail &mail ); 34 RecBody fetchBody( const RecMail &mail );
33 static void pop3_progress( size_t current, size_t maximum ); 35 static void pop3_progress( size_t current, size_t maximum );
34 36
35protected: 37protected:
36 void login(); 38 void login();
37 void logout(); 39 void logout();
38 40
39 RecMail *parseHeader( const char *header ); 41 RecMail *parseHeader( const char *header );
40 RecBody parseMail( char *message ); 42 RecBody parseMail( char *message );
41 QString parseMailboxList( mailimf_mailbox_list *list ); 43 QString parseMailboxList( mailimf_mailbox_list *list );
42 QString parseMailbox( mailimf_mailbox *box ); 44 QString parseMailbox( mailimf_mailbox *box );
43 QString parseGroup( mailimf_group *group ); 45 QString parseGroup( mailimf_group *group );
44 QString parseAddressList( mailimf_address_list *list ); 46 QString parseAddressList( mailimf_address_list *list );
45 QString parseDateTime( mailimf_date_time *date ); 47 QString parseDateTime( mailimf_date_time *date );
46 48
47 static void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0); 49 void cleanUpCache();
50
51 void traverseBody(RecBody&target,mailmessage*message,mailmime*mime,unsigned int current_rek=0);
48 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime); 52 static void fillSingleBody(RecPart&target,mailmessage*message,mailmime*mime);
49 static void fillParameters(RecPart&target,clist*parameters); 53 static void fillParameters(RecPart&target,clist*parameters);
50 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc); 54 static QString POP3wrapper::getencoding(mailmime_mechanism*aEnc);
51 55
52 POP3account *account; 56 POP3account *account;
53 mailpop3 *m_pop3; 57 mailpop3 *m_pop3;
54 QString msgTempName; 58 QString msgTempName;
55 unsigned int last_msg_id; 59 unsigned int last_msg_id;
60 QMap<QString,encodedString*> bodyCache;
56}; 61};
57 62
58#endif 63#endif