aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/abstract
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/abstract')
-rw-r--r--src/core/abstract/.DS_Storebin0 -> 6148 bytes
-rw-r--r--src/core/abstract/MCAbstract.h13
-rw-r--r--src/core/abstract/MCAbstractMessage.cc65
-rw-r--r--src/core/abstract/MCAbstractMessage.h29
-rw-r--r--src/core/abstract/MCAbstractMessagePart.cc88
-rw-r--r--src/core/abstract/MCAbstractMessagePart.h39
-rw-r--r--src/core/abstract/MCAbstractMultipart.cc95
-rw-r--r--src/core/abstract/MCAbstractMultipart.h32
-rw-r--r--src/core/abstract/MCAbstractPart.cc223
-rw-r--r--src/core/abstract/MCAbstractPart.h63
-rw-r--r--src/core/abstract/MCAddress.cc364
-rw-r--r--src/core/abstract/MCAddress.h55
-rw-r--r--src/core/abstract/MCMessageConstants.h208
-rw-r--r--src/core/abstract/MCMessageHeader.cc1054
-rw-r--r--src/core/abstract/MCMessageHeader.h90
15 files changed, 2418 insertions, 0 deletions
diff --git a/src/core/abstract/.DS_Store b/src/core/abstract/.DS_Store
new file mode 100644
index 00000000..5008ddfc
--- /dev/null
+++ b/src/core/abstract/.DS_Store
Binary files differ
diff --git a/src/core/abstract/MCAbstract.h b/src/core/abstract/MCAbstract.h
new file mode 100644
index 00000000..fd36af46
--- /dev/null
+++ b/src/core/abstract/MCAbstract.h
@@ -0,0 +1,13 @@
+#ifndef __MAILCORE_MCABSTRACT_H
+
+#define __MAILCORE_MCABSTRACT_H
+
+#include <mailcore/MCAbstractMessage.h>
+#include <mailcore/MCAbstractMessagePart.h>
+#include <mailcore/MCAbstractMultipart.h>
+#include <mailcore/MCAbstractPart.h>
+#include <mailcore/MCAddress.h>
+#include <mailcore/MCMessageConstants.h>
+#include <mailcore/MCMessageHeader.h>
+
+#endif
diff --git a/src/core/abstract/MCAbstractMessage.cc b/src/core/abstract/MCAbstractMessage.cc
new file mode 100644
index 00000000..00a4b9b9
--- /dev/null
+++ b/src/core/abstract/MCAbstractMessage.cc
@@ -0,0 +1,65 @@
+#include "MCAbstractMessage.h"
+
+#include "MCMessageHeader.h"
+
+using namespace mailcore;
+
+AbstractMessage::AbstractMessage()
+{
+ init();
+}
+
+AbstractMessage::AbstractMessage(AbstractMessage * other)
+{
+ init();
+ mHeader = (MessageHeader *) MC_SAFE_COPY(other->mHeader);
+}
+
+void AbstractMessage::init()
+{
+ mHeader = NULL;
+}
+
+AbstractMessage::~AbstractMessage()
+{
+ MC_SAFE_RELEASE(mHeader);
+}
+
+String * AbstractMessage::description()
+{
+ if (mHeader != NULL) {
+ String * result = String::string();
+ result->appendUTF8Format("<%s:%p\n", className()->UTF8Characters(), this);
+ result->appendString(mHeader->description());
+ result->appendUTF8Characters(">");
+ return result;
+ }
+ else {
+ return Object::description();
+ }
+}
+
+#if 0
+String * AbstractMessage::className()
+{
+ return MCSTR("MessageHeader");
+}
+#endif
+
+Object * AbstractMessage::copy()
+{
+ return new AbstractMessage(this);
+}
+
+MessageHeader * AbstractMessage::header()
+{
+ if (mHeader == NULL) {
+ mHeader = new MessageHeader();
+ }
+ return mHeader;
+}
+
+void AbstractMessage::setHeader(MessageHeader * header)
+{
+ MC_SAFE_REPLACE_RETAIN(MessageHeader, mHeader, header);
+}
diff --git a/src/core/abstract/MCAbstractMessage.h b/src/core/abstract/MCAbstractMessage.h
new file mode 100644
index 00000000..e5b62c8a
--- /dev/null
+++ b/src/core/abstract/MCAbstractMessage.h
@@ -0,0 +1,29 @@
+#ifndef __MAILCORE_MCABSTRACTMESSAGE_H_
+#define __MAILCORE_MCABSTRACTMESSAGE_H_
+
+#include <mailcore/MCBaseTypes.h>
+
+namespace mailcore {
+
+ class MessageHeader;
+
+ class AbstractMessage : public Object {
+ private:
+ MessageHeader * mHeader;
+ void init();
+
+ public:
+ AbstractMessage();
+ AbstractMessage(AbstractMessage * other);
+ virtual ~AbstractMessage();
+
+ virtual String * description();
+ //virtual String * className();
+ virtual Object * copy();
+
+ virtual MessageHeader * header();
+ virtual void setHeader(MessageHeader * header);
+ };
+}
+
+#endif
diff --git a/src/core/abstract/MCAbstractMessagePart.cc b/src/core/abstract/MCAbstractMessagePart.cc
new file mode 100644
index 00000000..6939d060
--- /dev/null
+++ b/src/core/abstract/MCAbstractMessagePart.cc
@@ -0,0 +1,88 @@
+#include "MCAbstractMessagePart.h"
+
+#include "MCMessageHeader.h"
+
+using namespace mailcore;
+
+void AbstractMessagePart::init()
+{
+ mMainPart = NULL;
+ mHeader = NULL;
+}
+
+AbstractMessagePart::AbstractMessagePart()
+{
+}
+
+AbstractMessagePart::AbstractMessagePart(AbstractMessagePart * other)
+{
+ if (other->mainPart() != NULL) {
+ setMainPart((AbstractPart *) other->mainPart()->copy()->autorelease());
+ }
+ if (other->mHeader != NULL) {
+ setHeader((MessageHeader *) other->header()->copy()->autorelease());
+ }
+}
+
+AbstractMessagePart::~AbstractMessagePart()
+{
+ MC_SAFE_RELEASE(mMainPart);
+ MC_SAFE_RELEASE(mHeader);
+}
+
+String * AbstractMessagePart::description()
+{
+ String * result = String::string();
+ result->appendUTF8Format("<%s:%p %s>", className(), this, mMainPart->description());
+ return result;
+}
+
+#if 0
+String * AbstractMessagePart::className()
+{
+ return MCSTR("AbstractMessagePart");
+}
+#endif
+
+Object * AbstractMessagePart::copy()
+{
+ return new AbstractMessagePart(this);
+}
+
+MessageHeader * AbstractMessagePart::header()
+{
+ if (mHeader == NULL) {
+ mHeader = new MessageHeader();
+ }
+ return mHeader;
+}
+
+void AbstractMessagePart::setHeader(MessageHeader * header)
+{
+ MC_SAFE_REPLACE_RETAIN(MessageHeader, mHeader, header);
+}
+
+AbstractPart * AbstractMessagePart::mainPart()
+{
+ return mMainPart;
+}
+
+void AbstractMessagePart::setMainPart(AbstractPart * mainPart)
+{
+ MC_SAFE_REPLACE_RETAIN(AbstractPart, mMainPart, mainPart);
+ applyMessage();
+}
+
+void AbstractMessagePart::applyMessage()
+{
+ if (mMainPart == NULL)
+ return;
+
+ mMainPart->setMessage(message());
+}
+
+void AbstractMessagePart::setMessage(AbstractMessage * message)
+{
+ AbstractPart::setMessage(message);
+ applyMessage();
+}
diff --git a/src/core/abstract/MCAbstractMessagePart.h b/src/core/abstract/MCAbstractMessagePart.h
new file mode 100644
index 00000000..a855202c
--- /dev/null
+++ b/src/core/abstract/MCAbstractMessagePart.h
@@ -0,0 +1,39 @@
+#ifndef __MAILCORE_MCABSTRACTMESSAGEPART_H_
+
+#define __MAILCORE_MCABSTRACTMESSAGEPART_H_
+
+#include <mailcore/MCBaseTypes.h>
+#include <mailcore/MCAbstractPart.h>
+
+namespace mailcore {
+
+ class MessageHeader;
+
+ class AbstractMessagePart : public AbstractPart {
+ private:
+ AbstractPart * mMainPart;
+ MessageHeader * mHeader;
+ void init();
+ void applyMessage();
+
+ public:
+ AbstractMessagePart();
+ AbstractMessagePart(AbstractMessagePart * other);
+ virtual ~AbstractMessagePart();
+
+ virtual String * description();
+ //virtual String * className();
+ virtual Object * copy();
+
+ virtual MessageHeader * header();
+ virtual void setHeader(MessageHeader * header);
+
+ virtual AbstractPart * mainPart();
+ virtual void setMainPart(AbstractPart * mainPart);
+
+ virtual void setMessage(AbstractMessage * message);
+ };
+}
+
+
+#endif
diff --git a/src/core/abstract/MCAbstractMultipart.cc b/src/core/abstract/MCAbstractMultipart.cc
new file mode 100644
index 00000000..fa48d959
--- /dev/null
+++ b/src/core/abstract/MCAbstractMultipart.cc
@@ -0,0 +1,95 @@
+#include "MCAbstractMultipart.h"
+
+using namespace mailcore;
+
+AbstractMultipart::AbstractMultipart()
+{
+ init();
+}
+
+AbstractMultipart::AbstractMultipart(AbstractMultipart * other) : AbstractPart(other)
+{
+ init();
+
+ setPartType(other->partType());
+ Array * parts = Array::array();
+ for(unsigned int i = 0 ; i < other->parts()->count() ; i ++) {
+ AbstractPart * part = (AbstractPart *) other->parts()->objectAtIndex(i);
+ parts->addObject(part->copy()->autorelease());
+ }
+ setParts(parts);
+}
+
+void AbstractMultipart::init()
+{
+ mParts = NULL;
+ setPartType(PartTypeMultipartMixed);
+}
+
+AbstractMultipart::~AbstractMultipart()
+{
+ MC_SAFE_RELEASE(mParts);
+}
+
+Array * AbstractMultipart::parts()
+{
+ return mParts;
+}
+
+void AbstractMultipart::setParts(Array * parts)
+{
+ MC_SAFE_REPLACE_COPY(Array, mParts, parts);
+ applyMessage();
+}
+
+String * AbstractMultipart::description()
+{
+ String * result = String::string();
+
+ const char * partTypeName = NULL;
+ switch (partType()) {
+ default:
+ case PartTypeMultipartMixed:
+ partTypeName = "mixed";
+ break;
+ case PartTypeMultipartRelated:
+ partTypeName = "related";
+ break;
+ case PartTypeMultipartAlternative:
+ partTypeName = "alernative";
+ break;
+ }
+
+ result->appendUTF8Format("<%s:%p %s %s>",
+ MCUTF8(className()), this, partTypeName, MCUTF8(mParts->description()));
+ return result;
+}
+
+#if 0
+String * AbstractMultipart::className()
+{
+ return MCSTR("AbstractMultipart");
+}
+#endif
+
+Object * AbstractMultipart::copy()
+{
+ return new AbstractMultipart(this);
+}
+
+void AbstractMultipart::applyMessage()
+{
+ if (mParts == NULL)
+ return;
+
+ for(unsigned int i = 0 ; i < mParts->count() ; i ++) {
+ AbstractPart * part = (AbstractPart *) mParts->objectAtIndex(i);
+ part->setMessage(message());
+ }
+}
+
+void AbstractMultipart::setMessage(AbstractMessage * message)
+{
+ AbstractPart::setMessage(message);
+ applyMessage();
+}
diff --git a/src/core/abstract/MCAbstractMultipart.h b/src/core/abstract/MCAbstractMultipart.h
new file mode 100644
index 00000000..c731ed7b
--- /dev/null
+++ b/src/core/abstract/MCAbstractMultipart.h
@@ -0,0 +1,32 @@
+#ifndef __MAILCORE_MCABSTRACTMULTIPART_H
+
+#define __MAILCORE_MCABSTRACTMULTIPART_H
+
+#include <mailcore/MCBaseTypes.h>
+#include <mailcore/MCAbstractPart.h>
+
+namespace mailcore {
+
+ class AbstractMultipart : public AbstractPart {
+ private:
+ Array * mParts;
+ void init();
+ void applyMessage();
+
+ public:
+ AbstractMultipart();
+ AbstractMultipart(AbstractMultipart * other);
+ virtual ~AbstractMultipart();
+
+ virtual String * description();
+ //virtual String * className();
+ virtual Object * copy();
+
+ virtual Array * parts();
+ virtual void setParts(Array * parts);
+
+ virtual void setMessage(AbstractMessage * message);
+ };
+}
+
+#endif
diff --git a/src/core/abstract/MCAbstractPart.cc b/src/core/abstract/MCAbstractPart.cc
new file mode 100644
index 00000000..30c4c8f0
--- /dev/null
+++ b/src/core/abstract/MCAbstractPart.cc
@@ -0,0 +1,223 @@
+#include "MCAbstractPart.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+using namespace mailcore;
+
+AbstractPart::AbstractPart()
+{
+ init();
+}
+
+AbstractPart::AbstractPart(AbstractPart * other)
+{
+ init();
+ setFilename(other->mFilename);
+ setMimeType(other->mMimeType);
+ setCharset(other->mCharset);
+ setContentID(other->mContentID);
+ setContentLocation(other->mContentLocation);
+ setInlineAttachment(other->mInlineAttachment);
+ setPartType(other->mPartType);
+}
+
+void AbstractPart::init()
+{
+ mFilename = NULL;
+ mMimeType = NULL;
+ mCharset = NULL;
+ mContentID = NULL;
+ mContentLocation = NULL;
+ mInlineAttachment = false;
+ mPartType = PartTypeSingle;
+}
+
+AbstractPart::~AbstractPart()
+{
+ MC_SAFE_RELEASE(mFilename);
+ MC_SAFE_RELEASE(mMimeType);
+ MC_SAFE_RELEASE(mCharset);
+ MC_SAFE_RELEASE(mContentID);
+ MC_SAFE_RELEASE(mContentLocation);
+}
+
+String * AbstractPart::description()
+{
+ String * result = String::string();
+ result->appendUTF8Format("<%s:%p\n", className()->UTF8Characters(), this);
+ if (mFilename != NULL) {
+ result->appendUTF8Format("filename: %s\n", mFilename->UTF8Characters());
+ }
+ if (mMimeType != NULL) {
+ result->appendUTF8Format("mime type: %s\n", mMimeType->UTF8Characters());
+ }
+ if (mCharset != NULL) {
+ result->appendUTF8Format("charset: %s\n", mCharset->UTF8Characters());
+ }
+ if (mContentID != NULL) {
+ result->appendUTF8Format("content-ID: %s\n", mContentID->UTF8Characters());
+ }
+ if (mContentLocation != NULL) {
+ result->appendUTF8Format("content-location: %s\n", mContentLocation->UTF8Characters());
+ }
+ result->appendUTF8Format("inline: %i\n", mInlineAttachment);
+ result->appendUTF8Format(">");
+
+ return result;
+}
+
+#if 0
+String * AbstractPart::className()
+{
+ return MCSTR("AbstractPart");
+}
+#endif
+
+Object * AbstractPart::copy()
+{
+ return new AbstractPart(this);
+}
+
+PartType AbstractPart::partType()
+{
+ return mPartType;
+}
+
+void AbstractPart::setPartType(PartType type)
+{
+ mPartType = type;
+}
+
+String * AbstractPart::filename()
+{
+ return mFilename;
+}
+
+void AbstractPart::setFilename(String * filename)
+{
+ MC_SAFE_REPLACE_COPY(String, mFilename, filename);
+}
+
+String * AbstractPart::mimeType()
+{
+ return mMimeType;
+}
+
+void AbstractPart::setMimeType(String * mimeType)
+{
+ MC_SAFE_REPLACE_COPY(String, mMimeType, mimeType);
+}
+
+String * AbstractPart::charset()
+{
+ return mCharset;
+}
+
+void AbstractPart::setCharset(String * charset)
+{
+ MC_SAFE_REPLACE_COPY(String, mCharset, charset);
+}
+
+String * AbstractPart::contentID()
+{
+ return mContentID;
+}
+
+void AbstractPart::setContentID(String * contentID)
+{
+ MC_SAFE_REPLACE_COPY(String, mContentID, contentID);
+}
+
+String * AbstractPart::contentLocation()
+{
+ return mContentLocation;
+}
+
+void AbstractPart::setContentLocation(String * contentLocation)
+{
+ MC_SAFE_REPLACE_COPY(String, mContentLocation, contentLocation);
+}
+
+bool AbstractPart::isInlineAttachment()
+{
+ return mInlineAttachment;
+}
+
+void AbstractPart::setInlineAttachment(bool inlineAttachment)
+{
+ mInlineAttachment = inlineAttachment;
+}
+
+AbstractMessage * AbstractPart::message()
+{
+ return mMessage;
+}
+
+void AbstractPart::setMessage(AbstractMessage * message)
+{
+ mMessage = message;
+}
+
+void AbstractPart::importIMAPFields(struct mailimap_body_fields * fields,
+ struct mailimap_body_ext_1part * extension)
+{
+ if (fields->bd_parameter != NULL) {
+ clistiter * cur;
+
+ for(cur = clist_begin(fields->bd_parameter->pa_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimap_single_body_fld_param * imap_param;
+
+ imap_param = (struct mailimap_single_body_fld_param *) clist_content(cur);
+
+ if (strcasecmp(imap_param->pa_name, "name") == 0) {
+ setFilename(String::stringByDecodingMIMEHeaderValue(imap_param->pa_value));
+ }
+ else if (strcasecmp(imap_param->pa_name, "charset") == 0) {
+ setCharset(String::stringByDecodingMIMEHeaderValue(imap_param->pa_value));
+ }
+ }
+ }
+ if (fields->bd_id != NULL) {
+ char * contentid;
+ size_t cur_token;
+ int r;
+
+ cur_token = 0;
+ r = mailimf_msg_id_parse(fields->bd_id, strlen(fields->bd_id),
+ &cur_token, &contentid);
+ if (r == MAILIMF_NO_ERROR) {
+ // msg id
+ setContentID(String::stringWithUTF8Characters(contentid));
+ free(contentid);
+ }
+ }
+
+ if (extension != NULL) {
+ if (extension->bd_disposition != NULL) {
+ if (strcasecmp(extension->bd_disposition->dsp_type, "inline") == 0) {
+ setInlineAttachment(true);
+ }
+
+ if (extension->bd_disposition->dsp_attributes != NULL) {
+ clistiter * cur;
+
+ for(cur = clist_begin(extension->bd_disposition->dsp_attributes->pa_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimap_single_body_fld_param * imap_param;
+
+ imap_param = (struct mailimap_single_body_fld_param *) clist_content(cur);
+
+ if (strcasecmp(imap_param->pa_name, "filename") == 0) {
+ setFilename(String::stringByDecodingMIMEHeaderValue(imap_param->pa_value));
+ }
+ }
+ }
+ }
+
+ if (extension->bd_loc != NULL) {
+ setContentLocation(String::stringWithUTF8Characters(extension->bd_loc));
+ }
+ }
+}
diff --git a/src/core/abstract/MCAbstractPart.h b/src/core/abstract/MCAbstractPart.h
new file mode 100644
index 00000000..356ed256
--- /dev/null
+++ b/src/core/abstract/MCAbstractPart.h
@@ -0,0 +1,63 @@
+#ifndef __MAILCORE_MCABSTRACTPART_H_
+
+#define __MAILCORE_MCABSTRACTPART_H_
+
+#include <mailcore/MCBaseTypes.h>
+#include <mailcore/MCMessageConstants.h>
+
+namespace mailcore {
+
+ class AbstractMessage;
+
+ class AbstractPart : public Object {
+ private:
+ String * mFilename;
+ String * mMimeType;
+ String * mCharset;
+ String * mContentID;
+ String * mContentLocation;
+ bool mInlineAttachment;
+ PartType mPartType;
+ AbstractMessage * mMessage; // weak
+ void init();
+
+ public:
+ AbstractPart();
+ AbstractPart(AbstractPart * other);
+ virtual ~AbstractPart();
+
+ virtual String * description();
+ //virtual String * className();
+ virtual Object * copy();
+
+ virtual PartType partType();
+ virtual void setPartType(PartType type);
+
+ virtual String * filename();
+ virtual void setFilename(String * filename);
+
+ virtual String * mimeType();
+ virtual void setMimeType(String * mimeType);
+
+ virtual String * charset();
+ virtual void setCharset(String * charset);
+
+ virtual String * contentID();
+ virtual void setContentID(String * contentID);
+
+ virtual String * contentLocation();
+ virtual void setContentLocation(String * contentLocation);
+
+ virtual bool isInlineAttachment();
+ virtual void setInlineAttachment(bool inlineAttachment);
+
+ virtual AbstractMessage * message();
+ virtual void setMessage(AbstractMessage * message);
+
+ virtual void importIMAPFields(struct mailimap_body_fields * fields,
+ struct mailimap_body_ext_1part * extension);
+ };
+
+}
+
+#endif
diff --git a/src/core/abstract/MCAddress.cc b/src/core/abstract/MCAddress.cc
new file mode 100644
index 00000000..25bed974
--- /dev/null
+++ b/src/core/abstract/MCAddress.cc
@@ -0,0 +1,364 @@
+#include "MCAddress.h"
+
+#include <string.h>
+
+using namespace mailcore;
+
+Address::Address()
+{
+ init();
+}
+
+Address::Address(Address * other)
+{
+ init();
+ setDisplayName(other->displayName());
+ setMailbox(other->mailbox());
+}
+
+void Address::init()
+{
+ mDisplayName = NULL;
+ mMailbox = NULL;
+}
+
+Address::~Address()
+{
+ MC_SAFE_RELEASE(mDisplayName);
+ MC_SAFE_RELEASE(mMailbox);
+}
+
+Address * Address::addressWithDisplayName(String * displayName, String * mailbox)
+{
+ Address * result = new Address();
+ result->setDisplayName(displayName);
+ result->setMailbox(mailbox);
+ return (Address *) result->autorelease();
+}
+
+Address * Address::addressWithMailbox(String * mailbox)
+{
+ return addressWithDisplayName(NULL, mailbox);
+}
+
+Address * Address::addressWithIMFMailbox(struct mailimf_mailbox * mailbox)
+{
+ Address * address;
+
+ address = new Address();
+ if (mailbox->mb_display_name != NULL) {
+ address->setDisplayName(String::stringByDecodingMIMEHeaderValue(mailbox->mb_display_name));
+ }
+ if (mailbox->mb_addr_spec != NULL) {
+ address->setMailbox(String::stringWithUTF8Characters(mailbox->mb_addr_spec));
+ }
+ if (address->mailbox() == NULL) {
+ address->setMailbox(String::string());
+ }
+
+ return (Address *) address->autorelease();
+}
+
+Address * Address::addressWithIMAPAddress(struct mailimap_address * imap_addr)
+{
+ char * dsp_name;
+ Address * address;
+ String * mailbox;
+
+ if (imap_addr->ad_personal_name == NULL)
+ dsp_name = NULL;
+ else {
+ dsp_name = imap_addr->ad_personal_name;
+ }
+
+ if (imap_addr->ad_host_name == NULL) {
+ const char * addr;
+
+ if (imap_addr->ad_mailbox_name == NULL) {
+ addr = "";
+ }
+ else {
+ addr = imap_addr->ad_mailbox_name;
+ }
+ mailbox = String::stringWithUTF8Characters(addr);
+ if (mailbox == NULL) {
+ mailbox = MCSTR("");
+ }
+ }
+ else if (imap_addr->ad_mailbox_name == NULL) {
+ // fix by Gabor Cselle, (http://gaborcselle.com/), reported 8/16/2009
+ mailbox = String::stringWithUTF8Format("@%s", imap_addr->ad_host_name);
+ }
+ else {
+ mailbox = String::stringWithUTF8Format("%s@%s", imap_addr->ad_mailbox_name, imap_addr->ad_host_name);
+ }
+
+ address = new Address();
+ if (dsp_name != NULL) {
+ address->setDisplayName(String::stringByDecodingMIMEHeaderValue(dsp_name));
+ }
+ address->setMailbox(mailbox);
+
+ return (Address *) address->autorelease();
+}
+
+Address * Address::addressWithRFC822String(String * RFC822String)
+{
+ const char * utf8String;
+ size_t currentIndex;
+ struct mailimf_mailbox * mb;
+ int r;
+ Address * result;
+
+ utf8String = RFC822String->UTF8Characters();
+ currentIndex = 0;
+ r = mailimf_mailbox_parse(utf8String, strlen(utf8String), &currentIndex, &mb);
+ if (r != MAILIMF_NO_ERROR)
+ return NULL;
+
+ result = addressWithIMFMailbox(mb);
+ mailimf_mailbox_free(mb);
+
+ return result;
+}
+
+Address * Address::addressWithNonEncodedIMFMailbox(struct mailimf_mailbox * mailbox)
+{
+ Address * address;
+
+ address = new Address();
+ if (mailbox->mb_display_name != NULL) {
+ address->setDisplayName(String::stringWithUTF8Characters(mailbox->mb_display_name));
+ }
+ if (mailbox->mb_addr_spec != NULL) {
+ address->setMailbox(String::stringWithUTF8Characters(mailbox->mb_addr_spec));
+ }
+ if (address->mailbox() == NULL) {
+ address->setMailbox(String::string());
+ }
+
+ return (Address *) address->autorelease();
+}
+
+Address * Address::addressWithNonEncodedRFC822String(String * nonEncodedRFC822String)
+{
+ const char * utf8String;
+ size_t currentIndex;
+ struct mailimf_mailbox * mb;
+ int r;
+ Address * result;
+
+ utf8String = nonEncodedRFC822String->UTF8Characters();
+ currentIndex = 0;
+ r = mailimf_mailbox_parse(utf8String, strlen(utf8String), &currentIndex, &mb);
+ if (r != MAILIMF_NO_ERROR)
+ return NULL;
+
+ result = addressWithNonEncodedIMFMailbox(mb);
+ mailimf_mailbox_free(mb);
+
+ return result;
+}
+
+String * Address::description()
+{
+ String * result = String::string();
+ result->appendString(className());
+ result->appendUTF8Format(":%p ", this);
+ if (mDisplayName != NULL) {
+ result->appendString(mDisplayName);
+ }
+ result->appendUTF8Characters(" <");
+ if (mMailbox != NULL) {
+ result->appendString(mMailbox);
+ }
+ result->appendUTF8Characters(">");
+
+ return result;
+}
+
+#if 0
+String * Address::className()
+{
+ return MCSTR("Address");
+}
+#endif
+
+bool Address::isEqual(Object * otherObject)
+{
+ Address * otherAddress = (Address *) otherObject;
+
+ if (mDisplayName == NULL) {
+ if (otherAddress->displayName() != NULL) {
+ return false;
+ }
+ }
+ else if (mDisplayName != NULL) {
+ if (otherAddress->displayName() == NULL) {
+ return false;
+ }
+ else {
+ if (!mDisplayName->isEqual(otherAddress->displayName()))
+ return false;
+ }
+ }
+
+ if (mMailbox == NULL) {
+ if (otherAddress->mailbox() != NULL) {
+ return false;
+ }
+ }
+ else if (mMailbox != NULL) {
+ if (otherAddress->mailbox() == NULL) {
+ return false;
+ }
+ else {
+ if (!mMailbox->isEqual(otherAddress->mailbox()))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+unsigned int Address::hash()
+{
+ unsigned int value;
+
+ value = 0;
+ if (mDisplayName != NULL) {
+ value += mDisplayName->hash();
+ }
+ if (mMailbox != NULL) {
+ value += mMailbox->hash();
+ }
+
+ return value;
+}
+
+Object * Address::copy()
+{
+ return new Address(this);
+}
+
+void Address::setDisplayName(String * displayName)
+{
+ MC_SAFE_REPLACE_COPY(String, mDisplayName, displayName);
+}
+
+String * Address::displayName()
+{
+ return mDisplayName;
+}
+
+void Address::setMailbox(String * mailbox)
+{
+ MC_SAFE_REPLACE_COPY(String, mMailbox, mailbox);
+}
+
+String * Address::mailbox()
+{
+ return mMailbox;
+}
+
+struct mailimf_address * Address::createIMFAddress()
+{
+ struct mailimf_mailbox * mailbox;
+ struct mailimf_address * result;
+
+ mailbox = createIMFMailbox();
+ result = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mailbox, NULL);
+
+ return result;
+}
+
+struct mailimf_mailbox * Address::createIMFMailbox()
+{
+ struct mailimf_mailbox * result;
+ char * display_name;
+ char * addr_spec;
+
+ display_name = NULL;
+ if (displayName() != NULL) {
+ if (displayName()->length() > 0) {
+ Data * data;
+
+ data = displayName()->encodedAddressDisplayNameValue();
+ if (data->bytes() != NULL) {
+ display_name = strdup(data->bytes());
+ }
+ }
+ }
+ addr_spec = strdup(mailbox()->UTF8Characters());
+ result = mailimf_mailbox_new(display_name, addr_spec);
+
+ return result;
+}
+
+String * Address::RFC822String()
+{
+ struct mailimf_mailbox * mb;
+ MMAPString * str;
+ int col;
+ struct mailimf_mailbox_list * mb_list;
+ clist * list;
+ String * result;
+
+ mb = createIMFMailbox();
+
+ list = clist_new();
+ clist_append(list, mb);
+ mb_list = mailimf_mailbox_list_new(list);
+
+ str = mmap_string_new("");
+ col = 0;
+ mailimf_mailbox_list_write_mem(str, &col, mb_list);
+
+ result = String::stringWithUTF8Characters(str->str);
+
+ mailimf_mailbox_list_free(mb_list);
+ mmap_string_free(str);
+
+ return result;
+}
+
+String * Address::nonEncodedRFC822String()
+{
+ struct mailimf_mailbox * mb;
+ MMAPString * str;
+ int col;
+ struct mailimf_mailbox_list * mb_list;
+ clist * list;
+ String * result;
+ char * display_name;
+ char * addr_spec;
+
+ display_name = NULL;
+ if (displayName() != NULL) {
+ if (displayName()->length() > 0) {
+ display_name = strdup(displayName()->UTF8Characters());
+ }
+ }
+ if ((mailbox() == NULL) || (mailbox()->length() == 0)) {
+ addr_spec = strdup("invalid");
+ }
+ else {
+ addr_spec = strdup(mailbox()->UTF8Characters());
+ }
+ mb = mailimf_mailbox_new(display_name, addr_spec);
+
+ list = clist_new();
+ clist_append(list, mb);
+ mb_list = mailimf_mailbox_list_new(list);
+
+ str = mmap_string_new("");
+ col = 0;
+ mailimf_mailbox_list_write_mem(str, &col, mb_list);
+
+ result = String::stringWithUTF8Characters(str->str);
+
+ mailimf_mailbox_list_free(mb_list);
+ mmap_string_free(str);
+
+ return result;
+}
diff --git a/src/core/abstract/MCAddress.h b/src/core/abstract/MCAddress.h
new file mode 100644
index 00000000..227c1136
--- /dev/null
+++ b/src/core/abstract/MCAddress.h
@@ -0,0 +1,55 @@
+#ifndef __MAILCORE_MCADDRESS_H_
+
+#define __MAILCORE_MCADDRESS_H_
+
+#include <libetpan/libetpan.h>
+#include <mailcore/MCBaseTypes.h>
+
+namespace mailcore {
+
+ class Address : public Object {
+ private:
+ String * mDisplayName;
+ String * mMailbox;
+ void init();
+
+ public:
+ Address();
+ Address(Address * other);
+ virtual ~Address();
+
+ static Address * addressWithDisplayName(String * displayName, String * mailbox);
+ static Address * addressWithMailbox(String * mailbox);
+ static Address * addressWithRFC822String(String * RFC822String);
+ static Address * addressWithNonEncodedRFC822String(String * nonEncodedRFC822String);
+
+ virtual String * description();
+ //virtual String * className();
+
+ virtual bool isEqual(Object * otherObject);
+ virtual unsigned int hash();
+
+ virtual Object * copy();
+
+ virtual void setDisplayName(String * displayName);
+ virtual String * displayName();
+
+ virtual void setMailbox(String * address);
+ virtual String * mailbox();
+
+ virtual String * RFC822String();
+ virtual String * nonEncodedRFC822String();
+
+ // Additions
+ static Address * addressWithIMFMailbox(struct mailimf_mailbox * mb);
+ static Address * addressWithNonEncodedIMFMailbox(struct mailimf_mailbox * mb);
+ static Address * addressWithIMAPAddress(struct mailimap_address * imap_addr);
+
+ // Must be released
+ virtual struct mailimf_address * createIMFAddress();
+ virtual struct mailimf_mailbox * createIMFMailbox();
+ };
+
+}
+
+#endif
diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h
new file mode 100644
index 00000000..ab30b8c4
--- /dev/null
+++ b/src/core/abstract/MCMessageConstants.h
@@ -0,0 +1,208 @@
+#ifndef __MAILCORE_MCMESSAGECONSTANTS_H_
+#define __MAILCORE_MCMESSAGECONSTANTS_H_
+
+namespace mailcore {
+
+ enum ConnectionType {
+ ConnectionTypeClear = 1 << 0,
+ ConnectionTypeStartTLS = 1 << 1,
+ ConnectionTypeTLS = 1 << 2,
+ };
+
+ enum AuthType {
+ AuthTypeSASLNone = 0,
+ AuthTypeSASLCRAMMD5 = 1 << 0,
+ AuthTypeSASLPlain = 1 << 1,
+ AuthTypeSASLGSSAPI = 1 << 2,
+ AuthTypeSASLDIGESTMD5 = 1 << 3,
+ AuthTypeSASLLogin = 1 << 4,
+ AuthTypeSASLSRP = 1 << 5,
+ AuthTypeSASLNTLM = 1 << 6,
+ AuthTypeSASLKerberosV4 = 1 << 7,
+ };
+
+ enum IMAPFolderFlag {
+ IMAPFolderFlagNone = 0,
+ IMAPFolderFlagMarked = 1 << 0,
+ IMAPFolderFlagUnmarked = 1 << 1,
+ IMAPFolderFlagNoSelect = 1 << 2,
+ IMAPFolderFlagNoInferiors = 1 << 3,
+ IMAPFolderFlagInbox = 1 << 4,
+ IMAPFolderFlagSentMail = 1 << 5,
+ IMAPFolderFlagStarred = 1 << 6,
+ IMAPFolderFlagAllMail = 1 << 7,
+ IMAPFolderFlagTrash = 1 << 8,
+ IMAPFolderFlagDrafts = 1 << 9,
+ IMAPFolderFlagSpam = 1 << 10,
+ IMAPFolderFlagImportant = 1 << 11,
+ IMAPFolderFlagArchive = 1 << 12,
+ };
+
+ enum MessageFlag {
+ MessageFlagNone = 0,
+ MessageFlagSeen = 1 << 0,
+ MessageFlagAnswered = 1 << 1,
+ MessageFlagFlagged = 1 << 2,
+ MessageFlagDeleted = 1 << 3,
+ MessageFlagDraft = 1 << 4,
+ MessageFlagMDNSent = 1 << 5,
+ MessageFlagForwarded = 1 << 6,
+ MessageFlagSubmitPending = 1 << 7,
+ MessageFlagSubmitted = 1 << 8,
+ } ;
+
+ enum IMAPMessagesRequestKind {
+ IMAPMessagesRequestKindUid = 0, // This is the default and it's always fetched
+ IMAPMessagesRequestKindFlags = 1 << 0,
+ IMAPMessagesRequestKindHeaders = 1 << 1,
+ IMAPMessagesRequestKindStructure = 1 << 2,
+ IMAPMessagesRequestKindInternalDate = 1 << 3,
+ IMAPMessagesRequestKindFullHeaders = 1 << 4,
+ IMAPMessagesRequestKindHeaderSubject = 1 << 5,
+ IMAPMessagesRequestKindGmailLabels = 1 << 6,
+ };
+
+ enum IMAPFetchRequestType {
+ IMAPFetchRequestTypeUID = 0,
+ IMAPFetchRequestTypeSequence = 1
+ };
+
+ enum IMAPStoreFlagsRequestKind {
+ IMAPStoreFlagsRequestKindAdd,
+ IMAPStoreFlagsRequestKindRemove,
+ IMAPStoreFlagsRequestKindSet,
+ };
+
+ enum IMAPWorkaround {
+ IMAPWorkaroundGmail = 1 << 0,
+ IMAPWorkaroundYahoo = 1 << 1,
+ IMAPWorkaroundExchange2003 = 1 << 2,
+ };
+
+ enum IMAPCapability {
+ IMAPCapabilityACL,
+ IMAPCapabilityBinary,
+ IMAPCapabilityCatenate,
+ IMAPCapabilityChildren,
+ IMAPCapabilityCompressDeflate,
+ IMAPCapabilityCondstore,
+ IMAPCapabilityEnable,
+ IMAPCapabilityIdle,
+ IMAPCapabilityLiteralPlus,
+ IMAPCapabilityMultiAppend,
+ IMAPCapabilityNamespace,
+ IMAPCapabilityQResync,
+ IMAPCapabilityQuota,
+ IMAPCapabilitySort,
+ IMAPCapabilityStartTLS,
+ IMAPCapabilityThreadOrderedSubject,
+ IMAPCapabilityThreadReferences,
+ IMAPCapabilityUIDPlus,
+ IMAPCapabilityUnselect,
+ IMAPCapabilityXList,
+ IMAPCapabilityAuthAnonymous,
+ IMAPCapabilityAuthCRAMMD5,
+ MAPCapabilityAuthDigestMD5,
+ IMAPCapabilityAuthExternal,
+ IMAPCapabilityAuthGSSAPI,
+ IMAPCapabilityAuthKerberosV4,
+ IMAPCapabilityAuthLogin,
+ IMAPCapabilityAuthNTLM,
+ IMAPCapabilityAuthOTP,
+ IMAPCapabilityAuthPlain,
+ IMAPCapabilityAuthSKey,
+ IMAPCapabilityAuthSRP,
+ };
+
+ enum POPCapability {
+ POPCapabilityNone,
+ POPCapabilityStartTLS,
+ POPCapabilityTop,
+ POPCapabilityUser,
+ POPCapabilityRespCodes,
+ POPCapabilityPipelining,
+ POPCapabilityUIDL,
+ POPCapabilitySASL,
+ POPCapabilityAuthAnonymous,
+ POPCapabilityAuthCRAMMD5,
+ POPCapabilityAuthDigestMD5,
+ POPCapabilityAuthExternal,
+ POPCapabilityAuthGSSAPI,
+ POPCapabilityAuthKerberosV4,
+ POPCapabilityAuthLogin,
+ POPCapabilityAuthNTLM,
+ POPCapabilityAuthOTP,
+ POPCapabilityAuthPlain,
+ POPCapabilityAuthSKey,
+ POPCapabilityAuthSRP,
+ };
+
+ enum Encoding {
+ Encoding7Bit = 0, // should match MAILIMAP_BODY_FLD_ENC_7BIT
+ Encoding8Bit = 1, // should match MAILIMAP_BODY_FLD_ENC_8BIT
+ EncodingBinary = 2, // should match MAILIMAP_BODY_FLD_ENC_BINARY
+ EncodingBase64 = 3, // should match MAILIMAP_BODY_FLD_ENC_BASE64
+ EncodingQuotedPrintable = 4, // should match MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE
+ EncodingOther = 5, // should match MAILIMAP_BODY_FLD_ENC_OTHER
+ // negative values should be used for other encoding
+ EncodingUUEncode = -1
+ };
+
+ enum IMAPSearchKind {
+ IMAPSearchKindNone,
+ IMAPSearchKindFrom,
+ IMAPSearchKindRecipient,
+ IMAPSearchKindSubject,
+ IMAPSearchKindContent,
+ IMAPSearchKindHeader,
+ IMAPSearchKindOr,
+ IMAPSearchKindAnd,
+ };
+
+ enum ErrorCode {
+ ErrorNone,
+ ErrorConnection,
+ ErrorTLSNotAvailable,
+ ErrorTLSCertificate,
+ ErrorParse,
+ ErrorCertificate,
+ ErrorAuthentication,
+ ErrorGmailIMAPNotEnabled,
+ ErrorGmailExceededBandwidthLimit,
+ ErrorGmailTooManySimultaneousConnections,
+ ErrorMobileMeMoved,
+ ErrorYahooUnavailable,
+ ErrorNonExistantFolder,
+ ErrorRename,
+ ErrorDelete,
+ ErrorCreate,
+ ErrorSubscribe,
+ ErrorAppend,
+ ErrorCopy,
+ ErrorExpunge,
+ ErrorFetch,
+ ErrorIdle,
+ ErrorIdentity,
+ ErrorNamespace,
+ ErrorStore,
+ ErrorStartTLSNotAvailable,
+ ErrorSendMessageIllegalAttachment,
+ ErrorStorageLimit,
+ ErrorSendMessageNotAllowed,
+ ErrorNeedsConnectToWebmail,
+ ErrorSendMessage,
+ ErrorAuthenticationRequired,
+ ErrorFetchMessageList,
+ ErrorDeleteMessage,
+ };
+
+ enum PartType {
+ PartTypeSingle,
+ PartTypeMessage,
+ PartTypeMultipartMixed,
+ PartTypeMultipartRelated,
+ PartTypeMultipartAlternative,
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc
new file mode 100644
index 00000000..06ad386b
--- /dev/null
+++ b/src/core/abstract/MCMessageHeader.cc
@@ -0,0 +1,1054 @@
+#include "MCMessageHeader.h"
+
+#include "MCAddress.h"
+
+#include <string.h>
+#include <unistd.h>
+
+using namespace mailcore;
+
+static time_t timestamp_from_date(struct mailimf_date_time * date_time);
+static struct mailimf_date_time * get_date_from_timestamp(time_t timeval);
+static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time);
+static time_t mkgmtime(struct tm * tmp);
+static int tmcomp(struct tm * atmp, struct tm * btmp);
+
+static struct mailimf_address_list * lep_address_list_from_array(Array * addresses);
+static struct mailimf_mailbox_list * lep_mailbox_list_from_array(Array * addresses);
+static Array * lep_address_list_from_lep_addr(struct mailimf_address_list * addr_list);
+static Array * lep_address_list_from_lep_mailbox(struct mailimf_mailbox_list * mb_list);
+
+static Array * msg_id_to_string_array(clist * msgids);
+static clist * msg_id_from_string_array(Array * msgids);
+
+#define MAX_HOSTNAME 512
+
+MessageHeader::MessageHeader()
+{
+ init(true, true);
+}
+
+MessageHeader::MessageHeader(MessageHeader * other)
+{
+ init(false, other->mMessageID == NULL);
+ setMessageID(other->mMessageID);
+ setReferences(other->mReferences);
+ setInReplyTo(other->mInReplyTo);
+ setSender(other->mSender);
+ setFrom(other->mFrom);
+ setTo(other->mTo);
+ setCc(other->mCc);
+ setBcc(other->mBcc);
+ setReplyTo(other->mReplyTo);
+ setSubject(other->mSubject);
+ setUserAgent(other->mUserAgent);
+}
+
+void MessageHeader::init(bool generateDate, bool generateMessageID)
+{
+ mMessageID = NULL;
+ mReferences = NULL;
+ mInReplyTo = NULL;
+ mSender = NULL;
+ mFrom = NULL;
+ mTo = NULL;
+ mCc = NULL;
+ mBcc = NULL;
+ mReplyTo = NULL;
+ mSubject = NULL;
+ mDate = (time_t) -1;
+ mReceivedDate = (time_t) -1;
+ mUserAgent = NULL;
+
+ if (generateDate) {
+ time_t date;
+ date = time(NULL);
+ setDate(date);
+ setReceivedDate(date);
+ }
+ if (generateMessageID) {
+ static String * hostname = NULL;
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+ pthread_mutex_lock(&lock);
+ if (hostname == NULL) {
+ char name[MAX_HOSTNAME];
+ int r;
+
+ r = gethostname(name, MAX_HOSTNAME);
+ if (r < 0) {
+ hostname = NULL;
+ }
+ else {
+ hostname = new String(name);
+ }
+ if (hostname == NULL) {
+ hostname = new String("localhost");
+ }
+ }
+ pthread_mutex_unlock(&lock);
+
+ String * messageID = new String();
+ messageID->appendString(String::uuidString());
+ messageID->appendUTF8Characters("@");
+ messageID->appendString(hostname);
+ setMessageID(messageID);
+ messageID->release();
+ }
+}
+
+MessageHeader::~MessageHeader()
+{
+ MC_SAFE_RELEASE(mMessageID);
+ MC_SAFE_RELEASE(mReferences);
+ MC_SAFE_RELEASE(mInReplyTo);
+ MC_SAFE_RELEASE(mSender);
+ MC_SAFE_RELEASE(mFrom);
+ MC_SAFE_RELEASE(mTo);
+ MC_SAFE_RELEASE(mCc);
+ MC_SAFE_RELEASE(mBcc);
+ MC_SAFE_RELEASE(mReplyTo);
+ MC_SAFE_RELEASE(mSubject);
+ MC_SAFE_RELEASE(mUserAgent);
+}
+
+String * MessageHeader::description()
+{
+ String * result = String::string();
+ result->appendUTF8Format("<%s:%p\n", className()->UTF8Characters(), this);
+ if (mMessageID != NULL) {
+ result->appendUTF8Format("Message-ID: %s\n", mMessageID->UTF8Characters());
+ }
+ if (mReferences != NULL) {
+ result->appendUTF8Format("References: %s\n", mReferences->description()->UTF8Characters());
+ }
+ if (mInReplyTo != NULL) {
+ result->appendUTF8Format("In-Reply-To: %s\n", mInReplyTo->description()->UTF8Characters());
+ }
+ if (mSender != NULL) {
+ result->appendUTF8Format("Sender: %s\n", mSender->description()->UTF8Characters());
+ }
+ if (mFrom != NULL) {
+ result->appendUTF8Format("From: %s\n", mFrom->description()->UTF8Characters());
+ }
+ if (mTo != NULL) {
+ result->appendUTF8Format("To: %s\n", mTo->description()->UTF8Characters());
+ }
+ if (mCc != NULL) {
+ result->appendUTF8Format("Cc: %s\n", mCc->description()->UTF8Characters());
+ }
+ if (mBcc != NULL) {
+ result->appendUTF8Format("Bcc: %s\n", mBcc->description()->UTF8Characters());
+ }
+ if (mReplyTo != NULL) {
+ result->appendUTF8Format("Reply-To: %s\n", mReplyTo->description()->UTF8Characters());
+ }
+ if (mSubject != NULL) {
+ result->appendUTF8Format("Subject: %s\n", mSubject->UTF8Characters());
+ }
+ if (mUserAgent != NULL) {
+ result->appendUTF8Format("X-Mailer: %s\n", mUserAgent->UTF8Characters());
+ }
+ result->appendUTF8Format(">");
+
+ return result;
+}
+
+#if 0
+String * MessageHeader::className()
+{
+ return MCSTR("MessageHeader");
+}
+#endif
+
+Object * MessageHeader::copy()
+{
+ return new MessageHeader(this);
+}
+
+void MessageHeader::setMessageID(String * messageID)
+{
+ MC_SAFE_REPLACE_COPY(String, mMessageID, messageID);
+}
+
+String * MessageHeader::messageID()
+{
+ return mMessageID;
+}
+
+void MessageHeader::setReferences(Array * references)
+{
+ MC_SAFE_REPLACE_COPY(Array, mReferences, references);
+}
+
+Array * MessageHeader::references()
+{
+ return mReferences;
+}
+
+void MessageHeader::setInReplyTo(Array * inReplyTo)
+{
+ MC_SAFE_REPLACE_COPY(Array, mInReplyTo, inReplyTo);
+}
+
+Array * MessageHeader::inReplyTo()
+{
+ return mInReplyTo;
+}
+
+void MessageHeader::setDate(time_t date)
+{
+ mDate = date;
+}
+
+time_t MessageHeader::date()
+{
+ return mDate;
+}
+
+void MessageHeader::setReceivedDate(time_t date)
+{
+ mReceivedDate = date;
+}
+
+time_t MessageHeader::receivedDate()
+{
+ return mReceivedDate;
+}
+
+void MessageHeader::setSender(Address * sender)
+{
+ MC_SAFE_REPLACE_RETAIN(Address, mSender, sender);
+}
+
+Address * MessageHeader::sender()
+{
+ return mSender;
+}
+
+void MessageHeader::setFrom(Address * from)
+{
+ MC_SAFE_REPLACE_RETAIN(Address, mFrom, from);
+}
+
+Address * MessageHeader::from()
+{
+ return mFrom;
+}
+
+void MessageHeader::setTo(Array * to)
+{
+ MC_SAFE_REPLACE_COPY(Array, mTo, to);
+}
+
+Array * MessageHeader::to()
+{
+ return mTo;
+}
+
+void MessageHeader::setCc(Array * cc)
+{
+ MC_SAFE_REPLACE_COPY(Array, mCc, cc);
+}
+
+Array * MessageHeader::cc()
+{
+ return mCc;
+}
+
+void MessageHeader::setBcc(Array * bcc)
+{
+ MC_SAFE_REPLACE_COPY(Array, mBcc, bcc);
+}
+
+Array * MessageHeader::bcc()
+{
+ return mBcc;
+}
+
+void MessageHeader::setReplyTo(Array * replyTo)
+{
+ MC_SAFE_REPLACE_COPY(Array, mReplyTo, replyTo);
+}
+
+Array * MessageHeader::replyTo()
+{
+ return mReplyTo;
+}
+
+void MessageHeader::setSubject(String * subject)
+{
+ MC_SAFE_REPLACE_COPY(String, mSubject, subject);
+}
+
+String * MessageHeader::subject()
+{
+ return mSubject;
+}
+
+void MessageHeader::setUserAgent(String * userAgent)
+{
+ MC_SAFE_REPLACE_COPY(String, mUserAgent, userAgent);
+}
+
+String * MessageHeader::userAgent()
+{
+ return mUserAgent;
+}
+
+String * MessageHeader::extractedSubject()
+{
+ return subject()->extractedSubject();
+}
+
+String * MessageHeader::partialExtractedSubject()
+{
+ return subject()->extractedSubjectAndKeepBracket(true);
+}
+
+void MessageHeader::importHeadersData(Data * data)
+{
+ size_t cur_token;
+ struct mailimf_fields * fields;
+ int r;
+
+ cur_token = 0;
+ r = mailimf_fields_parse(data->bytes(), data->length(), &cur_token, &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ return;
+ }
+
+ importIMFFields(fields);
+
+ mailimf_fields_free(fields);
+}
+
+void MessageHeader::importIMFFields(struct mailimf_fields * fields)
+{
+ struct mailimf_single_fields single_fields;
+
+ mailimf_single_fields_init(&single_fields, fields);
+
+ /* date */
+
+ if (single_fields.fld_orig_date != NULL) {
+ time_t timestamp;
+ timestamp = timestamp_from_date(single_fields.fld_orig_date->dt_date_time);
+ setDate(timestamp);
+ setReceivedDate(timestamp);
+ //MCLog("%lu %lu", (unsigned long) timestamp, date());
+ }
+
+ /* subject */
+ if (single_fields.fld_subject != NULL) {
+ char * subject;
+
+ subject = single_fields.fld_subject->sbj_value;
+ setSubject(String::stringByDecodingMIMEHeaderValue(subject));
+ }
+
+ /* sender */
+ if (single_fields.fld_sender != NULL) {
+ struct mailimf_mailbox * mb;
+ Address * address;
+
+ mb = single_fields.fld_sender->snd_mb;
+ if (mb != NULL) {
+ address = Address::addressWithIMFMailbox(mb);
+ setSender(address);
+ }
+ }
+
+ /* from */
+ if (single_fields.fld_from != NULL) {
+ struct mailimf_mailbox_list * mb_list;
+ Array * addresses;
+
+ mb_list = single_fields.fld_from->frm_mb_list;
+ addresses = lep_address_list_from_lep_mailbox(mb_list);
+ if (addresses->count() > 0) {
+ setFrom((Address *) (addresses->objectAtIndex(0)));
+ }
+ }
+
+ /* replyto */
+ if (single_fields.fld_reply_to != NULL) {
+ struct mailimf_address_list * addr_list;
+ Array * addresses;
+
+ addr_list = single_fields.fld_reply_to->rt_addr_list;
+ addresses = lep_address_list_from_lep_addr(addr_list);
+ setReplyTo(addresses);
+ }
+
+ /* to */
+ if (single_fields.fld_to != NULL) {
+ struct mailimf_address_list * addr_list;
+ Array * addresses;
+
+ addr_list = single_fields.fld_to->to_addr_list;
+ addresses = lep_address_list_from_lep_addr(addr_list);
+ setTo(addresses);
+ }
+
+ /* cc */
+ if (single_fields.fld_cc != NULL) {
+ struct mailimf_address_list * addr_list;
+ Array * addresses;
+
+ addr_list = single_fields.fld_cc->cc_addr_list;
+ addresses = lep_address_list_from_lep_addr(addr_list);
+ setCc(addresses);
+ }
+
+ /* bcc */
+ if (single_fields.fld_bcc != NULL) {
+ struct mailimf_address_list * addr_list;
+ Array * addresses;
+
+ addr_list = single_fields.fld_bcc->bcc_addr_list;
+ addresses = lep_address_list_from_lep_addr(addr_list);
+ setBcc(addresses);
+ }
+
+ /* msgid */
+ if (single_fields.fld_message_id != NULL) {
+ char * msgid;
+ String * str;
+
+ msgid = single_fields.fld_message_id->mid_value;
+ str = String::stringWithUTF8Characters(msgid);
+ setMessageID(str);
+ }
+
+ /* references */
+ if (single_fields.fld_references != NULL) {
+ clist * msg_id_list;
+ Array * msgids;
+
+ msg_id_list = single_fields.fld_references->mid_list;
+ msgids = msg_id_to_string_array(msg_id_list);
+ setReferences(msgids);
+ }
+
+ /* inreplyto */
+ if (single_fields.fld_in_reply_to != NULL) {
+ clist * msg_id_list;
+ Array * msgids;
+
+ msg_id_list = single_fields.fld_in_reply_to->mid_list;
+ msgids = msg_id_to_string_array(msg_id_list);
+ setInReplyTo(msgids);
+ }
+}
+
+static time_t timestamp_from_date(struct mailimf_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+static struct mailimf_date_time * get_date_from_timestamp(time_t timeval)
+{
+ struct tm gmt;
+ struct tm lt;
+ int off;
+ struct mailimf_date_time * date_time;
+ int sign;
+ int hour;
+ int min;
+
+ gmtime_r(&timeval, &gmt);
+ localtime_r(&timeval, &lt);
+
+ off = (mkgmtime(&lt) - mkgmtime(&gmt)) / 60;
+ if (off < 0) {
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ off = off * sign;
+ min = off % 60;
+ hour = off / 60;
+ off = hour * 100 + min;
+ off = off * sign;
+
+ date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1,
+ lt.tm_year + 1900,
+ lt.tm_hour, lt.tm_min, lt.tm_sec,
+ off);
+
+ return date_time;
+}
+
+static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+#define INVALID_TIMESTAMP (-1)
+
+static int tmcomp(struct tm * atmp, struct tm * btmp)
+{
+ register int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t mkgmtime(struct tm * tmp)
+{
+ register int dir;
+ register int bits;
+ register int saved_seconds;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ yourtm = *tmp;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ /*
+ ** Calculate the number of magnitude bits in a time_t
+ ** (this works regardless of whether time_t is
+ ** signed or unsigned, though lint complains if unsigned).
+ */
+ for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+ ;
+ /*
+ ** If time_t is signed, then 0 is the median value,
+ ** if time_t is unsigned, then 1 << bits is median.
+ */
+ if(bits > 40) bits = 40;
+ t = (t < 0) ? 0 : ((time_t) 1 << bits);
+ for ( ; ; ) {
+ gmtime_r(&t, &mytm);
+ dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0) {
+ if (bits-- < 0) {
+ return INVALID_TIMESTAMP;
+ }
+ if (bits < 0)
+ --t;
+ else if (dir > 0)
+ t -= (time_t) 1 << bits;
+ else t += (time_t) 1 << bits;
+ continue;
+ }
+ break;
+ }
+ t += saved_seconds;
+ return t;
+}
+
+#pragma mark RFC 2822 mailbox conversion
+
+static Array * lep_address_list_from_lep_mailbox(struct mailimf_mailbox_list * mb_list)
+{
+ Array * result;
+ clistiter * cur;
+
+ result = Array::array();
+ for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ; cur = clist_next(cur)) {
+ struct mailimf_mailbox * mb;
+ Address * address;
+
+ mb = (struct mailimf_mailbox *) clist_content(cur);
+ address = Address::addressWithIMFMailbox(mb);
+ result->addObject(address);
+ }
+
+ return result;
+}
+
+static Array * lep_address_list_from_lep_addr(struct mailimf_address_list * addr_list)
+{
+ Array * result;
+ clistiter * cur;
+
+ result = Array::array();
+
+ if (addr_list == NULL) {
+ return result;
+ }
+
+ if (addr_list->ad_list == NULL) {
+ return result;
+ }
+
+ for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimf_address * addr;
+
+ addr = (struct mailimf_address *) clist_content(cur);
+ switch (addr->ad_type) {
+ case MAILIMF_ADDRESS_MAILBOX:
+ {
+ Address * address;
+
+ address = Address::addressWithIMFMailbox(addr->ad_data.ad_mailbox);
+ result->addObject(address);
+ break;
+ }
+
+ case MAILIMF_ADDRESS_GROUP:
+ {
+ if (addr->ad_data.ad_group->grp_mb_list != NULL) {
+ Array * subArray;
+
+ subArray = lep_address_list_from_lep_mailbox(addr->ad_data.ad_group->grp_mb_list);
+ result->addObjectsFromArray(subArray);
+ }
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+static struct mailimf_mailbox_list * lep_mailbox_list_from_array(Array * addresses)
+{
+ struct mailimf_mailbox_list * mb_list;
+
+ if (addresses == NULL)
+ return NULL;
+
+ if (addresses->count() == 0)
+ return NULL;
+
+ mb_list = mailimf_mailbox_list_new_empty();
+
+ for(unsigned i = 0 ; i < addresses->count() ; i ++) {
+ Address * address = (Address *) addresses->objectAtIndex(i);
+ struct mailimf_mailbox * mailbox = address->createIMFMailbox();
+ mailimf_mailbox_list_add(mb_list, mailbox);
+ }
+
+ return mb_list;
+}
+
+static struct mailimf_address_list * lep_address_list_from_array(Array * addresses)
+{
+ struct mailimf_address_list * addr_list;
+
+ if (addresses == NULL)
+ return NULL;
+
+ if (addresses->count() == 0)
+ return NULL;
+
+ addr_list = mailimf_address_list_new_empty();
+
+ for(unsigned i = 0 ; i < addresses->count() ; i ++) {
+ Address * address = (Address *) addresses->objectAtIndex(i);
+ struct mailimf_address * addr = address->createIMFAddress();
+ mailimf_address_list_add(addr_list, addr);
+ }
+
+ return addr_list;
+}
+
+#pragma mark Message-ID conversion
+
+static Array * msg_id_to_string_array(clist * msgids)
+{
+ clistiter * cur;
+ Array * result;
+
+ result = Array::array();
+
+ for(cur = clist_begin(msgids) ; cur != NULL ; cur = clist_next(cur)) {
+ char * msgid;
+ String * str;
+
+ msgid = (char *) clist_content(cur);
+ str = String::stringWithUTF8Characters(msgid);
+ result->addObject(str);
+ }
+
+ return result;
+}
+
+static clist * msg_id_from_string_array(Array * msgids)
+{
+ clist * result;
+
+ if (msgids == NULL)
+ return NULL;
+
+ if (msgids->count() == 0)
+ return NULL;
+
+ result = clist_new();
+ for(unsigned int i = 0 ; i < msgids->count() ; i ++) {
+ String * msgid = (String *) msgids->objectAtIndex(i);
+ clist_append(result, strdup(msgid->UTF8Characters()));
+ }
+
+ return result;
+}
+
+struct mailimf_fields * MessageHeader::createIMFFieldsAndFilterBcc(bool filterBcc)
+{
+ struct mailimf_date_time * imfDate;
+ char * imfMsgid;
+ char * imfSubject;
+ struct mailimf_mailbox_list * imfFrom;
+ struct mailimf_address_list * imfReplyTo;
+ struct mailimf_address_list * imfTo;
+ struct mailimf_address_list * imfCc;
+ struct mailimf_address_list * imfBcc;
+ clist * imfInReplyTo;
+ clist * imfReferences;
+ struct mailimf_fields * fields;
+
+ imfDate = NULL;
+ if (date() != (time_t) -1) {
+ MCLog("%lu", date());
+ imfDate = get_date_from_timestamp(date());
+ }
+ imfFrom = NULL;
+ if (from() != NULL) {
+ imfFrom = lep_mailbox_list_from_array(Array::arrayWithObject(from()));
+ }
+ imfReplyTo = lep_address_list_from_array(replyTo());
+ imfTo = lep_address_list_from_array(to());
+ imfCc = lep_address_list_from_array(cc());
+ imfBcc = NULL;
+ if (!filterBcc) {
+ imfBcc = lep_address_list_from_array(bcc());
+ }
+ imfMsgid = NULL;
+ if (messageID() != NULL) {
+ imfMsgid = strdup(messageID()->UTF8Characters());
+ }
+ imfInReplyTo = msg_id_from_string_array(inReplyTo());
+ imfReferences = msg_id_from_string_array(references());
+ imfSubject = NULL;
+ if ((subject() != NULL) && (subject()->length() > 0)) {
+ Data * data;
+
+ data = subject()->encodedMIMEHeaderValueForSubject();
+ if (data->bytes() != NULL) {
+ imfSubject = strdup(data->bytes());
+ }
+ }
+
+ if ((imfTo == NULL) && (imfCc == NULL) && (imfBcc == NULL)) {
+ imfTo = mailimf_address_list_new_empty();
+ mailimf_address_list_add_parse(imfTo, (char *) "Undisclosed recipients:;");
+ }
+
+ fields = mailimf_fields_new_with_data_all(imfDate,
+ imfFrom,
+ NULL /* sender */,
+ imfReplyTo,
+ imfTo,
+ imfCc,
+ imfBcc,
+ imfMsgid,
+ imfInReplyTo,
+ imfReferences,
+ imfSubject);
+
+ if (mUserAgent != NULL) {
+ struct mailimf_field * field;
+
+ field = mailimf_field_new_custom(strdup("X-Mailer"), strdup(mUserAgent->UTF8Characters()));
+ mailimf_fields_add(fields, field);
+ }
+
+ return fields;
+}
+
+extern "C" {
+ extern int mailimap_hack_date_time_parse(char * str,
+ struct mailimap_date_time ** result,
+ size_t progr_rate,
+ progress_function * progr_fun);
+}
+
+#pragma mark IMAP mailbox conversion
+
+static Array * imap_mailbox_list_to_address_array(clist * imap_mailbox_list)
+{
+ clistiter * cur;
+ Array * result;
+
+ result = Array::array();
+
+ for(cur = clist_begin(imap_mailbox_list) ; cur != NULL ;
+ cur = clist_next(cur)) {
+ struct mailimap_address * imap_addr;
+ Address * address;
+
+ imap_addr = (struct mailimap_address *) clist_content(cur);
+ address = Address::addressWithIMAPAddress(imap_addr);
+ result->addObject(address);
+ }
+
+ return result;
+}
+
+void MessageHeader::importIMAPEnvelope(struct mailimap_envelope * env)
+{
+ if (env->env_date != NULL) {
+ size_t cur_token;
+ struct mailimf_date_time * date_time;
+ int r;
+
+ cur_token = 0;
+ r = mailimf_date_time_parse(env->env_date, strlen(env->env_date),
+ &cur_token, &date_time);
+ if (r == MAILIMF_NO_ERROR) {
+ time_t timestamp;
+
+ // date
+ timestamp = timestamp_from_date(date_time);
+ setDate(timestamp);
+ setReceivedDate(timestamp);
+ mailimf_date_time_free(date_time);
+ }
+ else {
+ struct mailimap_date_time * imap_date;
+
+ r = mailimap_hack_date_time_parse(env->env_date, &imap_date, 0, NULL);
+ if (r == MAILIMAP_NO_ERROR) {
+ time_t timestamp;
+
+ timestamp = timestamp_from_imap_date(imap_date);
+ setDate(timestamp);
+ setReceivedDate(timestamp);
+ mailimap_date_time_free(imap_date);
+ }
+ }
+ }
+
+ if (env->env_subject != NULL) {
+ char * subject;
+
+ // subject
+ subject = env->env_subject;
+ setSubject(String::stringByDecodingMIMEHeaderValue(subject));
+ }
+
+ if (env->env_sender != NULL) {
+ if (env->env_sender->snd_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_sender->snd_list);
+ if (addresses->count() > 0) {
+ setSender((Address *) addresses->objectAtIndex(0));
+ }
+ }
+ }
+
+ if (env->env_from != NULL) {
+ if (env->env_from->frm_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_from->frm_list);
+ if (addresses->count() > 0) {
+ setFrom((Address *) addresses->objectAtIndex(0));
+ }
+ }
+ }
+
+ // skip Sender header
+
+ if (env->env_reply_to != NULL) {
+ if (env->env_reply_to->rt_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_reply_to->rt_list);
+ setReplyTo(addresses);
+ }
+ }
+
+ if (env->env_to != NULL) {
+ if (env->env_to->to_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_to->to_list);
+ setTo(addresses);
+ }
+ }
+
+ if (env->env_cc != NULL) {
+ if (env->env_cc->cc_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_cc->cc_list);
+ setCc(addresses);
+ }
+ }
+
+ if (env->env_bcc != NULL) {
+ if (env->env_bcc->bcc_list != NULL) {
+ Array * addresses;
+
+ addresses = imap_mailbox_list_to_address_array(env->env_bcc->bcc_list);
+ setBcc(addresses);
+ }
+ }
+
+ if (env->env_in_reply_to != NULL) {
+ size_t cur_token;
+ clist * msg_id_list;
+ int r;
+
+ cur_token = 0;
+ r = mailimf_msg_id_list_parse(env->env_in_reply_to,
+ strlen(env->env_in_reply_to), &cur_token, &msg_id_list);
+ if (r == MAILIMF_NO_ERROR) {
+ Array * msgids;
+
+ msgids = msg_id_to_string_array(msg_id_list);
+ setInReplyTo(msgids);
+ // in-reply-to
+ clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
+ clist_free(msg_id_list);
+ }
+ }
+
+ if (env->env_message_id != NULL) {
+ char * msgid;
+ size_t cur_token;
+ int r;
+
+ cur_token = 0;
+ r = mailimf_msg_id_parse(env->env_message_id, strlen(env->env_message_id),
+ &cur_token, &msgid);
+ if (r == MAILIMF_NO_ERROR) {
+ // msg id
+ String * str;
+
+ str = String::stringWithUTF8Characters(msgid);
+ setMessageID(str);
+ mailimf_msg_id_free(msgid);
+ }
+ }
+}
+
+void MessageHeader::importIMAPReferences(Data * data)
+{
+ size_t cur_token;
+ struct mailimf_fields * fields;
+ int r;
+ struct mailimf_single_fields single_fields;
+
+ cur_token = 0;
+ r = mailimf_fields_parse(data->bytes(), data->length(), &cur_token, &fields);
+ if (r != MAILIMF_NO_ERROR) {
+ return;
+ }
+
+ mailimf_single_fields_init(&single_fields, fields);
+ if (single_fields.fld_references != NULL) {
+ Array * msgids;
+
+ msgids = msg_id_to_string_array(single_fields.fld_references->mid_list);
+ setReferences(msgids);
+ }
+ if (single_fields.fld_subject != NULL) {
+ if (single_fields.fld_subject->sbj_value != NULL) {
+ bool broken;
+ char * value;
+ bool isASCII;
+
+ broken = false;
+ value = single_fields.fld_subject->sbj_value;
+
+ isASCII = true;
+ for(char * p = value ; * p != 0 ; p ++) {
+ if ((unsigned char) * p >= 128) {
+ isASCII = false;
+ }
+ }
+ if (strstr(value, "windows-1251") == NULL) {
+ if (isASCII) {
+ broken = true;
+ }
+ }
+
+ //MCLog("charset: %s %s", value, MCUTF8(charset));
+
+ if (!broken) {
+ setSubject(String::stringByDecodingMIMEHeaderValue(single_fields.fld_subject->sbj_value));
+ }
+ }
+ }
+
+ mailimf_fields_free(fields);
+}
+
+void MessageHeader::importIMAPInternalDate(struct mailimap_date_time * date)
+{
+ setReceivedDate(timestamp_from_imap_date(date));
+}
+
diff --git a/src/core/abstract/MCMessageHeader.h b/src/core/abstract/MCMessageHeader.h
new file mode 100644
index 00000000..5a7483e2
--- /dev/null
+++ b/src/core/abstract/MCMessageHeader.h
@@ -0,0 +1,90 @@
+#ifndef __MAILCORE_MCMESSAGEHEADER_H_
+
+#define __MAILCORE_MCMESSAGEHEADER_H_
+
+#include <mailcore/MCBaseTypes.h>
+#include <time.h>
+
+namespace mailcore {
+
+ class Address;
+
+ class MessageHeader : public Object {
+ private:
+ String * mMessageID;
+ Array * /* String */ mReferences;
+ Array * /* String */ mInReplyTo;
+ Address * mSender;
+ Address * mFrom;
+ Array * /* Address */ mTo;
+ Array * /* Address */ mCc;
+ Array * /* Address */ mBcc;
+ Array * /* Address */ mReplyTo;
+ String * mSubject;
+ time_t mDate;
+ time_t mReceivedDate;
+ String * mUserAgent;
+ void init(bool generateDate, bool generateMessageID);
+
+ public:
+ MessageHeader();
+ MessageHeader(MessageHeader * other);
+ virtual ~MessageHeader();
+
+ virtual String * description();
+ //virtual String * className();
+ virtual Object * copy();
+
+ virtual void setMessageID(String * messageID);
+ virtual String * messageID();
+
+ virtual void setReferences(Array * references);
+ virtual Array * references();
+
+ virtual void setInReplyTo(Array * inReplyTo);
+ virtual Array * inReplyTo();
+
+ virtual void setDate(time_t date);
+ virtual time_t date();
+
+ virtual void setReceivedDate(time_t date);
+ virtual time_t receivedDate();
+
+ virtual void setSender(Address * sender);
+ virtual Address * sender();
+
+ virtual void setFrom(Address * from);
+ virtual Address * from();
+
+ virtual void setTo(Array * to);
+ virtual Array * to();
+
+ virtual void setCc(Array * cc);
+ virtual Array * cc();
+
+ virtual void setBcc(Array * bcc);
+ virtual Array * bcc();
+
+ virtual void setReplyTo(Array * replyTo);
+ virtual Array * replyTo();
+
+ virtual void setSubject(String * subject);
+ virtual String * subject();
+
+ virtual void setUserAgent(String * userAgent);
+ virtual String * userAgent();
+
+ virtual String * extractedSubject();
+ virtual String * partialExtractedSubject();
+ virtual void importHeadersData(Data * data);
+ virtual void importIMAPEnvelope(struct mailimap_envelope * env);
+ virtual void importIMAPReferences(Data * data);
+ virtual void importIMAPInternalDate(struct mailimap_date_time * date);
+
+ virtual struct mailimf_fields * createIMFFieldsAndFilterBcc(bool filterBcc);
+ virtual void importIMFFields(struct mailimf_fields * fields);
+ };
+
+}
+
+#endif