diff options
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"))); |