aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/imap/MCIMAPPart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/imap/MCIMAPPart.cpp')
-rw-r--r--src/core/imap/MCIMAPPart.cpp369
1 files changed, 369 insertions, 0 deletions
diff --git a/src/core/imap/MCIMAPPart.cpp b/src/core/imap/MCIMAPPart.cpp
new file mode 100644
index 00000000..21336aa3
--- /dev/null
+++ b/src/core/imap/MCIMAPPart.cpp
@@ -0,0 +1,369 @@
+#include "MCWin32.h" // Should be included first.
+
+#include "MCIMAPPart.h"
+
+#include <string.h>
+#include <libetpan/libetpan.h>
+
+#include "MCDefines.h"
+#include "MCIMAPMessagePart.h"
+#include "MCIMAPMultipart.h"
+#include "MCMessageHeader.h"
+
+using namespace mailcore;
+
+void IMAPPart::init()
+{
+ mPartID = NULL;
+ mEncoding = Encoding8Bit;
+ mSize = 0;
+}
+
+IMAPPart::IMAPPart()
+{
+ init();
+}
+
+IMAPPart::IMAPPart(IMAPPart * other) : AbstractPart(other)
+{
+ init();
+ MC_SAFE_REPLACE_COPY(String, mPartID, other->mPartID);
+ mEncoding = other->mEncoding;
+ mSize = other->mSize;
+}
+
+IMAPPart::~IMAPPart()
+{
+ MC_SAFE_RELEASE(mPartID);
+}
+
+Object * IMAPPart::copy()
+{
+ return new IMAPPart(this);
+}
+
+void IMAPPart::setPartID(String * partID)
+{
+ MC_SAFE_REPLACE_COPY(String, mPartID, partID);
+}
+
+String * IMAPPart::partID()
+{
+ return mPartID;
+}
+
+void IMAPPart::setSize(unsigned int size)
+{
+ mSize = size;
+}
+
+unsigned int IMAPPart::size()
+{
+ return mSize;
+}
+
+void IMAPPart::setEncoding(Encoding encoding)
+{
+ mEncoding = encoding;
+}
+
+Encoding IMAPPart::encoding()
+{
+ return mEncoding;
+}
+
+unsigned int IMAPPart::decodedSize()
+{
+ switch (mEncoding) {
+ case MAILIMAP_BODY_FLD_ENC_BASE64:
+ return mSize * 3 / 4;
+
+ default:
+ return mSize;
+ }
+}
+
+AbstractPart * IMAPPart::attachmentWithIMAPBody(struct mailimap_body * body)
+{
+ String * partID;
+ AbstractPart * result;
+
+ partID = NULL;
+ if (body->bd_type == MAILIMAP_BODY_1PART) {
+ partID = MCSTR("1");
+ }
+ result = attachmentWithIMAPBodyInternal(body, partID);
+ result->applyUniquePartID();
+
+ return result;
+}
+
+AbstractPart * IMAPPart::attachmentWithIMAPBodyInternal(struct mailimap_body * body, String * partID)
+{
+ switch (body->bd_type) {
+ case MAILIMAP_BODY_1PART:
+ return attachmentWithIMAPBody1Part(body->bd_data.bd_body_1part, partID);
+ case MAILIMAP_BODY_MPART:
+ return attachmentWithIMAPBodyMultipart(body->bd_data.bd_body_mpart, partID);
+ }
+
+ return NULL;
+}
+
+AbstractPart * IMAPPart::attachmentWithIMAPBody1Part(struct mailimap_body_type_1part * body_1part,
+ String * partID)
+{
+ switch (body_1part->bd_type) {
+ case MAILIMAP_BODY_TYPE_1PART_BASIC:
+ {
+ IMAPPart * attachment;
+
+ attachment = attachmentWithIMAPBody1PartBasic(body_1part->bd_data.bd_type_basic,
+ body_1part->bd_ext_1part);
+ attachment->setPartID(partID);
+ return attachment;
+ }
+ case MAILIMAP_BODY_TYPE_1PART_MSG:
+ {
+ return attachmentWithIMAPBody1PartMessage(body_1part->bd_data.bd_type_msg,
+ body_1part->bd_ext_1part, partID);
+ }
+ case MAILIMAP_BODY_TYPE_1PART_TEXT:
+ {
+ IMAPPart * attachment;
+
+ attachment = attachmentWithIMAPBody1PartText(body_1part->bd_data.bd_type_text,
+ body_1part->bd_ext_1part);
+ attachment->setPartID(partID);
+ MCLog("attachment %s", MCUTF8(partID));
+ return attachment;
+ }
+ }
+
+ return NULL;
+}
+
+IMAPMessagePart * IMAPPart::attachmentWithIMAPBody1PartMessage(struct mailimap_body_type_msg * message,
+ struct mailimap_body_ext_1part * extension,
+ String * partID)
+{
+ IMAPMessagePart * attachment;
+ AbstractPart * subAttachment;
+ String * nextPartID;
+
+ nextPartID = NULL;
+ if (message->bd_body->bd_type == MAILIMAP_BODY_1PART) {
+ // msg or 1part
+ nextPartID = partID->stringByAppendingUTF8Format(".1");
+ }
+ else if (message->bd_body->bd_type == MAILIMAP_BODY_MPART) {
+ // mpart
+ nextPartID = partID;
+ }
+
+ attachment = new IMAPMessagePart();
+ attachment->setPartID(partID);
+ attachment->header()->importIMAPEnvelope(message->bd_envelope);
+ attachment->importIMAPFields(message->bd_fields, extension);
+
+ subAttachment = attachmentWithIMAPBodyInternal(message->bd_body, nextPartID);
+ attachment->setMainPart(subAttachment);
+ attachment->setMimeType(MCSTR("message/rfc822"));
+
+ return (IMAPMessagePart *) attachment->autorelease();
+}
+
+void IMAPPart::importIMAPFields(struct mailimap_body_fields * fields,
+ struct mailimap_body_ext_1part * extension)
+{
+ AbstractPart::importIMAPFields(fields, extension);
+
+ setSize(fields->bd_size);
+ if (fields->bd_encoding != NULL) {
+ bool isUUEncode;
+
+ isUUEncode = false;
+ if (fields->bd_encoding->enc_type == MAILIMAP_BODY_FLD_ENC_OTHER) {
+ if (strcasecmp(fields->bd_encoding->enc_value, "x-uuencode") == 0) {
+ isUUEncode = true;
+ }
+ }
+ if (isUUEncode) {
+ setEncoding(EncodingUUEncode);
+ }
+ else {
+ setEncoding((Encoding) fields->bd_encoding->enc_type);
+ }
+ }
+}
+
+IMAPPart * IMAPPart::attachmentWithIMAPBody1PartBasic(struct mailimap_body_type_basic * basic,
+ struct mailimap_body_ext_1part * extension)
+{
+ IMAPPart * attachment;
+ String * mimeType;
+
+ attachment = new IMAPPart();
+ attachment->importIMAPFields(basic->bd_fields, extension);
+
+ mimeType = NULL;
+ switch (basic->bd_media_basic->med_type) {
+ case MAILIMAP_MEDIA_BASIC_APPLICATION:
+ mimeType = String::stringWithUTF8Format("application/%s", basic->bd_media_basic->med_subtype);
+ break;
+ case MAILIMAP_MEDIA_BASIC_AUDIO:
+ mimeType = String::stringWithUTF8Format("audio/%s", basic->bd_media_basic->med_subtype);
+ break;
+ case MAILIMAP_MEDIA_BASIC_IMAGE:
+ mimeType = String::stringWithUTF8Format("image/%s", basic->bd_media_basic->med_subtype);
+ break;
+ case MAILIMAP_MEDIA_BASIC_MESSAGE:
+ mimeType = String::stringWithUTF8Format("message/%s", basic->bd_media_basic->med_subtype);
+ break;
+ case MAILIMAP_MEDIA_BASIC_VIDEO:
+ mimeType = String::stringWithUTF8Format("video/%s", basic->bd_media_basic->med_subtype);
+ break;
+ case MAILIMAP_MEDIA_BASIC_OTHER:
+ mimeType = String::stringWithUTF8Format("%s/%s", basic->bd_media_basic->med_basic_type, basic->bd_media_basic->med_subtype);
+ break;
+ }
+ attachment->setMimeType(mimeType);
+
+ return (IMAPPart *) attachment->autorelease();
+}
+
+IMAPPart * IMAPPart::attachmentWithIMAPBody1PartText(struct mailimap_body_type_text * text,
+ struct mailimap_body_ext_1part * extension)
+{
+ IMAPPart * attachment;
+
+ attachment = new IMAPPart();
+ attachment->importIMAPFields(text->bd_fields, extension);
+ attachment->setMimeType(String::stringWithUTF8Format("text/%s", text->bd_media_text));
+
+ return (IMAPPart *) attachment->autorelease();
+}
+
+IMAPMultipart * IMAPPart::attachmentWithIMAPBodyMultipart(struct mailimap_body_type_mpart * body_mpart,
+ String * partID)
+{
+ clistiter * cur;
+ IMAPMultipart * attachment;
+ unsigned int count;
+ Array * attachments;
+
+ attachments = new Array();
+
+ count = 1;
+ for(cur = clist_begin(body_mpart->bd_list) ; cur != NULL ; cur = clist_next(cur)) {
+ struct mailimap_body * body;
+ AbstractPart * subResult;
+ String * nextPartID;
+
+ if (partID == NULL) {
+ nextPartID = String::stringWithUTF8Format("%u", count);
+ }
+ else {
+ nextPartID = partID->stringByAppendingUTF8Format(".%u", count);
+ }
+ body = (struct mailimap_body *) clist_content(cur);
+ subResult = attachmentWithIMAPBodyInternal(body, nextPartID);
+ attachments->addObject(subResult);
+
+ count ++;
+ }
+
+ attachment = new IMAPMultipart();
+ attachment->setPartID(partID);
+ if (strcasecmp(body_mpart->bd_media_subtype, "alternative") == 0) {
+ attachment->setPartType(PartTypeMultipartAlternative);
+ }
+ else if (strcasecmp(body_mpart->bd_media_subtype, "related") == 0) {
+ attachment->setPartType(PartTypeMultipartRelated);
+ }
+ attachment->setMimeType(String::stringWithUTF8Format("multipart/%s", body_mpart->bd_media_subtype));
+ attachment->setParts(attachments);
+
+ attachments->release();
+
+ return (IMAPMultipart *) attachment->autorelease();
+}
+
+HashMap * IMAPPart::serializable()
+{
+ HashMap * result = AbstractPart::serializable();
+ if (partID() != NULL) {
+ result->setObjectForKey(MCSTR("partID"), partID());
+ }
+ String * encodingString;
+ switch (encoding()) {
+ case Encoding7Bit:
+ encodingString = MCSTR("7bit");
+ break;
+ case Encoding8Bit:
+ default:
+ encodingString = MCSTR("8bit");
+ break;
+ case EncodingBinary:
+ encodingString = MCSTR("binary");
+ break;
+ case EncodingBase64:
+ encodingString = MCSTR("base64");
+ break;
+ case EncodingQuotedPrintable:
+ encodingString = MCSTR("quoted-printable");
+ break;
+ case EncodingUUEncode:
+ encodingString = MCSTR("uuencode");
+ break;
+ }
+ result->setObjectForKey(MCSTR("encoding"), encodingString);
+ String * sizeString = String::stringWithUTF8Format("%lu", size());
+ result->setObjectForKey(MCSTR("size"), sizeString);
+ return result;
+}
+
+void IMAPPart::importSerializable(HashMap * serializable)
+{
+ AbstractPart::importSerializable(serializable);
+ String * partID = (String *) serializable->objectForKey(MCSTR("partID"));
+ setPartID(partID);
+ String * encodingString = (String *) serializable->objectForKey(MCSTR("encoding"));
+ if (encodingString != NULL) {
+ Encoding encoding = Encoding8Bit;
+ if (encodingString->isEqual(MCSTR("7bit"))) {
+ encoding = Encoding7Bit;
+ }
+ else if (encodingString->isEqual(MCSTR("8bit"))) {
+ encoding = Encoding8Bit;
+ }
+ else if (encodingString->isEqual(MCSTR("binary"))) {
+ encoding = EncodingBinary;
+ }
+ else if (encodingString->isEqual(MCSTR("base64"))) {
+ encoding = EncodingBase64;
+ }
+ else if (encodingString->isEqual(MCSTR("quoted-printable"))) {
+ encoding = EncodingQuotedPrintable;
+ }
+ else if (encodingString->isEqual(MCSTR("uuencode"))) {
+ encoding = EncodingUUEncode;
+ }
+ setEncoding(encoding);
+ }
+ String * sizeString = (String *) serializable->objectForKey(MCSTR("size"));
+ if (sizeString != NULL) {
+ setSize(sizeString->unsignedIntValue());
+ }
+}
+
+static void * createObject()
+{
+ return new IMAPPart();
+}
+
+INITIALIZE(IMAPPart)
+{
+ Object::registerObjectConstructor("mailcore::IMAPPart", &createObject);
+}
+