00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#include "kmime_headers.h"
00019
00020
#include "kmime_util.h"
00021
#include "kmime_content.h"
00022
#include "kmime_codecs.h"
00023
#include "kmime_header_parsing.h"
00024
#include "kmime_warning.h"
00025
00026
#include "kqcstringsplitter.h"
00027
00028
#include <qtextcodec.h>
00029
#include <qstring.h>
00030
#include <qcstring.h>
00031
#include <qstringlist.h>
00032
#include <qvaluelist.h>
00033
00034
#include <kglobal.h>
00035
#include <kcharsets.h>
00036
#include <krfcdate.h>
00037
00038
#include <assert.h>
00039
00040
00041
using namespace KMime;
00042
using namespace KMime::Headers;
00043
using namespace KMime::Types;
00044
using namespace KMime::HeaderParsing;
00045
00046
namespace KMime {
00047
namespace Headers {
00048
00049
00050 QCString Base::rfc2047Charset()
00051 {
00052
if( (e_ncCS==0) ||
forceCS() )
00053
return defaultCS();
00054
else
00055
return QCString(e_ncCS);
00056 }
00057
00058
00059 void Base::setRFC2047Charset(
const QCString &cs)
00060 {
00061 e_ncCS=cachedCharset(cs);
00062 }
00063
00064
00065 bool Base::forceCS()
00066 {
00067
return ( p_arent!=0 ? p_arent->
forceDefaultCS() :
false );
00068 }
00069
00070
00071 QCString Base::defaultCS()
00072 {
00073
return ( p_arent!=0 ? p_arent->
defaultCharset() : Latin1 );
00074 }
00075
00076
00077
00078
00079
namespace Generics {
00080
00081
00082
00083 void GUnstructured::from7BitString(
const QCString & str )
00084 {
00085 d_ecoded = decodeRFC2047String( str, &e_ncCS,
defaultCS(),
forceCS() );
00086 }
00087
00088 QCString GUnstructured::as7BitString(
bool withHeaderType )
00089 {
00090
QCString result;
00091
if ( withHeaderType )
00092 result = typeIntro();
00093 result += encodeRFC2047String( d_ecoded, e_ncCS ) ;
00094
00095
return result;
00096 }
00097
00098 void GUnstructured::fromUnicodeString(
const QString & str,
00099
const QCString & suggestedCharset )
00100 {
00101 d_ecoded = str;
00102 e_ncCS = cachedCharset( suggestedCharset );
00103 }
00104
00105 QString GUnstructured::asUnicodeString()
00106 {
00107
return d_ecoded;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
bool MailboxList::parse(
const char* & scursor,
const char *
const send,
00131
bool isCRLF ) {
00132
00133
00134
00135
00136
00137
QValueList<Address> maybeAddressList;
00138
if ( !parseAddressList( scursor, send, maybeAddressList, isCRLF ) )
00139
return false;
00140
00141 mMailboxList.clear();
00142
00143
00144
QValueList<Address>::Iterator it;
00145
for ( it = maybeAddressList.begin(); it != maybeAddressList.end() ; ++it ) {
00146
if ( !(*it).displayName.isEmpty() ) {
00147 KMIME_WARN <<
"mailbox groups in header disallowing them! Name: \""
00148 << (*it).displayName <<
"\"" << endl;
00149 }
00150 mMailboxList += (*it).mailboxList;
00151 }
00152
return true;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
bool SingleMailbox::parse(
const char* & scursor,
const char *
const send,
00162
bool isCRLF ) {
00163
if ( !MailboxList::parse( scursor, send, isCRLF ) )
return false;
00164
00165
if ( mMailboxList.count() > 1 ) {
00166 KMIME_WARN <<
"multiple mailboxes in header allowing only a single one!"
00167 << endl;
00168 }
00169
return true;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
bool AddressList::parse(
const char* & scursor,
const char *
const send,
00179
bool isCRLF ) {
00180
00181
QValueList<Address> maybeAddressList;
00182
if ( !parseAddressList( scursor, send, maybeAddressList, isCRLF ) )
00183
return false;
00184
00185 mAddressList = maybeAddressList;
00186
return true;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
bool GToken::parse(
const char* & scursor,
const char *
const send,
00196
bool isCRLF ) {
00197
00198 eatCFWS( scursor, send, isCRLF );
00199
00200
if ( scursor == send )
return false;
00201
00202
QPair<const char*,int> maybeToken;
00203
if ( !parseToken( scursor, send, maybeToken,
false ) )
00204
return false;
00205 mToken =
QCString( maybeToken.first, maybeToken.second );
00206
00207
00208 eatCFWS( scursor, send, isCRLF );
00209
if ( scursor != send ) {
00210 KMIME_WARN <<
"trailing garbage after token in header allowing "
00211
"only a single token!" << endl;
00212 }
00213
return true;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
bool GPhraseList::parse(
const char* & scursor,
const char *
const send,
00223
bool isCRLF ) {
00224
00225 mPhraseList.clear();
00226
00227
while ( scursor != send ) {
00228 eatCFWS( scursor, send, isCRLF );
00229
00230
if ( scursor == send )
return true;
00231
00232
if ( *scursor !=
',' ) { scursor++;
continue; }
00233
00234
QString maybePhrase;
00235
if ( !parsePhrase( scursor, send, maybePhrase, isCRLF ) )
00236
return false;
00237 mPhraseList.append( maybePhrase );
00238
00239 eatCFWS( scursor, send, isCRLF );
00240
00241
if ( scursor == send )
return true;
00242
00243
if ( *scursor !=
',' ) scursor++;
00244 }
00245
return true;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
bool GDotAtom::parse(
const char* & scursor,
const char *
const send,
00255
bool isCRLF ) {
00256
00257
QString maybeDotAtom;
00258
if ( !parseDotAtom( scursor, send, maybeDotAtom, isCRLF ) )
00259
return false;
00260
00261 mDotAtom = maybeDotAtom;
00262
00263 eatCFWS( scursor, send, isCRLF );
00264
if ( scursor != send ) {
00265 KMIME_WARN <<
"trailing garbage after dot-atom in header allowing "
00266
"only a single dot-atom!" << endl;
00267 }
00268
return true;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
bool GContentType::parse(
const char* & scursor,
const char *
const send,
00285
bool isCRLF ) {
00286
00287
00288
00289 mMimeType = 0;
00290 mMimeSubType = 0;
00291 mParameterHash.clear();
00292
00293 eatCFWS( scursor, send, isCRLF );
00294
if ( scursor == send ) {
00295
00296
return false;
00297 }
00298
00299
00300
00301
00302
00303
QPair<const char*,int> maybeMimeType;
00304
if ( !parseToken( scursor, send, maybeMimeType,
false ) )
00305
return false;
00306
00307 mMimeType =
QCString( maybeMimeType.first, maybeMimeType.second ).lower();
00308
00309
00310
00311
00312
00313 eatCFWS( scursor, send, isCRLF );
00314
if ( scursor == send || *scursor !=
'/' )
return false;
00315 scursor++;
00316 eatCFWS( scursor, send, isCRLF );
00317
if ( scursor == send )
return false;
00318
00319
QPair<const char*,int> maybeSubType;
00320
if ( !parseToken( scursor, send, maybeSubType,
false ) )
00321
return false;
00322
00323 mMimeSubType = QCString( maybeSubType.first, maybeSubType.second ).lower();
00324
00325
00326
00327
00328
00329 eatCFWS( scursor, send, isCRLF );
00330
if ( scursor == send )
return true;
00331
00332
if ( *scursor !=
';' )
return false;
00333 scursor++;
00334
00335
if ( !parseParameterList( scursor, send, mParameterHash, isCRLF ) )
00336
return false;
00337
00338
return true;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
bool GCISTokenWithParameterList::parse(
const char* & scursor,
00348
const char *
const send,
bool isCRLF ) {
00349
00350 mToken = 0;
00351 mParameterHash.clear();
00352
00353
00354
00355
00356
00357 eatCFWS( scursor, send, isCRLF );
00358
if ( scursor == send )
return false;
00359
00360
QPair<const char*,int> maybeToken;
00361
if ( !parseToken( scursor, send, maybeToken,
false ) )
00362
return false;
00363
00364 mToken =
QCString( maybeToken.first, maybeToken.second ).lower();
00365
00366
00367
00368
00369
00370 eatCFWS( scursor, send, isCRLF );
00371
if ( scursor == send )
return true;
00372
00373
if ( *scursor !=
';' )
return false;
00374 scursor++;
00375
00376
if ( !parseParameterList( scursor, send, mParameterHash, isCRLF ) )
00377
return false;
00378
00379
return true;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
bool GIdent::parse(
const char* & scursor,
const char *
const send,
bool isCRLF ) {
00389
00390
00391
00392
00393
00394
00395
00396
00397 mMsgIdList.clear();
00398
00399
while ( scursor != send ) {
00400 eatCFWS( scursor, send, isCRLF );
00401
00402
if ( scursor == send )
return true;
00403
00404
if ( *scursor ==
',' ) { scursor++;
continue; }
00405
00406 AddrSpec maybeMsgId;
00407
if ( !parseAngleAddr( scursor, send, maybeMsgId, isCRLF ) )
00408
return false;
00409 mMsgIdList.append( maybeMsgId );
00410
00411 eatCFWS( scursor, send, isCRLF );
00412
00413
if ( scursor == send )
return true;
00414
00415
if ( *scursor ==
',' ) scursor++;
00416 }
00417
return true;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
bool GSingleIdent::parse(
const char* & scursor,
const char *
const send,
bool isCRLF ) {
00427
00428
if ( !GIdent::parse( scursor, send, isCRLF ) )
return false;
00429
00430
if ( mMsgIdList.count() > 1 ) {
00431 KMIME_WARN <<
"more than one msg-id in header "
00432
"allowing only a single one!" << endl;
00433 }
00434
return true;
00435 }
00436
00437
00438
00439
00440
00441
00442 }
00443
00444
00445
00446
00447
bool ReturnPath::parse(
const char* & scursor,
const char *
const send,
bool isCRLF ) {
00448
00449 eatCFWS( scursor, send, isCRLF );
00450
if ( scursor == send )
return false;
00451
00452
const char * oldscursor = scursor;
00453
00454 Mailbox maybeMailbox;
00455
if ( !parseMailbox( scursor, send, maybeMailbox, isCRLF ) ) {
00456
00457 scursor = oldscursor;
00458
if ( *scursor !=
'<' )
return false;
00459 scursor++;
00460 eatCFWS( scursor, send, isCRLF );
00461
if ( scursor == send || *scursor !=
'>' )
return false;
00462 scursor++;
00463
00464
00465 AddrSpec emptyAddrSpec;
00466 maybeMailbox.displayName = QString::null;
00467 maybeMailbox.addrSpec = emptyAddrSpec;
00468 }
else
00469
00470
if ( !maybeMailbox.displayName.isEmpty() ) {
00471 KMIME_WARN <<
"display-name \"" << maybeMailbox.displayName
00472 <<
"\" in Return-Path!" << endl;
00473 }
00474
00475
00476 eatCFWS( scursor, send, isCRLF );
00477
00478
if ( scursor != send ) {
00479 KMIME_WARN <<
"trailing garbage after angle-addr in Return-Path!" << endl;
00480 }
00481
return true;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
void Generic::setType(
const char *type)
00492 {
00493
if(t_ype)
00494
delete[] t_ype;
00495
if(type) {
00496 t_ype=
new char[strlen(type)+1];
00497 strcpy(t_ype, type);
00498 }
00499
else
00500 t_ype=0;
00501 }
00502
00503
00504
00505
00506
#if !defined(KMIME_NEW_STYLE_CLASSTREE)
00507
00508
00509 void MessageID::from7BitString(
const QCString &s)
00510 {
00511 m_id=s;
00512 }
00513
00514
00515 QCString MessageID::as7BitString(
bool incType)
00516 {
00517
if(incType)
00518
return ( typeIntro()+m_id );
00519
else
00520
return m_id;
00521 }
00522
00523
00524 void MessageID::fromUnicodeString(
const QString &s,
const QCString&)
00525 {
00526 m_id=s.latin1();
00527 }
00528
00529
00530 QString MessageID::asUnicodeString()
00531 {
00532
return QString::fromLatin1(m_id);
00533 }
00534
00535
00536
void MessageID::generate(
const QCString &fqdn)
00537 {
00538 m_id=
"<"+uniqueString()+
"@"+fqdn+
">";
00539 }
00540
00541
00542
#endif
00543
00544
00545
00546
00547 void Control::from7BitString(
const QCString &s)
00548 {
00549 c_trlMsg=s;
00550 }
00551
00552
00553 QCString Control::as7BitString(
bool incType)
00554 {
00555
if(incType)
00556
return ( typeIntro()+c_trlMsg );
00557
else
00558
return c_trlMsg;
00559 }
00560
00561
00562 void Control::fromUnicodeString(
const QString &s,
const QCString&)
00563 {
00564 c_trlMsg=s.latin1();
00565 }
00566
00567
00568 QString Control::asUnicodeString()
00569 {
00570
return QString::fromLatin1(c_trlMsg);
00571 }
00572
00573
00574
00575
00576
00577
#if !defined(KMIME_NEW_STYLE_CLASSTREE)
00578
00579 void AddressField::from7BitString(
const QCString &s)
00580 {
00581
int pos1=0, pos2=0, type=0;
00582
QCString n;
00583
00584
00585
if(s.find(
QRegExp(
"*@*(*)",
false,
true) )!=-1) type=2;
00586
else if(s.find(
QRegExp(
"*<*@*>",
false,
true) )!=-1) type=1;
00587
else if(s.find(
QRegExp(
"*@*",
false,
true) )!=-1) type=0;
00588
else {
00589 n_ame=decodeRFC2047String(s, &e_ncCS, defaultCS(), forceCS());
00590
return;
00591 }
00592
00593
switch(type) {
00594
00595
case 0:
00596 e_mail=s.copy();
00597
break;
00598
00599
case 1:
00600 pos1=0;
00601 pos2=s.find(
'<');
00602
if(pos2!=-1) {
00603 n=s.mid(pos1, pos2-pos1).stripWhiteSpace();
00604 pos1=pos2+1;
00605 pos2=s.find(
'>', pos1);
00606
if(pos2!=-1)
00607 e_mail=s.mid(pos1, pos2-pos1);
00608 }
00609
else return;
00610
break;
00611
00612
case 2:
00613 pos1=0;
00614 pos2=s.find(
'(');
00615
if(pos2!=-1) {
00616 e_mail=s.mid(pos1, pos2-pos1).stripWhiteSpace();
00617 pos1=pos2+1;
00618 pos2=s.find(
')', pos1);
00619
if(pos2!=-1)
00620 n=s.mid(pos1, pos2-pos1).stripWhiteSpace();
00621 }
00622
break;
00623
00624
default:
break;
00625 }
00626
00627
if(!n.isEmpty()) {
00628 removeQuots(n);
00629 n_ame=decodeRFC2047String(n, &e_ncCS, defaultCS(), forceCS());
00630 }
00631 }
00632
00633
00634 QCString AddressField::as7BitString(
bool incType)
00635 {
00636
QCString ret;
00637
00638
if(incType && type()[0]!=
'\0')
00639 ret=typeIntro();
00640
00641
if(n_ame.isEmpty())
00642 ret+=e_mail;
00643
else {
00644
if (isUsAscii(n_ame)) {
00645
QCString tmp(n_ame.latin1());
00646 addQuotes(tmp,
false);
00647 ret+=tmp;
00648 }
else {
00649 ret+=encodeRFC2047String(n_ame, e_ncCS,
true);
00650 }
00651
if (!e_mail.isEmpty())
00652 ret +=
" <"+e_mail+
">";
00653 }
00654
00655
return ret;
00656 }
00657
00658
00659 void AddressField::fromUnicodeString(
const QString &s,
const QCString &cs)
00660 {
00661
int pos1=0, pos2=0, type=0;
00662
QCString n;
00663
00664 e_ncCS=cachedCharset(cs);
00665
00666
00667
if(s.find(
QRegExp(
"*@*(*)",
false,
true) )!=-1) type=2;
00668
else if(s.find(
QRegExp(
"*<*@*>",
false,
true) )!=-1) type=1;
00669
else if(s.find(
QRegExp(
"*@*",
false,
true) )!=-1) type=0;
00670
else {
00671 n_ame=s;
00672
return;
00673 }
00674
00675
switch(type) {
00676
00677
case 0:
00678 e_mail=s.latin1();
00679
break;
00680
00681
case 1:
00682 pos1=0;
00683 pos2=s.find(
'<');
00684
if(pos2!=-1) {
00685 n_ame=s.mid(pos1, pos2-pos1).stripWhiteSpace();
00686 pos1=pos2+1;
00687 pos2=s.find(
'>', pos1);
00688
if(pos2!=-1)
00689 e_mail=s.mid(pos1, pos2-pos1).latin1();
00690 }
00691
else return;
00692
break;
00693
00694
case 2:
00695 pos1=0;
00696 pos2=s.find(
'(');
00697
if(pos2!=-1) {
00698 e_mail=s.mid(pos1, pos2-pos1).stripWhiteSpace().latin1();
00699 pos1=pos2+1;
00700 pos2=s.find(
')', pos1);
00701
if(pos2!=-1)
00702 n_ame=s.mid(pos1, pos2-pos1).stripWhiteSpace();
00703 }
00704
break;
00705
00706
default:
break;
00707 }
00708
00709
if(!n_ame.isEmpty())
00710 removeQuots(n_ame);
00711 }
00712
00713
00714 QString AddressField::asUnicodeString()
00715 {
00716
if(n_ame.isEmpty())
00717
return QString(e_mail);
00718
else {
00719
QString s = n_ame;
00720
if (!e_mail.isEmpty())
00721 s +=
" <"+e_mail+
">";
00722
return s;
00723 }
00724 }
00725
00726
00727
QCString AddressField::nameAs7Bit()
00728 {
00729
return encodeRFC2047String(n_ame, e_ncCS);
00730 }
00731
00732
00733
void AddressField::setNameFrom7Bit(
const QCString &s)
00734 {
00735 n_ame=decodeRFC2047String(s, &e_ncCS, defaultCS(), forceCS());
00736 }
00737
00738
00739
#endif
00740
00741
00742
00743
00744
bool MailCopiesTo::isValid()
00745 {
00746
if (hasEmail())
00747
return true;
00748
00749
if ((n_ame ==
"nobody") ||
00750 (n_ame ==
"never") ||
00751 (n_ame ==
"poster") ||
00752 (n_ame ==
"always"))
00753
return true;
00754
else
00755
return false;
00756 }
00757
00758
00759
bool MailCopiesTo::alwaysCopy()
00760 {
00761
return (hasEmail() || (n_ame ==
"poster") || (n_ame ==
"always"));
00762 }
00763
00764
00765
bool MailCopiesTo::neverCopy()
00766 {
00767
return ((n_ame ==
"nobody") || (n_ame ==
"never"));
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777 void Date::from7BitString(
const QCString &s)
00778 {
00779 t_ime=KRFCDate::parseDate(s);
00780 }
00781
00782
00783 QCString Date::as7BitString(
bool incType)
00784 {
00785
if(incType)
00786
return ( typeIntro()+KRFCDate::rfc2822DateString(t_ime) );
00787
else
00788
return QCString(KRFCDate::rfc2822DateString(t_ime));
00789 }
00790
00791
00792 void Date::fromUnicodeString(
const QString &s,
const QCString&)
00793 {
00794
from7BitString(
QCString(s.latin1()) );
00795 }
00796
00797
00798 QString Date::asUnicodeString()
00799 {
00800
return QString::fromLatin1(
as7BitString(
false));
00801 }
00802
00803
00804
QDateTime Date::qdt()
00805 {
00806
QDateTime dt;
00807 dt.setTime_t(t_ime);
00808
return dt;
00809 }
00810
00811
00812
int Date::ageInDays()
00813 {
00814
QDate today=QDate::currentDate();
00815
return ( qdt().date().daysTo(today) );
00816 }
00817
00818
00819
00820
00821
00822
#if !defined(KMIME_NEW_STYLE_CLASSTREE)
00823
00824
00825 void To::from7BitString(
const QCString &s)
00826 {
00827
if(a_ddrList)
00828 a_ddrList->clear();
00829
else {
00830 a_ddrList=
new QPtrList<AddressField>;
00831 a_ddrList->setAutoDelete(
true);
00832 }
00833
00834 KQCStringSplitter split;
00835 split.init(s,
",");
00836
bool splitOk=split.first();
00837
if(!splitOk)
00838 a_ddrList->append(
new AddressField(p_arent, s ));
00839
else {
00840
do {
00841 a_ddrList->append(
new AddressField(p_arent, split.string()) );
00842 }
while(split.next());
00843 }
00844
00845 e_ncCS=cachedCharset(a_ddrList->first()->rfc2047Charset());
00846 }
00847
00848
00849 QCString To::as7BitString(
bool incType)
00850 {
00851
QCString ret;
00852
00853
if(incType)
00854 ret+=typeIntro();
00855
00856
if (a_ddrList) {
00857
AddressField *it=a_ddrList->first();
00858
if (it)
00859 ret+=it->
as7BitString(
false);
00860
for (it=a_ddrList->next() ; it != 0; it=a_ddrList->next() )
00861 ret+=
","+it->
as7BitString(
false);
00862 }
00863
00864
return ret;
00865 }
00866
00867
00868 void To::fromUnicodeString(
const QString &s,
const QCString &cs)
00869 {
00870
if(a_ddrList)
00871 a_ddrList->clear();
00872
else {
00873 a_ddrList=
new QPtrList<AddressField>;
00874 a_ddrList->setAutoDelete(
true);
00875 }
00876
00877
QStringList l=QStringList::split(
",", s);
00878
00879 QStringList::Iterator it=l.begin();
00880
for(; it!=l.end(); ++it)
00881 a_ddrList->append(
new AddressField( p_arent, (*it), cs ));
00882
00883 e_ncCS=cachedCharset(cs);
00884 }
00885
00886
00887 QString To::asUnicodeString()
00888 {
00889
if(!a_ddrList)
00890
return QString::null;
00891
00892
QString ret;
00893
AddressField *it=a_ddrList->first();
00894
00895
if (it)
00896 ret+=it->
asUnicodeString();
00897
for (it=a_ddrList->next() ; it != 0; it=a_ddrList->next() )
00898 ret+=
","+it->
asUnicodeString();
00899
return ret;
00900 }
00901
00902
00903
void To::addAddress(
const AddressField &a)
00904 {
00905
if(!a_ddrList) {
00906 a_ddrList=
new QPtrList<AddressField>;
00907 a_ddrList->setAutoDelete(
true);
00908 }
00909
00910
AddressField *add=
new AddressField(a);
00911 add->
setParent(p_arent);
00912 a_ddrList->append(add);
00913 }
00914
00915
00916
void To::emails(
QStrList *l)
00917 {
00918 l->clear();
00919
00920
for (
AddressField *it=a_ddrList->first(); it != 0; it=a_ddrList->next() )
00921
if( it->
hasEmail() )
00922 l->append( it->
email() );
00923 }
00924
00925
00926
#endif
00927
00928
00929
00930
00931 void Newsgroups::from7BitString(
const QCString &s)
00932 {
00933 g_roups=s;
00934 e_ncCS=cachedCharset(
"UTF-8");
00935 }
00936
00937
00938 QCString Newsgroups::as7BitString(
bool incType)
00939 {
00940
if(incType)
00941
return (typeIntro()+g_roups);
00942
else
00943
return g_roups;
00944 }
00945
00946
00947 void Newsgroups::fromUnicodeString(
const QString &s,
const QCString&)
00948 {
00949 g_roups=s.utf8();
00950 e_ncCS=cachedCharset(
"UTF-8");
00951 }
00952
00953
00954 QString Newsgroups::asUnicodeString()
00955 {
00956
return QString::fromUtf8(g_roups);
00957 }
00958
00959
00960
QCString Newsgroups::firstGroup()
00961 {
00962
int pos=0;
00963
if(!g_roups.isEmpty()) {
00964 pos=g_roups.find(
',');
00965
if(pos==-1)
00966
return g_roups;
00967
else
00968
return g_roups.left(pos);
00969 }
00970
else
00971
return QCString();
00972 }
00973
00974
00975
QStringList Newsgroups::getGroups()
00976 {
00977
QStringList temp = QStringList::split(
',', g_roups);
00978
QStringList ret;
00979
QString s;
00980
00981
for (QStringList::Iterator it = temp.begin(); it != temp.end(); ++it ) {
00982 s = (*it).simplifyWhiteSpace();
00983 ret.append(s);
00984 }
00985
00986
return ret;
00987 }
00988
00989
00990
00991
00992
00993
00994
00995 void Lines::from7BitString(
const QCString &s)
00996 {
00997 l_ines=s.toInt();
00998 e_ncCS=cachedCharset(Latin1);
00999 }
01000
01001
01002 QCString Lines::as7BitString(
bool incType)
01003 {
01004
QCString num;
01005 num.setNum(l_ines);
01006
01007
if(incType)
01008
return ( typeIntro()+num );
01009
else
01010
return num;
01011 }
01012
01013
01014 void Lines::fromUnicodeString(
const QString &s,
const QCString&)
01015 {
01016 l_ines=s.toInt();
01017 e_ncCS=cachedCharset(Latin1);
01018 }
01019
01020
01021 QString Lines::asUnicodeString()
01022 {
01023
QString num;
01024 num.setNum(l_ines);
01025
01026
return num;
01027 }
01028
01029
01030
01031
01032
01033
#if !defined(KMIME_NEW_STYLE_CLASSTREE)
01034
01035
01036 void References::from7BitString(
const QCString &s)
01037 {
01038 r_ef=s;
01039 e_ncCS=cachedCharset(Latin1);
01040 }
01041
01042
01043 QCString References::as7BitString(
bool incType)
01044 {
01045
if(incType)
01046
return ( typeIntro()+r_ef );
01047
else
01048
return r_ef;
01049 }
01050
01051
01052 void References::fromUnicodeString(
const QString &s,
const QCString&)
01053 {
01054 r_ef=s.latin1();
01055 e_ncCS=cachedCharset(Latin1);
01056 }
01057
01058
01059 QString References::asUnicodeString()
01060 {
01061
return QString::fromLatin1(r_ef);
01062 }
01063
01064
01065
int References::count()
01066 {
01067
int cnt1=0, cnt2=0;
01068
unsigned int r_efLen=r_ef.length();
01069
char *dataPtr=r_ef.data();
01070
for(
unsigned int i=0; i<r_efLen; i++) {
01071
if(dataPtr[i]==
'<') cnt1++;
01072
else if(dataPtr[i]==
'>') cnt2++;
01073 }
01074
01075
if(cnt1<cnt2)
return cnt1;
01076
else return cnt2;
01077 }
01078
01079
01080
QCString References::first()
01081 {
01082 p_os=-1;
01083
return next();
01084 }
01085
01086
01087
QCString References::next()
01088 {
01089
int pos1=0, pos2=0;
01090
QCString ret;
01091
01092
if(p_os!=0) {
01093 pos2=r_ef.findRev(
'>', p_os);
01094 p_os=0;
01095
if(pos2!=-1) {
01096 pos1=r_ef.findRev(
'<', pos2);
01097
if(pos1!=-1) {
01098 ret=r_ef.mid(pos1, pos2-pos1+1);
01099 p_os=pos1;
01100 }
01101 }
01102 }
01103
return ret;
01104 }
01105
01106
01107
QCString References::at(
unsigned int i)
01108 {
01109
QCString ret;
01110
int pos1=0, pos2=0;
01111
unsigned int cnt=0;
01112
01113
while(pos1!=-1 && cnt < i+1) {
01114 pos2=pos1-1;
01115 pos1=r_ef.findRev(
'<', pos2);
01116 cnt++;
01117 }
01118
01119
if(pos1!=-1) {
01120 pos2=r_ef.find(
'>', pos1);
01121
if(pos2!=-1)
01122 ret=r_ef.mid(pos1, pos2-pos1+1);
01123 }
01124
01125
return ret;
01126 }
01127
01128
01129
void References::append(
const QCString &s)
01130 {
01131
QString temp=r_ef.data();
01132 temp +=
" ";
01133 temp += s.data();
01134
QStringList lst=QStringList::split(
' ',temp);
01135
QRegExp exp(
"^<.+@.+>$");
01136
01137
01138 QStringList::Iterator it = lst.begin();
01139
while (it != lst.end()) {
01140
if (-1==(*it).find(exp))
01141 it = lst.remove(it);
01142
else
01143 it++;
01144 }
01145
01146
if (lst.isEmpty()) {
01147 r_ef = s.copy();
01148
return;
01149 }
else
01150 r_ef =
"";
01151
01152 temp = lst.first();
01153 r_ef = temp.latin1();
01154 lst.remove(temp);
01155
int insPos = r_ef.length();
01156
01157
for (
int i=1;i<=3;i++) {
01158
if (!lst.isEmpty()) {
01159 temp = lst.last();
01160 r_ef.insert(insPos,(
QString(
" %1").arg(temp)).latin1());
01161 lst.remove(temp);
01162 }
else
01163
break;
01164 }
01165
01166
while (!lst.isEmpty()) {
01167 temp = lst.last();
01168
if ((15+r_ef.length()+temp.length())<1000) {
01169 r_ef.insert(insPos,(
QString(
" %1").arg(temp)).latin1());
01170 lst.remove(temp);
01171 }
else
01172
return;
01173 }
01174 }
01175
01176
01177
#endif
01178
01179
01180
01181
01182 void UserAgent::from7BitString(
const QCString &s)
01183 {
01184 u_agent=s;
01185 e_ncCS=cachedCharset(Latin1);
01186 }
01187
01188
01189 QCString UserAgent::as7BitString(
bool incType)
01190 {
01191
if(incType)
01192
return ( typeIntro()+u_agent );
01193
else
01194
return u_agent;
01195 }
01196
01197
01198 void UserAgent::fromUnicodeString(
const QString &s,
const QCString&)
01199 {
01200 u_agent=s.latin1();
01201 e_ncCS=cachedCharset(Latin1);
01202 }
01203
01204
01205 QString UserAgent::asUnicodeString()
01206 {
01207
return QString::fromLatin1(u_agent);
01208 }
01209
01210
01211
01212
01213
01214
#if !defined(KMIME_NEW_STYLE_CLASSTREE)
01215
01216
01217 void ContentType::from7BitString(
const QCString &s)
01218 {
01219
int pos=s.find(
';');
01220
01221
if(pos==-1)
01222 m_imeType=s.simplifyWhiteSpace();
01223
else {
01224 m_imeType=s.left(pos).simplifyWhiteSpace();
01225 p_arams=s.mid(pos, s.length()-pos).simplifyWhiteSpace();
01226 }
01227
01228
if(isMultipart())
01229 c_ategory=CCcontainer;
01230
else
01231 c_ategory=CCsingle;
01232
01233 e_ncCS=cachedCharset(Latin1);
01234 }
01235
01236
01237 QCString ContentType::as7BitString(
bool incType)
01238 {
01239
if(incType)
01240
return (typeIntro()+m_imeType+p_arams);
01241
else
01242
return (m_imeType+p_arams);
01243 }
01244
01245
01246 void ContentType::fromUnicodeString(
const QString &s,
const QCString&)
01247 {
01248 from7BitString(
QCString(s.latin1()) );
01249 }
01250
01251
01252 QString ContentType::asUnicodeString()
01253 {
01254
return QString::fromLatin1(as7BitString(
false));
01255 }
01256
01257
01258
QCString ContentType::mediaType()
01259 {
01260
int pos=m_imeType.find(
'/');
01261
if(pos==-1)
01262
return m_imeType;
01263
else
01264
return m_imeType.left(pos);
01265 }
01266
01267
01268
QCString ContentType::subType()
01269 {
01270
int pos=m_imeType.find(
'/');
01271
if(pos==-1)
01272
return QCString();
01273
else
01274
return m_imeType.mid(pos, m_imeType.length()-pos);
01275 }
01276
01277
01278
void ContentType::setMimeType(
const QCString &s)
01279 {
01280 p_arams.resize(0);
01281 m_imeType=s;
01282
01283
if(isMultipart())
01284 c_ategory=CCcontainer;
01285
else
01286 c_ategory=CCsingle;
01287 }
01288
01289
01290
bool ContentType::isMediatype(
const char *s)
01291 {
01292
return ( strncasecmp(m_imeType.data(), s, strlen(s)) );
01293 }
01294
01295
01296
bool ContentType::isSubtype(
const char *s)
01297 {
01298
char *c=strchr(m_imeType.data(),
'/');
01299
01300
if( (c==0) || (*(c+1)==
'\0') )
01301
return false;
01302
else
01303
return ( strcasecmp(c+1, s)==0 );
01304 }
01305
01306
01307
bool ContentType::isText()
01308 {
01309
return (strncasecmp(m_imeType.data(),
"text", 4)==0);
01310 }
01311
01312
01313
bool ContentType::isPlainText()
01314 {
01315
return (strcasecmp(m_imeType.data(),
"text/plain")==0);
01316 }
01317
01318
01319
bool ContentType::isHTMLText()
01320 {
01321
return (strcasecmp(m_imeType.data(),
"text/html")==0);
01322 }
01323
01324
01325
bool ContentType::isImage()
01326 {
01327
return (strncasecmp(m_imeType.data(),
"image", 5)==0);
01328 }
01329
01330
01331
bool ContentType::isMultipart()
01332 {
01333
return (strncasecmp(m_imeType.data(),
"multipart", 9)==0);
01334 }
01335
01336
01337
bool ContentType::isPartial()
01338 {
01339
return (strcasecmp(m_imeType.data(),
"message/partial")==0);
01340 }
01341
01342
01343
QCString ContentType::charset()
01344 {
01345
QCString ret=getParameter(
"charset");
01346
if( ret.isEmpty() || forceCS() ) {
01347 ret=defaultCS();
01348 }
01349
return ret;
01350 }
01351
01352
01353
void ContentType::setCharset(
const QCString &s)
01354 {
01355 setParameter(
"charset", s);
01356 }
01357
01358
01359
QCString ContentType::boundary()
01360 {
01361
return getParameter(
"boundary");
01362 }
01363
01364
01365
void ContentType::setBoundary(
const QCString &s)
01366 {
01367 setParameter(
"boundary", s,
true);
01368 }
01369
01370
01371
QString ContentType::name()
01372 {
01373
const char *dummy=0;
01374
return ( decodeRFC2047String(getParameter(
"name"), &dummy, defaultCS(), forceCS()) );
01375 }
01376
01377
01378
void ContentType::setName(
const QString &s,
const QCString &cs)
01379 {
01380 e_ncCS=cs;
01381
01382
if (isUsAscii(s)) {
01383
QCString tmp(s.latin1());
01384 addQuotes(tmp,
true);
01385 setParameter(
"name", tmp,
false);
01386 }
else {
01387
01388 setParameter(
"name", encodeRFC2047String(s, cs),
true);
01389 }
01390 }
01391
01392
01393
QCString ContentType::id()
01394 {
01395
return (getParameter(
"id"));
01396 }
01397
01398
01399
void ContentType::setId(
const QCString &s)
01400 {
01401 setParameter(
"id", s,
true);
01402 }
01403
01404
01405
int ContentType::partialNumber()
01406 {
01407
QCString p=getParameter(
"number");
01408
if(!p.isEmpty())
01409
return p.toInt();
01410
else
01411
return -1;
01412 }
01413
01414
01415
int ContentType::partialCount()
01416 {
01417
QCString p=getParameter(
"total");
01418
if(!p.isEmpty())
01419
return p.toInt();
01420
else
01421
return -1;
01422 }
01423
01424
01425
void ContentType::setPartialParams(
int total,
int number)
01426 {
01427
QCString num;
01428 num.setNum(number);
01429 setParameter(
"number", num);
01430 num.setNum(total);
01431 setParameter(
"total", num);
01432 }
01433
01434
01435
QCString ContentType::getParameter(
const char *name)
01436 {
01437
QCString ret;
01438
int pos1=0, pos2=0;
01439 pos1=p_arams.find(name, 0,
false);
01440
if(pos1!=-1) {
01441
if( (pos2=p_arams.find(
';', pos1))==-1 )
01442 pos2=p_arams.length();
01443 pos1+=strlen(name)+1;
01444 ret=p_arams.mid(pos1, pos2-pos1);
01445 removeQuots(ret);
01446 }
01447
return ret;
01448 }
01449
01450
01451
void ContentType::setParameter(
const QCString &name,
const QCString &value,
bool doubleQuotes)
01452 {
01453
int pos1=0, pos2=0;
01454
QCString param;
01455
01456
if(doubleQuotes)
01457 param=name+
"=\""+value+
"\"";
01458
else
01459 param=name+
"="+value;
01460
01461 pos1=p_arams.find(name, 0,
false);
01462
if(pos1==-1) {
01463 p_arams+=
"; "+param;
01464 }
01465
else {
01466 pos2=p_arams.find(
';', pos1);
01467
if(pos2==-1)
01468 pos2=p_arams.length();
01469 p_arams.remove(pos1, pos2-pos1);
01470 p_arams.insert(pos1, param);
01471 }
01472 }
01473
01474
01475
01476
01477
01478
01479
01480
typedef struct {
const char *s;
int e; } encTableType;
01481
01482
static const encTableType encTable[] = { {
"7Bit", CE7Bit },
01483 {
"8Bit", CE8Bit },
01484 {
"quoted-printable", CEquPr },
01485 {
"base64", CEbase64 },
01486 {
"x-uuencode", CEuuenc },
01487 {
"binary", CEbinary },
01488 { 0, 0} };
01489
01490
01491 void CTEncoding::from7BitString(
const QCString &s)
01492 {
01493
QCString stripped(s.simplifyWhiteSpace());
01494 c_te=CE7Bit;
01495
for(
int i=0; encTable[i].s!=0; i++)
01496
if(strcasecmp(stripped.data(), encTable[i].s)==0) {
01497 c_te=(contentEncoding)encTable[i].e;
01498
break;
01499 }
01500 d_ecoded=( c_te==CE7Bit || c_te==CE8Bit );
01501
01502 e_ncCS=cachedCharset(Latin1);
01503 }
01504
01505
01506 QCString CTEncoding::as7BitString(
bool incType)
01507 {
01508
QCString str;
01509
for(
int i=0; encTable[i].s!=0; i++)
01510
if(c_te==encTable[i].e) {
01511 str=encTable[i].s;
01512
break;
01513 }
01514
01515
if(incType)
01516
return ( typeIntro()+str );
01517
else
01518
return str;
01519 }
01520
01521
01522 void CTEncoding::fromUnicodeString(
const QString &s,
const QCString&)
01523 {
01524 from7BitString(
QCString(s.latin1()) );
01525 }
01526
01527
01528 QString CTEncoding::asUnicodeString()
01529 {
01530
return QString::fromLatin1(as7BitString(
false));
01531 }
01532
01533
01534
01535
01536
01537
01538
01539 void CDisposition::from7BitString(
const QCString &s)
01540 {
01541
if(strncasecmp(s.data(),
"attachment", 10)==0)
01542 d_isp=CDattachment;
01543
else d_isp=CDinline;
01544
01545
int pos=s.find(
"filename=", 0,
false);
01546
QCString fn;
01547
if(pos>-1) {
01548 pos+=9;
01549 fn=s.mid(pos, s.length()-pos);
01550 removeQuots(fn);
01551 f_ilename=decodeRFC2047String(fn, &e_ncCS, defaultCS(), forceCS());
01552 }
01553 }
01554
01555
01556 QCString CDisposition::as7BitString(
bool incType)
01557 {
01558
QCString ret;
01559
if(d_isp==CDattachment)
01560 ret=
"attachment";
01561
else
01562 ret=
"inline";
01563
01564
if(!f_ilename.isEmpty()) {
01565
if (isUsAscii(f_ilename)) {
01566
QCString tmp(f_ilename.latin1());
01567 addQuotes(tmp,
true);
01568 ret+=
"; filename="+tmp;
01569 }
else {
01570
01571 ret+=
"; filename=\""+encodeRFC2047String(f_ilename, e_ncCS)+
"\"";
01572 }
01573 }
01574
01575
if(incType)
01576
return ( typeIntro()+ret );
01577
else
01578
return ret;
01579 }
01580
01581
01582 void CDisposition::fromUnicodeString(
const QString &s,
const QCString &cs)
01583 {
01584
if(strncasecmp(s.latin1(),
"attachment", 10)==0)
01585 d_isp=CDattachment;
01586
else d_isp=CDinline;
01587
01588
int pos=s.find(
"filename=", 0,
false);
01589
if(pos>-1) {
01590 pos+=9;
01591 f_ilename=s.mid(pos, s.length()-pos);
01592 removeQuots(f_ilename);
01593 }
01594
01595 e_ncCS=cachedCharset(cs);
01596 }
01597
01598
01599 QString CDisposition::asUnicodeString()
01600 {
01601
QString ret;
01602
if(d_isp==CDattachment)
01603 ret=
"attachment";
01604
else
01605 ret=
"inline";
01606
01607
if(!f_ilename.isEmpty())
01608 ret+=
"; filename=\""+f_ilename+
"\"";
01609
01610
return ret;
01611 }
01612
01613
01614
#endif
01615
}
01616
01617 }