diff options
| -rw-r--r-- | project2/sendmailTask.cpp | 71 | ||||
| -rw-r--r-- | project2/sendmailTask.h | 10 | 
2 files changed, 62 insertions, 19 deletions
diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp index ba2f3b0..073022f 100644 --- a/project2/sendmailTask.cpp +++ b/project2/sendmailTask.cpp @@ -12,6 +12,8 @@  DECLARE_LOADER("sendmail", SendMailTask); +uint8_t SendMailTask::MailPart::mimeIdx; +  class SendEmailFailed : public std::runtime_error {  	public:  		SendEmailFailed(const std::string & what) : std::runtime_error(what) { } @@ -45,9 +47,29 @@ SendMailTask::writeMailWrapper(void ** buf, int * len, void * arg)  	return static_cast<const SendMailTask*>(arg)->writeMail(buf, len);  } +SendMailTask::MailPart::MailPart(uint8_t s, uint8_t i, uint8_t p) : +	sec(s), +	ind(i), +	prt(p) +{ +} + +SendMailTask::MailPart::~MailPart() +{ +} + +bool +SendMailTask::SortMailParts::operator()(const MailPartPtr & a, const MailPartPtr & b) const +{ +	return (a->sec < b->sec) || ((a->sec == b->sec) && (a->ind < b->ind)) +		 || ((a->sec == b->sec) && (a->ind == b->ind) && (a->prt < b->prt)); +} +  class BoundaryBegin : public SendMailTask::MailPart {  	public: -		BoundaryBegin(const std::string & ct) : contentType(ct) { +		BoundaryBegin(const std::string & ct, uint8_t m) : +			MailPart(m, MailPart::mimeIdx, 0), +			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()); @@ -59,6 +81,9 @@ class BoundaryBegin : public SendMailTask::MailPart {  class BoundaryEnd : public SendMailTask::MailPart {  	public: +		BoundaryEnd() : +			MailPart(255, 0, 0) { +		}  		const char * write(char **, int * len) {  			*len = 19;  			return "\r\n--<<divider>>--\r\n"; @@ -68,10 +93,14 @@ class BoundaryEnd : public SendMailTask::MailPart {  class Header : public SendMailTask::MailPart {  	public:  		Header(const std::string & h, const VariableType & v) : -			header(h), value(v) { +			MailPart(0, 0, 0), +			header(h), +			value(v) {  		}  		Header(const std::string & h, const char * v) : -			header(h), value(v) { +			MailPart(0, 0, 0), +			header(h), +			value(v) {  		}  		const char * write(char ** buf, int * len) {  			writeText(buf, len, value); @@ -87,7 +116,10 @@ class Header : public SendMailTask::MailPart {  class MimeContent : public SendMailTask::MailPart {  	public: -		MimeContent(const char * s, int l) : str(s), length(l) { +		MimeContent(const char * s, int l, uint8_t m) : +			MailPart(m, MailPart::mimeIdx, 1), +			str(s), +			length(l) {  		}  		const char * write(char ** buf, int * len) {  			*buf = NULL; @@ -119,23 +151,25 @@ class TransformHtmlToEmail : public TransformImpl<HtmlDocument, SendMailTask::Pa  			xmlDoc * doc = const_cast<xmlDoc *>(cdoc->doc);  			int len = 0;  			xmlDocDumpFormatMemoryEnc(doc, &buf, &len, "utf-8", 1); -			parts->parts.push_back(new BoundaryBegin("text/html; utf-8")); -			parts->parts.push_back(new MimeContent(reinterpret_cast<const char *>(buf), len)); +			parts->parts.insert(new BoundaryBegin("text/html; utf-8", 2)); +			parts->parts.insert(new MimeContent(reinterpret_cast<const char *>(buf), len, 2)); +			SendMailTask::MailPart::mimeIdx += 1;  		}  	private:  		mutable xmlChar * buf;  }; -DECLARE_TRANSFORM(TransformHtmlToEmail) +DECLARE_TRANSFORM(TransformHtmlToEmail);  class TransformTextToEmail : public TransformImpl<TextDocument, SendMailTask::Parts> {  	public:  		void transform(const TextDocument * str, SendMailTask::Parts * parts) const  		{ -			parts->parts.push_back(new BoundaryBegin("text/plain; utf-8")); -			parts->parts.push_back(new MimeContent(str->doc.c_str(), str->doc.length())); +			parts->parts.insert(new BoundaryBegin("text/plain; utf-8", 1)); +			parts->parts.insert(new MimeContent(str->doc.c_str(), str->doc.length(), 1)); +			SendMailTask::MailPart::mimeIdx += 1;  		}  }; -DECLARE_TRANSFORM(TransformTextToEmail) +DECLARE_TRANSFORM(TransformTextToEmail);  PresenterPtr  SendMailTask::createDefaultPresenter(const xmlpp::Element * n) const @@ -155,17 +189,18 @@ void  SendMailTask::execute() const  {  	parts = new Parts(); -	parts->parts.push_back(new Header("To", to)); -	parts->parts.push_back(new Header("From", from)); -	parts->parts.push_back(new Header("Subject", subject)); -	parts->parts.push_back(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\"")); -	parts->parts.push_back(new Header("MIME-Version", "1.0")); -	parts->parts.push_back(new Header("Content-Transfer-Encoding", "binary")); +	MailPart::mimeIdx = 0; +	parts->parts.insert(new Header("To", to)); +	parts->parts.insert(new Header("From", from)); +	parts->parts.insert(new Header("Subject", subject)); +	parts->parts.insert(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\"")); +	parts->parts.insert(new Header("MIME-Version", "1.0")); +	parts->parts.insert(new Header("Content-Transfer-Encoding", "binary")); +	parts->parts.insert(new BoundaryEnd());  	ViewHostPtr vsp = new ViewHost("emails", present);  	vsp->executeViews(boost::bind(&SendMailTask::createDefaultPresenter, this, _1));  	vsp->doTransforms(); -	parts->parts.push_back(new BoundaryEnd());  	part = parts->parts.begin();  	// Write email @@ -180,7 +215,7 @@ SendMailTask::execute() const  		smtp_strerror(smtp_errno(), buf, sizeof buf);  		throw SendEmailFailed(buf);  	} -	parts->parts.clear(); +	parts.reset();  }  const char * diff --git a/project2/sendmailTask.h b/project2/sendmailTask.h index e57a309..f871574 100644 --- a/project2/sendmailTask.h +++ b/project2/sendmailTask.h @@ -14,10 +14,18 @@ class SendMailTask : public Task {  	public:  		class MailPart : public IntrusivePtrBase {  			public: +				MailPart(uint8_t, uint8_t, uint8_t); +				~MailPart();  				virtual const char * write(char ** buf, int * len) = 0; +				const uint8_t sec, ind, prt; +				static uint8_t mimeIdx;  		};  		typedef boost::intrusive_ptr<MailPart> MailPartPtr; -		typedef std::list<MailPartPtr> PartList; +		class SortMailParts { +			public: +				bool operator()(const MailPartPtr &, const MailPartPtr &) const; +		}; +		typedef std::multiset<MailPartPtr, SortMailParts> PartList;  		class Parts : public TransformChainLink {  			public:  				PartList parts;  | 
