summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project2/sendmailTask.cpp112
-rw-r--r--project2/sendmailTask.h17
2 files changed, 76 insertions, 53 deletions
diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp
index e4a9af5..3fc0039 100644
--- a/project2/sendmailTask.cpp
+++ b/project2/sendmailTask.cpp
@@ -10,6 +10,8 @@
ElementLoaderImpl<_SendMailTask> sendmailLoader("sendmail");
+typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr;
+
_SendMailTask::_SendMailTask(const xmlpp::Element * p) :
_SourceObject(p),
_Task(p),
@@ -17,16 +19,12 @@ _SendMailTask::_SendMailTask(const xmlpp::Element * p) :
subject(p->get_attribute("subject")),
from(p->get_attribute("from")),
server(p->get_attribute("server")),
- present(p->get_attribute_value("present").raw()),
- body(NULL)
+ present(p->get_attribute_value("present").raw())
{
}
_SendMailTask::~_SendMailTask()
{
- if (body) {
- xmlFree(body);
- }
}
void
@@ -40,29 +38,77 @@ _SendMailTask::writeMailWrapper(void ** buf, int * len, void * arg)
return static_cast<const _SendMailTask*>(arg)->writeMail(buf, len);
}
+class BoundaryBegin : public _SendMailTask::MailPart {
+ public:
+ BoundaryBegin(const std::string & ct) : contentType(ct) {
+ }
+ const char * write(char ** buf, int * len) {
+ *len = asprintf(buf, "\r\n--<<divider>>\r\nContent-Type: %s\r\n\r\n", contentType.c_str());
+ return *buf;
+ }
+ private:
+ const std::string contentType;
+};
+class BoundaryEnd : public _SendMailTask::MailPart {
+ public:
+ const char * write(char ** buf, int * len) {
+ *len = 19;
+ return "\r\n--<<divider>>--\r\n";
+ }
+};
+class Header : public _SendMailTask::MailPart {
+ public:
+ Header(const std::string & h, const Glib::ustring & v) :
+ header(h), value(v) {
+ }
+ const char * write(char ** buf, int * len) {
+ *len = asprintf(buf, "%s: %s\r\n", header.c_str(), value.c_str());
+ return (const char *)*buf;
+ }
+ private:
+ const std::string header;
+ const Glib::ustring value;
+};
+class HtmlContent : public _SendMailTask::MailPart {
+ public:
+ HtmlContent(XmlDocumentPtr d) : doc(d) {
+ }
+ const char * write(char ** buf, int * len) {
+ xmlDocDumpFormatMemoryEnc(doc.get(), (xmlChar**)buf, len, "utf-8", 0);
+ return *buf;
+ }
+ private:
+ const XmlDocumentPtr doc;
+};
+
void
_SendMailTask::execute() const
{
PresenterPtr p = ApplicationEngine::getCurrent()->getPresenter("emails", present);
Presenter::XmlDocumentPtr data = p->getDataDocument();
typedef boost::shared_ptr<xsltStylesheet> XsltStyleSheetPtr;
- typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr;
// Do transform
- XsltStyleSheetPtr cur = XsltStyleSheetPtr(xsltParseStylesheetFile(BAD_CAST p->responseStyle.c_str()),
- xsltFreeStylesheet);
- if (!cur) { throw std::runtime_error("Failed to load stylesheet"); }
+ XsltStyleSheetPtr cur = XsltStyleSheetPtr(xsltParseStylesheetFile(BAD_CAST p->responseStyle.c_str()), xsltFreeStylesheet);
+ if (!cur) {
+ throw std::runtime_error("Failed to load stylesheet");
+ }
XmlDocumentPtr result = XmlDocumentPtr(xsltApplyStylesheet(cur.get(), data->cobj(), NULL), xmlFreeDoc);
- if (!result) { throw std::runtime_error("Failed to perform transformation"); }
- xmlDocDumpFormatMemoryEnc(result.get(), &body, &bodyLength, "utf-8", 0);
+ if (!result) {
+ throw std::runtime_error("Failed to perform transformation");
+ }
- headers[-1] = HeaderPtr(new Header("To", to));
- headers[-2] = HeaderPtr(new Header("From", from));
- headers[-3] = HeaderPtr(new Header("Subject", subject));
- headers[-4] = HeaderPtr(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\""));
- headers[-5] = HeaderPtr(new Header("MIME-Version", "1.0"));
- headers[-6] = HeaderPtr(new Header("Content-Transfer-Encoding", "binary"));
- position = -1;
+ parts.clear();
+ parts.push_back(new Header("To", to));
+ parts.push_back(new Header("From", from));
+ parts.push_back(new Header("Subject", subject));
+ parts.push_back(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\""));
+ parts.push_back(new Header("MIME-Version", "1.0"));
+ parts.push_back(new Header("Content-Transfer-Encoding", "binary"));
+ parts.push_back(new BoundaryBegin("text/html; utf-8"));
+ parts.push_back(new HtmlContent(result));
+ parts.push_back(new BoundaryEnd());
+ part = parts.begin();
// Write email
smtp_session_t session = smtp_create_session();
@@ -81,33 +127,9 @@ _SendMailTask::execute() const
const char *
_SendMailTask::writeMail(void ** buf, int * len) const
{
- if (!len) {
- position = -1;
- return NULL;
- }
- Headers::const_iterator h = headers.find(position);
- if (h != headers.end()) {
- *len = asprintf((char**)buf, "%s: %s\r\n", h->second->first.c_str(), h->second->second.c_str());
- position -= 1;
- return (const char *)*buf;
- }
- else if (position < 0) {
- position = 0;
- *len = 51;
- return "\r\n--<<divider>>\r\nContent-Type: text/html; utf-8\r\n\r\n";
- }
- else if (position == bodyLength) {
- position = bodyLength + 1;
- *len = 17;
- return "--<<divider>>--\r\n";
- }
- else if (position >= 0 && position < bodyLength) {
- *buf = NULL;
- *len = bodyLength;
- position = bodyLength;
- return (const char *)body;
- }
- else {
+ if (len == NULL || part == parts.end()) {
return NULL;
}
+ return (*part++)->write((char**)buf, len);
}
+
diff --git a/project2/sendmailTask.h b/project2/sendmailTask.h
index ef66c3f..2193974 100644
--- a/project2/sendmailTask.h
+++ b/project2/sendmailTask.h
@@ -3,7 +3,6 @@
#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
-#include <boost/shared_ptr.hpp>
#include <map>
#include "task.h"
#include "variables.h"
@@ -14,6 +13,11 @@ typedef unsigned char xmlChar;
class _SendMailTask : public _Task {
public:
+ class MailPart : public IntrusivePtrBase {
+ public:
+ virtual const char * write(char ** buf, int * len) = 0;
+ };
+
_SendMailTask(const xmlpp::Element * p);
virtual ~_SendMailTask();
virtual void loadComplete();
@@ -30,13 +34,10 @@ class _SendMailTask : public _Task {
static const char * writeMailWrapper(void ** buf, int * len, void * arg);
const char * writeMail(void ** buf, int * len) const;
- typedef std::pair<std::string, const Glib::ustring> Header;
- typedef boost::shared_ptr<Header> HeaderPtr;
- typedef std::map<int, HeaderPtr> Headers;
- mutable Headers headers;
- mutable xmlChar * body;
- mutable int bodyLength;
- mutable int position;
+ typedef boost::intrusive_ptr<MailPart> MailPartPtr;
+ typedef std::list<MailPartPtr> Parts;
+ mutable Parts parts;
+ mutable Parts::iterator part;
};
typedef boost::intrusive_ptr<_SendMailTask> SendMailTask;
typedef std::map<std::string, SendMailTask> SendMailTasks;