1010#include " Poco/TextConverter.h"
1111#include " Poco/Net/MessageHeader.h"
1212
13+ #include < Windows.h>
14+
1315#include < iostream>
16+ #include < codecvt>
1417#include < sstream>
1518#include < algorithm>
1619#include < iterator>
1720#include < string>
1821#include < vector>
22+ #include < fstream>
1923
2024using Poco::NumberFormatter;
2125using Poco::DateTimeFormatter;
@@ -32,6 +36,43 @@ namespace Poco {
3236
3337 // POCO_IMPLEMENT_EXCEPTION(IMAPException, NetException, "IMAP Exception")
3438
39+ // GB2312转UTF8
40+ std::string GB2312ToUTF8 (const char * lpszGb32Text)
41+ {
42+ int nUnicodeBufLen = MultiByteToWideChar (CP_ACP, 0 , lpszGb32Text, -1 , 0 , 0 );
43+ if (nUnicodeBufLen == 0 )
44+ return " " ;
45+
46+ WCHAR* pUnicodeBuf = new WCHAR[nUnicodeBufLen];
47+ if (pUnicodeBuf == 0 )
48+ return " " ;
49+
50+ MultiByteToWideChar (CP_ACP, 0 , lpszGb32Text, -1 , pUnicodeBuf, nUnicodeBufLen);
51+
52+ int nUtf8BufLen = WideCharToMultiByte (CP_UTF8, 0 , pUnicodeBuf, -1 , 0 , 0 , NULL , NULL );
53+ if (nUtf8BufLen == 0 )
54+ {
55+ delete[] pUnicodeBuf;
56+ return " " ;
57+ }
58+
59+ char * pUft8Buf = new char [nUtf8BufLen];
60+ if (pUft8Buf == 0 )
61+ {
62+ delete[] pUnicodeBuf;
63+ return " " ;
64+ }
65+
66+ WideCharToMultiByte (CP_UTF8, 0 , pUnicodeBuf, -1 , pUft8Buf, nUtf8BufLen, NULL , NULL );
67+
68+ std::string strUtf8 = pUft8Buf;
69+
70+ delete[] pUnicodeBuf;
71+ delete[] pUft8Buf;
72+
73+ return strUtf8;
74+ }
75+
3576 template <class S =std::string>
3677 S trimchar (const S& str, const char ch)
3778 {
@@ -317,35 +358,41 @@ namespace Poco {
317358 if (!sendCommand (" DELETE \" " + folder + " \" *" , response, data)) throw NetException (" Can't delete folder" , response);
318359 }
319360
320- void IMAPClientSession::loadMessage (const std::string & folder, const MessageInfo & info, std::string & message ) {
361+ void IMAPClientSession::loadMessage (const std::string & folder, MessageInfo & info) {
321362 std::string response, tmpdata;
322363 std::vector<std::string> data, data1;
323- message.clear ( );
324364
325365 if ( !sendCommand (" SELECT \" " + folder + " \" " , response, data) ) throw NetException (" Can't select from folder" , response);
326366
327- loadText (info.uid , info.parts , " " , message);
367+ loadText (info.uid , info.parts , " " , " HTML" , info.htmlText );
368+ loadText (info.uid , info.parts , " " , " PLAIN" , info.text );
328369
329370// sendCommand ("CLOSE", response, data1);
330371
331- if ( data.size ( ) <= 2 ) return ;
372+ // if ( data.size ( ) <= 2 ) return;
373+
374+ // for ( int i = 1; i < data.size ( ) - 2; i++ ) {
375+ // if( data[i].length() > 0 && data[i][0] != '*' ){
376+ // message += data[i];
377+ // message += "\r\n";
378+ // }
379+ // }
332380
333- for ( int i = 1 ; i < data.size ( ) - 2 ; i++ ) {
334- if ( data[i].length () > 0 && data[i][0 ] != ' *' ){
335- message += data[i];
336- message += " \r\n " ;
337- }
338- }
339381 }
340382
341- void IMAPClientSession::loadText (const std::string & uid, const PartInfo & info, const std::string & index, std::string & text) {
383+ void IMAPClientSession::loadText (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & _type, std::string & text) {
384+
342385 auto & attrs = info.attributes ;
343386
387+ std::string type = _type;
388+
389+ std::transform (type.begin (), type.end (), type.begin (), ::toupper );
390+
344391 std::string response;
345392 std::vector<std::string> result;
346393 std::stringstream ss;
347394
348- if ( std::find (attrs.begin ( ), attrs.end ( ), " TEXT " ) != info.attributes .end ( ) ) { // 如果是正文类型
395+ if ( std::find (attrs.begin ( ), attrs.end ( ), type ) != info.attributes .end ( ) ) { // 如果是正文类型
349396
350397 if ( !sendCommand (" UID FETCH " + uid + " BODY.PEEK[" + ( index.length () == 0 ? " 1" : index ) + " ]" , response, result) )
351398 throw NetException (" Cannot Load Mail Text" , response);
@@ -371,29 +418,54 @@ namespace Poco {
371418 }
372419
373420 } else {
374- std::cout << " UNKNONW CONTENT TRANSFER TYPE : " ;
421+ std::cout << " Unknown Content Transfer Type : " ;
375422 for (auto s : attrs){
376423 std::cout << s << " ;" ;
377424 }
378- std::cout << std::endl;
425+ // std::cout << "Content: " << ss.str () << std::endl;
379426 text += ss.str ( );
380427 // throw NetException ("UNKNOWN CONTENT TRANSFER TYPE");
381428 }
382429
383- } else if ( std::find (attrs.begin ( ), attrs.end ( ), " APPLICATION" ) != attrs.end ()) { // 附件类型, 只记录index和文件名(需要用decoder解码), 不需要读内容
384-
385430 }
386431
387432 for ( int i = 0 ; i < info.childs .size ( ); i++ ) {
388- loadText (uid, info.childs .at (i), index + " ." + std::to_string (i+1 ), text);
433+ std::string nextindex = index.length () == 0 ? std::to_string (i+1 ) : index + " ." + std::to_string (i+1 );
434+ loadText (uid, info.childs .at (i), nextindex, type, text);
389435 }
390436
391- text += " \n " ;
437+ // text += "\n";
392438
393439 return ;
394440
395441 }
396442
443+ void IMAPClientSession::loadParts (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & _type, std::vector<std::string> & paths){
444+
445+ auto & attrs = info.attributes ;
446+
447+ std::string type = _type;
448+
449+ std::transform (type.begin (), type.end (), type.begin (), ::toupper );
450+
451+ std::string response;
452+ std::vector<std::string> result;
453+
454+ if ( std::find (attrs.begin ( ), attrs.end ( ), type) != info.attributes .end ( ) ) {
455+
456+ paths.push_back (index);
457+
458+ }
459+
460+ for ( int i = 0 ; i < info.childs .size ( ); i++ ) {
461+ std::string nextindex = index.length () == 0 ? std::to_string (i+1 ) : index + " ." + std::to_string (i+1 );
462+ loadParts (uid, info.childs .at (i), nextindex, type, paths);
463+ }
464+
465+
466+ }
467+
468+
397469 void IMAPClientSession::getMessages (const std::string& folder, std::vector<std::string>& uids, MessageInfoVec& messages)
398470 {
399471 std::string response, response1;
@@ -481,7 +553,7 @@ namespace Poco {
481553 m.from = IMAPClientSession::decoder (trim (tokens4[1 ]));
482554 // m.from = MessageHeader::decodeWord(trim(tokens4[1]));
483555 else if ( cmd == " TO" )
484- m.from = IMAPClientSession::decoder (trim (tokens4[1 ]));
556+ m.to = IMAPClientSession::decoder (trim (tokens4[1 ]));
485557 // m.to = MessageHeader::decodeWord(trim(tokens4[1]));
486558 }
487559 messages.push_back (m);
@@ -541,30 +613,41 @@ namespace Poco {
541613
542614 if ( encoding[0 ] == ' B' ) { // Base64编码
543615 Base64Decoder decode (iss);
544- while ( !decode. eof ( ) && ( c = decode.get ()) ) {
616+ while ( ( c = decode.get ( ) ) != - 1 ) {
545617 tmp += c;
546618 }
547619 } else if ( encoding[0 ] == ' Q' ) { // Quote-Printable编码
548620 QuotedPrintableDecoder qpd (iss);
549- while ( !qpd. eof ( ) && ( c = qpd.get ( ) ) ) {
550- text += c;
621+ while ( ( c = qpd.get ( ) ) != - 1 ) {
622+ tmp += c;
551623 }
552624
553625 } else { // 编码未知, 直接返回原字符串
554626 outs = ins;
555627 return ;
556628 }
557629
558- // 转换字符集
630+ // 标题转换字符集
559631 if ( charset != charset_to ) {
560- try {
561- TextEncoding & enc = TextEncoding::byName (charset);
562- TextEncoding & dec = TextEncoding::byName (charset_to);
563- TextConverter converter (enc, dec);
564- converter.convert (tmp, outs);
565- } catch ( ... ) { // 无法转换的未知字符集(包括GB2312)
566- std::cout << " Unknown charset " << charset << std::endl;
567- outs = tmp;
632+ std::transform (charset.begin (), charset.end (), charset.begin (), ::toupper);
633+ if ( charset == " GB2312" ){
634+ std::cout << " charset == gb2312" << std::endl;
635+ try {
636+ outs = GB2312ToUTF8 (tmp.c_str ());
637+ }catch ( std::exception & e ){
638+ std::cout << e.what () << std::endl;
639+ }
640+ }else {
641+ try {
642+ TextEncoding & enc = TextEncoding::byName (charset);
643+ TextEncoding & dec = TextEncoding::byName (charset_to);
644+ TextConverter converter (enc, dec);
645+ converter.convert (tmp, outs);
646+ } catch ( ... ) { // 无法转换的未知字符集(包括GB2312)
647+ std::cout << " Unknown charset " << charset << std::endl;
648+ std::cout << " Content: " << tmp << std::endl;
649+ outs = tmp;
650+ }
568651 }
569652 } else { // 不需要转换字符集
570653 outs = tmp;
@@ -581,7 +664,7 @@ namespace Poco {
581664 break ;
582665 }
583666 if ( start > 0 ) {
584- outs = text.substr (0 , start);
667+ outs + = text.substr (0 , start);
585668 }
586669
587670 text = text.substr (start+2 ); // 从=?之后开始查找其余信息
0 commit comments