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.
196 indexOf(
"\nend", ( uuStart > 0 ) ? uuStart-1:0 ) ) == -1 ) {
197 endPos = s_rc.length();
202 if ( ( containsBegin && containsEnd ) || firstIteration ) {
206 for (
int idx=uuStart; idx<endPos; idx++ ) {
207 if ( s_rc[idx] ==
'\n' ) {
209 if ( idx+1 < endPos && s_rc[idx+1] ==
'M') {
217 if ( MCount == 0 || ( lineCount - MCount ) > 10 ||
218 ( ( !containsBegin || !containsEnd ) && ( MCount < 15 ) ) ) {
224 if ( ( !containsBegin || !containsEnd ) && !s_ubject.isNull() ) {
226 QRegExp rx( QLatin1String(
"[0-9]+/[0-9]+") );
227 pos = rx.indexIn( QLatin1String( s_ubject ), 0 );
228 len = rx.matchedLength();
230 tmp = s_ubject.mid( pos, len );
231 pos = tmp.indexOf(
'/' );
232 p_artNr = tmp.left( pos ).toInt();
233 t_otalNr = tmp.right( tmp.length() - pos - 1).toInt();
241 if ( beginPos > 0 ) {
242 t_ext.append( s_rc.mid( currentPos, beginPos - currentPos ) );
245 if ( containsBegin ) {
247 fileName = s_rc.mid( beginPos + 10, uuStart - beginPos - 11 );
251 f_ilenames.append( fileName );
253 b_ins.append( s_rc.mid( uuStart, endPos - uuStart + 1 ) );
255 firstIteration =
false;
257 int next = s_rc.indexOf(
'\n', endPos + 1 );
272 t_ext.append( s_rc.right( s_rc.length() - currentPos ) );
274 return ( ( b_ins.count() > 0 ) || isPartial() );
279 YENCEncoded::YENCEncoded(
const QByteArray &src ) :
284 bool YENCEncoded::yencMeta( QByteArray &src,
const QByteArray &name,
int *value )
287 QByteArray sought=name +
'=';
289 int iPos = src.indexOf( sought );
291 int pos1 = src.indexOf(
' ', iPos );
292 int pos2 = src.indexOf(
'\r', iPos );
293 int pos3 = src.indexOf(
'\t', iPos );
294 int pos4 = src.indexOf(
'\n', iPos );
295 if ( pos2 >= 0 && ( pos1 < 0 || pos1 > pos2 ) ) {
298 if ( pos3 >= 0 && ( pos1 < 0 || pos1 > pos3 ) ) {
301 if ( pos4 >= 0 && ( pos1 < 0 || pos1 > pos4 ) ) {
304 iPos=src.lastIndexOf(
'=', pos1 ) + 1;
306 char c = src.at( iPos );
307 if ( c>=
'0' && c<=
'9' ) {
309 *value = src.mid( iPos, pos1 - iPos ).toInt();
316 bool YENCEncoded::parse()
322 int beginPos=currentPos, yencStart=currentPos;
323 bool containsPart=
false;
324 QByteArray fileName, mimeType;
326 if ( ( beginPos = s_rc.
327 indexOf(
"=ybegin ", currentPos ) ) > -1 &&
328 ( beginPos == 0 || s_rc.at( beginPos - 1 ) ==
'\n' ) ) {
329 yencStart = s_rc.indexOf(
'\n', beginPos );
330 if ( yencStart == -1 ) {
335 if ( s_rc.indexOf(
"=ypart", yencStart ) == yencStart ) {
337 yencStart = s_rc.indexOf(
'\n', yencStart );
338 if ( yencStart == -1 ) {
348 QByteArray meta = s_rc.mid( beginPos, yencStart - beginPos );
349 int namePos = meta.indexOf(
"name=" );
350 if ( namePos == -1 ) {
354 int eolPos = meta.indexOf(
'\r', namePos );
355 if ( eolPos == -1 ) {
356 eolPos = meta.indexOf(
'\n', namePos );
358 if ( eolPos == -1 ) {
362 fileName = meta.mid( namePos + 5, eolPos - ( namePos + 5 ) );
366 if ( !yencMeta( meta,
"line", ¥cLine ) ) {
371 if ( !yencMeta( meta,
"size", ¥cSize ) ) {
376 int partBegin, partEnd;
377 if ( containsPart ) {
378 if ( !yencMeta( meta,
"part", &p_artNr ) ) {
382 if ( !yencMeta( meta,
"begin", &partBegin ) ||
383 !yencMeta( meta,
"end", &partEnd ) ) {
387 if ( !yencMeta( meta,
"total", &t_otalNr ) ) {
388 t_otalNr = p_artNr + 1;
390 if ( yencSize == partEnd - partBegin + 1 ) {
393 yencSize = partEnd - partBegin + 1;
400 int len = s_rc.length();
401 bool lineStart =
true;
403 bool containsEnd =
false;
405 binary.resize( yencSize );
406 while ( pos < len ) {
407 int ch = s_rc.at( pos );
412 if ( lineLength != yencLine && totalSize != yencSize ) {
417 else if ( ch ==
'\n' ) {
423 if ( pos + 1 < len ) {
424 ch = s_rc.at( pos + 1 );
425 if ( lineStart && ch ==
'y' ) {
434 if ( totalSize >= yencSize ) {
437 binary[totalSize++] = ch;
447 if ( totalSize >= yencSize ) {
450 binary[totalSize++] = ch;
458 if ( !containsEnd ) {
462 if ( totalSize != yencSize ) {
468 eolPos = s_rc.indexOf(
'\n', pos );
469 if ( eolPos == -1 ) {
473 meta = s_rc.mid( pos, eolPos - pos );
474 if ( !yencMeta( meta,
"size", &totalSize ) ) {
478 if ( totalSize != yencSize ) {
483 f_ilenames.append( fileName );
485 b_ins.append( binary );
488 if ( beginPos > 0 ) {
489 t_ext.append( s_rc.mid( currentPos, beginPos - currentPos ) );
491 currentPos = eolPos + 1;
499 t_ext.append( s_rc.right( s_rc.length() - currentPos ) );
501 return b_ins.count()>0;