10#include "kmime_parsers_p.h"
12#include <QRegularExpression>
14using namespace KMime::Parser;
23 , m_boundary(boundary)
27bool MultiPart::parse()
39 if ((pos1 = m_src.indexOf(b, pos1)) == -1 || pos1 == 0 ||
40 m_src[pos1 - 1] ==
'\n') {
48 if (m_src[pos1] ==
'-' && m_src[pos1 + 1] ==
'-') {
52 }
else if ((pos1 - blen) > 1) {
53 m_preamble = m_src.left(pos1 - blen - 1);
57 while (pos1 > -1 && pos2 > -1) {
60 if ((pos1 = m_src.indexOf(
'\n', pos1)) > -1) {
65 if ((pos2 = m_src.indexOf(b, pos2)) == -1 ||
66 m_src[pos2 - 1] ==
'\n') {
73 part = m_src.
mid(pos1, m_src.length() - pos1);
78 part = m_src.
mid(pos1, pos2 - pos1 - 1);
81 if (m_src[pos2] ==
'-' && m_src[pos2 + 1] ==
'-') {
84 if ((pos1 = m_src.indexOf(
'\n', pos1)) > -1) {
86 m_epilouge = m_src.mid(pos1 + 1, m_src.length() - pos1 - 1);
97 return !m_parts.isEmpty();
102NonMimeParser::NonMimeParser(
const QByteArray &src) :
103 m_src(src), m_partNr(-1), m_totalNr(-1)
107NonMimeParser::~NonMimeParser() =
default;
122 if (tmp ==
"JPG" || tmp ==
"JPEG") {
123 mimeType = QByteArrayLiteral(
"image/jpeg");
124 }
else if (tmp ==
"GIF") {
125 mimeType = QByteArrayLiteral(
"image/gif");
126 }
else if (tmp ==
"PNG") {
127 mimeType = QByteArrayLiteral(
"image/png");
128 }
else if (tmp ==
"TIFF" || tmp ==
"TIF") {
129 mimeType = QByteArrayLiteral(
"image/tiff");
130 }
else if (tmp ==
"XPM") {
131 mimeType = QByteArrayLiteral(
"image/x-xpixmap");
132 }
else if (tmp ==
"XBM") {
133 mimeType = QByteArrayLiteral(
"image/x-xbitmap");
134 }
else if (tmp ==
"BMP") {
135 mimeType = QByteArrayLiteral(
"image/bmp");
136 }
else if (tmp ==
"TXT" ||
142 mimeType = QByteArrayLiteral(
"text/plain");
143 }
else if (tmp ==
"HTML" || tmp ==
"HTM") {
144 mimeType = QByteArrayLiteral(
"text/html");
146 mimeType = QByteArrayLiteral(
"application/octet-stream");
149 mimeType = QByteArrayLiteral(
"application/octet-stream");
152 mimeType = QByteArrayLiteral(
"application/octet-stream");
161 NonMimeParser(src), m_subject(subject)
164bool UUEncoded::parse()
168 bool firstIteration =
true;
175 int beginPos = currentPos;
176 int uuStart = currentPos;
182 bool containsBegin =
false;
183 bool containsEnd =
false;
187 if ((beginPos = srcStr.indexOf(beginRegex, currentPos)) > -1 &&
188 (beginPos == 0 || m_src.at(beginPos - 1) ==
'\n')) {
189 containsBegin =
true;
190 uuStart = m_src.indexOf(
'\n', beginPos);
198 beginPos = currentPos;
201 if ((endPos = m_src.indexOf(
"\nend", (uuStart > 0) ? uuStart - 1 : 0)) == -1) {
202 endPos = m_src.length();
207 if ((containsBegin && containsEnd) || firstIteration) {
211 for (
int idx = uuStart; idx < endPos; idx++) {
212 if (m_src[idx] ==
'\n') {
214 if (idx + 1 < endPos && m_src[idx + 1] ==
'M') {
222 if (MCount == 0 || (lineCount - MCount) > 10 ||
223 ((!containsBegin || !containsEnd) && (MCount < 15))) {
229 if ((!containsBegin || !containsEnd) && !m_subject.isNull()) {
233 pos =
match.capturedStart(0);
234 len =
match.capturedLength(0);
236 tmp = m_subject.
mid(pos, len);
248 m_text.append(m_src.mid(currentPos, beginPos - currentPos));
253 fileName = m_src.
mid(beginPos + 10, uuStart - beginPos - 11);
257 m_filenames.
append(fileName);
259 m_bins.
append(m_src.mid(uuStart, endPos - uuStart + 1));
260 m_mimeTypes.
append(guessMimeType(fileName));
261 firstIteration =
false;
263 int next = m_src.indexOf(
'\n', endPos + 1);
278 m_text.append(m_src.right(m_src.length() - currentPos));
280 return ((!m_bins.isEmpty()) || isPartial());
285YENCEncoded::YENCEncoded(
const QByteArray &src) :
295 int iPos = src.
indexOf(sought);
297 int pos1 = src.
indexOf(
' ', iPos);
298 int pos2 = src.
indexOf(
'\r', iPos);
299 int pos3 = src.
indexOf(
'\t', iPos);
300 int pos4 = src.
indexOf(
'\n', iPos);
301 if (pos2 >= 0 && (pos1 < 0 || pos1 > pos2)) {
304 if (pos3 >= 0 && (pos1 < 0 || pos1 > pos3)) {
307 if (pos4 >= 0 && (pos1 < 0 || pos1 > pos4)) {
312 char c = src.
at(iPos);
313 if (c >=
'0' && c <=
'9') {
315 *value = src.
mid(iPos, pos1 - iPos).
toInt();
322bool YENCEncoded::parse()
327 int beginPos = currentPos;
328 int yencStart = currentPos;
329 bool containsPart =
false;
332 if ((beginPos = m_src.indexOf(
"=ybegin ", currentPos)) > -1 &&
333 (beginPos == 0 || m_src.at(beginPos - 1) ==
'\n')) {
334 yencStart = m_src.indexOf(
'\n', beginPos);
335 if (yencStart == -1) {
340 if (m_src.indexOf(
"=ypart", yencStart) == yencStart) {
342 yencStart = m_src.indexOf(
'\n', yencStart);
343 if (yencStart == -1) {
354 int namePos = meta.
indexOf(
"name=");
359 int eolPos = meta.
indexOf(
'\r', namePos);
361 eolPos = meta.
indexOf(
'\n', namePos);
367 fileName = meta.
mid(namePos + 5, eolPos - (namePos + 5));
371 if (!yencMeta(meta,
"line", ¥cLine)) {
376 if (!yencMeta(meta,
"size", ¥cSize)) {
384 if (!yencMeta(meta,
"part", &m_partNr)) {
388 if (!yencMeta(meta,
"begin", &partBegin) ||
389 !yencMeta(meta,
"end", &partEnd)) {
393 if (!yencMeta(meta,
"total", &m_totalNr)) {
394 m_totalNr = m_partNr + 1;
396 if (yencSize == partEnd - partBegin + 1) {
399 yencSize = partEnd - partBegin + 1;
406 int len = m_src.length();
407 bool lineStart =
true;
409 bool containsEnd =
false;
413 int ch = m_src.at(pos);
418 if (lineLength != yencLine && totalSize != yencSize) {
422 }
else if (ch ==
'\n') {
429 ch = m_src.at(pos + 1);
430 if (lineStart && ch ==
'y') {
439 if (totalSize >= yencSize) {
442 binary[totalSize++] = ch;
452 if (totalSize >= yencSize) {
455 binary[totalSize++] = ch;
467 if (totalSize != yencSize) {
473 eolPos = m_src.indexOf(
'\n', pos);
478 meta = m_src.
mid(pos, eolPos - pos);
479 if (!yencMeta(meta,
"size", &totalSize)) {
483 if (totalSize != yencSize) {
488 m_filenames.append(fileName);
489 m_mimeTypes.append(guessMimeType(fileName));
490 m_bins.append(binary);
494 m_text.append(m_src.mid(currentPos, beginPos - currentPos));
496 currentPos = eolPos + 1;
504 m_text.append(m_src.right(m_src.length() - currentPos));
506 return !m_bins.isEmpty();
KCALUTILS_EXPORT QString mimeType()
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
const QList< QKeySequence > & next()
QString name(StandardShortcut id)
QByteArray & append(QByteArrayView data)
char at(qsizetype i) const const
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
bool isEmpty() const const
qsizetype lastIndexOf(QByteArrayView bv) const const
QByteArray left(qsizetype len) const const
qsizetype length() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
void resize(qsizetype newSize, char c)
QByteArray right(qsizetype len) const const
int toInt(bool *ok, int base) const const
QByteArray toUpper() const const
QString fromLatin1(QByteArrayView str)