23 #include "kmime_parsers.h"
25 #include <QtCore/QRegExp>
26 #include <QtCore/QByteArray>
28 using namespace KMime::Parser;
33 MultiPart::MultiPart(
const QByteArray &src,
const QByteArray &boundary )
39 bool MultiPart::parse()
41 QByteArray b =
"--" + b_oundary, part;
42 int pos1=0, pos2=0, blen=b.length();
48 if ( ( pos1 = s_rc.indexOf( b, pos1 ) ) == -1 || pos1 == 0 ||
49 s_rc[pos1-1] ==
'\n' ) {
57 if ( s_rc[pos1] ==
'-' && s_rc[pos1+1] ==
'-' ) {
61 }
else if ( ( pos1 - blen ) > 1 ) {
62 p_reamble = s_rc.left( pos1 - blen - 1 );
66 while ( pos1 > -1 && pos2 > -1 ) {
69 if ( ( pos1 = s_rc.indexOf(
'\n', pos1 ) ) > -1 ) {
74 if ( ( pos2 = s_rc.indexOf( b, pos2 ) ) == -1 ||
75 s_rc[pos2-1] ==
'\n' ) {
82 part = s_rc.mid( pos1, s_rc.length() - pos1 );
83 p_arts.append( part );
87 part = s_rc.mid( pos1, pos2 - pos1 - 1 );
88 p_arts.append( part );
90 if ( s_rc[pos2] ==
'-' && s_rc[pos2+1] ==
'-' ) {
93 if ( ( pos1 = s_rc.indexOf(
'\n', pos1 ) ) > -1 ) {
95 e_pilouge = s_rc.mid( pos1 + 1, s_rc.length() - pos1 - 1 );
106 return !p_arts.isEmpty();
111 NonMimeParser::NonMimeParser(
const QByteArray &src ) :
112 s_rc( src ), p_artNr( -1 ), t_otalNr( -1 )
119 QByteArray NonMimeParser::guessMimeType(
const QByteArray &fileName )
121 QByteArray tmp, mimeType;
124 if ( !fileName.isEmpty() ) {
125 pos = fileName.lastIndexOf(
'.' );
127 tmp = fileName.mid( pos, fileName.length() - pos ).toUpper();
128 if ( tmp ==
"JPG" || tmp ==
"JPEG" ) {
129 mimeType =
"image/jpeg";
130 }
else if ( tmp ==
"GIF" ) {
131 mimeType =
"image/gif";
132 }
else if ( tmp ==
"PNG" ) {
133 mimeType =
"image/png";
134 }
else if ( tmp ==
"TIFF" || tmp ==
"TIF" ) {
135 mimeType =
"image/tiff";
136 }
else if ( tmp ==
"XPM" ) {
137 mimeType =
"image/x-xpixmap";
138 }
else if ( tmp ==
"XBM" ) {
139 mimeType =
"image/x-xbitmap";
140 }
else if ( tmp ==
"BMP" ) {
141 mimeType =
"image/bmp";
142 }
else if ( tmp ==
"TXT" ||
148 mimeType =
"text/plain";
149 }
else if ( tmp ==
"HTML" || tmp ==
"HTM" ) {
150 mimeType =
"text/html";
152 mimeType =
"application/octet-stream";
155 mimeType =
"application/octet-stream";
158 mimeType =
"application/octet-stream";
166 UUEncoded::UUEncoded(
const QByteArray &src,
const QByteArray &subject ) :
170 bool UUEncoded::parse()
173 bool success=
true, firstIteration=
true;
176 int beginPos=currentPos, uuStart=currentPos, endPos=0, lineCount=0, MCount=0, pos=0, len=0;
177 bool containsBegin=
false, containsEnd=
false;
178 QByteArray tmp, fileName;
180 if ( ( beginPos = QString::fromLatin1( s_rc ).indexOf( QRegExp( QLatin1String(
"begin [0-9][0-9][0-9]" ) ),
181 currentPos ) ) > -1 &&
182 ( beginPos == 0 || s_rc.at( beginPos - 1 ) ==
'\n' ) ) {
183 containsBegin =
true;
184 uuStart = s_rc.indexOf(
'\n', beginPos );
185 if ( uuStart == -1 ) {
195 if ( ( endPos = s_rc.indexOf(
"\nend", ( uuStart > 0 ) ? uuStart - 1 : 0 ) ) == -1 ) {
196 endPos = s_rc.length();
201 if ( ( containsBegin && containsEnd ) || firstIteration ) {
205 for (
int idx=uuStart; idx<endPos; idx++ ) {
206 if ( s_rc[idx] ==
'\n' ) {
208 if ( idx + 1 < endPos && s_rc[idx + 1] ==
'M' ) {
216 if ( MCount == 0 || ( lineCount - MCount ) > 10 ||
217 ( ( !containsBegin || !containsEnd ) && ( MCount < 15 ) ) ) {
223 if ( ( !containsBegin || !containsEnd ) && !s_ubject.isNull() ) {
225 QRegExp rx( QLatin1String(
"[0-9]+/[0-9]+" ) );
226 pos = rx.indexIn( QLatin1String( s_ubject ), 0 );
227 len = rx.matchedLength();
229 tmp = s_ubject.mid( pos, len );
230 pos = tmp.indexOf(
'/' );
231 p_artNr = tmp.left( pos ).toInt();
232 t_otalNr = tmp.right( tmp.length() - pos - 1 ).toInt();
240 if ( beginPos > 0 ) {
241 t_ext.append( s_rc.mid( currentPos, beginPos - currentPos ) );
244 if ( containsBegin ) {
246 fileName = s_rc.mid( beginPos + 10, uuStart - beginPos - 11 );
250 f_ilenames.append( fileName );
252 b_ins.append( s_rc.mid( uuStart, endPos - uuStart + 1 ) );
254 firstIteration =
false;
256 int next = s_rc.indexOf(
'\n', endPos + 1 );
271 t_ext.append( s_rc.right( s_rc.length() - currentPos ) );
273 return ( ( b_ins.count() > 0 ) || isPartial() );
278 YENCEncoded::YENCEncoded(
const QByteArray &src ) :
283 bool YENCEncoded::yencMeta( QByteArray &src,
const QByteArray &name,
int *value )
286 QByteArray sought=name +
'=';
288 int iPos = src.indexOf( sought );
290 int pos1 = src.indexOf(
' ', iPos );
291 int pos2 = src.indexOf(
'\r', iPos );
292 int pos3 = src.indexOf(
'\t', iPos );
293 int pos4 = src.indexOf(
'\n', iPos );
294 if ( pos2 >= 0 && ( pos1 < 0 || pos1 > pos2 ) ) {
297 if ( pos3 >= 0 && ( pos1 < 0 || pos1 > pos3 ) ) {
300 if ( pos4 >= 0 && ( pos1 < 0 || pos1 > pos4 ) ) {
303 iPos=src.lastIndexOf(
'=', pos1 ) + 1;
305 char c = src.at( iPos );
306 if ( c>=
'0' && c<=
'9' ) {
308 *value = src.mid( iPos, pos1 - iPos ).toInt();
315 bool YENCEncoded::parse()
321 int beginPos=currentPos, yencStart=currentPos;
322 bool containsPart=
false;
323 QByteArray fileName, mimeType;
325 if ( ( beginPos = s_rc.indexOf(
"=ybegin ", currentPos ) ) > -1 &&
326 ( beginPos == 0 || s_rc.at( beginPos - 1 ) ==
'\n' ) ) {
327 yencStart = s_rc.indexOf(
'\n', beginPos );
328 if ( yencStart == -1 ) {
333 if ( s_rc.indexOf(
"=ypart", yencStart ) == yencStart ) {
335 yencStart = s_rc.indexOf(
'\n', yencStart );
336 if ( yencStart == -1 ) {
346 QByteArray meta = s_rc.mid( beginPos, yencStart - beginPos );
347 int namePos = meta.indexOf(
"name=" );
348 if ( namePos == -1 ) {
352 int eolPos = meta.indexOf(
'\r', namePos );
353 if ( eolPos == -1 ) {
354 eolPos = meta.indexOf(
'\n', namePos );
356 if ( eolPos == -1 ) {
360 fileName = meta.mid( namePos + 5, eolPos - ( namePos + 5 ) );
364 if ( !yencMeta( meta,
"line", ¥cLine ) ) {
369 if ( !yencMeta( meta,
"size", ¥cSize ) ) {
374 int partBegin, partEnd;
375 if ( containsPart ) {
376 if ( !yencMeta( meta,
"part", &p_artNr ) ) {
380 if ( !yencMeta( meta,
"begin", &partBegin ) ||
381 !yencMeta( meta,
"end", &partEnd ) ) {
385 if ( !yencMeta( meta,
"total", &t_otalNr ) ) {
386 t_otalNr = p_artNr + 1;
388 if ( yencSize == partEnd - partBegin + 1 ) {
391 yencSize = partEnd - partBegin + 1;
398 int len = s_rc.length();
399 bool lineStart =
true;
401 bool containsEnd =
false;
403 binary.resize( yencSize );
404 while ( pos < len ) {
405 int ch = s_rc.at( pos );
410 if ( lineLength != yencLine && totalSize != yencSize ) {
415 else if ( ch ==
'\n' ) {
421 if ( pos + 1 < len ) {
422 ch = s_rc.at( pos + 1 );
423 if ( lineStart && ch ==
'y' ) {
432 if ( totalSize >= yencSize ) {
435 binary[totalSize++] = ch;
445 if ( totalSize >= yencSize ) {
448 binary[totalSize++] = ch;
456 if ( !containsEnd ) {
460 if ( totalSize != yencSize ) {
466 eolPos = s_rc.indexOf(
'\n', pos );
467 if ( eolPos == -1 ) {
471 meta = s_rc.mid( pos, eolPos - pos );
472 if ( !yencMeta( meta,
"size", &totalSize ) ) {
476 if ( totalSize != yencSize ) {
481 f_ilenames.append( fileName );
483 b_ins.append( binary );
486 if ( beginPos > 0 ) {
487 t_ext.append( s_rc.mid( currentPos, beginPos - currentPos ) );
489 currentPos = eolPos + 1;
497 t_ext.append( s_rc.right( s_rc.length() - currentPos ) );
499 return b_ins.count()>0;
static QByteArray guessMimeType(const QByteArray &fileName)
try to guess the mimetype from the file-extension
Helper-class: abstract base class of all parsers for non-mime binary data (uuencoded, yenc)