TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mailsubject.cpp 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include"mailsubject.h"
  2. #include <kmime_codecs.h>
  3. #include <kcharsets.h>
  4. #include <kdebug.h>
  5. #include <tdeglobal.h>
  6. #include <tdelocale.h>
  7. #include <tqdatetime.h>
  8. #include <tqtextcodec.h>
  9. #include <ctype.h>
  10. KornMailSubject::KornMailSubject() : _id(0), _drop(0), _size(-1), _date(-1), _fullMessage(false)
  11. {
  12. }
  13. KornMailSubject::KornMailSubject(KornMailId * id, KMailDrop *drop)
  14. : _id(id), _drop( drop ), _size(-1), _date(-1), _fullMessage(false)
  15. {
  16. }
  17. KornMailSubject::KornMailSubject(const KornMailSubject & src)
  18. : _id(0), _drop(0), _size(-1), _date(-1)
  19. {
  20. operator=(src);
  21. }
  22. KornMailSubject & KornMailSubject::operator= (const KornMailSubject & src)
  23. {
  24. _size = src._size;
  25. _date = src._date;
  26. _subject = src._subject;
  27. _sender = src._sender;
  28. _header = src._header;
  29. _fullMessage = src._fullMessage;
  30. if (_id)
  31. delete _id;
  32. _id = 0;
  33. if (src._id)
  34. _id = src._id->clone();
  35. _drop = src._drop;
  36. return *this;
  37. }
  38. KornMailSubject::~KornMailSubject()
  39. {
  40. if (_id)
  41. delete _id;
  42. _id = 0;
  43. }
  44. TQString KornMailSubject::toString() const
  45. {
  46. TQDateTime date;
  47. date.setTime_t(_date);
  48. return TQString("KornMailSubject, Id: ") + (_id?_id->toString():TQString("NULL")) + ", " + i18n("Subject:") + " " + _subject
  49. + ", " + i18n("Sender:") + " " + _sender + ", " + i18n("Size:") + " " + TQString::number(_size)
  50. + ", " + i18n("Date:") + " " + date.toString(Qt::ISODate);
  51. }
  52. TQString KornMailSubject::decodeRFC2047String(const TQCString& aStr)
  53. {
  54. if ( aStr.isEmpty() )
  55. return TQString();
  56. const TQCString str = unfold( aStr );
  57. if ( str.isEmpty() )
  58. return TQString();
  59. if ( str.find( "=?" ) < 0 ) {
  60. // No need to decode
  61. return TQString(str);
  62. }
  63. TQString result;
  64. TQCString LWSP_buffer;
  65. bool lastWasEncodedWord = false;
  66. for ( const char * pos = str.data() ; *pos ; ++pos ) {
  67. // collect LWSP after encoded-words,
  68. // because we might need to throw it out
  69. // (when the next word is an encoded-word)
  70. if ( lastWasEncodedWord && isBlank( pos[0] ) ) {
  71. LWSP_buffer += pos[0];
  72. continue;
  73. }
  74. // verbatimly copy normal text
  75. if (pos[0]!='=' || pos[1]!='?') {
  76. result += LWSP_buffer + pos[0];
  77. LWSP_buffer = 0;
  78. lastWasEncodedWord = false;
  79. continue;
  80. }
  81. // found possible encoded-word
  82. const char * const beg = pos;
  83. {
  84. // parse charset name
  85. TQCString charset;
  86. int i = 2;
  87. pos += 2;
  88. for ( ; *pos != '?' && ( *pos==' ' || ispunct(*pos) || isalnum(*pos) ); ++i, ++pos ) {
  89. charset += *pos;
  90. }
  91. if ( *pos!='?' || i<4 )
  92. goto invalid_encoded_word;
  93. // get encoding and check delimiting question marks
  94. const char encoding[2] = { pos[1], '\0' };
  95. if (pos[2]!='?' || (encoding[0]!='Q' && encoding[0]!='q' &&
  96. encoding[0]!='B' && encoding[0]!='b'))
  97. goto invalid_encoded_word;
  98. pos+=3; i+=3; // skip ?x?
  99. const char * enc_start = pos;
  100. // search for end of encoded part
  101. while ( *pos && !(*pos=='?' && *(pos+1)=='=') ) {
  102. i++;
  103. pos++;
  104. }
  105. if ( !*pos )
  106. goto invalid_encoded_word;
  107. // valid encoding: decode and throw away separating LWSP
  108. const KMime::Codec * c = KMime::Codec::codecForName( encoding );
  109. kdFatal( !c ) << "No \"" << encoding << "\" codec!?" << endl;
  110. TQByteArray in; in.setRawData( enc_start, pos - enc_start );
  111. const TQByteArray enc = c->decode( in );
  112. in.resetRawData( enc_start, pos - enc_start );
  113. const TQTextCodec * codec = codecForName(charset);
  114. if (!codec) return TQString();
  115. result += codec->toUnicode(enc);
  116. lastWasEncodedWord = true;
  117. ++pos; // eat '?' (for loop eats '=')
  118. LWSP_buffer = 0;
  119. }
  120. continue;
  121. invalid_encoded_word:
  122. // invalid encoding, keep separating LWSP.
  123. pos = beg;
  124. if ( !LWSP_buffer.isNull() )
  125. result += LWSP_buffer;
  126. result += "=?";
  127. lastWasEncodedWord = false;
  128. ++pos; // eat '?' (for loop eats '=')
  129. LWSP_buffer = 0;
  130. }
  131. return result;
  132. }
  133. TQCString KornMailSubject::unfold( const TQCString & header )
  134. {
  135. if ( header.isEmpty() )
  136. return TQCString();
  137. TQCString result( header.size() ); // size() >= length()+1 and size() is O(1)
  138. char * d = result.data();
  139. for ( const char * s = header.data() ; *s ; )
  140. if ( *s == '\r' ) { // ignore
  141. ++s;
  142. continue;
  143. } else if ( *s == '\n' ) { // unfold
  144. while ( this->isBlank( *++s ) );
  145. *d++ = ' ';
  146. } else
  147. *d++ = *s++;
  148. *d++ = '\0';
  149. result.truncate( d - result.data() );
  150. return result;
  151. }
  152. //-----------------------------------------------------------------------------
  153. const TQTextCodec* KornMailSubject::codecForName(const TQCString& _str)
  154. {
  155. if (_str.isEmpty()) return 0;
  156. TQCString codec = _str;
  157. return TDEGlobal::charsets()->codecForName(codec);
  158. }
  159. void KornMailSubject::decodeHeaders()
  160. {
  161. _subject = decodeRFC2047String( _subject.latin1() );
  162. _sender = decodeRFC2047String( _sender.latin1() );
  163. }