aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--build-mac/mailcore2.xcodeproj/project.pbxproj60
-rw-r--r--src/core/abstract/MCAbstractMessage.cc13
-rw-r--r--src/core/abstract/MCAbstractMessage.h30
-rw-r--r--src/core/abstract/MCAbstractMessagePart.cc19
-rw-r--r--src/core/abstract/MCAbstractMessagePart.h46
-rw-r--r--src/core/abstract/MCAbstractMultipart.cc14
-rw-r--r--src/core/abstract/MCAbstractMultipart.h36
-rw-r--r--src/core/abstract/MCAbstractPart.cc84
-rw-r--r--src/core/abstract/MCAbstractPart.h96
-rw-r--r--src/core/abstract/MCAddress.cc29
-rw-r--r--src/core/abstract/MCAddress.h88
-rw-r--r--src/core/abstract/MCMessageHeader.cc105
-rw-r--r--src/core/abstract/MCMessageHeader.h11
-rw-r--r--src/core/basetypes/MCArray.cc31
-rw-r--r--src/core/basetypes/MCArray.h68
-rw-r--r--src/core/basetypes/MCBase64.c111
-rw-r--r--src/core/basetypes/MCBase64.h23
-rw-r--r--src/core/basetypes/MCData.cc33
-rw-r--r--src/core/basetypes/MCData.h88
-rw-r--r--src/core/basetypes/MCHashMap.cc41
-rw-r--r--src/core/basetypes/MCHashMap.h2
-rw-r--r--src/core/basetypes/MCIterator.h12
-rw-r--r--src/core/basetypes/MCLibetpan.cc3
-rw-r--r--src/core/basetypes/MCLog.c3
-rw-r--r--src/core/basetypes/MCObject.cc58
-rw-r--r--src/core/basetypes/MCObject.h68
-rw-r--r--src/core/basetypes/MCSet.cc13
-rw-r--r--src/core/basetypes/MCSet.h58
-rw-r--r--src/core/basetypes/MCString.cc10
-rw-r--r--src/core/basetypes/MCString.h2
-rw-r--r--src/core/basetypes/MCUtils.h2
-rw-r--r--src/core/imap/MCIMAPMessage.cc81
-rw-r--r--src/core/imap/MCIMAPMessage.h8
-rw-r--r--src/core/imap/MCIMAPMessagePart.cc27
-rw-r--r--src/core/imap/MCIMAPMessagePart.h26
-rw-r--r--src/core/imap/MCIMAPMultipart.cc28
-rw-r--r--src/core/imap/MCIMAPMultipart.h28
-rw-r--r--src/core/imap/MCIMAPPart.cc80
-rw-r--r--src/core/imap/MCIMAPPart.h2
-rw-r--r--src/core/imap/MCIMAPSession.cc3
-rw-r--r--src/core/provider/MCMailProvider.cc2
-rw-r--r--src/core/provider/MCMailProvidersManager.cc6
-rw-r--r--src/objc/abstract/MCOMessageHeader.mm16
-rw-r--r--src/objc/imap/MCOIMAPMessage.mm2
-rw-r--r--src/objc/imap/MCOIMAPMessagePart.mm2
-rw-r--r--src/objc/imap/MCOIMAPMultipart.mm2
-rw-r--r--src/objc/imap/MCOIMAPPart.mm2
-rw-r--r--src/objc/utils/NSObject+MCO.h14
-rw-r--r--tests/test-all.mm2
49 files changed, 1201 insertions, 387 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj
index e127f4f2..9a1c64c3 100644
--- a/build-mac/mailcore2.xcodeproj/project.pbxproj
+++ b/build-mac/mailcore2.xcodeproj/project.pbxproj
@@ -236,6 +236,8 @@
C668E2CC1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */; };
C668E2CD1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */; };
C668E2DD1736333900A2BB47 /* providers.json in Resources */ = {isa = PBXBuildFile; fileRef = 84AF9E7D172DBAF600E60AA3 /* providers.json */; };
+ C67597C217A8D65000DA69DF /* MCBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = C67597C117A8D65000DA69DF /* MCBase64.c */; };
+ C67597C317A8D65000DA69DF /* MCBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = C67597C117A8D65000DA69DF /* MCBase64.c */; };
C68B2AEE1778A865005E61EF /* MCConnectionLogger.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */; };
C68B2AEF1778A869005E61EF /* MCConnectionLogger.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */; };
C68B2AF717797389005E61EF /* MCConnectionLoggerUtils.cc in Sources */ = {isa = PBXBuildFile; fileRef = C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */; };
@@ -1348,6 +1350,8 @@
C64FF39016B3C13000F8C162 /* MCOObjectWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOObjectWrapper.mm; sourceTree = "<group>"; };
C668E2C51735C8D500A2BB47 /* MCObjectMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCObjectMac.mm; sourceTree = "<group>"; };
C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCAutoreleasePoolMac.mm; sourceTree = "<group>"; };
+ C67597C117A8D65000DA69DF /* MCBase64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MCBase64.c; sourceTree = "<group>"; };
+ C67597C417A8D66000DA69DF /* MCBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCBase64.h; sourceTree = "<group>"; };
C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCConnectionLogger.h; sourceTree = "<group>"; };
C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCConnectionLoggerUtils.cc; sourceTree = "<group>"; };
C68B2AF617797389005E61EF /* MCConnectionLoggerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCConnectionLoggerUtils.h; sourceTree = "<group>"; };
@@ -1840,33 +1844,55 @@
C64EA6A1169E847800778456 /* basetypes */ = {
isa = PBXGroup;
children = (
- C64EA6A2169E847800778456 /* MCAutoreleasePool.cc */,
- C64EA6A3169E847800778456 /* MCAutoreleasePool.h */,
- C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */,
- C64EA6A4169E847800778456 /* MCBaseTypes.h */,
C64EA6A5169E847800778456 /* MCArray.cc */,
C64EA6A6169E847800778456 /* MCArray.h */,
C64EA6A7169E847800778456 /* MCAssert.c */,
C64EA6A8169E847800778456 /* MCAssert.h */,
+ C64EA6A2169E847800778456 /* MCAutoreleasePool.cc */,
+ C64EA6A3169E847800778456 /* MCAutoreleasePool.h */,
+ C668E2CA1735CB8900A2BB47 /* MCAutoreleasePoolMac.mm */,
+ C67597C117A8D65000DA69DF /* MCBase64.c */,
+ C67597C417A8D66000DA69DF /* MCBase64.h */,
+ C64EA6A4169E847800778456 /* MCBaseTypes.h */,
+ C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */,
+ C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */,
+ C68B2AF617797389005E61EF /* MCConnectionLoggerUtils.h */,
C64EA6A9169E847800778456 /* MCData.cc */,
C64EA6AA169E847800778456 /* MCData.h */,
C64EA6AB169E847800778456 /* MCHash.cc */,
C64EA6AC169E847800778456 /* MCHash.h */,
C64EA6AD169E847800778456 /* MCHashMap.cc */,
C64EA6AE169E847800778456 /* MCHashMap.h */,
+ C63CD68F16BE566D00DB18F1 /* MCHTMLCleaner.cc */,
+ C63CD69016BE566E00DB18F1 /* MCHTMLCleaner.h */,
+ C6D6F9691720F8F4006F5B28 /* MCICUTypes.h */,
+ C64BB22C16E5C1EE000DB34C /* MCIndexSet.cc */,
+ C64BB22D16E5C1EE000DB34C /* MCIndexSet.h */,
+ C6D6F96D1721028D006F5B28 /* MCIterator.h */,
C6D6F7F7171E595D006F5B28 /* MCJSON.cc */,
C6D6F7F8171E595D006F5B28 /* MCJSON.h */,
C6D6F965171FCF9F006F5B28 /* MCJSONParser.cc */,
C6D6F966171FCF9F006F5B28 /* MCJSONParser.h */,
- C6D6F950171E5CB8006F5B28 /* MCMD5.cc */,
- C6D6F951171E5CB8006F5B28 /* MCMD5.h */,
+ BD637139177DFF080094121B /* MCLibetpan.cc */,
+ BD63713A177DFF080094121B /* MCLibetpan.h */,
+ C6AC1131171249DF00B715B7 /* MCLibetpanTypes.h */,
C64EA6AF169E847800778456 /* MCLog.c */,
C64EA6B0169E847800778456 /* MCLog.h */,
+ C64EA6BC169E847800778456 /* MCMainThread.h */,
+ C64EA6BD169E847800778456 /* MCMainThread.mm */,
+ C6D6F950171E5CB8006F5B28 /* MCMD5.cc */,
+ C6D6F951171E5CB8006F5B28 /* MCMD5.h */,
C6D6F952171E5CB8006F5B28 /* MCNull.cc */,
C6D6F953171E5CB8006F5B28 /* MCNull.h */,
C64EA6B1169E847800778456 /* MCObject.cc */,
C64EA6B2169E847800778456 /* MCObject.h */,
C668E2C51735C8D500A2BB47 /* MCObjectMac.mm */,
+ C64EA6BE169E847800778456 /* MCOperation.cc */,
+ C64EA6BF169E847800778456 /* MCOperation.h */,
+ C64EA6C0169E847800778456 /* MCOperationCallback.h */,
+ C64EA6C1169E847800778456 /* MCOperationQueue.cc */,
+ C64EA6C2169E847800778456 /* MCOperationQueue.h */,
+ C6081678177625AD001F1018 /* MCOperationQueueCallback.h */,
C64EA6B3169E847800778456 /* MCRange.cc */,
C64EA6B4169E847800778456 /* MCRange.h */,
C64EA6B5169E847800778456 /* MCSet.cc */,
@@ -1877,26 +1903,6 @@
C64EA6BA169E847800778456 /* MCValue.cc */,
C64EA6BB169E847800778456 /* MCValue.h */,
C64BB25316FC2AA0000DB34C /* MCValuePrivate.h */,
- C64EA6BC169E847800778456 /* MCMainThread.h */,
- C64EA6BD169E847800778456 /* MCMainThread.mm */,
- C64EA6BE169E847800778456 /* MCOperation.cc */,
- C64EA6BF169E847800778456 /* MCOperation.h */,
- C64EA6C0169E847800778456 /* MCOperationCallback.h */,
- C64EA6C1169E847800778456 /* MCOperationQueue.cc */,
- C64EA6C2169E847800778456 /* MCOperationQueue.h */,
- C6081678177625AD001F1018 /* MCOperationQueueCallback.h */,
- C63CD68F16BE566D00DB18F1 /* MCHTMLCleaner.cc */,
- C63CD69016BE566E00DB18F1 /* MCHTMLCleaner.h */,
- C64BB22C16E5C1EE000DB34C /* MCIndexSet.cc */,
- C64BB22D16E5C1EE000DB34C /* MCIndexSet.h */,
- C6AC1131171249DF00B715B7 /* MCLibetpanTypes.h */,
- C6D6F9691720F8F4006F5B28 /* MCICUTypes.h */,
- C6D6F96D1721028D006F5B28 /* MCIterator.h */,
- C68B2AEB1778A589005E61EF /* MCConnectionLogger.h */,
- C68B2AF517797389005E61EF /* MCConnectionLoggerUtils.cc */,
- C68B2AF617797389005E61EF /* MCConnectionLoggerUtils.h */,
- BD637139177DFF080094121B /* MCLibetpan.cc */,
- BD63713A177DFF080094121B /* MCLibetpan.h */,
);
path = basetypes;
sourceTree = "<group>";
@@ -2526,6 +2532,7 @@
C64BB26A16FD44C2000DB34C /* MCOMultipart.mm in Sources */,
C623C58F16FE6B45001BBEFC /* MCOIMAPOperation.mm in Sources */,
C623C59316FE750E001BBEFC /* MCOIMAPFolder.mm in Sources */,
+ C67597C217A8D65000DA69DF /* MCBase64.c in Sources */,
C6F5B9E216FEA1E800D9DABD /* MCOIMAPMessage.mm in Sources */,
C6F5B9E516FEA27500D9DABD /* MCOIMAPMessagePart.mm in Sources */,
C6F5B9E816FEA28600D9DABD /* MCOIMAPMultipart.mm in Sources */,
@@ -2716,6 +2723,7 @@
C6BA2BFC1705F4E6003F0E9E /* MCOMultipart.mm in Sources */,
C6BA2BFD1705F4E6003F0E9E /* MCOIMAPOperation.mm in Sources */,
C6BA2BFE1705F4E6003F0E9E /* MCOIMAPFolder.mm in Sources */,
+ C67597C317A8D65000DA69DF /* MCBase64.c in Sources */,
C6BA2BFF1705F4E6003F0E9E /* MCOIMAPMessage.mm in Sources */,
C6BA2C001705F4E6003F0E9E /* MCOIMAPMessagePart.mm in Sources */,
C6BA2C011705F4E6003F0E9E /* MCOIMAPMultipart.mm in Sources */,
diff --git a/src/core/abstract/MCAbstractMessage.cc b/src/core/abstract/MCAbstractMessage.cc
index a7e73992..cf3fd6c4 100644
--- a/src/core/abstract/MCAbstractMessage.cc
+++ b/src/core/abstract/MCAbstractMessage.cc
@@ -80,3 +80,16 @@ Array * AbstractMessage::htmlInlineAttachments()
return HTMLRenderer::htmlInlineAttachmentsForMessage(this);
}
+HashMap * AbstractMessage::serializable()
+{
+ HashMap * result = Object::serializable();
+ if (header() != NULL) {
+ result->setObjectForKey(MCSTR("header"), mHeader->serializable());
+ }
+ return result;
+}
+
+void AbstractMessage::importSerializable(HashMap * hashmap)
+{
+ setHeader((MessageHeader *) Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("header"))));
+}
diff --git a/src/core/abstract/MCAbstractMessage.h b/src/core/abstract/MCAbstractMessage.h
index d7384b36..2c7766f8 100644
--- a/src/core/abstract/MCAbstractMessage.h
+++ b/src/core/abstract/MCAbstractMessage.h
@@ -8,15 +8,15 @@
namespace mailcore {
class AbstractPart;
- class MessageHeader;
+ class MessageHeader;
- class AbstractMessage : public Object {
- public:
- AbstractMessage();
- virtual ~AbstractMessage();
+ class AbstractMessage : public Object {
+ public:
+ AbstractMessage();
+ virtual ~AbstractMessage();
- virtual MessageHeader * header();
- virtual void setHeader(MessageHeader * header);
+ virtual MessageHeader * header();
+ virtual void setHeader(MessageHeader * header);
virtual AbstractPart * partForContentID(String * contentID);
virtual AbstractPart * partForUniqueID(String * uniqueID);
@@ -25,15 +25,17 @@ namespace mailcore {
virtual Array * /* AbstractPart */ htmlInlineAttachments();
public: //subclass behavior
- AbstractMessage(AbstractMessage * other);
- virtual String * description();
- virtual Object * copy();
+ AbstractMessage(AbstractMessage * other);
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * hashmap);
- private:
- MessageHeader * mHeader;
- void init();
+ private:
+ MessageHeader * mHeader;
+ void init();
- };
+ };
}
#endif
diff --git a/src/core/abstract/MCAbstractMessagePart.cc b/src/core/abstract/MCAbstractMessagePart.cc
index be6e8e9b..65d7b8cc 100644
--- a/src/core/abstract/MCAbstractMessagePart.cc
+++ b/src/core/abstract/MCAbstractMessagePart.cc
@@ -77,3 +77,22 @@ AbstractPart * AbstractMessagePart::partForUniqueID(String * contentID)
{
return mainPart()->partForUniqueID(contentID);
}
+
+HashMap * AbstractMessagePart::serializable()
+{
+ HashMap * result = (HashMap *) AbstractPart::serializable();
+ if (mainPart() != NULL) {
+ result->setObjectForKey(MCSTR("mainPart"), mainPart()->serializable());
+ }
+ if (header() != NULL) {
+ result->setObjectForKey(MCSTR("header"), header()->serializable());
+ }
+ return result;
+}
+
+void AbstractMessagePart::importSerializable(HashMap * serializable)
+{
+ AbstractPart::importSerializable(serializable);
+ setMainPart((AbstractPart *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("mainPart"))));
+ setHeader((MessageHeader *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("header"))));
+}
diff --git a/src/core/abstract/MCAbstractMessagePart.h b/src/core/abstract/MCAbstractMessagePart.h
index bd2ac4e0..1d975d62 100644
--- a/src/core/abstract/MCAbstractMessagePart.h
+++ b/src/core/abstract/MCAbstractMessagePart.h
@@ -8,33 +8,35 @@
#ifdef __cplusplus
namespace mailcore {
-
- class MessageHeader;
-
- class AbstractMessagePart : public AbstractPart {
- public:
- AbstractMessagePart();
- virtual ~AbstractMessagePart();
-
- virtual MessageHeader * header();
- virtual void setHeader(MessageHeader * header);
-
- virtual AbstractPart * mainPart();
- virtual void setMainPart(AbstractPart * mainPart);
-
+
+ class MessageHeader;
+
+ class AbstractMessagePart : public AbstractPart {
+ public:
+ AbstractMessagePart();
+ virtual ~AbstractMessagePart();
+
+ virtual MessageHeader * header();
+ virtual void setHeader(MessageHeader * header);
+
+ virtual AbstractPart * mainPart();
+ virtual void setMainPart(AbstractPart * mainPart);
+
public: //subclass behavior
- AbstractMessagePart(AbstractMessagePart * other);
- virtual String * description();
- virtual Object * copy();
+ AbstractMessagePart(AbstractMessagePart * other);
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
virtual AbstractPart * partForContentID(String * contentID);
virtual AbstractPart * partForUniqueID(String * uniqueID);
- private:
- AbstractPart * mMainPart;
- MessageHeader * mHeader;
- void init();
- };
+ private:
+ AbstractPart * mMainPart;
+ MessageHeader * mHeader;
+ void init();
+ };
}
#endif
diff --git a/src/core/abstract/MCAbstractMultipart.cc b/src/core/abstract/MCAbstractMultipart.cc
index d70b2974..e3a2f9f7 100644
--- a/src/core/abstract/MCAbstractMultipart.cc
+++ b/src/core/abstract/MCAbstractMultipart.cc
@@ -92,3 +92,17 @@ AbstractPart * AbstractMultipart::partForUniqueID(String * uniqueID)
return NULL;
}
+HashMap * AbstractMultipart::serializable()
+{
+ HashMap * result = (HashMap *) AbstractPart::serializable();
+ if (mParts != NULL) {
+ result->setObjectForKey(MCSTR("parts"), mParts->serializable());
+ }
+ return result;
+}
+
+void AbstractMultipart::importSerializable(HashMap * serializable)
+{
+ AbstractPart::importSerializable(serializable);
+ setParts((Array *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("parts"))));
+}
diff --git a/src/core/abstract/MCAbstractMultipart.h b/src/core/abstract/MCAbstractMultipart.h
index 11d33666..b499f848 100644
--- a/src/core/abstract/MCAbstractMultipart.h
+++ b/src/core/abstract/MCAbstractMultipart.h
@@ -8,27 +8,29 @@
#ifdef __cplusplus
namespace mailcore {
-
- class AbstractMultipart : public AbstractPart {
- public:
- AbstractMultipart();
- virtual ~AbstractMultipart();
-
- virtual Array * parts();
- virtual void setParts(Array * parts);
-
+
+ class AbstractMultipart : public AbstractPart {
+ public:
+ AbstractMultipart();
+ virtual ~AbstractMultipart();
+
+ virtual Array * parts();
+ virtual void setParts(Array * parts);
+
public: //subclass behavior
- AbstractMultipart(AbstractMultipart * other);
- virtual String * description();
- virtual Object * copy();
+ AbstractMultipart(AbstractMultipart * other);
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
virtual AbstractPart * partForContentID(String * contentID);
virtual AbstractPart * partForUniqueID(String * uniqueID);
-
- private:
- Array * mParts;
- void init();
- };
+
+ private:
+ Array * mParts;
+ void init();
+ };
}
#endif
diff --git a/src/core/abstract/MCAbstractPart.cc b/src/core/abstract/MCAbstractPart.cc
index 6991e5fc..d7b57544 100644
--- a/src/core/abstract/MCAbstractPart.cc
+++ b/src/core/abstract/MCAbstractPart.cc
@@ -282,3 +282,87 @@ void AbstractPart::applyUniquePartID()
}
queue->release();
}
+
+HashMap * AbstractPart::serializable()
+{
+ HashMap * result = Object::serializable();
+
+ if (uniqueID() != NULL) {
+ result->setObjectForKey(MCSTR("uniqueID"), uniqueID());
+ }
+ if (filename() != NULL) {
+ result->setObjectForKey(MCSTR("filename"), filename());
+ }
+ if (mimeType() != NULL) {
+ result->setObjectForKey(MCSTR("mimeType"), mimeType());
+ }
+ if (charset() != NULL) {
+ result->setObjectForKey(MCSTR("charset"), charset());
+ }
+ if (contentID() != NULL) {
+ result->setObjectForKey(MCSTR("contentID"), contentID());
+ }
+ if (contentLocation() != NULL) {
+ result->setObjectForKey(MCSTR("contentLocation"), contentLocation());
+ }
+ if (mInlineAttachment) {
+ result->setObjectForKey(MCSTR("inlineAttachment"), MCSTR("1"));
+ }
+ String * partTypeStr;
+ switch (mPartType) {
+ default:
+ case PartTypeSingle:
+ partTypeStr = MCSTR("single");
+ break;
+ case PartTypeMessage:
+ partTypeStr = MCSTR("message");
+ break;
+ case PartTypeMultipartMixed:
+ partTypeStr = MCSTR("multipart/mixed");
+ break;
+ case PartTypeMultipartRelated:
+ partTypeStr = MCSTR("multipart/related");
+ break;
+ case PartTypeMultipartAlternative:
+ partTypeStr = MCSTR("multipart/alternative");
+ break;
+ }
+ result->setObjectForKey(MCSTR("partType"), partTypeStr);
+
+ return result;
+}
+
+void AbstractPart::importSerializable(HashMap * serializable)
+{
+ setUniqueID((String *) serializable->objectForKey(MCSTR("uniqueID")));
+ setFilename((String *) serializable->objectForKey(MCSTR("filename")));
+ setMimeType((String *) serializable->objectForKey(MCSTR("mimeType")));
+ setCharset((String *) serializable->objectForKey(MCSTR("charset")));
+ setContentID((String *) serializable->objectForKey(MCSTR("contentID")));
+ setContentLocation((String *) serializable->objectForKey(MCSTR("contentLocation")));
+ String * value = (String *) serializable->objectForKey(MCSTR("inlineAttachment"));
+ if (value != NULL) {
+ if (value->intValue()) {
+ setInlineAttachment(true);
+ }
+ }
+ value = (String *) serializable->objectForKey(MCSTR("partType"));
+ if (value != NULL) {
+ if (value->isEqual(MCSTR("single"))) {
+ setPartType(PartTypeSingle);
+ }
+ else if (value->isEqual(MCSTR("message"))) {
+ setPartType(PartTypeMessage);
+ }
+ else if (value->isEqual(MCSTR("multipart/mixed"))) {
+ setPartType(PartTypeMultipartMixed);
+ }
+ else if (value->isEqual(MCSTR("multipart/related"))) {
+ setPartType(PartTypeMultipartRelated);
+ }
+ else if (value->isEqual(MCSTR("multipart/alternative"))) {
+ setPartType(PartTypeMultipartAlternative);
+ }
+ }
+ PartType mPartType;
+}
diff --git a/src/core/abstract/MCAbstractPart.h b/src/core/abstract/MCAbstractPart.h
index b38c1b38..e4f68666 100644
--- a/src/core/abstract/MCAbstractPart.h
+++ b/src/core/abstract/MCAbstractPart.h
@@ -9,64 +9,66 @@
namespace mailcore {
- class AbstractMessage;
+ class AbstractMessage;
- class AbstractPart : public Object {
- public:
- AbstractPart();
- virtual ~AbstractPart();
-
- 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 * uniqueID();
- virtual void setUniqueID(String * uniqueID);
+ class AbstractPart : public Object {
+ public:
+ AbstractPart();
+ virtual ~AbstractPart();
+
+ 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 * uniqueID();
+ virtual void setUniqueID(String * uniqueID);
+
+ 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 String * contentID();
- virtual void setContentID(String * contentID);
-
- virtual String * contentLocation();
- virtual void setContentLocation(String * contentLocation);
-
- virtual bool isInlineAttachment();
- virtual void setInlineAttachment(bool inlineAttachment);
-
virtual AbstractPart * partForContentID(String * contentID);
virtual AbstractPart * partForUniqueID(String * uniqueID);
- virtual String * decodedStringForData(Data * data);
-
+ virtual String * decodedStringForData(Data * data);
+
public: // subclass behavior
- AbstractPart(AbstractPart * other);
- virtual String * description();
- virtual Object * copy();
+ AbstractPart(AbstractPart * other);
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
public: // private
- virtual void importIMAPFields(struct mailimap_body_fields * fields,
+ virtual void importIMAPFields(struct mailimap_body_fields * fields,
struct mailimap_body_ext_1part * extension);
virtual void applyUniquePartID();
- private:
- String * mUniqueID;
- String * mFilename;
- String * mMimeType;
- String * mCharset;
- String * mContentID;
- String * mContentLocation;
- bool mInlineAttachment;
- PartType mPartType;
- void init();
- };
-
+ private:
+ String * mUniqueID;
+ String * mFilename;
+ String * mMimeType;
+ String * mCharset;
+ String * mContentID;
+ String * mContentLocation;
+ bool mInlineAttachment;
+ PartType mPartType;
+ void init();
+ };
+
}
#endif
diff --git a/src/core/abstract/MCAddress.cc b/src/core/abstract/MCAddress.cc
index ebfc8f0d..213f6e65 100644
--- a/src/core/abstract/MCAddress.cc
+++ b/src/core/abstract/MCAddress.cc
@@ -494,3 +494,32 @@ static Array * lep_address_list_from_lep_addr(struct mailimf_address_list * addr
return result;
}
+static void * createObject()
+{
+ return new Address();
+}
+
+HashMap * Address::serializable()
+{
+ HashMap * result = Object::serializable();
+ if (mailbox() != NULL) {
+ result->setObjectForKey(MCSTR("mailbox"), mailbox());
+ }
+ if (displayName() != NULL) {
+ result->setObjectForKey(MCSTR("displayName"), displayName());
+ }
+ return result;
+}
+
+void Address::importSerializable(HashMap * serializable)
+{
+ setMailbox((String *) serializable->objectForKey(MCSTR("mailbox")));
+ setDisplayName((String *) serializable->objectForKey(MCSTR("mailbox")));
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::Address", &createObject);
+}
+
diff --git a/src/core/abstract/MCAddress.h b/src/core/abstract/MCAddress.h
index ad8a36f6..867ee02d 100644
--- a/src/core/abstract/MCAddress.h
+++ b/src/core/abstract/MCAddress.h
@@ -8,53 +8,55 @@
namespace mailcore {
- class Address : public Object {
- public:
- Address();
- virtual ~Address();
-
- static Address * addressWithDisplayName(String * displayName, String * mailbox);
- static Address * addressWithMailbox(String * mailbox);
- static Address * addressWithRFC822String(String * RFC822String);
- static Address * addressWithNonEncodedRFC822String(String * nonEncodedRFC822String);
-
- static Array * addressesWithRFC822String(String * string);
- static Array * addressesWithNonEncodedRFC822String(String * string);
-
- static String * RFC822StringForAddresses(Array * addresses);
- static String * nonEncodedRFC822StringForAddresses(Array * addresses);
-
- virtual void setDisplayName(String * displayName);
- virtual String * displayName();
-
- virtual void setMailbox(String * address);
- virtual String * mailbox();
-
- virtual String * RFC822String();
- virtual String * nonEncodedRFC822String();
-
+ class Address : public Object {
+ public:
+ Address();
+ virtual ~Address();
+
+ static Address * addressWithDisplayName(String * displayName, String * mailbox);
+ static Address * addressWithMailbox(String * mailbox);
+ static Address * addressWithRFC822String(String * RFC822String);
+ static Address * addressWithNonEncodedRFC822String(String * nonEncodedRFC822String);
+
+ static Array * addressesWithRFC822String(String * string);
+ static Array * addressesWithNonEncodedRFC822String(String * string);
+
+ static String * RFC822StringForAddresses(Array * addresses);
+ static String * nonEncodedRFC822StringForAddresses(Array * addresses);
+
+ virtual void setDisplayName(String * displayName);
+ virtual String * displayName();
+
+ virtual void setMailbox(String * address);
+ virtual String * mailbox();
+
+ virtual String * RFC822String();
+ virtual String * nonEncodedRFC822String();
+
public: // subclass behavior.
- Address(Address * other);
- virtual String * description();
- virtual bool isEqual(Object * otherObject);
- virtual unsigned int hash();
- virtual Object * copy();
+ Address(Address * other);
+ virtual String * description();
+ virtual bool isEqual(Object * otherObject);
+ virtual unsigned int hash();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
public: // private
- // Must be released
- virtual struct mailimf_address * createIMFAddress();
- virtual struct mailimf_mailbox * createIMFMailbox();
+ // Must be released
+ virtual struct mailimf_address * createIMFAddress();
+ virtual struct mailimf_mailbox * createIMFMailbox();
+
+ // Additions
+ static Address * addressWithIMFMailbox(struct mailimf_mailbox * mb);
+ static Address * addressWithNonEncodedIMFMailbox(struct mailimf_mailbox * mb);
+ static Address * addressWithIMAPAddress(struct mailimap_address * imap_addr);
- // Additions
- static Address * addressWithIMFMailbox(struct mailimf_mailbox * mb);
- static Address * addressWithNonEncodedIMFMailbox(struct mailimf_mailbox * mb);
- static Address * addressWithIMAPAddress(struct mailimap_address * imap_addr);
-
- private:
- String * mDisplayName;
- String * mMailbox;
- void init();
- };
+ private:
+ String * mDisplayName;
+ String * mMailbox;
+ void init();
+ };
}
diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc
index abb20fc4..6808899d 100644
--- a/src/core/abstract/MCMessageHeader.cc
+++ b/src/core/abstract/MCMessageHeader.cc
@@ -44,7 +44,6 @@ MessageHeader::MessageHeader(MessageHeader * other)
setSubject(other->mSubject);
setDate(other->date());
setReceivedDate(other->receivedDate());
- setUserAgent(other->mUserAgent);
setExtraHeaders(other->mExtraHeaders);
}
@@ -62,7 +61,6 @@ void MessageHeader::init(bool generateDate, bool generateMessageID)
mSubject = NULL;
mDate = (time_t) -1;
mReceivedDate = (time_t) -1;
- mUserAgent = NULL;
mExtraHeaders = NULL;
if (generateDate) {
@@ -114,7 +112,6 @@ MessageHeader::~MessageHeader()
MC_SAFE_RELEASE(mBcc);
MC_SAFE_RELEASE(mReplyTo);
MC_SAFE_RELEASE(mSubject);
- MC_SAFE_RELEASE(mUserAgent);
MC_SAFE_RELEASE(mExtraHeaders);
}
@@ -152,11 +149,8 @@ String * MessageHeader::description()
if (mSubject != NULL) {
result->appendUTF8Format("Subject: %s\n", mSubject->UTF8Characters());
}
- if (mUserAgent != NULL) {
- result->appendUTF8Format("X-Mailer: %s\n", mUserAgent->UTF8Characters());
- }
if (mExtraHeaders != NULL) {
- mc_foreachdictionaryKeyAndValue(String, header, String, value, mExtraHeaders) {
+ mc_foreachhashmapKeyAndValue(String, header, String, value, mExtraHeaders) {
result->appendUTF8Format("%s: %s\n", header->UTF8Characters(), value->UTF8Characters());
}
}
@@ -292,12 +286,12 @@ String * MessageHeader::subject()
void MessageHeader::setUserAgent(String * userAgent)
{
- MC_SAFE_REPLACE_COPY(String, mUserAgent, userAgent);
+ setExtraHeader(MCSTR("X-Mailer"), userAgent);
}
String * MessageHeader::userAgent()
{
- return mUserAgent;
+ return extraHeaderValueForName(MCSTR("X-Mailer"));
}
void MessageHeader::setExtraHeaders(HashMap * headers)
@@ -312,21 +306,25 @@ Array * MessageHeader::allExtraHeadersNames()
return mExtraHeaders->allKeys();
}
-void MessageHeader::addHeader(String * name, String * object)
+void MessageHeader::setExtraHeader(String * name, String * object)
{
if (mExtraHeaders == NULL)
mExtraHeaders = new HashMap();
+ if (object == NULL) {
+ removeExtraHeader(name);
+ return;
+ }
mExtraHeaders->setObjectForKey(name, object);
}
-void MessageHeader::removeHeader(String * name)
+void MessageHeader::removeExtraHeader(String * name)
{
if (mExtraHeaders == NULL)
return;
mExtraHeaders->removeObjectForKey(name);
}
-String * MessageHeader::headerValueForName(String * name)
+String * MessageHeader::extraHeaderValueForName(String * name)
{
if (mExtraHeaders == NULL)
return NULL;
@@ -498,13 +496,13 @@ void MessageHeader::importIMFFields(struct mailimf_fields * fields)
fieldName = field->fld_data.fld_optional_field->fld_name;
fieldNameStr = String::stringWithUTF8Characters(fieldName);
// Set only if this optional-field is not set
- if (headerValueForName(fieldNameStr) == NULL) {
+ if (extraHeaderValueForName(fieldNameStr) == NULL) {
char * fieldValue;
String * fieldValueStr;
fieldValue = field->fld_data.fld_optional_field->fld_value;
fieldValueStr = String::stringWithUTF8Characters(fieldValue);
- addHeader(fieldNameStr, fieldValueStr);
+ setExtraHeader(fieldNameStr, fieldValueStr);
}
}
}
@@ -883,15 +881,8 @@ struct mailimf_fields * MessageHeader::createIMFFieldsAndFilterBcc(bool filterBc
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);
- }
-
if (mExtraHeaders != NULL) {
- mc_foreachdictionaryKeyAndValue(String, header, String, value, mExtraHeaders) {
+ mc_foreachhashmapKeyAndValue(String, header, String, value, mExtraHeaders) {
struct mailimf_field * field;
field = mailimf_field_new_custom(strdup(header->UTF8Characters()), strdup(value->UTF8Characters()));
@@ -1347,3 +1338,73 @@ MessageHeader * MessageHeader::forwardHeader()
return result;
}
+HashMap * MessageHeader::serializable()
+{
+ HashMap * result = Object::serializable();
+
+ if (messageID() != NULL) {
+ result->setObjectForKey(MCSTR("messageID"), messageID());
+ }
+ if (references() != NULL) {
+ result->setObjectForKey(MCSTR("references"), references());
+ }
+ if (inReplyTo() != NULL) {
+ result->setObjectForKey(MCSTR("inReplyTo"), inReplyTo());
+ }
+ if (sender() != NULL) {
+ result->setObjectForKey(MCSTR("sender"), sender()->serializable());
+ }
+ if (from() != NULL) {
+ result->setObjectForKey(MCSTR("from"), from()->serializable());
+ }
+ if (to() != NULL) {
+ result->setObjectForKey(MCSTR("to"), to()->serializable());
+ }
+ if (cc() != NULL) {
+ result->setObjectForKey(MCSTR("cc"), cc()->serializable());
+ }
+ if (bcc() != NULL) {
+ result->setObjectForKey(MCSTR("bcc"), bcc()->serializable());
+ }
+ if (replyTo() != NULL) {
+ result->setObjectForKey(MCSTR("replyTo"), replyTo()->serializable());
+ }
+ if (subject() != NULL) {
+ result->setObjectForKey(MCSTR("subject"), subject());
+ }
+ result->setObjectForKey(MCSTR("date"), String::stringWithUTF8Format("%lld", (unsigned long long) date()));
+ result->setObjectForKey(MCSTR("receivedDate"), String::stringWithUTF8Format("%lld", (unsigned long long) receivedDate()));
+ if (mExtraHeaders != NULL) {
+ result->setObjectForKey(MCSTR("extraHeaders"), mExtraHeaders);
+ }
+
+ return result;
+}
+
+void MessageHeader::importSerializable(HashMap * hashmap)
+{
+ setMessageID((String *) hashmap->objectForKey(MCSTR("messageID")));
+ setReferences((Array *) hashmap->objectForKey(MCSTR("references")));
+ setInReplyTo((Array *) hashmap->objectForKey(MCSTR("inReplyTo")));
+ setSender((Address *) Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("sender"))));
+ setFrom((Address *) Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("from"))));
+ setTo((Array *) Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("to"))));
+ setCc((Array *)Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("cc"))));
+ setBcc((Array *)Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("bcc"))));
+ setReplyTo((Array *)Object::objectWithSerializable((HashMap *) hashmap->objectForKey(MCSTR("replyTo"))));
+ setSubject((String *) hashmap->objectForKey(MCSTR("subject")));
+ setDate((time_t) ((String *) hashmap->objectForKey(MCSTR("date")))->unsignedLongLongValue());
+ setReceivedDate((time_t) ((String *) hashmap->objectForKey(MCSTR("receivedDate")))->unsignedLongLongValue());
+ setExtraHeaders((HashMap *) hashmap->objectForKey(MCSTR("extraHeaders")));
+}
+
+static void * createObject()
+{
+ return new MessageHeader();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::MessageHeader", &createObject);
+}
diff --git a/src/core/abstract/MCMessageHeader.h b/src/core/abstract/MCMessageHeader.h
index 8da5f980..828d3a47 100644
--- a/src/core/abstract/MCMessageHeader.h
+++ b/src/core/abstract/MCMessageHeader.h
@@ -15,7 +15,7 @@ namespace mailcore {
public:
MessageHeader();
virtual ~MessageHeader();
-
+
virtual void setMessageID(String * messageID);
virtual String * messageID();
@@ -55,9 +55,9 @@ namespace mailcore {
virtual void setUserAgent(String * userAgent);
virtual String * userAgent();
- virtual void addHeader(String *name, String * value);
- virtual void removeHeader(String *name);
- virtual String * headerValueForName(String *name);
+ virtual void setExtraHeader(String *name, String * value);
+ virtual void removeExtraHeader(String *name);
+ virtual String * extraHeaderValueForName(String *name);
virtual Array * allExtraHeadersNames();
String * extractedSubject();
@@ -71,6 +71,8 @@ namespace mailcore {
MessageHeader(MessageHeader * other);
virtual String * description();
virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
public: // private
virtual void importIMAPEnvelope(struct mailimap_envelope * env);
@@ -93,7 +95,6 @@ namespace mailcore {
String * mSubject;
time_t mDate;
time_t mReceivedDate;
- String * mUserAgent;
HashMap * mExtraHeaders;
void init(bool generateDate, bool generateMessageID);
void setExtraHeaders(HashMap *headers);
diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc
index c77d29ad..a59e3648 100644
--- a/src/core/basetypes/MCArray.cc
+++ b/src/core/basetypes/MCArray.cc
@@ -8,6 +8,7 @@
#include "MCString.h"
#include "MCLog.h"
#include "MCUtils.h"
+#include "MCIterator.h"
using namespace mailcore;
@@ -235,3 +236,33 @@ String * Array::componentsJoinedByString(String * delimiter)
}
return result;
}
+
+HashMap * Array::serializable()
+{
+ HashMap * result = Object::serializable();
+ Array * array = Array::array();
+ mc_foreacharray(Object, item, this) {
+ array->addObject(item->serializable());
+ }
+ result->setObjectForKey(MCSTR("items"), array);
+ return result;
+}
+
+void Array::importSerializable(HashMap * serializable)
+{
+ Array * array = (Array *) serializable->objectForKey(MCSTR("items"));
+ mc_foreacharray(HashMap, item, array) {
+ addObject(Object::objectWithSerializable(item));
+ }
+}
+
+static void * createObject()
+{
+ return new Array();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::Array", &createObject);
+}
diff --git a/src/core/basetypes/MCArray.h b/src/core/basetypes/MCArray.h
index 564924f8..392c4aff 100644
--- a/src/core/basetypes/MCArray.h
+++ b/src/core/basetypes/MCArray.h
@@ -10,42 +10,44 @@ typedef struct carray_s carray;
namespace mailcore {
- class String;
-
- class Array : public Object {
- public:
- Array();
- virtual ~Array();
-
- static Array * array();
- static Array * arrayWithObject(Object * obj);
-
- virtual unsigned int count();
- virtual void addObject(Object * obj);
- virtual void removeObjectAtIndex(unsigned int idx);
- virtual void removeObject(Object * obj);
- virtual int indexOfObject(Object * obj);
- virtual Object * objectAtIndex(unsigned int idx);
- virtual void replaceObject(unsigned int idx, Object * obj);
- virtual void insertObject(unsigned int idx, Object * obj);
- virtual void removeAllObjects();
-
- virtual void addObjectsFromArray(Array * array);
- virtual Object * lastObject();
- virtual bool containsObject(Object * obj);
-
- virtual Array * sortedArray(int (* compare)(void * a, void * b, void * context), void * context);
- virtual String * componentsJoinedByString(String * delimiter);
+ class String;
+
+ class Array : public Object {
+ public:
+ Array();
+ virtual ~Array();
+
+ static Array * array();
+ static Array * arrayWithObject(Object * obj);
+
+ virtual unsigned int count();
+ virtual void addObject(Object * obj);
+ virtual void removeObjectAtIndex(unsigned int idx);
+ virtual void removeObject(Object * obj);
+ virtual int indexOfObject(Object * obj);
+ virtual Object * objectAtIndex(unsigned int idx);
+ virtual void replaceObject(unsigned int idx, Object * obj);
+ virtual void insertObject(unsigned int idx, Object * obj);
+ virtual void removeAllObjects();
+
+ virtual void addObjectsFromArray(Array * array);
+ virtual Object * lastObject();
+ virtual bool containsObject(Object * obj);
+
+ virtual Array * sortedArray(int (* compare)(void * a, void * b, void * context), void * context);
+ virtual String * componentsJoinedByString(String * delimiter);
public: // subclass behavior
- Array(Array * o);
- virtual String * description();
- virtual Object * copy();
+ Array(Array * o);
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
- private:
- carray * mArray;
- void init();
- };
+ private:
+ carray * mArray;
+ void init();
+ };
}
diff --git a/src/core/basetypes/MCBase64.c b/src/core/basetypes/MCBase64.c
new file mode 100644
index 00000000..87ee97bd
--- /dev/null
+++ b/src/core/basetypes/MCBase64.c
@@ -0,0 +1,111 @@
+//
+// MCBase64.c
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 7/30/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCBase64.h"
+
+#include <stdlib.h>
+
+#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+
+static char index_64[128] = {
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+static char basis_64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+char * MCEncodeBase64(const char * in, int len)
+{
+ char * output, * tmp;
+ unsigned char oval;
+ int out_len;
+
+ out_len = ((len + 2) / 3 * 4) + 1;
+
+ if ((len > 0) && (in == NULL))
+ return NULL;
+
+ output = malloc(out_len);
+ if (!output)
+ return NULL;
+
+ tmp = output;
+ while (len >= 3) {
+ *tmp++ = basis_64[in[0] >> 2];
+ *tmp++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
+ *tmp++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
+ *tmp++ = basis_64[in[2] & 0x3f];
+ in += 3;
+ len -= 3;
+ }
+ if (len > 0) {
+ *tmp++ = basis_64[in[0] >> 2];
+ oval = (in[0] << 4) & 0x30;
+ if (len > 1) oval |= in[1] >> 4;
+ *tmp++ = basis_64[oval];
+ *tmp++ = (len < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
+ *tmp++ = '=';
+ }
+
+ *tmp = '\0';
+
+ return output;
+}
+
+char * MCDecodeBase64(const char * in, int len)
+{
+ char * output, * out;
+ int i, c1, c2, c3, c4, out_len;
+ int max_out_len;
+
+ out_len = 0;
+ max_out_len = ((len + 3) * 4 / 3) + 1;
+
+ output = malloc(max_out_len);
+ if (output == NULL)
+ return NULL;
+ out = output;
+
+ if (in[0] == '+' && in[1] == ' ')
+ in += 2;
+
+ for (i = 0; i < (len / 4); i++) {
+ c1 = in[0];
+ c2 = in[1];
+ c3 = in[2];
+ c4 = in[3];
+ if (CHAR64(c1) == -1 || CHAR64(c2) == -1 ||
+ (c3 != '=' && CHAR64(c3) == -1) ||
+ (c4 != '=' && CHAR64(c4) == -1)) {
+ free(out);
+ return NULL;
+ }
+
+ in += 4;
+ *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
+
+ if (c3 != '=') {
+ *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
+
+ if (c4 != '=') {
+ *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
+ }
+ }
+ }
+
+ *output = 0;
+
+ return out;
+}
diff --git a/src/core/basetypes/MCBase64.h b/src/core/basetypes/MCBase64.h
new file mode 100644
index 00000000..ff61188b
--- /dev/null
+++ b/src/core/basetypes/MCBase64.h
@@ -0,0 +1,23 @@
+//
+// MCBase64.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 7/30/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCBASE64_H_
+#define __MAILCORE_MCBASE64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char * MCDecodeBase64(const char * in, int len);
+extern char * MCEncodeBase64(const char * in, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/core/basetypes/MCData.cc b/src/core/basetypes/MCData.cc
index 7ae63988..b8f2fa4e 100644
--- a/src/core/basetypes/MCData.cc
+++ b/src/core/basetypes/MCData.cc
@@ -9,6 +9,8 @@
#include "MCString.h"
#include "MCHash.h"
#include "MCUtils.h"
+#include "MCHashMap.h"
+#include "MCBase64.h"
#define DEFAULT_CHARSET "iso-8859-1"
@@ -539,3 +541,34 @@ Data * Data::dataWithCapacity(int capacity)
Data * result = new Data(capacity);
return (Data *) result->autorelease();
}
+
+String * Data::base64String()
+{
+ char * encoded = MCEncodeBase64(bytes(), length());
+ String * result = String::stringWithUTF8Characters(encoded);
+ free(encoded);
+ return result;
+}
+
+HashMap * Data::serializable()
+{
+ HashMap * result = Object::serializable();
+ result->setObjectForKey(MCSTR("data"), base64String());
+ return result;
+}
+
+void Data::importSerializable(HashMap * serializable)
+{
+ setData(((String *) (serializable->objectForKey(MCSTR("data"))))->decodedBase64Data());
+}
+
+static void * createObject()
+{
+ return new Data();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::Data", &createObject);
+}
diff --git a/src/core/basetypes/MCData.h b/src/core/basetypes/MCData.h
index a8f3fe8b..f54cada0 100644
--- a/src/core/basetypes/MCData.h
+++ b/src/core/basetypes/MCData.h
@@ -9,54 +9,58 @@
namespace mailcore {
- class String;
+ class String;
- class Data : public Object {
- public:
- Data();
- Data(int capacity);
- Data(const char * bytes, unsigned int length);
- virtual ~Data();
-
- static Data * data();
- static Data * dataWithCapacity(int capacity);
- static Data * dataWithContentsOfFile(String * filename);
- static Data * dataWithBytes(const char * bytes, unsigned int length);
-
- virtual char * bytes();
- virtual unsigned int length();
-
- virtual void appendData(Data * otherData);
- virtual void appendBytes(const char * bytes, unsigned int length);
- virtual void setBytes(const char * bytes, unsigned int length);
- virtual void setData(Data * otherData);
-
- // Helpers
- virtual String * stringWithDetectedCharset();
- virtual String * stringWithDetectedCharset(String * charset, bool isHTML);
- virtual String * stringWithCharset(const char * charset);
- virtual Data * decodedDataUsingEncoding(Encoding encoding);
+ class Data : public Object {
+ public:
+ Data();
+ Data(int capacity);
+ Data(const char * bytes, unsigned int length);
+ virtual ~Data();
+
+ static Data * data();
+ static Data * dataWithCapacity(int capacity);
+ static Data * dataWithContentsOfFile(String * filename);
+ static Data * dataWithBytes(const char * bytes, unsigned int length);
+
+ virtual char * bytes();
+ virtual unsigned int length();
+
+ virtual void appendData(Data * otherData);
+ virtual void appendBytes(const char * bytes, unsigned int length);
+ virtual void setBytes(const char * bytes, unsigned int length);
+ virtual void setData(Data * otherData);
+
+ // Helpers
+ virtual String * stringWithDetectedCharset();
+ virtual String * stringWithDetectedCharset(String * charset, bool isHTML);
+ virtual String * stringWithCharset(const char * charset);
+ virtual Data * decodedDataUsingEncoding(Encoding encoding);
+
+ virtual String * base64String();
public: // private
- virtual String * charsetWithFilteredHTML(bool filterHTML, String * hintCharset = NULL);
+ virtual String * charsetWithFilteredHTML(bool filterHTML, String * hintCharset = NULL);
public: // subclass behavior
- Data(Data * otherData);
- virtual String * description();
- virtual Object * copy();
- virtual bool isEqual(Object * otherObject);
- virtual unsigned int hash();
+ Data(Data * otherData);
+ virtual String * description();
+ virtual Object * copy();
+ virtual bool isEqual(Object * otherObject);
+ virtual unsigned int hash();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
+
+ private:
+ char * mBytes;
+ unsigned int mLength;
+ unsigned int mAllocated;
+ void allocate(unsigned int length);
+ void reset();
+ static String * normalizeCharset(String * charset);
+ String * charsetWithFilteredHTMLWithoutHint(bool filterHTML);
- private:
- char * mBytes;
- unsigned int mLength;
- unsigned int mAllocated;
- void allocate(unsigned int length);
- void reset();
- static String * normalizeCharset(String * charset);
- String * charsetWithFilteredHTMLWithoutHint(bool filterHTML);
-
- };
+ };
}
diff --git a/src/core/basetypes/MCHashMap.cc b/src/core/basetypes/MCHashMap.cc
index 164198f5..551392a6 100644
--- a/src/core/basetypes/MCHashMap.cc
+++ b/src/core/basetypes/MCHashMap.cc
@@ -7,6 +7,8 @@
#include "MCString.h"
#include "MCUtils.h"
#include "MCLog.h"
+#include "MCIterator.h"
+#include "MCAssert.h"
using namespace mailcore;
@@ -274,3 +276,42 @@ void HashMap::removeAllObjects()
memset(mCells, 0, mAllocated * sizeof(* mCells));
mCount = 0;
}
+
+HashMap * HashMap::serializable()
+{
+ HashMap * result = Object::serializable();
+ Array * keys = Array::array();
+ Array * values = Array::array();
+ mc_foreachhashmapKeyAndValue(Object, key, Object, value, this) {
+ if (MCISKINDOFCLASS(key, String)) {
+ keys->addObject(key);
+ }
+ else {
+ keys->addObject(key->serializable());
+ }
+ values->addObject(value->serializable());
+ }
+ result->setObjectForKey(MCSTR("keys"), keys);
+ result->setObjectForKey(MCSTR("values"), values);
+ return result;
+}
+
+void HashMap::importSerializable(HashMap * serializable)
+{
+ Array * keys = (Array *) serializable->objectForKey(MCSTR("keys"));
+ Array * values = (Array *) serializable->objectForKey(MCSTR("values"));
+ unsigned int count = keys->count();
+ MCAssert(count == values->count());
+ for(unsigned int i = 0 ; i < count ; i ++) {
+ Object * serializedKey = keys->objectAtIndex(i);
+ Object * key;
+ if (MCISKINDOFCLASS(serializedKey, String)) {
+ key = serializedKey;
+ }
+ else {
+ key = Object::objectWithSerializable((HashMap *) serializedKey);
+ }
+ Object * value = Object::objectWithSerializable((HashMap *) keys->objectAtIndex(i));
+ setObjectForKey(key, value);
+ }
+}
diff --git a/src/core/basetypes/MCHashMap.h b/src/core/basetypes/MCHashMap.h
index 40751b8e..41e0be4c 100644
--- a/src/core/basetypes/MCHashMap.h
+++ b/src/core/basetypes/MCHashMap.h
@@ -32,6 +32,8 @@ namespace mailcore {
HashMap(HashMap * o);
virtual String * description();
virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
private:
unsigned int mAllocated;
diff --git a/src/core/basetypes/MCIterator.h b/src/core/basetypes/MCIterator.h
index 964a2cce..22c264ad 100644
--- a/src/core/basetypes/MCIterator.h
+++ b/src/core/basetypes/MCIterator.h
@@ -26,22 +26,22 @@ type * __variable; \
mailcore::ArrayIterator __variable##__iterator = mailcore::ArrayIteratorInit(__array); \
for (unsigned int __index = 0; NULL != (__variable = mailcore::ArrayIteratorNext(&__variable##__iterator)); __index++)
-#define mc_foreachdictionaryKey(keyType, __key, __dictionary) \
+#define mc_foreachhashmapKey(keyType, __key, __hashmap) \
keyType * __key; \
-HashMapIterator __key##__iterator = HashMapIteratorInit(__dictionary, true, false); \
+HashMapIterator __key##__iterator = HashMapIteratorInit(__hashmap, true, false); \
while (HashMapIteratorRun(&__key##__iterator)) \
while (HashMapIteratorNext(&__key##__iterator, &__key, NULL))
-#define mc_foreachdictionaryValue(valueType, __value, __dictionary) \
+#define mc_foreachhashmapValue(valueType, __value, __hashmap) \
valueType * __value; \
-HashMapIterator __value##__iterator = HashMapIteratorInit(__dictionary, false, true); \
+HashMapIterator __value##__iterator = HashMapIteratorInit(__hashmap, false, true); \
while (HashMapIteratorRun(&__value##__iterator)) \
while (HashMapIteratorNext(&__value##__iterator, NULL, (Object **) &__value))
-#define mc_foreachdictionaryKeyAndValue(keyType, __key, valueType, __value, __dictionary) \
+#define mc_foreachhashmapKeyAndValue(keyType, __key, valueType, __value, __hashmap) \
keyType * __key; \
valueType * __value; \
-HashMapIterator __key##__value##__iterator = HashMapIteratorInit(__dictionary, true, true); \
+HashMapIterator __key##__value##__iterator = HashMapIteratorInit(__hashmap, true, true); \
while (HashMapIteratorRun(&__key##__value##__iterator)) \
while (HashMapIteratorNext(&__key##__value##__iterator, (Object **) &__key, (Object **) &__value))
diff --git a/src/core/basetypes/MCLibetpan.cc b/src/core/basetypes/MCLibetpan.cc
index 5da4452b..fcc1b772 100644
--- a/src/core/basetypes/MCLibetpan.cc
+++ b/src/core/basetypes/MCLibetpan.cc
@@ -11,7 +11,8 @@
#include <libetpan/libetpan.h>
__attribute__((constructor))
-static void initialize() {
+static void initialize()
+{
// It will enable CFStream on platforms that supports it.
mailstream_cfstream_enabled = 1;
}
diff --git a/src/core/basetypes/MCLog.c b/src/core/basetypes/MCLog.c
index 8744f2dd..11407f00 100644
--- a/src/core/basetypes/MCLog.c
+++ b/src/core/basetypes/MCLog.c
@@ -12,7 +12,8 @@ static pid_t sPid = -1;
int MCLogEnabled = 0;
__attribute__((constructor))
-static void initialize() {
+static void initialize()
+{
sPid = getpid();
}
diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc
index 527b0c71..fff2055d 100644
--- a/src/core/basetypes/MCObject.cc
+++ b/src/core/basetypes/MCObject.cc
@@ -4,6 +4,7 @@
#include <typeinfo>
#include <cxxabi.h>
#include <libetpan/libetpan.h>
+#include <string.h>
#include "MCAutoreleasePool.h"
#include "MCString.h"
@@ -13,6 +14,7 @@
#include "MCAssert.h"
#include "MCMainThread.h"
#include "MCLog.h"
+#include "MCHashMap.h"
using namespace mailcore;
@@ -250,3 +252,59 @@ void Object::cancelDelayedPerformMethod(Method method, void * context)
cancelDelayedCall(data->caller);
free(data);
}
+
+HashMap * Object::serializable()
+{
+ HashMap * result = HashMap::hashMap();
+ result->setObjectForKey(MCSTR("class"), className());
+ return result;
+}
+
+void Object::importSerializable(HashMap * serializable)
+{
+ MCAssert(0);
+}
+
+static chash * constructors = NULL;
+
+void Object::initObjectConstructors()
+{
+ constructors = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
+}
+
+void Object::registerObjectConstructor(char * className, void * (* objectConstructor)(void))
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, initObjectConstructors);
+
+ chashdatum key;
+ chashdatum value;
+ key.data = className;
+ key.len = strlen(className);
+ value.data = (void *) objectConstructor;
+ value.len = 0;
+ chash_set(constructors, &key, &value, NULL);
+}
+
+Object * Object::objectWithSerializable(HashMap * serializable)
+{
+ if (serializable == NULL)
+ return NULL;
+
+ void * (* objectConstructor)(void) = NULL;
+
+ chashdatum key;
+ chashdatum value;
+ const char * className = ((String *) serializable->objectForKey(MCSTR("class")))->UTF8Characters();
+ key.data = (void *) className;
+ key.len = strlen(className);
+ int r = chash_get(constructors, &key, &value);
+ if (r < 0)
+ return NULL;
+
+ objectConstructor = (void * (*)()) value.data;
+ Object * obj = (Object *) objectConstructor();
+ obj->importSerializable(serializable);
+ return obj->autorelease();
+}
+
diff --git a/src/core/basetypes/MCObject.h b/src/core/basetypes/MCObject.h
index 01812191..6bde74e5 100644
--- a/src/core/basetypes/MCObject.h
+++ b/src/core/basetypes/MCObject.h
@@ -14,37 +14,47 @@ namespace mailcore {
extern bool zombieEnabled;
- class String;
-
- class Object {
- public:
- Object();
- virtual ~Object();
-
- virtual int retainCount();
- virtual Object * retain();
- virtual void release();
- virtual Object * autorelease();
- virtual String * description();
- virtual String * className();
+ class String;
+ class HashMap;
+
+ class Object {
+ public:
+ Object();
+ virtual ~Object();
+
+ virtual int retainCount();
+ virtual Object * retain();
+ virtual void release();
+ virtual Object * autorelease();
+ virtual String * description();
+ virtual String * className();
- virtual bool isEqual(Object * otherObject);
- virtual unsigned int hash();
-
- // optional
- virtual Object * copy();
-
- typedef void (Object::*Method) (void *);
- virtual void performMethod(Method method, void * context);
- virtual void performMethodOnMainThread(Method method, void * context, bool waitUntilDone = false);
- virtual void performMethodAfterDelay(Method method, void * context, double delay);
- virtual void cancelDelayedPerformMethod(Method method, void * context);
+ virtual bool isEqual(Object * otherObject);
+ virtual unsigned int hash();
- private:
- pthread_mutex_t mLock;
- int mCounter;
- void init();
- };
+ // optional
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
+
+ typedef void (Object::*Method) (void *);
+ virtual void performMethod(Method method, void * context);
+ virtual void performMethodOnMainThread(Method method, void * context, bool waitUntilDone = false);
+ virtual void performMethodAfterDelay(Method method, void * context, double delay);
+ virtual void cancelDelayedPerformMethod(Method method, void * context);
+
+ // serialization utils
+ static void registerObjectConstructor(char * className, void * (* objectConstructor)(void));
+ static Object * objectWithSerializable(HashMap * serializable);
+
+ public: // private
+
+ private:
+ pthread_mutex_t mLock;
+ int mCounter;
+ void init();
+ static void initObjectConstructors();
+ };
}
diff --git a/src/core/basetypes/MCSet.cc b/src/core/basetypes/MCSet.cc
index 393873b0..ca66a10f 100644
--- a/src/core/basetypes/MCSet.cc
+++ b/src/core/basetypes/MCSet.cc
@@ -100,3 +100,16 @@ void Set::addObjectsFromArray(Array * objects)
addObject(objects->objectAtIndex(i));
}
}
+
+HashMap * Set::serializable()
+{
+ HashMap * result = Object::serializable();
+ result->setObjectForKey(MCSTR("items"), allObjects()->serializable());
+ return result;
+}
+
+void Set::importSerializable(HashMap * serializable)
+{
+ Array * array = (Array *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("items")));
+ addObjectsFromArray(array);
+}
diff --git a/src/core/basetypes/MCSet.h b/src/core/basetypes/MCSet.h
index 8b82ad33..41075d69 100644
--- a/src/core/basetypes/MCSet.h
+++ b/src/core/basetypes/MCSet.h
@@ -8,37 +8,39 @@
namespace mailcore {
- class String;
- class Array;
- class HashMap;
-
- class Set : public Object {
- public:
- Set();
- Set(Set * o);
-
- static Set * set();
- static Set * setWithArray(Array * objects);
-
- virtual unsigned int count();
- virtual void addObject(Object * obj);
- virtual void removeObject(Object * obj);
- virtual bool containsObject(Object * obj);
- virtual Object * member(Object * obj);
-
- virtual Array * allObjects();
- virtual void removeAllObjects();
- virtual void addObjectsFromArray(Array * objects);
+ class String;
+ class Array;
+ class HashMap;
+
+ class Set : public Object {
+ public:
+ Set();
+ Set(Set * o);
+
+ static Set * set();
+ static Set * setWithArray(Array * objects);
+
+ virtual unsigned int count();
+ virtual void addObject(Object * obj);
+ virtual void removeObject(Object * obj);
+ virtual bool containsObject(Object * obj);
+ virtual Object * member(Object * obj);
+
+ virtual Array * allObjects();
+ virtual void removeAllObjects();
+ virtual void addObjectsFromArray(Array * objects);
public: // subclass behavior
- virtual ~Set();
- virtual String * description();
- virtual Object * copy();
+ virtual ~Set();
+ virtual String * description();
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
- private:
- HashMap * mHash;
- void init();
- };
+ private:
+ HashMap * mHash;
+ void init();
+ };
}
diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc
index badf1425..94587f3b 100644
--- a/src/core/basetypes/MCString.cc
+++ b/src/core/basetypes/MCString.cc
@@ -25,6 +25,7 @@
#include "MCAutoreleasePool.h"
#include "MCValue.h"
#include "MCHTMLCleaner.h"
+#include "MCBase64.h"
using namespace mailcore;
@@ -2110,6 +2111,15 @@ bool String::isEqualCaseInsensitive(String * otherString)
return caseInsensitiveCompare(otherString) == 0;
}
+Data * String::decodedBase64Data()
+{
+ const char * utf8 = UTF8Characters();
+ char * decoded = MCDecodeBase64(utf8, strlen(utf8));
+ Data * result = Data::dataWithBytes(decoded, strlen(decoded));
+ free(decoded);
+ return result;
+}
+
void mailcore::setICUDataDirectory(String * directory)
{
u_setDataDirectory(directory->fileSystemRepresentation());
diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h
index f06a429f..d5ffd0e5 100644
--- a/src/core/basetypes/MCString.h
+++ b/src/core/basetypes/MCString.h
@@ -108,6 +108,8 @@ namespace mailcore {
virtual String * htmlEncodedString();
virtual String * cleanedHTMLString();
+ virtual Data * decodedBase64Data();
+
public: // private
static String * uniquedStringWithUTF8Characters(const char * UTF8Characters);
diff --git a/src/core/basetypes/MCUtils.h b/src/core/basetypes/MCUtils.h
index c1ef5037..8309842e 100644
--- a/src/core/basetypes/MCUtils.h
+++ b/src/core/basetypes/MCUtils.h
@@ -34,6 +34,8 @@
#define MCLOCALIZEDSTRING(key) key
+#define MCISKINDOFCLASS(instance, class) (dynamic_cast<class *>(instance) != NULL)
+
#endif
#endif
diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc
index ee9b6b0f..d8a0d943 100644
--- a/src/core/imap/MCIMAPMessage.cc
+++ b/src/core/imap/MCIMAPMessage.cc
@@ -18,10 +18,10 @@ void IMAPMessage::init()
mFlags = MessageFlagNone;
mOriginalFlags = MessageFlagNone;
mMainPart = NULL;
- mLabels = NULL;
+ mGmailLabels = NULL;
mModSeqValue = 0;
- mThreadID = 0;
- mMessageID = 0;
+ mGmailThreadID = 0;
+ mGmailMessageID = 0;
}
IMAPMessage::IMAPMessage()
@@ -44,7 +44,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other) : AbstractMessage(other)
IMAPMessage::~IMAPMessage()
{
MC_SAFE_RELEASE(mMainPart);
- MC_SAFE_RELEASE(mLabels);
+ MC_SAFE_RELEASE(mGmailLabels);
}
Object * IMAPMessage::copy()
@@ -117,32 +117,32 @@ AbstractPart * IMAPMessage::mainPart()
void IMAPMessage::setGmailLabels(Array * labels)
{
- MC_SAFE_REPLACE_COPY(Array, mLabels, labels);
+ MC_SAFE_REPLACE_COPY(Array, mGmailLabels, labels);
}
Array * IMAPMessage::gmailLabels()
{
- return mLabels;
+ return mGmailLabels;
}
void IMAPMessage::setGmailMessageID(uint64_t msgID)
{
- mMessageID = msgID;
+ mGmailMessageID = msgID;
}
uint64_t IMAPMessage::gmailMessageID()
{
- return mMessageID;
+ return mGmailMessageID;
}
void IMAPMessage::setGmailThreadID(uint64_t threadID)
{
- mThreadID = threadID;
+ mGmailThreadID = threadID;
}
uint64_t IMAPMessage::gmailThreadID()
{
- return mThreadID;
+ return mGmailThreadID;
}
AbstractPart * IMAPMessage::partForPartID(String * partID)
@@ -208,3 +208,64 @@ String * IMAPMessage::htmlRendering(String * folder,
return HTMLRenderer::htmlForIMAPMessage(folder, this, dataCallback, htmlCallback);
}
+HashMap * IMAPMessage::serializable()
+{
+ HashMap * result = AbstractMessage::serializable();
+ result->setObjectForKey(MCSTR("modSeqValue"), String::stringWithUTF8Format("%llu", (long long unsigned) modSeqValue()));
+ result->setObjectForKey(MCSTR("uid"), String::stringWithUTF8Format("%lu", (long unsigned) uid()));
+ result->setObjectForKey(MCSTR("flags"), String::stringWithUTF8Format("%u", (unsigned) flags()));
+ result->setObjectForKey(MCSTR("originalFlags"), String::stringWithUTF8Format("%u", (unsigned) originalFlags()));
+ result->setObjectForKey(MCSTR("mainPart"), mMainPart->serializable());
+ if (gmailLabels() != NULL) {
+ result->setObjectForKey(MCSTR("gmailLabels"), gmailLabels());
+ }
+ if (gmailMessageID() != 0) {
+ result->setObjectForKey(MCSTR("gmailMessageID"), String::stringWithUTF8Format("%llu", (long long unsigned) gmailMessageID()));
+ }
+ if (gmailThreadID() != 0) {
+ result->setObjectForKey(MCSTR("gmailThreadID"), String::stringWithUTF8Format("%llu", (long long unsigned) gmailThreadID()));
+ }
+ return result;
+}
+
+void IMAPMessage::importSerializable(HashMap * serializable)
+{
+ AbstractMessage::importSerializable(serializable);
+ String * modSeq = (String *) serializable->objectForKey(MCSTR("modSeqValue"));
+ if (modSeq != NULL) {
+ setModSeqValue(modSeq->unsignedLongLongValue());
+ }
+ String * uid = (String *) serializable->objectForKey(MCSTR("uid"));
+ if (uid != NULL) {
+ setUid(uid->unsignedLongValue());
+ }
+ String * flags = (String *) serializable->objectForKey(MCSTR("flags"));
+ if (flags != NULL) {
+ setFlags((MessageFlag) flags->unsignedIntValue());
+ }
+ String * originalFlags = (String *) serializable->objectForKey(MCSTR("originalFlags"));
+ if (originalFlags != NULL) {
+ setFlags((MessageFlag) originalFlags->unsignedIntValue());
+ }
+ setMainPart((AbstractPart *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("mainPart"))));
+ setGmailLabels((Array *) serializable->objectForKey(MCSTR("gmailLabels")));
+ String * gmailMessageID = (String *) serializable->objectForKey(MCSTR("gmailMessageID"));
+ if (gmailMessageID != NULL) {
+ setGmailMessageID(gmailMessageID->unsignedLongLongValue());
+ }
+ String * gmailThreadID = (String *) serializable->objectForKey(MCSTR("gmailThreadID"));
+ if (gmailThreadID != NULL) {
+ setGmailThreadID(gmailThreadID->unsignedLongLongValue());
+ }
+}
+
+static void * createObject()
+{
+ return new IMAPMessage();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::IMAPMessage", &createObject);
+}
diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h
index 7053ef92..2f72cd7b 100644
--- a/src/core/imap/MCIMAPMessage.h
+++ b/src/core/imap/MCIMAPMessage.h
@@ -57,6 +57,8 @@ namespace mailcore {
IMAPMessage(IMAPMessage * other);
virtual Object * copy();
virtual String * description();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
private:
uint64_t mModSeqValue;
@@ -64,9 +66,9 @@ namespace mailcore {
MessageFlag mFlags;
MessageFlag mOriginalFlags;
AbstractPart * mMainPart;
- Array * /* String */ mLabels;
- uint64_t mMessageID;
- uint64_t mThreadID;
+ Array * /* String */ mGmailLabels;
+ uint64_t mGmailMessageID;
+ uint64_t mGmailThreadID;
void init();
};
diff --git a/src/core/imap/MCIMAPMessagePart.cc b/src/core/imap/MCIMAPMessagePart.cc
index bd97657c..1b1f8921 100644
--- a/src/core/imap/MCIMAPMessagePart.cc
+++ b/src/core/imap/MCIMAPMessagePart.cc
@@ -37,3 +37,30 @@ String * IMAPMessagePart::partID()
{
return mPartID;
}
+
+HashMap * IMAPMessagePart::serializable()
+{
+ HashMap * result = AbstractMessagePart::serializable();
+ if (partID() != NULL) {
+ result->setObjectForKey(MCSTR("partID"), partID());
+ }
+ return result;
+}
+
+void IMAPMessagePart::importSerializable(HashMap * serializable)
+{
+ AbstractMessagePart::importSerializable(serializable);
+ String * partID = (String *) serializable->objectForKey(MCSTR("partID"));
+ setPartID(partID);
+}
+
+static void * createObject()
+{
+ return new IMAPMessagePart();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::IMAPMessagePart", &createObject);
+}
diff --git a/src/core/imap/MCIMAPMessagePart.h b/src/core/imap/MCIMAPMessagePart.h
index a4ff6e39..3afb2b98 100644
--- a/src/core/imap/MCIMAPMessagePart.h
+++ b/src/core/imap/MCIMAPMessagePart.h
@@ -7,23 +7,25 @@
#ifdef __cplusplus
namespace mailcore {
-
- class IMAPMessagePart : public AbstractMessagePart {
- public:
- IMAPMessagePart();
- virtual ~IMAPMessagePart();
+
+ class IMAPMessagePart : public AbstractMessagePart {
+ public:
+ IMAPMessagePart();
+ virtual ~IMAPMessagePart();
- virtual void setPartID(String * partID);
- virtual String * partID();
+ virtual void setPartID(String * partID);
+ virtual String * partID();
public: // subclass behavior
- IMAPMessagePart(IMAPMessagePart * other);
- virtual Object * copy();
+ IMAPMessagePart(IMAPMessagePart * other);
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
private:
- String * mPartID;
- void init();
- };
+ String * mPartID;
+ void init();
+ };
}
#endif
diff --git a/src/core/imap/MCIMAPMultipart.cc b/src/core/imap/MCIMAPMultipart.cc
index be0b2c8e..9bd107e6 100644
--- a/src/core/imap/MCIMAPMultipart.cc
+++ b/src/core/imap/MCIMAPMultipart.cc
@@ -37,3 +37,31 @@ String * IMAPMultipart::partID()
{
return mPartID;
}
+
+HashMap * IMAPMultipart::serializable()
+{
+ HashMap * result = AbstractMultipart::serializable();
+ if (partID() != NULL) {
+ result->setObjectForKey(MCSTR("partID"), partID());
+ }
+ return result;
+}
+
+void IMAPMultipart::importSerializable(HashMap * serializable)
+{
+ AbstractMultipart::importSerializable(serializable);
+ String * partID = (String *) serializable->objectForKey(MCSTR("partID"));
+ setPartID(partID);
+}
+
+static void * createObject()
+{
+ return new IMAPMultipart();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::IMAPMultipart", &createObject);
+}
+
diff --git a/src/core/imap/MCIMAPMultipart.h b/src/core/imap/MCIMAPMultipart.h
index 126a4398..ca3574ab 100644
--- a/src/core/imap/MCIMAPMultipart.h
+++ b/src/core/imap/MCIMAPMultipart.h
@@ -7,23 +7,25 @@
#ifdef __cplusplus
namespace mailcore {
-
- class IMAPMultipart : public AbstractMultipart {
- public:
- IMAPMultipart();
- virtual ~IMAPMultipart();
-
- virtual void setPartID(String * partID);
- virtual String * partID();
+
+ class IMAPMultipart : public AbstractMultipart {
+ public:
+ IMAPMultipart();
+ virtual ~IMAPMultipart();
+
+ virtual void setPartID(String * partID);
+ virtual String * partID();
public: // subclass behavior
- IMAPMultipart(IMAPMultipart * other);
- virtual Object * copy();
+ IMAPMultipart(IMAPMultipart * other);
+ virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
private:
- String * mPartID;
- void init();
- };
+ String * mPartID;
+ void init();
+ };
}
#endif
diff --git a/src/core/imap/MCIMAPPart.cc b/src/core/imap/MCIMAPPart.cc
index 14b23c3a..76e59021 100644
--- a/src/core/imap/MCIMAPPart.cc
+++ b/src/core/imap/MCIMAPPart.cc
@@ -285,3 +285,83 @@ IMAPMultipart * IMAPPart::attachmentWithIMAPBodyMultipart(struct mailimap_body_t
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();
+}
+
+__attribute__((constructor))
+static void initialize()
+{
+ Object::registerObjectConstructor("mailcore::IMAPPart", &createObject);
+}
+
diff --git a/src/core/imap/MCIMAPPart.h b/src/core/imap/MCIMAPPart.h
index 970c01e5..eddc661a 100644
--- a/src/core/imap/MCIMAPPart.h
+++ b/src/core/imap/MCIMAPPart.h
@@ -31,6 +31,8 @@ namespace mailcore {
public: // subclass behavior
IMAPPart(IMAPPart * other);
virtual Object * copy();
+ virtual HashMap * serializable();
+ virtual void importSerializable(HashMap * serializable);
public: // private
static AbstractPart * attachmentWithIMAPBody(struct mailimap_body * body);
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index e2fb4e1d..7ebe4354 100644
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -37,7 +37,8 @@ String * mailcore::IMAPNamespaceOther = NULL;
String * mailcore::IMAPNamespaceShared = NULL;
__attribute__((constructor))
-static void initialize() {
+static void initialize()
+{
AutoreleasePool * pool = new AutoreleasePool();
IMAPNamespacePersonal = (String *) MCSTR("IMAPNamespacePersonal")->retain();
IMAPNamespaceOther = (String *) MCSTR("IMAPNamespaceOther")->retain();
diff --git a/src/core/provider/MCMailProvider.cc b/src/core/provider/MCMailProvider.cc
index 43fd94f9..8f4e349e 100644
--- a/src/core/provider/MCMailProvider.cc
+++ b/src/core/provider/MCMailProvider.cc
@@ -210,7 +210,7 @@ String * MailProvider::importantFolderPath()
bool MailProvider::isMainFolder(String * folderPath, String * prefix)
{
- mc_foreachdictionaryValue(String, path, mMailboxPaths) {
+ mc_foreachhashmapValue(String, path, mMailboxPaths) {
String * fullPath;
if (prefix != NULL) {
diff --git a/src/core/provider/MCMailProvidersManager.cc b/src/core/provider/MCMailProvidersManager.cc
index 71041c06..5214b284 100644
--- a/src/core/provider/MCMailProvidersManager.cc
+++ b/src/core/provider/MCMailProvidersManager.cc
@@ -30,7 +30,7 @@ MailProvidersManager * MailProvidersManager::sharedManager()
MailProvider * MailProvidersManager::providerForEmail(String * email)
{
- mc_foreachdictionaryValue(MailProvider, provider, mProviders) {
+ mc_foreachhashmapValue(MailProvider, provider, mProviders) {
if (provider->matchEmail(email))
return provider;
}
@@ -40,7 +40,7 @@ MailProvider * MailProvidersManager::providerForEmail(String * email)
MailProvider * MailProvidersManager::providerForMX(String * hostname)
{
- mc_foreachdictionaryValue(MailProvider, provider, mProviders) {
+ mc_foreachhashmapValue(MailProvider, provider, mProviders) {
if (provider->matchMX(hostname))
return provider;
}
@@ -55,7 +55,7 @@ MailProvider * MailProvidersManager::providerForIdentifier(String * identifier)
void MailProvidersManager::registerProviders(HashMap * providers)
{
- mc_foreachdictionaryKeyAndValue(String, identifier, HashMap, providerInfo, providers) {
+ mc_foreachhashmapKeyAndValue(String, identifier, HashMap, providerInfo, providers) {
MailProvider * provider = MailProvider::providerWithInfo(providerInfo);
provider->setIdentifier(identifier);
//MCLog("register %s", MCUTF8DESC(identifier));
diff --git a/src/objc/abstract/MCOMessageHeader.mm b/src/objc/abstract/MCOMessageHeader.mm
index 9374614f..241dab88 100644
--- a/src/objc/abstract/MCOMessageHeader.mm
+++ b/src/objc/abstract/MCOMessageHeader.mm
@@ -67,6 +67,8 @@
return self;
}
+MCO_SYNTHESIZE_NSCODING
+
- (void) dealloc
{
_nativeHeader->release();
@@ -100,18 +102,18 @@ MCO_OBJC_SYNTHESIZE_ARRAY(setReplyTo, replyTo)
MCO_OBJC_SYNTHESIZE_STRING(setSubject, subject)
MCO_OBJC_SYNTHESIZE_STRING(setUserAgent, userAgent)
-- (void)addHeaderValue:(NSString *)value forName:(NSString *)name {
- _nativeHeader->addHeader(MCO_FROM_OBJC(mailcore::String, name), MCO_FROM_OBJC(mailcore::String, value));
+- (void)addExtraHeaderValue:(NSString *)value forName:(NSString *)name {
+ _nativeHeader->setExtraHeader(MCO_FROM_OBJC(mailcore::String, name), MCO_FROM_OBJC(mailcore::String, value));
}
-- (NSString *)headerValueForName:(NSString *)name {
- return MCO_TO_OBJC(_nativeHeader->headerValueForName((MCO_FROM_OBJC(mailcore::String, name))));
+- (NSString *)extraHeaderValueForName:(NSString *)name {
+ return MCO_TO_OBJC(_nativeHeader->extraHeaderValueForName((MCO_FROM_OBJC(mailcore::String, name))));
}
-- (void)removeHeaderForName:(NSString *)name {
- _nativeHeader->removeHeader(MCO_FROM_OBJC(mailcore::String, name));
+- (void)removeExtraHeaderForName:(NSString *)name {
+ _nativeHeader->removeExtraHeader(MCO_FROM_OBJC(mailcore::String, name));
}
-- (NSArray * /* NSString */)allHeadersNames {
+- (NSArray * /* NSString */)allExtraHeadersNames {
return MCO_TO_OBJC(_nativeHeader->allExtraHeadersNames());
}
diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm
index b4e83d2d..325f2b09 100644
--- a/src/objc/imap/MCOIMAPMessage.mm
+++ b/src/objc/imap/MCOIMAPMessage.mm
@@ -31,6 +31,8 @@
return [[[self alloc] initWithMCMessage:msg] autorelease];
}
+MCO_SYNTHESIZE_NSCODING
+
MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setUid, uid)
MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setFlags, flags)
MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFlags, originalFlags)
diff --git a/src/objc/imap/MCOIMAPMessagePart.mm b/src/objc/imap/MCOIMAPMessagePart.mm
index 05a7e102..909d5ea9 100644
--- a/src/objc/imap/MCOIMAPMessagePart.mm
+++ b/src/objc/imap/MCOIMAPMessagePart.mm
@@ -28,6 +28,8 @@
return [[[self alloc] initWithMCPart:part] autorelease];
}
+MCO_SYNTHESIZE_NSCODING
+
MCO_OBJC_SYNTHESIZE_STRING(setPartID, partID)
@end
diff --git a/src/objc/imap/MCOIMAPMultipart.mm b/src/objc/imap/MCOIMAPMultipart.mm
index c3761ade..056322b4 100644
--- a/src/objc/imap/MCOIMAPMultipart.mm
+++ b/src/objc/imap/MCOIMAPMultipart.mm
@@ -28,6 +28,8 @@
return [[[self alloc] initWithMCPart:part] autorelease];
}
+MCO_SYNTHESIZE_NSCODING
+
MCO_OBJC_SYNTHESIZE_STRING(setPartID, partID)
@end
diff --git a/src/objc/imap/MCOIMAPPart.mm b/src/objc/imap/MCOIMAPPart.mm
index 80fc2f1e..da44eb9d 100644
--- a/src/objc/imap/MCOIMAPPart.mm
+++ b/src/objc/imap/MCOIMAPPart.mm
@@ -28,6 +28,8 @@
return [[[self alloc] initWithMCPart:part] autorelease];
}
+MCO_SYNTHESIZE_NSCODING
+
MCO_OBJC_SYNTHESIZE_STRING(setPartID, partID)
MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setSize, size)
MCO_OBJC_SYNTHESIZE_SCALAR(MCOEncoding, mailcore::Encoding, setEncoding, encoding)
diff --git a/src/objc/utils/NSObject+MCO.h b/src/objc/utils/NSObject+MCO.h
index 31818ce3..4d8d4274 100644
--- a/src/objc/utils/NSObject+MCO.h
+++ b/src/objc/utils/NSObject+MCO.h
@@ -78,6 +78,20 @@ MCO_NATIVE_INSTANCE->setter((mcType) getter); \
MCO_NATIVE_INSTANCE->setter([getter timeIntervalSince1970]); \
}
+#define MCO_SYNTHESIZE_NSCODING \
+- (id) initWithCoder:(NSCoder *)coder \
+{ \
+ mailcore::HashMap * serializable = MCO_FROM_OBJC(mailcore::HashMap, [coder decodeObjectForKey:@"info"]); \
+ self = MCO_TO_OBJC(mailcore::Object::objectWithSerializable(serializable)); \
+ [self retain]; \
+ return self; \
+} \
+\
+- (void) encodeWithCoder:(NSCoder *)coder \
+{ \
+ [coder encodeObject:MCO_TO_OBJC(MCO_FROM_OBJC(nativeType, self)->serializable()) forKey:@"info"]; \
+}
+
@interface NSObject (MCO)
#ifdef __cplusplus
diff --git a/tests/test-all.mm b/tests/test-all.mm
index 552ffe8e..255e518a 100644
--- a/tests/test-all.mm
+++ b/tests/test-all.mm
@@ -56,7 +56,7 @@ static mailcore::Data * testMessageBuilder()
to->release();
bcc->release();
MCAssert(msg->header()->allExtraHeadersNames()->count() == 0);
- msg->header()->addHeader(MCSTR("X-Custom-Header"), MCSTR("Custom Header Value"));
+ msg->header()->setExtraHeader(MCSTR("X-Custom-Header"), MCSTR("Custom Header Value"));
msg->header()->setSubject(MCSTR("Mon projet d'été"));
msg->setHTMLBody(MCSTR("<div>Hello <img src=\"cid:1234\"></div>"));
msg->addAttachment(mailcore::Attachment::attachmentWithContentsOfFile(MCSTR("first-filename")));