State machine implementation terminated. Added some functions
(waitForReadyConnected, waitForAuthenticated, waitForMailSent) synchronous waiting. Added writeToDevice() function to MimeMessage and MimePart (and subclasses), now these are used in SmtpClient instead of toString(). Added some unit tests.
This commit is contained in:
parent
afb66b4fff
commit
9e048495ba
@ -1,46 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2011-08-11T20:59:25
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT += core gui network
|
|
||||||
|
|
||||||
TARGET = SMTPEmail
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
src/emailaddress.cpp \
|
|
||||||
src/mimeattachment.cpp \
|
|
||||||
src/mimefile.cpp \
|
|
||||||
src/mimehtml.cpp \
|
|
||||||
src/mimeinlinefile.cpp \
|
|
||||||
src/mimemessage.cpp \
|
|
||||||
src/mimepart.cpp \
|
|
||||||
src/mimetext.cpp \
|
|
||||||
src/smtpclient.cpp \
|
|
||||||
src/quotedprintable.cpp \
|
|
||||||
src/mimemultipart.cpp \
|
|
||||||
src/mimecontentformatter.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
src/emailaddress.h \
|
|
||||||
src/mimeattachment.h \
|
|
||||||
src/mimefile.h \
|
|
||||||
src/mimehtml.h \
|
|
||||||
src/mimeinlinefile.h \
|
|
||||||
src/mimemessage.h \
|
|
||||||
src/mimepart.h \
|
|
||||||
src/mimetext.h \
|
|
||||||
src/smtpclient.h \
|
|
||||||
src/SmtpMime \
|
|
||||||
src/quotedprintable.h \
|
|
||||||
src/mimemultipart.h \
|
|
||||||
src/mimecontentformatter.h
|
|
||||||
|
|
||||||
OTHER_FILES += \
|
|
||||||
LICENSE \
|
|
||||||
README.md
|
|
||||||
|
|
||||||
FORMS +=
|
|
59
src/SMTPEmail.pro
Normal file
59
src/SMTPEmail.pro
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2011-08-11T20:59:25
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core network
|
||||||
|
|
||||||
|
TARGET = SmtpMime
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
DEFINE += SMTP_MIME_LIBRARY
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
emailaddress.cpp \
|
||||||
|
mimeattachment.cpp \
|
||||||
|
mimefile.cpp \
|
||||||
|
mimehtml.cpp \
|
||||||
|
mimeinlinefile.cpp \
|
||||||
|
mimemessage.cpp \
|
||||||
|
mimepart.cpp \
|
||||||
|
mimetext.cpp \
|
||||||
|
smtpclient.cpp \
|
||||||
|
quotedprintable.cpp \
|
||||||
|
mimemultipart.cpp \
|
||||||
|
mimecontentencoder.cpp \
|
||||||
|
mimebase64encoder.cpp \
|
||||||
|
mimeqpencoder.cpp \
|
||||||
|
mimeqpformatter.cpp \
|
||||||
|
mimebase64formatter.cpp \
|
||||||
|
mimecontentformatter.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
emailaddress.h \
|
||||||
|
mimeattachment.h \
|
||||||
|
mimefile.h \
|
||||||
|
mimehtml.h \
|
||||||
|
mimeinlinefile.h \
|
||||||
|
mimemessage.h \
|
||||||
|
mimepart.h \
|
||||||
|
mimetext.h \
|
||||||
|
smtpclient.h \
|
||||||
|
SmtpMime \
|
||||||
|
quotedprintable.h \
|
||||||
|
mimemultipart.h \
|
||||||
|
smtpmime_global.h \
|
||||||
|
mimecontentencoder.h \
|
||||||
|
mimebase64encoder.h \
|
||||||
|
mimeqpencoder.h \
|
||||||
|
mimeqpformatter.h \
|
||||||
|
mimepart.cpp.autosave \
|
||||||
|
mimebase64formatter.h \
|
||||||
|
mimecontentformatter.h
|
||||||
|
|
||||||
|
OTHER_FILES += \
|
||||||
|
LICENSE \
|
||||||
|
README.md
|
||||||
|
|
||||||
|
FORMS +=
|
@ -19,9 +19,10 @@
|
|||||||
#ifndef EMAILADDRESS_H
|
#ifndef EMAILADDRESS_H
|
||||||
#define EMAILADDRESS_H
|
#define EMAILADDRESS_H
|
||||||
|
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class EmailAddress : public QObject
|
class SMTP_MIME_EXPORT EmailAddress : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
MimeAttachment::MimeAttachment(QFile *file)
|
MimeAttachment::MimeAttachment(QFile *file)
|
||||||
: MimeFile(file)
|
: MimeFile(file)
|
||||||
{
|
{
|
||||||
|
this->headerLines += "Content-disposition: attachment\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeAttachment::~MimeAttachment()
|
MimeAttachment::~MimeAttachment()
|
||||||
@ -35,12 +36,4 @@ MimeAttachment::~MimeAttachment()
|
|||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
void MimeAttachment::prepare()
|
|
||||||
{
|
|
||||||
this->header += "Content-disposition: attachment\r\n";
|
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
|
||||||
MimeFile::prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
#ifndef MIMEATTACHMENT_H
|
#ifndef MIMEATTACHMENT_H
|
||||||
#define MIMEATTACHMENT_H
|
#define MIMEATTACHMENT_H
|
||||||
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "mimefile.h"
|
#include "mimefile.h"
|
||||||
|
|
||||||
class MimeAttachment : public MimeFile
|
class SMTP_MIME_EXPORT MimeAttachment : public MimeFile
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -38,9 +40,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* [2] Protected methods */
|
/* [2] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
7
src/mimebase64encoder.cpp
Normal file
7
src/mimebase64encoder.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "mimebase64encoder.h"
|
||||||
|
|
||||||
|
MimeBase64Encoder::MimeBase64Encoder() {}
|
||||||
|
|
||||||
|
QByteArray MimeBase64Encoder::encode(const QByteArray &data) {
|
||||||
|
return data.toBase64();
|
||||||
|
}
|
14
src/mimebase64encoder.h
Normal file
14
src/mimebase64encoder.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef MIMEBASE64ENCODER_H
|
||||||
|
#define MIMEBASE64ENCODER_H
|
||||||
|
|
||||||
|
#include "mimecontentencoder.h"
|
||||||
|
|
||||||
|
class MimeBase64Encoder : public MimeContentEncoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MimeBase64Encoder();
|
||||||
|
|
||||||
|
QByteArray encode(const QByteArray &data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEBASE64ENCODER_H
|
17
src/mimebase64formatter.cpp
Normal file
17
src/mimebase64formatter.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "mimebase64formatter.h"
|
||||||
|
|
||||||
|
MimeBase64Formatter::MimeBase64Formatter(QIODevice *out) :
|
||||||
|
MimeContentFormatter(out) {}
|
||||||
|
|
||||||
|
qint64 MimeBase64Formatter::writeData(const char *data, qint64 maxLength) {
|
||||||
|
qDebug("called");
|
||||||
|
int lines = (maxLength - 1) / lineLength + 1;
|
||||||
|
for (int i = 1; i < lines; ++i) {
|
||||||
|
output->write(data, lineLength);
|
||||||
|
output->write("\r\n");
|
||||||
|
data += lineLength;
|
||||||
|
}
|
||||||
|
output->write(data, maxLength - (lines - 1) * lineLength);
|
||||||
|
output->write("\r\n");
|
||||||
|
return maxLength;
|
||||||
|
}
|
15
src/mimebase64formatter.h
Normal file
15
src/mimebase64formatter.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef MIMEBASE64FORMATTER_H
|
||||||
|
#define MIMEBASE64FORMATTER_H
|
||||||
|
|
||||||
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
|
class MimeBase64Formatter : public MimeContentFormatter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MimeBase64Formatter(QIODevice*);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual qint64 writeData(const char *data, qint64 len);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEBASE64FORMATTER_H
|
3
src/mimecontentencoder.cpp
Normal file
3
src/mimecontentencoder.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "mimecontentencoder.h"
|
||||||
|
|
||||||
|
MimeContentEncoder::MimeContentEncoder() {}
|
16
src/mimecontentencoder.h
Normal file
16
src/mimecontentencoder.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef MIMEENCODER_H
|
||||||
|
#define MIMEENCODER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
class MimeContentEncoder : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual QByteArray encode(const QByteArray &data) =0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MimeContentEncoder();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEENCODER_H
|
@ -1,66 +1,20 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011-2012 - Tőkés Attila
|
|
||||||
|
|
||||||
This file is part of SmtpClient for Qt.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
See the LICENSE file for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mimecontentformatter.h"
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
MimeContentFormatter::MimeContentFormatter(int max_length) :
|
MimeContentFormatter::MimeContentFormatter(QIODevice *out, int length) :
|
||||||
max_length(max_length)
|
output(out),
|
||||||
{}
|
lineLength(length)
|
||||||
|
{
|
||||||
QString MimeContentFormatter::format(const QString &content, bool quotedPrintable) const {
|
QIODevice::open(WriteOnly);
|
||||||
|
|
||||||
QString out;
|
|
||||||
|
|
||||||
int chars = 0;
|
|
||||||
for (int i = 0; i < content.length() ; ++i) {
|
|
||||||
chars++;
|
|
||||||
if (!quotedPrintable) {
|
|
||||||
if (chars > max_length) {
|
|
||||||
out.append("\r\n");
|
|
||||||
chars = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (content[i] == '\n') { // new line
|
|
||||||
out.append(content[i]);
|
|
||||||
chars = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((chars > max_length - 1)
|
|
||||||
|| ((content[i] == '=') && (chars > max_length - 3) )) {
|
|
||||||
out.append('=');
|
|
||||||
out.append("\r\n");
|
|
||||||
chars = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
out.append(content[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeContentFormatter::setMaxLength(int l) {
|
int MimeContentFormatter::getLineLength() const {
|
||||||
max_length = l;
|
return lineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MimeContentFormatter::getMaxLength() const {
|
void MimeContentFormatter::setLineLength(int l) {
|
||||||
return max_length;
|
lineLength = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 MimeContentFormatter::readData(char*, qint64) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,24 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011-2012 - Tőkés Attila
|
|
||||||
|
|
||||||
This file is part of SmtpClient for Qt.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
See the LICENSE file for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MIMECONTENTFORMATTER_H
|
#ifndef MIMECONTENTFORMATTER_H
|
||||||
#define MIMECONTENTFORMATTER_H
|
#define MIMECONTENTFORMATTER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QByteArray>
|
#include <QIODevice>
|
||||||
|
|
||||||
class MimeContentFormatter : public QObject
|
class MimeContentFormatter : public QIODevice
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MimeContentFormatter (int max_length = 76);
|
MimeContentFormatter(QIODevice *device, int lineLength = 76);
|
||||||
|
|
||||||
void setMaxLength(int l);
|
int getLineLength() const;
|
||||||
int getMaxLength() const;
|
void setLineLength(int l);
|
||||||
|
|
||||||
QString format(const QString &content, bool quotedPrintable = false) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int max_length;
|
qint64 readData(char *data, qint64 maxlen);
|
||||||
|
qint64 writeData(const char *data, qint64 len) = 0;
|
||||||
|
|
||||||
|
QIODevice *output;
|
||||||
|
int lineLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMECONTENTFORMATTER_H
|
#endif // MIMECONTENTFORMATTER_H
|
||||||
|
@ -44,14 +44,15 @@ MimeFile::~MimeFile()
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeFile::prepare()
|
|
||||||
{
|
void MimeFile::writeContent(QIODevice &device) {
|
||||||
file->open(QIODevice::ReadOnly);
|
file->open(QIODevice::ReadOnly);
|
||||||
this->content = file->readAll();
|
this->content = file->readAll();
|
||||||
file->close();
|
file->close();
|
||||||
|
|
||||||
/* !!! IMPORTANT !!!! */
|
MimePart::writeContent(device);
|
||||||
MimePart::prepare();
|
|
||||||
|
this->content.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,10 +19,11 @@
|
|||||||
#ifndef MIMEFILE_H
|
#ifndef MIMEFILE_H
|
||||||
#define MIMEFILE_H
|
#define MIMEFILE_H
|
||||||
|
|
||||||
#include "mimepart.h"
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "smtpmime_global.h"
|
||||||
|
|
||||||
class MimeFile : public MimePart
|
class SMTP_MIME_EXPORT MimeFile : public MimePart
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -50,7 +51,8 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
void writeContent(QIODevice &device);
|
||||||
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -48,10 +48,4 @@ const QString & MimeHtml::getHtml() const
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeHtml::prepare()
|
|
||||||
{
|
|
||||||
/* !!! IMPORTANT !!! */
|
|
||||||
MimeText::prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
#ifndef MIMEHTML_H
|
#ifndef MIMEHTML_H
|
||||||
#define MIMEHTML_H
|
#define MIMEHTML_H
|
||||||
|
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimetext.h"
|
#include "mimetext.h"
|
||||||
|
|
||||||
class MimeHtml : public MimeText
|
class SMTP_MIME_EXPORT MimeHtml : public MimeText
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -51,8 +52,6 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
MimeInlineFile::MimeInlineFile(QFile *f)
|
MimeInlineFile::MimeInlineFile(QFile *f)
|
||||||
: MimeFile(f)
|
: MimeFile(f)
|
||||||
{
|
{
|
||||||
|
this->headerLines += "Content-Disposition: inline\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeInlineFile::~MimeInlineFile()
|
MimeInlineFile::~MimeInlineFile()
|
||||||
@ -38,14 +39,6 @@ MimeInlineFile::~MimeInlineFile()
|
|||||||
|
|
||||||
/* [3] Protected methods */
|
/* [3] Protected methods */
|
||||||
|
|
||||||
void MimeInlineFile::prepare()
|
|
||||||
{
|
|
||||||
this->header += "Content-Disposition: inline\r\n";
|
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
|
||||||
MimeFile::prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
#ifndef MIMEINLINEFILE_H
|
#ifndef MIMEINLINEFILE_H
|
||||||
#define MIMEINLINEFILE_H
|
#define MIMEINLINEFILE_H
|
||||||
|
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimefile.h"
|
#include "mimefile.h"
|
||||||
|
|
||||||
class MimeInlineFile : public MimeFile
|
class SMTP_MIME_EXPORT MimeInlineFile : public MimeFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -46,8 +47,6 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
virtual void prepare();
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
#include "mimemessage.h"
|
#include "mimemessage.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QBuffer>
|
||||||
#include "quotedprintable.h"
|
#include "quotedprintable.h"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
@ -140,117 +142,87 @@ const QList<MimePart*> & MimeMessage::getParts() const
|
|||||||
|
|
||||||
QString MimeMessage::toString()
|
QString MimeMessage::toString()
|
||||||
{
|
{
|
||||||
QString mimeString;
|
QBuffer out;
|
||||||
QTextStream out(&mimeString);
|
out.open(QIODevice::WriteOnly);
|
||||||
writeToStream(out);
|
writeToDevice(out);
|
||||||
return mimeString;
|
return QString(out.buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::writeToStream(QTextStream &out) {
|
QString MimeMessage::formatAddress(EmailAddress *address, MimePart::Encoding encoding) {
|
||||||
|
QString result;
|
||||||
|
if (address->getName() != "")
|
||||||
|
{
|
||||||
|
switch (encoding)
|
||||||
|
{
|
||||||
|
case MimePart::Base64:
|
||||||
|
result.append(" =?utf-8?B?" + QByteArray().append(address->getName()).toBase64() + "?=");
|
||||||
|
break;
|
||||||
|
case MimePart::QuotedPrintable:
|
||||||
|
result.append(" =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(address->getName())).replace(' ', "_").replace(':',"=3A") + "?=");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.append(" " + address->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(" <" + address->getAddress() + ">");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MimeMessage::writeToDevice(QIODevice &out) {
|
||||||
/* =========== MIME HEADER ============ */
|
/* =========== MIME HEADER ============ */
|
||||||
|
|
||||||
/* ---------- Sender / From ----------- */
|
/* ---------- Sender / From ----------- */
|
||||||
out << "From:";
|
QString header;
|
||||||
if (sender->getName() != "")
|
header.append("From:" + formatAddress(sender, hEncoding) + "\r\n");
|
||||||
{
|
|
||||||
switch (hEncoding)
|
|
||||||
{
|
|
||||||
case MimePart::Base64:
|
|
||||||
out << " =?utf-8?B?" + QByteArray().append(sender->getName()).toBase64() + "?=";
|
|
||||||
break;
|
|
||||||
case MimePart::QuotedPrintable:
|
|
||||||
out << " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(sender->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out << " " + sender->getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << " <" + sender->getAddress() + ">\r\n";
|
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
/* ------- Recipients / To ---------- */
|
/* ------- Recipients / To ---------- */
|
||||||
out << "To:";
|
header.append("To:");
|
||||||
QList<EmailAddress*>::iterator it; int i;
|
QList<EmailAddress*>::iterator it; int i;
|
||||||
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i)
|
for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
if (i != 0) { out << ","; }
|
if (i != 0) { header.append(","); }
|
||||||
|
header.append(formatAddress(*it, hEncoding));
|
||||||
if ((*it)->getName() != "")
|
|
||||||
{
|
|
||||||
switch (hEncoding)
|
|
||||||
{
|
|
||||||
case MimePart::Base64:
|
|
||||||
out << " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
|
||||||
break;
|
|
||||||
case MimePart::QuotedPrintable:
|
|
||||||
out << " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out << " " + (*it)->getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << " <" + (*it)->getAddress() + ">";
|
|
||||||
}
|
}
|
||||||
out << "\r\n";
|
header.append("\r\n");
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
/* ------- Recipients / Cc ---------- */
|
/* ------- Recipients / Cc ---------- */
|
||||||
if (recipientsCc.size() != 0) {
|
if (recipientsCc.size() != 0) {
|
||||||
out << "Cc:";
|
header.append("Cc:");
|
||||||
}
|
}
|
||||||
for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i)
|
for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
if (i != 0) { out << ","; }
|
if (i != 0) { header.append(","); }
|
||||||
|
header.append(formatAddress(*it, hEncoding));
|
||||||
if ((*it)->getName() != "")
|
|
||||||
{
|
|
||||||
switch (hEncoding)
|
|
||||||
{
|
|
||||||
case MimePart::Base64:
|
|
||||||
out << " =?utf-8?B?" + QByteArray().append((*it)->getName()).toBase64() + "?=";
|
|
||||||
break;
|
|
||||||
case MimePart::QuotedPrintable:
|
|
||||||
out << " =?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append((*it)->getName())).replace(' ', "_").replace(':',"=3A") + "?=";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out << " " + (*it)->getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << " <" + (*it)->getAddress() + ">";
|
|
||||||
}
|
}
|
||||||
if (recipientsCc.size() != 0) {
|
if (recipientsCc.size() != 0) {
|
||||||
out << "\r\n";
|
header.append("\r\n");
|
||||||
}
|
}
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
/* ------------ Subject ------------- */
|
/* ------------ Subject ------------- */
|
||||||
out << "Subject: ";
|
header.append("Subject: ");
|
||||||
|
|
||||||
|
|
||||||
switch (hEncoding)
|
switch (hEncoding)
|
||||||
{
|
{
|
||||||
case MimePart::Base64:
|
case MimePart::Base64:
|
||||||
out << "=?utf-8?B?" + QByteArray().append(subject).toBase64() + "?=";
|
header.append("=?utf-8?B?" + QByteArray().append(subject).toBase64() + "?=");
|
||||||
break;
|
break;
|
||||||
case MimePart::QuotedPrintable:
|
case MimePart::QuotedPrintable:
|
||||||
out << "=?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(subject)).replace(' ', "_").replace(':',"=3A") + "?=";
|
header.append("=?utf-8?Q?" + QuotedPrintable::encode(QByteArray().append(subject)).replace(' ', "_").replace(':',"=3A") + "?=");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out << subject;
|
header.append(subject);
|
||||||
}
|
}
|
||||||
/* ---------------------------------- */
|
/* ---------------------------------- */
|
||||||
|
|
||||||
out << "\r\n";
|
header.append("\r\n");
|
||||||
out << "MIME-Version: 1.0\r\n";
|
header.append("MIME-Version: 1.0\r\n");
|
||||||
|
|
||||||
out << content->toString();
|
out.write(header.toAscii());
|
||||||
|
content->writeToDevice(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMessage::writeToDevice(QIODevice &device) {
|
|
||||||
QTextStream out (&device);
|
|
||||||
writeToStream(out);
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,13 +19,15 @@
|
|||||||
#ifndef MIMEMESSAGE_H
|
#ifndef MIMEMESSAGE_H
|
||||||
#define MIMEMESSAGE_H
|
#define MIMEMESSAGE_H
|
||||||
|
|
||||||
#include "mimepart.h"
|
|
||||||
#include "mimemultipart.h"
|
|
||||||
#include "emailaddress.h"
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
class MimeMessage : public QObject
|
#include "smtpmime_global.h"
|
||||||
|
#include "mimepart.h"
|
||||||
|
#include "mimemultipart.h"
|
||||||
|
#include "emailaddress.h"
|
||||||
|
|
||||||
|
class SMTP_MIME_EXPORT MimeMessage : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -68,8 +70,7 @@ public:
|
|||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
virtual QString toString();
|
virtual QString toString();
|
||||||
virtual void writeToStream(QTextStream &stream);
|
void writeToDevice(QIODevice &device);
|
||||||
virtual void writeToDevice(QIODevice &device);
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
@ -84,6 +85,8 @@ protected:
|
|||||||
|
|
||||||
MimePart::Encoding hEncoding;
|
MimePart::Encoding hEncoding;
|
||||||
|
|
||||||
|
static QString formatAddress(EmailAddress*, MimePart::Encoding);
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,21 +53,23 @@ const QList<MimePart*> & MimeMultiPart::getParts() const {
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeMultiPart::prepare() {
|
void MimeMultiPart::writeContent(QIODevice &device) {
|
||||||
QList<MimePart*>::iterator it;
|
QList<MimePart*>::iterator it;
|
||||||
|
|
||||||
content = "";
|
content = "";
|
||||||
for (it = parts.begin(); it != parts.end(); it++) {
|
for (it = parts.begin(); it != parts.end(); it++) {
|
||||||
content += "--" + cBoundary + "\r\n";
|
device.write("--" );
|
||||||
(*it)->prepare();
|
device.write(cBoundary.toAscii());
|
||||||
content += (*it)->toString();
|
device.write("\r\n");
|
||||||
|
(*it)->writeToDevice(device);
|
||||||
};
|
};
|
||||||
|
|
||||||
content += "--" + cBoundary + "--\r\n";
|
device.write("--");
|
||||||
|
device.write(cBoundary.toAscii());
|
||||||
MimePart::prepare();
|
device.write("--\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
void MimeMultiPart::setMimeType(const MultiPartType type) {
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->cType = MULTI_PART_NAMES[type];
|
this->cType = MULTI_PART_NAMES[type];
|
||||||
|
@ -19,9 +19,12 @@
|
|||||||
#ifndef MIMEMULTIPART_H
|
#ifndef MIMEMULTIPART_H
|
||||||
#define MIMEMULTIPART_H
|
#define MIMEMULTIPART_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
|
|
||||||
class MimeMultiPart : public MimePart
|
class SMTP_MIME_EXPORT MimeMultiPart : public MimePart
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -59,7 +62,7 @@ public:
|
|||||||
|
|
||||||
void addPart(MimePart *part);
|
void addPart(MimePart *part);
|
||||||
|
|
||||||
virtual void prepare();
|
void writeContent(QIODevice &device);
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
@ -16,8 +16,13 @@
|
|||||||
See the LICENSE file for more details.
|
See the LICENSE file for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QBuffer>
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
#include "quotedprintable.h"
|
#include "quotedprintable.h"
|
||||||
|
#include "mimebase64formatter.h"
|
||||||
|
#include "mimeqpformatter.h"
|
||||||
|
#include "mimebase64encoder.h"
|
||||||
|
#include "mimeqpencoder.h"
|
||||||
|
|
||||||
/* [1] Constructors and Destructors */
|
/* [1] Constructors and Destructors */
|
||||||
|
|
||||||
@ -45,17 +50,17 @@ void MimePart::setContent(const QByteArray & content)
|
|||||||
|
|
||||||
void MimePart::setHeader(const QString & header)
|
void MimePart::setHeader(const QString & header)
|
||||||
{
|
{
|
||||||
this->header = header;
|
this->headerLines = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimePart::addHeaderLine(const QString & line)
|
void MimePart::addHeaderLine(const QString & line)
|
||||||
{
|
{
|
||||||
this->header += line + "\r\n";
|
this->headerLines += line + "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& MimePart::getHeader() const
|
const QString& MimePart::getHeader() const
|
||||||
{
|
{
|
||||||
return header;
|
return headerLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray& MimePart::getContent() const
|
const QByteArray& MimePart::getContent() const
|
||||||
@ -113,9 +118,12 @@ MimePart::Encoding MimePart::getEncoding() const
|
|||||||
return this->cEncoding;
|
return this->cEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeContentFormatter& MimePart::getContentFormatter()
|
void MimePart::setMaxLineLength(const int length) {
|
||||||
{
|
maxLineLength = length;
|
||||||
return this->formatter;
|
}
|
||||||
|
|
||||||
|
int MimePart::getMaxLineLength() const {
|
||||||
|
return maxLineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
@ -125,90 +133,91 @@ MimeContentFormatter& MimePart::getContentFormatter()
|
|||||||
|
|
||||||
QString MimePart::toString()
|
QString MimePart::toString()
|
||||||
{
|
{
|
||||||
if (!prepared)
|
QBuffer out;
|
||||||
prepare();
|
out.open(QIODevice::WriteOnly);
|
||||||
|
writeToDevice(out);
|
||||||
return mimeString;
|
return QString(out.buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
void MimePart::writeToDevice(QIODevice &device) {
|
||||||
|
QString header;
|
||||||
|
|
||||||
/* [4] Protected methods */
|
|
||||||
|
|
||||||
void MimePart::prepare()
|
|
||||||
{
|
|
||||||
mimeString = QString();
|
|
||||||
|
|
||||||
/* === Header Prepare === */
|
/* === Header Prepare === */
|
||||||
|
|
||||||
/* Content-Type */
|
/* Content-Type */
|
||||||
mimeString.append("Content-Type: ").append(cType);
|
header.append("Content-Type: ").append(cType);
|
||||||
|
|
||||||
if (cName != "")
|
if (cName != "")
|
||||||
mimeString.append("; name=\"").append(cName).append("\"");
|
header.append("; name=\"").append(cName).append("\"");
|
||||||
|
|
||||||
if (cCharset != "")
|
if (cCharset != "")
|
||||||
mimeString.append("; charset=").append(cCharset);
|
header.append("; charset=").append(cCharset);
|
||||||
|
|
||||||
if (cBoundary != "")
|
if (cBoundary != "")
|
||||||
mimeString.append("; boundary=").append(cBoundary);
|
header.append("; boundary=").append(cBoundary);
|
||||||
|
|
||||||
mimeString.append("\r\n");
|
header.append("\r\n");
|
||||||
/* ------------ */
|
/* ------------ */
|
||||||
|
|
||||||
/* Content-Transfer-Encoding */
|
/* Content-Transfer-Encoding */
|
||||||
mimeString.append("Content-Transfer-Encoding: ");
|
header.append("Content-Transfer-Encoding: ");
|
||||||
switch (cEncoding)
|
switch (cEncoding)
|
||||||
{
|
{
|
||||||
case _7Bit:
|
case _7Bit:
|
||||||
mimeString.append("7bit\r\n");
|
header.append("7bit\r\n");
|
||||||
break;
|
break;
|
||||||
case _8Bit:
|
case _8Bit:
|
||||||
mimeString.append("8bit\r\n");
|
header.append("8bit\r\n");
|
||||||
break;
|
break;
|
||||||
case Base64:
|
case Base64:
|
||||||
mimeString.append("base64\r\n");
|
header.append("base64\r\n");
|
||||||
break;
|
break;
|
||||||
case QuotedPrintable:
|
case QuotedPrintable:
|
||||||
mimeString.append("quoted-printable\r\n");
|
header.append("quoted-printable\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* ------------------------ */
|
/* ------------------------ */
|
||||||
|
|
||||||
/* Content-Id */
|
/* Content-Id */
|
||||||
if (cId != NULL)
|
if (cId != NULL)
|
||||||
mimeString.append("Content-ID: <").append(cId).append(">\r\n");
|
header.append("Content-ID: <").append(cId).append(">\r\n");
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
|
|
||||||
/* Addition header lines */
|
/* Additional header lines */
|
||||||
|
|
||||||
mimeString.append(header).append("\r\n");
|
header.append(headerLines).append("\r\n");
|
||||||
|
|
||||||
/* ------------------------- */
|
/* ------------------------- */
|
||||||
|
|
||||||
/* === End of Header Prepare === */
|
/* === End of Header Prepare === */
|
||||||
|
|
||||||
/* === Content === */
|
device.write(header.toAscii());
|
||||||
|
|
||||||
|
writeContent(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
/* [4] Protected methods */
|
||||||
|
|
||||||
|
void MimePart::writeContent(QIODevice &device) {
|
||||||
switch (cEncoding)
|
switch (cEncoding)
|
||||||
{
|
{
|
||||||
case _7Bit:
|
case _7Bit:
|
||||||
mimeString.append(QString(content).toAscii());
|
|
||||||
break;
|
|
||||||
case _8Bit:
|
case _8Bit:
|
||||||
mimeString.append(content);
|
device.write(content);
|
||||||
break;
|
break;
|
||||||
case Base64:
|
case Base64:
|
||||||
mimeString.append(formatter.format(content.toBase64()));
|
MimeBase64Formatter(&device).write(MimeBase64Encoder().encode(content));
|
||||||
break;
|
break;
|
||||||
case QuotedPrintable:
|
case QuotedPrintable:
|
||||||
mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
|
MimeQPFormatter(&device).write(MimeQpEncoder().encode(content));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mimeString.append("\r\n");
|
device.write("\r\n");
|
||||||
/* === End of Content === */
|
|
||||||
|
|
||||||
prepared = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
@ -20,9 +20,10 @@
|
|||||||
#define MIMEPART_H
|
#define MIMEPART_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "mimecontentformatter.h"
|
#include <QTextStream>
|
||||||
|
#include "smtpmime_global.h"
|
||||||
|
|
||||||
class MimePart : public QObject
|
class SMTP_MIME_EXPORT MimePart : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -53,7 +54,7 @@ public:
|
|||||||
const QByteArray& getContent() const;
|
const QByteArray& getContent() const;
|
||||||
|
|
||||||
void setContent(const QByteArray & content);
|
void setContent(const QByteArray & content);
|
||||||
void setHeader(const QString & header);
|
void setHeader(const QString & headerLines);
|
||||||
|
|
||||||
void addHeaderLine(const QString & line);
|
void addHeaderLine(const QString & line);
|
||||||
|
|
||||||
@ -72,7 +73,8 @@ public:
|
|||||||
void setEncoding(Encoding enc);
|
void setEncoding(Encoding enc);
|
||||||
Encoding getEncoding() const;
|
Encoding getEncoding() const;
|
||||||
|
|
||||||
MimeContentFormatter& getContentFormatter();
|
void setMaxLineLength(const int length);
|
||||||
|
int getMaxLineLength() const;
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
@ -80,18 +82,15 @@ public:
|
|||||||
/* [3] Public methods */
|
/* [3] Public methods */
|
||||||
|
|
||||||
virtual QString toString();
|
virtual QString toString();
|
||||||
|
void writeToDevice(QIODevice &device);
|
||||||
virtual void prepare();
|
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* [4] Protected members */
|
/* [4] Protected members */
|
||||||
|
|
||||||
QString header;
|
QString headerLines;
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
|
|
||||||
QString cId;
|
QString cId;
|
||||||
@ -101,12 +100,14 @@ protected:
|
|||||||
QString cBoundary;
|
QString cBoundary;
|
||||||
Encoding cEncoding;
|
Encoding cEncoding;
|
||||||
|
|
||||||
|
int maxLineLength;
|
||||||
|
|
||||||
QString mimeString;
|
QString mimeString;
|
||||||
bool prepared;
|
bool prepared;
|
||||||
|
|
||||||
MimeContentFormatter formatter;
|
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
virtual void writeContent(QIODevice &device);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMEPART_H
|
#endif // MIMEPART_H
|
||||||
|
8
src/mimeqpencoder.cpp
Normal file
8
src/mimeqpencoder.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "mimeqpencoder.h"
|
||||||
|
#include "quotedprintable.h"
|
||||||
|
|
||||||
|
MimeQpEncoder::MimeQpEncoder() {}
|
||||||
|
|
||||||
|
QByteArray MimeQpEncoder::encode(const QByteArray &data) {
|
||||||
|
return QuotedPrintable::encode(data).toAscii();
|
||||||
|
}
|
14
src/mimeqpencoder.h
Normal file
14
src/mimeqpencoder.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef MIMEQPENCODER_H
|
||||||
|
#define MIMEQPENCODER_H
|
||||||
|
|
||||||
|
#include "mimecontentencoder.h"
|
||||||
|
|
||||||
|
class MimeQpEncoder : public MimeContentEncoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MimeQpEncoder();
|
||||||
|
|
||||||
|
QByteArray encode(const QByteArray &data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEQPENCODER_H
|
29
src/mimeqpformatter.cpp
Normal file
29
src/mimeqpformatter.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "mimeqpformatter.h"
|
||||||
|
|
||||||
|
MimeQPFormatter::MimeQPFormatter(QIODevice *output) :
|
||||||
|
MimeContentFormatter(output) {}
|
||||||
|
|
||||||
|
qint64 MimeQPFormatter::writeData(const char *data, qint64 maxLength) {
|
||||||
|
int chars = 0;
|
||||||
|
const char *start = data;
|
||||||
|
for (int i = 0; i < maxLength; ++i) {
|
||||||
|
chars++;
|
||||||
|
if (data[i] == '\n') {
|
||||||
|
output->write(start, chars);
|
||||||
|
start += chars;
|
||||||
|
chars = 0;
|
||||||
|
} else if ((chars > lineLength - 3) && (data[i] == '=')) {
|
||||||
|
output->write(start, chars - 1);
|
||||||
|
output->write("=\r\n=");
|
||||||
|
start += chars;
|
||||||
|
chars = 0;
|
||||||
|
} else if (chars == lineLength - 1) {
|
||||||
|
output->write(start, chars);
|
||||||
|
output->write("=\r\n");
|
||||||
|
start += chars;
|
||||||
|
chars = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output->write(start, chars);
|
||||||
|
return maxLength;
|
||||||
|
}
|
15
src/mimeqpformatter.h
Normal file
15
src/mimeqpformatter.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef MIMEQPFORMATTER_H
|
||||||
|
#define MIMEQPFORMATTER_H
|
||||||
|
|
||||||
|
#include "mimecontentformatter.h"
|
||||||
|
|
||||||
|
class MimeQPFormatter : public MimeContentFormatter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MimeQPFormatter(QIODevice*);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual qint64 writeData(const char *data, qint64 len);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIMEQPFORMATTER_H
|
@ -50,13 +50,9 @@ const QString & MimeText::getText() const
|
|||||||
|
|
||||||
/* [3] Protected Methods */
|
/* [3] Protected Methods */
|
||||||
|
|
||||||
void MimeText::prepare()
|
void MimeText::writeContent(QIODevice &device) {
|
||||||
{
|
this->content = text.toAscii();
|
||||||
this->content.clear();
|
MimePart::writeContent(device);
|
||||||
this->content.append(text);
|
|
||||||
|
|
||||||
/* !!! IMPORTANT !!! */
|
|
||||||
MimePart::prepare();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [3] --- */
|
/* [3] --- */
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
#ifndef MIMETEXT_H
|
#ifndef MIMETEXT_H
|
||||||
#define MIMETEXT_H
|
#define MIMETEXT_H
|
||||||
|
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimepart.h"
|
#include "mimepart.h"
|
||||||
|
|
||||||
class MimeText : public MimePart
|
class SMTP_MIME_EXPORT MimeText : public MimePart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ protected:
|
|||||||
|
|
||||||
/* [4] Protected methods */
|
/* [4] Protected methods */
|
||||||
|
|
||||||
void prepare();
|
void writeContent(QIODevice &device);
|
||||||
|
|
||||||
/* [4] --- */
|
/* [4] --- */
|
||||||
|
|
||||||
|
@ -29,12 +29,10 @@ QString& QuotedPrintable::encode(const QByteArray &input)
|
|||||||
{
|
{
|
||||||
byte = input[i];
|
byte = input[i];
|
||||||
|
|
||||||
if ((byte == 0x20) || (byte >= 33) && (byte <= 126) && (byte != 61))
|
if ((byte == 0x20) || (byte >= 33) && (byte <= 126) && (byte != 61)) {
|
||||||
{
|
|
||||||
output->append(byte);
|
output->append(byte);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
output->append('=');
|
output->append('=');
|
||||||
output->append(hex[((byte >> 4) & 0x0F)]);
|
output->append(hex[((byte >> 4) & 0x0F)]);
|
||||||
output->append(hex[(byte & 0x0F)]);
|
output->append(hex[(byte & 0x0F)]);
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include "smtpmime_global.h"
|
||||||
|
|
||||||
class QuotedPrintable : public QObject
|
class SMTP_MIME_EXPORT QuotedPrintable : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -182,6 +182,7 @@ bool SmtpClient::login(const QString &user, const QString &password, AuthMethod
|
|||||||
bool SmtpClient::sendMail(MimeMessage& email)
|
bool SmtpClient::sendMail(MimeMessage& email)
|
||||||
{
|
{
|
||||||
this->email = &email;
|
this->email = &email;
|
||||||
|
this->rcptType = 0;
|
||||||
changeState(MailSendingState);
|
changeState(MailSendingState);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -238,10 +239,10 @@ void SmtpClient::changeState(ClientState state) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// emit all in debug mode
|
// emit all in debug mode
|
||||||
|
qDebug() << "State:" << state;
|
||||||
emit stateChanged(state);
|
emit stateChanged(state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case ConnectingState:
|
case ConnectingState:
|
||||||
@ -373,8 +374,8 @@ void SmtpClient::changeState(ClientState state) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _MAIL_4_SEND_DATA:
|
case _MAIL_4_SEND_DATA:
|
||||||
sendMessage(email->toString());
|
email->writeToDevice(*socket);
|
||||||
sendMessage(".");
|
sendMessage("\r\n.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _READY_MailSent:
|
case _READY_MailSent:
|
||||||
@ -528,6 +529,9 @@ void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SmtpClient::socketError(QAbstractSocket::SocketError socketError) {
|
void SmtpClient::socketError(QAbstractSocket::SocketError socketError) {
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
qDebug() << "SocketError:" << socketError << socket->error();
|
||||||
|
#endif
|
||||||
emit error(SocketError);
|
emit error(SocketError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,6 +543,12 @@ void SmtpClient::socketReadyRead()
|
|||||||
// Save the server's response
|
// Save the server's response
|
||||||
responseLine = socket->readLine();
|
responseLine = socket->readLine();
|
||||||
tempResponse += responseLine;
|
tempResponse += responseLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this the last line of the response
|
||||||
|
if (responseLine[3] == ' ') {
|
||||||
|
responseText = tempResponse;
|
||||||
|
tempResponse = "";
|
||||||
|
|
||||||
// Extract the respose code from the server's responce (first 3 digits)
|
// Extract the respose code from the server's responce (first 3 digits)
|
||||||
responseCode = responseLine.left(3).toInt();
|
responseCode = responseLine.left(3).toInt();
|
||||||
@ -554,13 +564,8 @@ void SmtpClient::socketReadyRead()
|
|||||||
emit error(ClientError);
|
emit error(ClientError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Is this the last line of the response
|
|
||||||
if (responseLine[3] == ' ') {
|
|
||||||
responseText = tempResponse;
|
|
||||||
processResponse();
|
processResponse();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtNetwork/QSslSocket>
|
#include <QtNetwork/QSslSocket>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
|
#include "smtpmime_global.h"
|
||||||
#include "mimemessage.h"
|
#include "mimemessage.h"
|
||||||
|
|
||||||
|
|
||||||
class SmtpClient : public QObject
|
class SMTP_MIME_EXPORT SmtpClient : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -52,9 +52,9 @@ public:
|
|||||||
|
|
||||||
enum ConnectionType
|
enum ConnectionType
|
||||||
{
|
{
|
||||||
TcpConnection,
|
TcpConnection = 0,
|
||||||
SslConnection,
|
SslConnection = 1,
|
||||||
TlsConnection // STARTTLS
|
TlsConnection = 2 // STARTTLS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ClientState {
|
enum ClientState {
|
||||||
@ -136,7 +136,6 @@ public:
|
|||||||
|
|
||||||
QTcpSocket* getSocket();
|
QTcpSocket* getSocket();
|
||||||
|
|
||||||
|
|
||||||
/* [2] --- */
|
/* [2] --- */
|
||||||
|
|
||||||
|
|
||||||
|
10
src/smtpmime_global.h
Normal file
10
src/smtpmime_global.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SMTPMIME_GLOBAL_H
|
||||||
|
#define SMTPMIME_GLOBAL_H
|
||||||
|
|
||||||
|
#ifdef SMTP_MIME_LIBRARY
|
||||||
|
#define SMTP_MIME_EXPORT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
|
#define SMTP_MIME_EXPORT Q_DECL_IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SMTPMIME_GLOBAL_H
|
55
test/connectiontest.cpp
Normal file
55
test/connectiontest.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "connectiontest.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include "../src/smtpclient.h"
|
||||||
|
|
||||||
|
ConnectionTest::ConnectionTest(QObject *parent) :
|
||||||
|
QObject(parent) {}
|
||||||
|
|
||||||
|
|
||||||
|
void ConnectionTest::init() {
|
||||||
|
//qDebug() << "Init...";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionTest::testConnect() {
|
||||||
|
QFETCH(QString, host);
|
||||||
|
QFETCH(int, port);
|
||||||
|
QFETCH(int, connectionType);
|
||||||
|
|
||||||
|
const SmtpClient::ConnectionType cTypes[] = {
|
||||||
|
SmtpClient::TcpConnection,
|
||||||
|
SmtpClient::SslConnection,
|
||||||
|
SmtpClient::TcpConnection
|
||||||
|
};
|
||||||
|
|
||||||
|
SmtpClient::ConnectionType cType = cTypes[--connectionType];
|
||||||
|
|
||||||
|
SmtpClient smtp(host, port, cType);
|
||||||
|
smtp.connectToHost();
|
||||||
|
|
||||||
|
QCOMPARE(smtp.waitForReadyConnected(5000), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionTest::testConnect_data() {
|
||||||
|
QTest::addColumn<QString>("host");
|
||||||
|
QTest::addColumn<int>("port");
|
||||||
|
QTest::addColumn<int>("connectionType");
|
||||||
|
|
||||||
|
QFile file("../connect_data.txt");
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QTextStream in(&file);
|
||||||
|
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString host;
|
||||||
|
int port;
|
||||||
|
int connectionType;
|
||||||
|
in >> host >> port >> connectionType;
|
||||||
|
if (!host.isEmpty()) {
|
||||||
|
QTest::newRow(QString("%1:%2").arg(host).arg(port).toLocal8Bit().data()) << host << port << connectionType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionTest::cleanup() {
|
||||||
|
}
|
21
test/connectiontest.h
Normal file
21
test/connectiontest.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef CONNECTIONTEST_H
|
||||||
|
#define CONNECTIONTEST_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class ConnectionTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConnectionTest(QObject *parent = 0);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
void testConnect();
|
||||||
|
void testConnect_data();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONNECTIONTEST_H
|
26
test/main.cpp
Normal file
26
test/main.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <QtGui/QApplication>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QtTest/QTest>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "connectiontest.h"
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
void runTest(QObject *test) {
|
||||||
|
int retVal = QTest::qExec(test);
|
||||||
|
success &= retVal == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
runTest(new ConnectionTest());
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
qDebug() << "SUCCESS";
|
||||||
|
else
|
||||||
|
qDebug() << "FAIL";
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
27
test/test.pro
Normal file
27
test/test.pro
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2012-09-22T16:39:45
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += testlib gui
|
||||||
|
|
||||||
|
TARGET = test
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
connectiontest.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
connectiontest.h
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../bin/lib/release/ -lSmtpMime
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../bin/lib/debug/ -lSmtpMime
|
||||||
|
else:unix:!symbian: LIBS += -L$$PWD/../bin/lib/release/ -lSmtpMime
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../bin/lib/release
|
||||||
|
DEPENDPATH += $$PWD/../bin/lib/release
|
Loading…
Reference in New Issue
Block a user