diff options
| -rw-r--r-- | project2/sendmailTask.cpp | 112 | ||||
| -rw-r--r-- | project2/sendmailTask.h | 17 | 
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; | 
