36 #include <sys/types.h>
41 #include <QtCore/QTextCodec>
42 #include <QtCore/QBuffer>
43 #include <QtCore/QRegExp>
44 #include <QtCore/QByteArray>
45 #include <QtCore/QLatin1Char>
48 using namespace KIMAP;
54 static const unsigned char base64chars[] =
55 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
58 static const char especials[17] =
"()<>@,;:\"/[]?.= ";
61 #define UTF16MASK 0x03FFUL
63 #define UTF16BASE 0x10000UL
64 #define UTF16HIGHSTART 0xD800UL
65 #define UTF16HIGHEND 0xDBFFUL
66 #define UTF16LOSTART 0xDC00UL
67 #define UTF16LOEND 0xDFFFUL
73 unsigned char c, i, bitcount;
74 unsigned long ucs4, utf16, bitbuf;
75 unsigned char base64[256], utf8[6];
76 unsigned int srcPtr = 0;
79 uint srcLen = inSrc.
length();
82 memset( base64, UNDEFINED,
sizeof( base64 ) );
83 for ( i = 0; i <
sizeof( base64chars ); ++i ) {
84 base64[(int)base64chars[i]] = i;
88 while ( srcPtr < srcLen ) {
91 if ( c !=
'&' || src[srcPtr] ==
'-' ) {
103 while ( ( c = base64[(
unsigned char)src[srcPtr]] ) != UNDEFINED ) {
105 bitbuf = ( bitbuf << 6 ) | c;
108 if ( bitcount >= 16 ) {
110 utf16 = ( bitcount ? bitbuf >> bitcount : bitbuf ) & 0xffff;
112 if ( utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND ) {
113 ucs4 = ( utf16 - UTF16HIGHSTART ) << UTF16SHIFT;
115 }
else if ( utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND ) {
116 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
121 if ( ucs4 <= 0x7fUL ) {
124 }
else if ( ucs4 <= 0x7ffUL ) {
125 utf8[0] = 0xc0 | ( ucs4 >> 6 );
126 utf8[1] = 0x80 | ( ucs4 & 0x3f );
128 }
else if ( ucs4 <= 0xffffUL ) {
129 utf8[0] = 0xe0 | ( ucs4 >> 12 );
130 utf8[1] = 0x80 | ( ( ucs4 >> 6 ) & 0x3f );
131 utf8[2] = 0x80 | ( ucs4 & 0x3f );
134 utf8[0] = 0xf0 | ( ucs4 >> 18 );
135 utf8[1] = 0x80 | ( ( ucs4 >> 12 ) & 0x3f );
136 utf8[2] = 0x80 | ( ( ucs4 >> 6 ) & 0x3f );
137 utf8[3] = 0x80 | ( ucs4 & 0x3f );
141 for ( c = 0; c < i; ++c ) {
147 if ( src[srcPtr] ==
'-' ) {
167 for (
unsigned int i = 0; i < len; i++ ) {
168 if ( src[i] ==
'"' || src[i] ==
'\\' ) {
182 for (
unsigned int i = 0; i < len; i++ ) {
200 unsigned int utf8pos, utf8total, c, utf7mode, bitstogo, utf16flag;
201 unsigned int ucs4, bitbuf;
212 while ( srcPtr < src.
length () ) {
213 c = (
unsigned char)src[srcPtr++];
215 if ( c >=
' ' && c <=
'~' ) {
219 dst += base64chars[( bitbuf << ( 6 - bitstogo ) ) & 0x3F];
241 }
else if ( utf8total ) {
243 ucs4 = ( ucs4 << 6 ) | ( c & 0x3FUL );
244 if ( ++utf8pos < utf8total ) {
252 }
else if ( c < 0xF0 ) {
266 if ( ucs4 >= UTF16BASE ) {
269 ( bitbuf << 16 ) | ( ( ucs4 >> UTF16SHIFT ) + UTF16HIGHSTART );
270 ucs4 = ( ucs4 & UTF16MASK ) + UTF16LOSTART;
273 bitbuf = ( bitbuf << 16 ) | ucs4;
278 while ( bitstogo >= 6 ) {
281 base64chars[( bitstogo ? ( bitbuf >> bitstogo ) : bitbuf ) & 0x3F];
289 dst += base64chars[( bitbuf << ( 6 - bitstogo ) ) & 0x3F];
293 return quoteIMAP( dst );
311 return decodeRFC2047String( str, throw_away );
320 return decodeRFC2047String( str, charset, throw_away );
336 char *pos, *beg, *end, *mid = 0;
338 char encoding = 0, ch;
340 const int maxLen = 200;
344 for ( pos = aStr.
data (); *pos; pos++ ) {
345 if ( pos[0] !=
'=' || pos[1] !=
'?' ) {
353 for ( i = 2, pos += 2;
355 ( *pos !=
'?' && ( ispunct( *pos ) || isalnum ( *pos ) ) );
359 if ( *pos !=
'?' || i < 4 || i >= maxLen ) {
366 language = charset.
right( charset.
length () - pt - 1 );
372 encoding = toupper( pos[1] );
373 if ( pos[2] !=
'?' ||
374 ( encoding !=
'Q' && encoding !=
'B' &&
375 encoding !=
'q' && encoding !=
'b' ) ) {
385 while ( i < maxLen && *pos && !( *pos ==
'?' && *( pos + 1 ) ==
'=' ) ) {
390 if ( i >= maxLen || !*pos ) {
398 if ( encoding ==
'Q' ) {
400 for ( i = cstr.
length () - 1; i >= 0; --i ) {
401 if ( cstr[i] ==
'_' ) {
407 cstr = KCodecs::quotedPrintableDecode( cstr );
416 for ( i = 0; i < len; ++i ) {
453 const signed char *latin =
454 reinterpret_cast<const signed char *
>
455 ( str.
data() ), *l, *start, *stop;
460 int resultLen = 3 * str.
length() / 2;
479 for ( i = 0; i < 16; ++i ) {
480 if ( *l == especials[i] ) {
488 if ( l - start + 2 * numQuotes >= 58 || *l == 60 ) {
495 while ( stop >= start && *stop != 32 ) {
498 if ( stop <= start ) {
504 if ( resultLen - rptr - 1 <= start - latin + 1 + 16 ) {
506 resultLen += ( start - latin + 1 ) * 2 + 20;
507 result.
resize( resultLen );
509 while ( latin < start ) {
510 result[rptr++] = *latin;
513 result.
replace( rptr, 15,
"=?iso-8859-1?q?" );
515 if ( resultLen - rptr - 1 <= 3 * ( stop - latin + 1 ) ) {
516 resultLen += ( stop - latin + 1 ) * 4 + 20;
517 result.
resize( resultLen );
519 while ( latin < stop ) {
522 for ( i = 0; i < 16; ++i ) {
523 if ( *latin == especials[i] ) {
531 result[rptr++] =
'=';
532 hexcode = ( ( *latin & 0xF0 ) >> 4 ) + 48;
533 if ( hexcode >= 58 ) {
536 result[rptr++] = hexcode;
537 hexcode = ( *latin & 0x0F ) + 48;
538 if ( hexcode >= 58 ) {
541 result[rptr++] = hexcode;
543 result[rptr++] = *latin;
547 result[rptr++] =
'?';
548 result[rptr++] =
'=';
551 if ( rptr == resultLen - 1 ) {
553 result.
resize( resultLen );
555 result[rptr++] = *latin;
571 signed char *latin = (
signed char *)calloc( 1, str.
length () + 1 );
572 char *latin_us = (
char *)latin;
573 strcpy( latin_us, str.
toLatin1 () );
574 signed char *l = latin;
592 for ( i = 0; i < 16; ++i ) {
593 if ( *l == especials[i] ) {
599 hexcode = ( ( *l & 0xF0 ) >> 4 ) + 48;
600 if ( hexcode >= 58 ) {
604 hexcode = ( *l & 0x0F ) + 48;
605 if ( hexcode >= 58 ) {
644 while ( p < (
int) st.
length () ) {
645 if ( st.
at( p ) == 37 ) {
654 st.
replace( p, 1, ch * 16 + ch2 );
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
This file is part of the IMAP support library and defines the RfcCodecs class.
void truncate(int position)
QString & remove(int position, int n)
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString fromUtf8(const char *str, int size)
QByteArray & replace(int pos, int len, const char *after)
QString right(int n) const
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QString & replace(int position, int n, QChar after)
QByteArray left(int len) const
QByteArray toLatin1() const
QString mid(int position, int n) const
QByteArray fromBase64(const QByteArray &base64)
const QChar at(int position) const
QTextCodec * codecForName(const QByteArray &name)
QString toUnicode(const QByteArray &a) const
QByteArray toUtf8() const