23 #include "rfcdecoder.h"
26 #include <sys/types.h>
31 #include <tqtextcodec.h>
39 static unsigned char base64chars[] =
40 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
45 #define UTF16MASK 0x03FFUL
47 #define UTF16BASE 0x10000UL
48 #define UTF16HIGHSTART 0xD800UL
49 #define UTF16HIGHEND 0xDBFFUL
50 #define UTF16LOSTART 0xDC00UL
51 #define UTF16LOEND 0xDFFFUL
57 unsigned char c, i, bitcount;
58 unsigned long ucs4, utf16, bitbuf;
59 unsigned char base64[256], utf8[6];
60 unsigned long srcPtr = 0;
62 TQCString src = inSrc.ascii ();
63 uint srcLen = inSrc.length();
66 memset (base64, UNDEFINED,
sizeof (base64));
67 for (i = 0; i <
sizeof (base64chars); ++i)
69 base64[(int)base64chars[i]] = i;
73 while (srcPtr < srcLen)
77 if (c !=
'&' || src[srcPtr] ==
'-')
91 while ((c = base64[(
unsigned char) src[srcPtr]]) != UNDEFINED)
94 bitbuf = (bitbuf << 6) | c;
100 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
102 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND)
104 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
107 else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND)
109 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
121 else if (ucs4 <= 0x7ffUL)
123 utf8[0] = 0xc0 | (ucs4 >> 6);
124 utf8[1] = 0x80 | (ucs4 & 0x3f);
127 else if (ucs4 <= 0xffffUL)
129 utf8[0] = 0xe0 | (ucs4 >> 12);
130 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
131 utf8[2] = 0x80 | (ucs4 & 0x3f);
136 utf8[0] = 0xf0 | (ucs4 >> 18);
137 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
138 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
139 utf8[3] = 0x80 | (ucs4 & 0x3f);
143 for (c = 0; c < i; ++c)
150 if (src[srcPtr] ==
'-')
154 return TQString::fromUtf8 (dst.data ());
160 uint len = src.length();
162 result.reserve(2 * len);
163 for (
unsigned int i = 0; i < len; i++)
165 if (src[i] ==
'"' || src[i] ==
'\\')
177 unsigned int utf8pos, utf8total, c, utf7mode, bitstogo, utf16flag;
178 unsigned long ucs4, bitbuf;
179 TQCString src = inSrc.utf8 ();
189 while (srcPtr < src.length ())
191 c = (
unsigned char) src[srcPtr++];
193 if (c >=
' ' && c <=
'~')
200 dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
229 ucs4 = (ucs4 << 6) | (c & 0x3FUL);
230 if (++utf8pos < utf8total)
260 if (ucs4 >= UTF16BASE)
263 bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT) + UTF16HIGHSTART);
264 ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART;
269 bitbuf = (bitbuf << 16) | ucs4;
274 while (bitstogo >= 6)
277 dst += base64chars[(bitstogo ? (bitbuf >> bitstogo) : bitbuf) & 0x3F];
287 dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
298 unsigned int strLength(aStr.length());
299 for (
unsigned int i = 0; i < strLength ; i++)
301 if (aStr[i] ==
"\\") i++;
313 return TQTextCodec::codecForName (_str.lower ().
314 replace (
"windows",
"cp").latin1 ());
341 if (_str.find(
"=?") < 0)
344 TQCString aStr = _str.ascii ();
346 char *pos, *beg, *end, *mid = NULL;
348 char encoding = 0, ch;
350 const int maxLen = 200;
354 for (pos = aStr.data (); *pos; pos++)
356 if (pos[0] !=
'=' || pos[1] !=
'?')
365 for (i = 2, pos += 2;
366 i < maxLen && (*pos !=
'?' && (ispunct (*pos) || isalnum (*pos)));
369 if (*pos !=
'?' || i < 4 || i >= maxLen)
373 charset = TQCString (beg, i - 1);
374 int pt = charset.findRev(
'*');
378 language = charset.right (charset.length () - pt - 1);
381 charset.truncate(pt);
384 encoding = toupper (pos[1]);
386 || (encoding !=
'Q' && encoding !=
'B' && encoding !=
'q'
397 while (i < maxLen && *pos && !(*pos ==
'?' && *(pos + 1) ==
'='))
403 if (i >= maxLen || !*pos)
410 str = TQCString (mid).left ((
int) (mid - pos - 1));
414 for (i = str.length () - 1; i >= 0; i--)
419 str = KCodecs::quotedPrintableDecode(str);
425 str = KCodecs::base64Decode(str);
428 int len = str.length();
429 for (i = 0; i < len; i++)
430 result += (
char) (TQChar) str[i];
444 if (!charset.isEmpty ())
450 return aCodec->toUnicode (result);
458 const char especials[17] =
"()<>@,;:\"/[]?.= ";
465 const signed char *latin =
reinterpret_cast<const signed char *
>(_str.latin1()), *l, *start, *stop;
470 int resultLen = 3 * _str.length() / 2;
471 TQCString result(resultLen);
491 for (i = 0; i < 16; i++)
492 if (*l == especials[i])
497 if (l - start + 2 * numQuotes >= 58 || *l == 60)
504 while (stop >= start && *stop != 32)
511 if (resultLen - rptr - 1 <= start - latin + 1 + 16 ) {
512 resultLen += (start - latin + 1) * 2 + 20;
513 result.resize(resultLen);
515 while (latin < start)
517 result[rptr++] = *latin;
520 strcpy(&result[rptr],
"=?iso-8859-1?q?"); rptr += 15;
521 if (resultLen - rptr - 1 <= 3*(stop - latin + 1)) {
522 resultLen += (stop - latin + 1) * 4 + 20;
523 result.resize(resultLen);
528 for (i = 0; i < 16; i++)
529 if (*latin == especials[i])
535 result[rptr++] =
'=';
536 hexcode = ((*latin & 0xF0) >> 4) + 48;
539 result[rptr++] = hexcode;
540 hexcode = (*latin & 0x0F) + 48;
543 result[rptr++] = hexcode;
547 result[rptr++] = *latin;
551 result[rptr++] =
'?';
552 result[rptr++] =
'=';
558 if (rptr == resultLen - 1) {
560 result.resize(resultLen);
562 result[rptr++] = *latin;
579 signed char *latin = (
signed char *) calloc (1, _str.length () + 1);
580 char *latin_us = (
char *) latin;
581 strcpy (latin_us, _str.latin1 ());
582 signed char *l = latin;
601 for (i = 0; i < 16; i++)
602 if (*l == especials[i])
607 hexcode = ((*l & 0xF0) >> 4) + 48;
611 hexcode = (*l & 0x0F) + 48;
631 int p = _str.find (
'\'');
637 int l = _str.findRev (
'\'');
644 TQString charset = _str.left (p);
645 TQString st = _str.mid (l + 1);
646 TQString language = _str.mid (p + 1, l - p - 1);
652 while (p < (
int) st.length ())
656 ch = st.at (p + 1).latin1 () - 48;
659 ch2 = st.at (p + 2).latin1 () - 48;
662 st.at (p) = ch * 16 + ch2;
663 st.remove (p + 1, 2);
static const TQString decodeRFC2047String(const TQString &_str, TQString &charset, TQString &language)
decode a RFC2047 String
static const TQString encodeRFC2231String(const TQString &_str)
encode a RFC2231 String
static TQString decodeQuoting(const TQString &aStr)
remove \ from a string
static TQString toIMAP(const TQString &inSrc)
Convert Unicode path to modified UTF-7 IMAP mailbox.
static TQTextCodec * codecForName(const TQString &)
fetch a codec by name
static TQString quoteIMAP(const TQString &src)
replace " with \" and \ with \ " and \ characters
static const TQString decodeRFC2231String(const TQString &_str)
decode a RFC2231 String
static TQString fromIMAP(const TQString &src)
Convert an IMAP mailbox to a Unicode path.
static const TQString encodeRFC2047String(const TQString &_str, TQString &charset, TQString &language)
encode a RFC2047 String