aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Scott Herscher <scott@porchdogsoft.com>2013-02-03 11:02:00 -0800
committerGravatar Scott Herscher <scott@porchdogsoft.com>2013-02-03 11:02:00 -0800
commit57ef6b75d7465a78c09ddbba07379625072077f5 (patch)
tree3619bb2742a957d4618123460c72bf12644e9837 /src
parent54b038df296c4bb85bcd1a586f7c90c4c76d09e0 (diff)
parent61e978ca00aab50aed44c82aaf5d98177629e82c (diff)
Merge branch 'master' of github.com:MailCore/mailcore2
Diffstat (limited to 'src')
-rw-r--r--src/core/MCCore.h2
-rw-r--r--src/core/abstract/MCAbstractMessage.cc19
-rw-r--r--src/core/abstract/MCAbstractMessage.h4
-rw-r--r--src/core/abstract/MCAbstractMessagePart.cc17
-rw-r--r--src/core/abstract/MCAbstractMessagePart.h3
-rw-r--r--src/core/abstract/MCAbstractMultipart.cc31
-rw-r--r--src/core/abstract/MCAbstractMultipart.h3
-rw-r--r--src/core/abstract/MCAbstractPart.cc41
-rw-r--r--src/core/abstract/MCAbstractPart.h13
-rw-r--r--src/core/abstract/MCAddress.cc7
-rw-r--r--src/core/abstract/MCMessageHeader.cc7
-rw-r--r--src/core/basetypes/MCArray.cc7
-rw-r--r--src/core/basetypes/MCData.cc7
-rw-r--r--src/core/basetypes/MCHashMap.cc7
-rw-r--r--src/core/basetypes/MCObject.cc17
-rw-r--r--src/core/basetypes/MCObject.h2
-rw-r--r--src/core/basetypes/MCSet.cc7
-rw-r--r--src/core/basetypes/MCString.cc22
-rw-r--r--src/core/basetypes/MCString.h2
-rw-r--r--src/core/basetypes/MCUtils.h2
-rw-r--r--src/core/basetypes/MCValue.cc7
-rw-r--r--src/core/imap/MCIMAPFolder.cc7
-rw-r--r--src/core/imap/MCIMAPMessage.cc78
-rw-r--r--src/core/imap/MCIMAPMessage.h13
-rw-r--r--src/core/imap/MCIMAPMessagePart.cc24
-rw-r--r--src/core/imap/MCIMAPMessagePart.h7
-rw-r--r--src/core/imap/MCIMAPMultipart.cc23
-rw-r--r--src/core/imap/MCIMAPMultipart.h7
-rw-r--r--src/core/imap/MCIMAPNamespace.cc7
-rw-r--r--src/core/imap/MCIMAPNamespaceItem.cc7
-rw-r--r--src/core/imap/MCIMAPPart.cc13
-rw-r--r--src/core/imap/MCIMAPPart.h15
-rw-r--r--src/core/imap/MCIMAPSearchExpression.cc7
-rw-r--r--src/core/imap/MCIMAPSession.cc7
-rw-r--r--src/core/pop/MCPOPMessageInfo.cc7
-rw-r--r--src/core/pop/MCPOPSession.cc7
-rw-r--r--src/core/renderer/MCAddressDisplay.cpp94
-rw-r--r--src/core/renderer/MCAddressDisplay.h34
-rw-r--r--src/core/renderer/MCDateFormatter.cpp160
-rw-r--r--src/core/renderer/MCDateFormatter.h69
-rw-r--r--src/core/renderer/MCHTMLRenderer.cpp448
-rw-r--r--src/core/renderer/MCHTMLRenderer.h38
-rw-r--r--src/core/renderer/MCHTMLRendererCallback.cpp259
-rw-r--r--src/core/renderer/MCHTMLRendererCallback.h51
-rw-r--r--src/core/renderer/MCRenderer.h14
-rw-r--r--src/core/renderer/MCSizeFormatter.cpp43
-rw-r--r--src/core/renderer/MCSizeFormatter.h28
-rw-r--r--src/core/rfc822/MCAttachment.cc9
-rw-r--r--src/core/rfc822/MCAttachment.h5
-rw-r--r--src/core/rfc822/MCMessageBuilder.cc7
-rw-r--r--src/core/rfc822/MCMessageParser.cc22
-rw-r--r--src/core/rfc822/MCMessageParser.h7
-rw-r--r--src/core/rfc822/MCMessagePart.cc7
-rw-r--r--src/core/rfc822/MCMultipart.cc7
-rw-r--r--src/core/smtp/MCSMTPSession.cc7
-rw-r--r--src/objc/MCOConstants.h6
-rw-r--r--src/objc/MCObjC.h7
-rw-r--r--src/objc/imap/MCOCheckAccountOperation.mm2
-rw-r--r--src/objc/imap/MCOOperation+Internals.h2
-rw-r--r--src/objc/utils/MCOObjectWrapper.h6
-rw-r--r--src/objc/utils/MCOObjectWrapper.mm1
-rw-r--r--src/objc/utils/NSArray+MCO.h23
-rw-r--r--src/objc/utils/NSArray+MCO.mm26
-rw-r--r--src/objc/utils/NSData+MCO.h6
-rw-r--r--src/objc/utils/NSData+MCO.mm2
-rw-r--r--src/objc/utils/NSDictionary+MCO.h23
-rw-r--r--src/objc/utils/NSDictionary+MCO.mm27
-rw-r--r--src/objc/utils/NSObject+MCO.h23
-rw-r--r--src/objc/utils/NSObject+MCO.mm42
-rw-r--r--src/objc/utils/NSString+MCO.h7
-rw-r--r--src/objc/utils/NSString+MCO.mm2
71 files changed, 1739 insertions, 231 deletions
diff --git a/src/core/MCCore.h b/src/core/MCCore.h
index d5d6f79d..a909e677 100644
--- a/src/core/MCCore.h
+++ b/src/core/MCCore.h
@@ -15,6 +15,6 @@
#include <mailcore/MCPOP.h>
#include <mailcore/MCRFC822.h>
#include <mailcore/MCSMTP.h>
-#include <mailcore/MCAsyncIMAP.h>
+#include <mailcore/MCRenderer.h>
#endif
diff --git a/src/core/abstract/MCAbstractMessage.cc b/src/core/abstract/MCAbstractMessage.cc
index 00a4b9b9..b7d9b9af 100644
--- a/src/core/abstract/MCAbstractMessage.cc
+++ b/src/core/abstract/MCAbstractMessage.cc
@@ -39,13 +39,6 @@ String * AbstractMessage::description()
}
}
-#if 0
-String * AbstractMessage::className()
-{
- return MCSTR("MessageHeader");
-}
-#endif
-
Object * AbstractMessage::copy()
{
return new AbstractMessage(this);
@@ -63,3 +56,15 @@ void AbstractMessage::setHeader(MessageHeader * header)
{
MC_SAFE_REPLACE_RETAIN(MessageHeader, mHeader, header);
}
+
+AbstractPart * AbstractMessage::partForContentID(String * contentID)
+{
+ MCAssert(0);
+ return NULL;
+}
+
+AbstractPart * AbstractMessage::partForUniqueID(String * uniqueID)
+{
+ MCAssert(0);
+ return NULL;
+}
diff --git a/src/core/abstract/MCAbstractMessage.h b/src/core/abstract/MCAbstractMessage.h
index 9f327cad..9dccdbb8 100644
--- a/src/core/abstract/MCAbstractMessage.h
+++ b/src/core/abstract/MCAbstractMessage.h
@@ -7,6 +7,7 @@
namespace mailcore {
+ class AbstractPart;
class MessageHeader;
class AbstractMessage : public Object {
@@ -17,6 +18,9 @@ namespace mailcore {
virtual MessageHeader * header();
virtual void setHeader(MessageHeader * header);
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
+
public: //subclass behavior
AbstractMessage(AbstractMessage * other);
virtual String * description();
diff --git a/src/core/abstract/MCAbstractMessagePart.cc b/src/core/abstract/MCAbstractMessagePart.cc
index 6939d060..a52d2196 100644
--- a/src/core/abstract/MCAbstractMessagePart.cc
+++ b/src/core/abstract/MCAbstractMessagePart.cc
@@ -37,13 +37,6 @@ String * AbstractMessagePart::description()
return result;
}
-#if 0
-String * AbstractMessagePart::className()
-{
- return MCSTR("AbstractMessagePart");
-}
-#endif
-
Object * AbstractMessagePart::copy()
{
return new AbstractMessagePart(this);
@@ -86,3 +79,13 @@ void AbstractMessagePart::setMessage(AbstractMessage * message)
AbstractPart::setMessage(message);
applyMessage();
}
+
+AbstractPart * AbstractMessagePart::partForContentID(String * contentID)
+{
+ return mainPart()->partForContentID(contentID);
+}
+
+AbstractPart * AbstractMessagePart::partForUniqueID(String * contentID)
+{
+ return mainPart()->partForContentID(contentID);
+}
diff --git a/src/core/abstract/MCAbstractMessagePart.h b/src/core/abstract/MCAbstractMessagePart.h
index bfbd00be..789f7676 100644
--- a/src/core/abstract/MCAbstractMessagePart.h
+++ b/src/core/abstract/MCAbstractMessagePart.h
@@ -24,6 +24,9 @@ namespace mailcore {
virtual void setMessage(AbstractMessage * message);
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
+
public: //subclass behavior
AbstractMessagePart(AbstractMessagePart * other);
virtual String * description();
diff --git a/src/core/abstract/MCAbstractMultipart.cc b/src/core/abstract/MCAbstractMultipart.cc
index fa48d959..2604bcac 100644
--- a/src/core/abstract/MCAbstractMultipart.cc
+++ b/src/core/abstract/MCAbstractMultipart.cc
@@ -65,13 +65,6 @@ String * AbstractMultipart::description()
return result;
}
-#if 0
-String * AbstractMultipart::className()
-{
- return MCSTR("AbstractMultipart");
-}
-#endif
-
Object * AbstractMultipart::copy()
{
return new AbstractMultipart(this);
@@ -93,3 +86,27 @@ void AbstractMultipart::setMessage(AbstractMessage * message)
AbstractPart::setMessage(message);
applyMessage();
}
+
+AbstractPart * AbstractMultipart::partForContentID(String * contentID)
+{
+ for(unsigned int i = 0 ; i < parts()->count() ; i ++) {
+ mailcore::AbstractPart * subpart = (mailcore::AbstractPart *) parts()->objectAtIndex(i);
+ mailcore::AbstractPart * result = subpart->partForContentID(contentID);
+ if (result != NULL)
+ return result;
+ }
+ return NULL;
+}
+
+
+AbstractPart * AbstractMultipart::partForUniqueID(String * uniqueID)
+{
+ for(unsigned int i = 0 ; i < parts()->count() ; i ++) {
+ mailcore::AbstractPart * subpart = (mailcore::AbstractPart *) parts()->objectAtIndex(i);
+ mailcore::AbstractPart * result = subpart->partForUniqueID(uniqueID);
+ if (result != NULL)
+ return result;
+ }
+ return NULL;
+}
+
diff --git a/src/core/abstract/MCAbstractMultipart.h b/src/core/abstract/MCAbstractMultipart.h
index 411e8af0..d5d5f343 100644
--- a/src/core/abstract/MCAbstractMultipart.h
+++ b/src/core/abstract/MCAbstractMultipart.h
@@ -19,6 +19,9 @@ namespace mailcore {
virtual void setMessage(AbstractMessage * message);
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
+
public: //subclass behavior
AbstractMultipart(AbstractMultipart * other);
virtual String * description();
diff --git a/src/core/abstract/MCAbstractPart.cc b/src/core/abstract/MCAbstractPart.cc
index 30c4c8f0..78e2e365 100644
--- a/src/core/abstract/MCAbstractPart.cc
+++ b/src/core/abstract/MCAbstractPart.cc
@@ -13,6 +13,7 @@ AbstractPart::AbstractPart()
AbstractPart::AbstractPart(AbstractPart * other)
{
init();
+ setUniqueID(other->mUniqueID);
setFilename(other->mFilename);
setMimeType(other->mMimeType);
setCharset(other->mCharset);
@@ -24,6 +25,7 @@ AbstractPart::AbstractPart(AbstractPart * other)
void AbstractPart::init()
{
+ mUniqueID = NULL;
mFilename = NULL;
mMimeType = NULL;
mCharset = NULL;
@@ -35,6 +37,7 @@ void AbstractPart::init()
AbstractPart::~AbstractPart()
{
+ MC_SAFE_RELEASE(mUniqueID);
MC_SAFE_RELEASE(mFilename);
MC_SAFE_RELEASE(mMimeType);
MC_SAFE_RELEASE(mCharset);
@@ -67,13 +70,6 @@ String * AbstractPart::description()
return result;
}
-#if 0
-String * AbstractPart::className()
-{
- return MCSTR("AbstractPart");
-}
-#endif
-
Object * AbstractPart::copy()
{
return new AbstractPart(this);
@@ -89,6 +85,16 @@ void AbstractPart::setPartType(PartType type)
mPartType = type;
}
+String * AbstractPart::uniqueID()
+{
+ return mUniqueID;
+}
+
+void AbstractPart::setUniqueID(String * uniqueID)
+{
+ MC_SAFE_REPLACE_COPY(String, mUniqueID, uniqueID);
+}
+
String * AbstractPart::filename()
{
return mFilename;
@@ -221,3 +227,24 @@ void AbstractPart::importIMAPFields(struct mailimap_body_fields * fields,
}
}
}
+
+AbstractPart * AbstractPart::partForContentID(String * contentID)
+{
+ if (contentID->isEqual(mContentID)) {
+ return this;
+ }
+ else {
+ return NULL;
+ }
+}
+
+AbstractPart * AbstractPart::partForUniqueID(String * uniqueID)
+{
+ if (uniqueID->isEqual(mUniqueID)) {
+ return this;
+ }
+ else {
+ return NULL;
+ }
+}
+
diff --git a/src/core/abstract/MCAbstractPart.h b/src/core/abstract/MCAbstractPart.h
index f7b29ced..49360089 100644
--- a/src/core/abstract/MCAbstractPart.h
+++ b/src/core/abstract/MCAbstractPart.h
@@ -28,6 +28,9 @@ namespace mailcore {
virtual String * charset();
virtual void setCharset(String * charset);
+ virtual String * uniqueID();
+ virtual void setUniqueID(String * uniqueID);
+
virtual String * contentID();
virtual void setContentID(String * contentID);
@@ -40,15 +43,21 @@ namespace mailcore {
virtual AbstractMessage * message();
virtual void setMessage(AbstractMessage * message);
- virtual void importIMAPFields(struct mailimap_body_fields * fields,
- struct mailimap_body_ext_1part * extension);
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
public: // subclass behavior
AbstractPart(AbstractPart * other);
virtual String * description();
virtual Object * copy();
+ public: // private
+ virtual void importIMAPFields(struct mailimap_body_fields * fields,
+ struct mailimap_body_ext_1part * extension);
+
+
private:
+ String * mUniqueID;
String * mFilename;
String * mMimeType;
String * mCharset;
diff --git a/src/core/abstract/MCAddress.cc b/src/core/abstract/MCAddress.cc
index 25bed974..2ef1cd2b 100644
--- a/src/core/abstract/MCAddress.cc
+++ b/src/core/abstract/MCAddress.cc
@@ -177,13 +177,6 @@ String * Address::description()
return result;
}
-#if 0
-String * Address::className()
-{
- return MCSTR("Address");
-}
-#endif
-
bool Address::isEqual(Object * otherObject)
{
Address * otherAddress = (Address *) otherObject;
diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc
index 765bc085..b0574293 100644
--- a/src/core/abstract/MCMessageHeader.cc
+++ b/src/core/abstract/MCMessageHeader.cc
@@ -154,13 +154,6 @@ String * MessageHeader::description()
return result;
}
-#if 0
-String * MessageHeader::className()
-{
- return MCSTR("MessageHeader");
-}
-#endif
-
Object * MessageHeader::copy()
{
return new MessageHeader(this);
diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc
index 212aa4ed..d457ece5 100644
--- a/src/core/basetypes/MCArray.cc
+++ b/src/core/basetypes/MCArray.cc
@@ -48,13 +48,6 @@ Array * Array::arrayWithObject(Object * obj)
return (Array *) result->autorelease();
}
-#if 0
-String * Array::className()
-{
- return MCSTR("Array");
-}
-#endif
-
String * Array::description()
{
String * result = String::string();
diff --git a/src/core/basetypes/MCData.cc b/src/core/basetypes/MCData.cc
index c0f7d908..f98f57c7 100644
--- a/src/core/basetypes/MCData.cc
+++ b/src/core/basetypes/MCData.cc
@@ -110,13 +110,6 @@ void Data::setData(Data * otherData)
appendData(otherData);
}
-#if 0
-String * Data::className()
-{
- return MCSTR("Data");
-}
-#endif
-
String * Data::description()
{
return String::stringWithUTF8Format("<%s:%p %i bytes>", MCUTF8(className()), this, length());
diff --git a/src/core/basetypes/MCHashMap.cc b/src/core/basetypes/MCHashMap.cc
index 8dcf0f30..164198f5 100644
--- a/src/core/basetypes/MCHashMap.cc
+++ b/src/core/basetypes/MCHashMap.cc
@@ -93,13 +93,6 @@ HashMap * HashMap::hashMap()
return (HashMap *) result->autorelease();
}
-#if 0
-String * HashMap::className()
-{
- return MCSTR("HashMap");
-}
-#endif
-
String * HashMap::description()
{
String * result = String::string();
diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc
index 220a5a16..1665e1ee 100644
--- a/src/core/basetypes/MCObject.cc
+++ b/src/core/basetypes/MCObject.cc
@@ -11,9 +11,12 @@
#include "MCUtils.h"
#include "MCAssert.h"
#include "MCMainThread.h"
+#include "MCLog.h"
using namespace mailcore;
+bool mailcore::zombieEnabled = 0;
+
Object::Object()
{
init();
@@ -55,9 +58,13 @@ void Object::release()
if (mCounter == 0) {
shouldRelease = true;
}
+ if (mCounter < 0) {
+ MCLog("release too much %p %s", this, MCUTF8(className()));
+ MCAssert(0);
+ }
pthread_mutex_unlock(&mLock);
- if (shouldRelease) {
+ if (shouldRelease && !zombieEnabled) {
//MCLog("dealloc %s", className()->description()->UTF8Characters());
delete this;
}
@@ -73,17 +80,9 @@ String * Object::className()
{
int status;
char * unmangled = abi::__cxa_demangle(typeid(* this).name(), NULL, NULL, &status);
- //return mailcore::String::uniquedStringWithUTF8Characters(typeid(* this).name());
return mailcore::String::uniquedStringWithUTF8Characters(unmangled);
}
-/*
-String * Object::className()
-{
- return MCSTR("Object");
-}
-*/
-
String * Object::description()
{
return String::stringWithUTF8Format("<%s:%p>", className()->UTF8Characters(), this);
diff --git a/src/core/basetypes/MCObject.h b/src/core/basetypes/MCObject.h
index beda7471..caeded70 100644
--- a/src/core/basetypes/MCObject.h
+++ b/src/core/basetypes/MCObject.h
@@ -8,6 +8,8 @@
namespace mailcore {
+ extern bool zombieEnabled;
+
class String;
class Object {
diff --git a/src/core/basetypes/MCSet.cc b/src/core/basetypes/MCSet.cc
index fcda7f62..d3d14dc8 100644
--- a/src/core/basetypes/MCSet.cc
+++ b/src/core/basetypes/MCSet.cc
@@ -42,13 +42,6 @@ Set * Set::setWithArray(Array * objects)
return (Set *) result->autorelease();
}
-#if 0
-String * Set::className()
-{
- return MCSTR("Set");
-}
-#endif
-
String * Set::description()
{
String * result = String::string();
diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc
index a5607475..d57e70ed 100644
--- a/src/core/basetypes/MCString.cc
+++ b/src/core/basetypes/MCString.cc
@@ -953,13 +953,6 @@ void String::setCharacters(const UChar * unicodeCharacters)
appendCharacters(unicodeCharacters);
}
-#if 0
-String * String::className()
-{
- return MCSTR("String");
-}
-#endif
-
String * String::description()
{
return this;
@@ -1206,7 +1199,7 @@ unsigned int String::replaceOccurrencesOfString(String * occurrence, String * re
int delta = replacement->length() - occurrence->length();
int modifiedLength = mLength + delta * count + 1;
unicodeChars = (UChar *) malloc(modifiedLength * sizeof(* unicodeChars));
- unicodeChars[modifiedLength] = 0;
+ unicodeChars[modifiedLength - 1] = 0;
UChar * dest_p = unicodeChars;
p = mUnicodeChars;
while (1) {
@@ -1729,7 +1722,9 @@ String * String::flattenHTMLAndShowBlockquoteAndLink(bool showBlockquote, bool s
state.linkStack = new Array();
state.paragraphSpacingStack = new Array();
- htmlSAXParseDoc((xmlChar*) UTF8Characters(), "utf-8", &handler, &state);
+ const char * characters = cleanedHTMLString()->UTF8Characters();
+
+ htmlSAXParseDoc((xmlChar*) characters, "utf-8", &handler, &state);
if (mem_base != xmlMemBlocks()) {
MCLog("Leak of %d blocks found in htmlSAXParseDoc",
@@ -1979,8 +1974,7 @@ String * String::uniquedStringWithUTF8Characters(const char * UTF8Characters)
String * String::htmlEncodedString()
{
- String * htmlStr;
- htmlStr = String::string();
+ String * htmlStr = String::string();
#define kBufSz 2000
const char * inStr = UTF8Characters();
@@ -2019,3 +2013,9 @@ String * String::cleanedHTMLString()
#warning implement HTML cleaning with tidy
return (String *) copy()->autorelease();
}
+
+bool String::isEqualCaseInsensitive(String * otherString)
+{
+ return caseInsensitiveCompare(otherString) == 0;
+}
+
diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h
index 97db50da..521291d3 100644
--- a/src/core/basetypes/MCString.h
+++ b/src/core/basetypes/MCString.h
@@ -61,6 +61,8 @@ namespace mailcore {
virtual Array * componentsSeparatedByString(String * separator);
+ virtual bool isEqualCaseInsensitive(String * otherString);
+
// Additions
static String * stringByDecodingMIMEHeaderValue(const char * phrase);
virtual Data * encodedAddressDisplayNameValue();
diff --git a/src/core/basetypes/MCUtils.h b/src/core/basetypes/MCUtils.h
index 9e3de1ac..30b0cefd 100644
--- a/src/core/basetypes/MCUtils.h
+++ b/src/core/basetypes/MCUtils.h
@@ -33,6 +33,8 @@
#define MMCUTF8(str) MCUTF8(str)
#define MCUTF8DESC(obj) ((obj) != NULL ? (obj)->description()->UTF8Characters() : NULL )
+#define MCLOCALIZEDSTRING(key) key
+
#endif
#endif
diff --git a/src/core/basetypes/MCValue.cc b/src/core/basetypes/MCValue.cc
index d275d3df..b450e3e3 100644
--- a/src/core/basetypes/MCValue.cc
+++ b/src/core/basetypes/MCValue.cc
@@ -94,13 +94,6 @@ String * Value::description()
}
}
-#if 0
-String * Value::className()
-{
- return MCSTR("Value");
-}
-#endif
-
bool Value::isEqual(Object * otherObject)
{
Value * otherValue = (Value *) otherObject;
diff --git a/src/core/imap/MCIMAPFolder.cc b/src/core/imap/MCIMAPFolder.cc
index 0f1b2105..e8f31959 100644
--- a/src/core/imap/MCIMAPFolder.cc
+++ b/src/core/imap/MCIMAPFolder.cc
@@ -27,13 +27,6 @@ IMAPFolder::~IMAPFolder()
MC_SAFE_RELEASE(mPath);
}
-#if 0
-String * IMAPFolder::className()
-{
- return MCSTR("IMAPFolder");
-}
-#endif
-
Object * IMAPFolder::copy()
{
return new IMAPFolder(this);
diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc
index faf91c66..7f5f4427 100644
--- a/src/core/imap/MCIMAPMessage.cc
+++ b/src/core/imap/MCIMAPMessage.cc
@@ -1,9 +1,17 @@
#include "MCIMAPMessage.h"
#include "MCMessageHeader.h"
+#include "MCIMAPPart.h"
+#include "MCIMAPMessagePart.h"
+#include "MCIMAPMultipart.h"
+#include "MCHTMLRenderer.h"
using namespace mailcore;
+static AbstractPart * partForPartIDInPart(AbstractPart * part, String * partID);
+static AbstractPart * partForPartIDInMultipart(AbstractMultipart * part, String * partID);
+static AbstractPart * partForPartIDInMessagePart(AbstractMessagePart * part, String * partID);
+
void IMAPMessage::init()
{
mUid = NULL;
@@ -34,13 +42,6 @@ IMAPMessage::~IMAPMessage()
MC_SAFE_RELEASE(mLabels);
}
-#if 0
-String * IMAPMessage::className()
-{
- return MCSTR("IMAPMessage");
-}
-#endif
-
Object * IMAPMessage::copy()
{
return new IMAPMessage(this);
@@ -109,3 +110,66 @@ Array * IMAPMessage::gmailLabels()
return mLabels;
}
+AbstractPart * IMAPMessage::partForPartID(String * partID)
+{
+ return partForPartIDInPart(mainPart(), partID);
+}
+
+static AbstractPart * partForPartIDInPart(AbstractPart * part, String * partID)
+{
+ switch (part->partType()) {
+ case PartTypeSingle:
+ if (partID->isEqual(((IMAPPart *) part)->partID())) {
+ return part;
+ }
+ return NULL;
+ case mailcore::PartTypeMultipartMixed:
+ case mailcore::PartTypeMultipartRelated:
+ case mailcore::PartTypeMultipartAlternative:
+ if (partID->isEqual(((IMAPMultipart *) part)->partID())) {
+ return part;
+ }
+ return partForPartIDInMultipart((AbstractMultipart *) part, partID);
+ case mailcore::PartTypeMessage:
+ if (partID->isEqual(((IMAPMessagePart *) part)->partID())) {
+ return part;
+ }
+ return partForPartIDInMessagePart((AbstractMessagePart *) part, partID);
+ default:
+ return NULL;
+ }
+}
+
+static AbstractPart * partForPartIDInMessagePart(AbstractMessagePart * part, String * partID)
+{
+ return partForPartIDInPart(part->mainPart(), partID);
+}
+
+static AbstractPart * partForPartIDInMultipart(AbstractMultipart * part, String * partID)
+{
+ for(unsigned int i = 0 ; i < part->parts()->count() ; i ++) {
+ mailcore::AbstractPart * subpart = (mailcore::AbstractPart *) part->parts()->objectAtIndex(i);
+ mailcore::AbstractPart * result = partForPartIDInPart(subpart, partID);
+ if (result != NULL)
+ return result;
+ }
+ return NULL;
+}
+
+AbstractPart * IMAPMessage::partForContentID(String * contentID)
+{
+ return mainPart()->partForContentID(contentID);
+}
+
+AbstractPart * IMAPMessage::partForUniqueID(String * uniqueID)
+{
+ return mainPart()->partForUniqueID(uniqueID);
+}
+
+String * IMAPMessage::htmlRendering(String * folder,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback)
+{
+ return HTMLRenderer::htmlForIMAPMessage(folder, this, dataCallback, htmlCallback);
+}
+
diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h
index 692ddc49..b1fd4647 100644
--- a/src/core/imap/MCIMAPMessage.h
+++ b/src/core/imap/MCIMAPMessage.h
@@ -11,6 +11,10 @@
namespace mailcore {
+ class IMAPPart;
+ class HTMLRendererIMAPCallback;
+ class HTMLRendererTemplateCallback;
+
class IMAPMessage : public AbstractMessage {
public:
IMAPMessage();
@@ -31,6 +35,15 @@ namespace mailcore {
virtual void setGmailLabels(Array * labels);
virtual Array * gmailLabels();
+ virtual AbstractPart * partForPartID(String * partID);
+
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
+
+ virtual String * htmlRendering(String * folder,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback = NULL);
+
public: // subclass behavior
IMAPMessage(IMAPMessage * other);
virtual Object * copy();
diff --git a/src/core/imap/MCIMAPMessagePart.cc b/src/core/imap/MCIMAPMessagePart.cc
index 31a6f7e5..bd97657c 100644
--- a/src/core/imap/MCIMAPMessagePart.cc
+++ b/src/core/imap/MCIMAPMessagePart.cc
@@ -4,24 +4,36 @@ using namespace mailcore;
IMAPMessagePart::IMAPMessagePart()
{
+ init();
}
IMAPMessagePart::IMAPMessagePart(IMAPMessagePart * other) : AbstractMessagePart(other)
{
+ init();
+ MC_SAFE_REPLACE_COPY(String, mPartID, other->mPartID);
}
IMAPMessagePart::~IMAPMessagePart()
{
+ MC_SAFE_RELEASE(mPartID);
}
-#if 0
-String * IMAPMessagePart::className()
+Object * IMAPMessagePart::copy()
{
- return MCSTR("IMAPMessagePart");
+ return new IMAPMessagePart(this);
}
-#endif
-Object * IMAPMessagePart::copy()
+void IMAPMessagePart::init()
{
- return new IMAPMessagePart(this);
+ mPartID = NULL;
+}
+
+void IMAPMessagePart::setPartID(String * partID)
+{
+ MC_SAFE_REPLACE_COPY(String, mPartID, partID);
+}
+
+String * IMAPMessagePart::partID()
+{
+ return mPartID;
}
diff --git a/src/core/imap/MCIMAPMessagePart.h b/src/core/imap/MCIMAPMessagePart.h
index 03747ac0..8e23eff2 100644
--- a/src/core/imap/MCIMAPMessagePart.h
+++ b/src/core/imap/MCIMAPMessagePart.h
@@ -13,9 +13,16 @@ namespace mailcore {
IMAPMessagePart();
virtual ~IMAPMessagePart();
+ virtual void setPartID(String * partID);
+ virtual String * partID();
+
public: // subclass behavior
IMAPMessagePart(IMAPMessagePart * other);
virtual Object * copy();
+
+ private:
+ String * mPartID;
+ void init();
};
}
diff --git a/src/core/imap/MCIMAPMultipart.cc b/src/core/imap/MCIMAPMultipart.cc
index a941cbc4..be0b2c8e 100644
--- a/src/core/imap/MCIMAPMultipart.cc
+++ b/src/core/imap/MCIMAPMultipart.cc
@@ -4,25 +4,36 @@ using namespace mailcore;
IMAPMultipart::IMAPMultipart()
{
+ init();
}
IMAPMultipart::IMAPMultipart(IMAPMultipart * other) : AbstractMultipart(other)
{
+ init();
+ MC_SAFE_REPLACE_COPY(String, mPartID, other->mPartID);
}
IMAPMultipart::~IMAPMultipart()
{
+ MC_SAFE_RELEASE(mPartID);
}
-#if 0
-String * IMAPMultipart::className()
+Object * IMAPMultipart::copy()
{
- return MCSTR("IMAPMultipart");
+ return new IMAPMultipart(this);
}
-#endif
-Object * IMAPMultipart::copy()
+void IMAPMultipart::init()
{
- return new IMAPMultipart(this);
+ mPartID = NULL;
}
+void IMAPMultipart::setPartID(String * partID)
+{
+ MC_SAFE_REPLACE_COPY(String, mPartID, partID);
+}
+
+String * IMAPMultipart::partID()
+{
+ return mPartID;
+}
diff --git a/src/core/imap/MCIMAPMultipart.h b/src/core/imap/MCIMAPMultipart.h
index 9a768d0a..02ee5cf8 100644
--- a/src/core/imap/MCIMAPMultipart.h
+++ b/src/core/imap/MCIMAPMultipart.h
@@ -13,9 +13,16 @@ namespace mailcore {
IMAPMultipart();
virtual ~IMAPMultipart();
+ virtual void setPartID(String * partID);
+ virtual String * partID();
+
public: // subclass behavior
IMAPMultipart(IMAPMultipart * other);
virtual Object * copy();
+
+ private:
+ String * mPartID;
+ void init();
};
}
diff --git a/src/core/imap/MCIMAPNamespace.cc b/src/core/imap/MCIMAPNamespace.cc
index b18752e4..c1c430fa 100644
--- a/src/core/imap/MCIMAPNamespace.cc
+++ b/src/core/imap/MCIMAPNamespace.cc
@@ -26,13 +26,6 @@ IMAPNamespace::~IMAPNamespace()
MC_SAFE_RELEASE(mItems);
}
-#if 0
-String * IMAPNamespace::className()
-{
- return MCSTR("IMAPNamespace");
-}
-#endif
-
String * IMAPNamespace::description()
{
String * result = String::string();
diff --git a/src/core/imap/MCIMAPNamespaceItem.cc b/src/core/imap/MCIMAPNamespaceItem.cc
index 62fca1f0..7a608d68 100644
--- a/src/core/imap/MCIMAPNamespaceItem.cc
+++ b/src/core/imap/MCIMAPNamespaceItem.cc
@@ -28,13 +28,6 @@ IMAPNamespaceItem::~IMAPNamespaceItem()
MC_SAFE_RELEASE(mPrefix);
}
-#if 0
-String * IMAPNamespaceItem::className()
-{
- return MCSTR("IMAPNamespaceItem");
-}
-#endif
-
String * IMAPNamespaceItem::description()
{
return String::stringWithUTF8Format("<%s:%p %s %c>",
diff --git a/src/core/imap/MCIMAPPart.cc b/src/core/imap/MCIMAPPart.cc
index 8f7e1e0e..dc1a687f 100644
--- a/src/core/imap/MCIMAPPart.cc
+++ b/src/core/imap/MCIMAPPart.cc
@@ -33,13 +33,6 @@ IMAPPart::~IMAPPart()
MC_SAFE_RELEASE(mPartID);
}
-#if 0
-String * IMAPPart::className()
-{
- return MCSTR("IMAPPart");
-}
-#endif
-
Object * IMAPPart::copy()
{
return new IMAPPart(this);
@@ -161,6 +154,7 @@ IMAPMessagePart * IMAPPart::attachmentWithIMAPBody1PartMessage(struct mailimap_b
}
attachment = new IMAPMessagePart();
+ attachment->setPartID(partID);
attachment->header()->importIMAPEnvelope(message->bd_envelope);
attachment->importIMAPFields(message->bd_fields, extension);
@@ -203,7 +197,8 @@ IMAPPart * IMAPPart::attachmentWithIMAPBody1PartBasic(struct mailimap_body_type_
attachment = new IMAPPart();
attachment->importIMAPFields(basic->bd_fields, extension);
-
+ attachment->setUniqueID(mailcore::String::uuidString());
+
mimeType = NULL;
switch (basic->bd_media_basic->med_type) {
case MAILIMAP_MEDIA_BASIC_APPLICATION:
@@ -236,6 +231,7 @@ IMAPPart * IMAPPart::attachmentWithIMAPBody1PartText(struct mailimap_body_type_t
IMAPPart * attachment;
attachment = new IMAPPart();
+ attachment->setUniqueID(mailcore::String::uuidString());
attachment->importIMAPFields(text->bd_fields, extension);
attachment->setMimeType(String::stringWithUTF8Format("text/%s", text->bd_media_text));
@@ -272,6 +268,7 @@ IMAPMultipart * IMAPPart::attachmentWithIMAPBodyMultipart(struct mailimap_body_t
}
attachment = new IMAPMultipart();
+ attachment->setPartID(partID);
if (strcasecmp(body_mpart->bd_media_subtype, "alternative") == 0) {
attachment->setPartType(PartTypeMultipartAlternative);
}
diff --git a/src/core/imap/MCIMAPPart.h b/src/core/imap/MCIMAPPart.h
index 2749a0a0..44d03b2f 100644
--- a/src/core/imap/MCIMAPPart.h
+++ b/src/core/imap/MCIMAPPart.h
@@ -24,20 +24,21 @@ namespace mailcore {
virtual void setSize(unsigned int size);
virtual unsigned int size();
+ virtual unsigned int decodedSize();
+
virtual void setEncoding(Encoding encoding);
virtual Encoding encoding();
- unsigned int decodedSize();
-
- static AbstractPart * attachmentWithIMAPBody(struct mailimap_body * body);
-
- virtual void importIMAPFields(struct mailimap_body_fields * fields,
- struct mailimap_body_ext_1part * extension);
-
public: // subclass behavior
IMAPPart(IMAPPart * other);
virtual Object * copy();
+ public: // private
+ static AbstractPart * attachmentWithIMAPBody(struct mailimap_body * body);
+
+ virtual void importIMAPFields(struct mailimap_body_fields * fields,
+ struct mailimap_body_ext_1part * extension);
+
private:
String * mPartID;
Encoding mEncoding;
diff --git a/src/core/imap/MCIMAPSearchExpression.cc b/src/core/imap/MCIMAPSearchExpression.cc
index 14875c43..55b0fc7f 100644
--- a/src/core/imap/MCIMAPSearchExpression.cc
+++ b/src/core/imap/MCIMAPSearchExpression.cc
@@ -64,13 +64,6 @@ String * IMAPSearchExpression::description()
}
}
-#if 0
-String * IMAPSearchExpression::className()
-{
- return MCSTR("IMAPSearchExpression");
-}
-#endif
-
Object * IMAPSearchExpression::copy()
{
return new IMAPSearchExpression(this);
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index dd0b6c6c..f79ebc44 100644
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -316,13 +316,6 @@ IMAPSession::~IMAPSession()
pthread_mutex_destroy(&mIdleLock);
}
-#if 0
-String * IMAPSession::className()
-{
- return MCSTR("IMAPSession");
-}
-#endif
-
void IMAPSession::setHostname(String * hostname)
{
MC_SAFE_REPLACE_COPY(String, mHostname, hostname);
diff --git a/src/core/pop/MCPOPMessageInfo.cc b/src/core/pop/MCPOPMessageInfo.cc
index eafbda9f..a1b1dcfe 100644
--- a/src/core/pop/MCPOPMessageInfo.cc
+++ b/src/core/pop/MCPOPMessageInfo.cc
@@ -27,13 +27,6 @@ POPMessageInfo::~POPMessageInfo()
MC_SAFE_RELEASE(mUid);
}
-#if 0
-String * POPMessageInfo::className()
-{
- return MCSTR("POPMessageInfo");
-}
-#endif
-
String * POPMessageInfo::description()
{
return String::stringWithUTF8Format("<%s:%p %u %s %u>",
diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc
index 26a0c868..95880198 100644
--- a/src/core/pop/MCPOPSession.cc
+++ b/src/core/pop/MCPOPSession.cc
@@ -44,13 +44,6 @@ POPSession::~POPSession()
MC_SAFE_RELEASE(mPassword);
}
-#if 0
-String * POPSession::className()
-{
- return MCSTR("POPSession");
-}
-#endif
-
void POPSession::setHostname(String * hostname)
{
MC_SAFE_REPLACE_COPY(String, mHostname, hostname);
diff --git a/src/core/renderer/MCAddressDisplay.cpp b/src/core/renderer/MCAddressDisplay.cpp
new file mode 100644
index 00000000..842dd0df
--- /dev/null
+++ b/src/core/renderer/MCAddressDisplay.cpp
@@ -0,0 +1,94 @@
+//
+// MCAddressUI.cpp
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/27/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCAddressDisplay.h"
+
+using namespace mailcore;
+
+String * AddressDisplay::displayStringForAddress(Address * address)
+{
+ return address->nonEncodedRFC822String();
+}
+
+String * AddressDisplay::shortDisplayStringForAddress(Address * address)
+{
+ if ((address->displayName() != NULL) && (address->displayName()->length() > 0)) {
+ return address->displayName();
+ }
+ else if (address->mailbox()) {
+ return address->mailbox();
+ }
+ else {
+ return MCSTR("invalid");
+ }
+}
+
+String * AddressDisplay::veryShortDisplayStringForAddress(Address * address)
+{
+ if ((address->displayName() != NULL) && (address->displayName()->length() > 0)) {
+ Array * components;
+ String * senderName;
+
+ senderName = address->displayName();
+ senderName = (String *) senderName->copy()->autorelease();
+
+ senderName->replaceOccurrencesOfString(MCSTR(","), MCSTR(" "));
+ senderName->replaceOccurrencesOfString(MCSTR("'"), MCSTR(" "));
+ senderName->replaceOccurrencesOfString(MCSTR("\""), MCSTR(" "));
+ components = senderName->componentsSeparatedByString(MCSTR(" "));
+ if (components->count() == 0) {
+ return MCLOCALIZEDSTRING(MCSTR("invalid"));
+ }
+ return (String *) components->objectAtIndex(0);
+ }
+ else if (address->mailbox()) {
+ return address->mailbox();
+ }
+ else {
+ return MCLOCALIZEDSTRING(MCSTR("invalid"));
+ }
+}
+
+String * AddressDisplay::displayStringForAddresses(Array * addresses)
+{
+ String * result = String::string();
+ for(unsigned int i = 0 ; i < addresses->count() ; i ++) {
+ Address * address = (Address *) addresses->objectAtIndex(i);
+ if (i != 0) {
+ result->appendString(MCSTR(", "));
+ }
+ result->appendString(displayStringForAddress(address));
+ }
+ return result;
+}
+
+String * AddressDisplay::shortDisplayStringForAddresses(Array * addresses)
+{
+ String * result = String::string();
+ for(unsigned int i = 0 ; i < addresses->count() ; i ++) {
+ Address * address = (Address *) addresses->objectAtIndex(i);
+ if (i != 0) {
+ result->appendString(MCSTR(", "));
+ }
+ result->appendString(shortDisplayStringForAddress(address));
+ }
+ return result;
+}
+
+String * AddressDisplay::veryShortDisplayStringForAddresses(Array * addresses)
+{
+ String * result = String::string();
+ for(unsigned int i = 0 ; i < addresses->count() ; i ++) {
+ Address * address = (Address *) addresses->objectAtIndex(i);
+ if (i != 0) {
+ result->appendString(MCSTR(", "));
+ }
+ result->appendString(veryShortDisplayStringForAddress(address));
+ }
+ return result;
+}
diff --git a/src/core/renderer/MCAddressDisplay.h b/src/core/renderer/MCAddressDisplay.h
new file mode 100644
index 00000000..153ad245
--- /dev/null
+++ b/src/core/renderer/MCAddressDisplay.h
@@ -0,0 +1,34 @@
+//
+// MCAddressUI.h
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/27/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MCAddressDisplay__
+#define __MCAddressDisplay__
+
+#include <mailcore/MCAbstract.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class AddressDisplay {
+
+ public:
+ static String * displayStringForAddress(Address * address);
+ static String * shortDisplayStringForAddress(Address * address);
+ static String * veryShortDisplayStringForAddress(Address * address);
+
+ static String * displayStringForAddresses(Array * addresses);
+ static String * shortDisplayStringForAddresses(Array * addresses);
+ static String * veryShortDisplayStringForAddresses(Array * addresses);
+ };
+
+};
+
+#endif
+
+#endif /* defined(__MCAddressDisplay__) */
diff --git a/src/core/renderer/MCDateFormatter.cpp b/src/core/renderer/MCDateFormatter.cpp
new file mode 100644
index 00000000..0fa86699
--- /dev/null
+++ b/src/core/renderer/MCDateFormatter.cpp
@@ -0,0 +1,160 @@
+//
+// MCDateFormatter.cpp
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/28/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCDateFormatter.h"
+
+using namespace mailcore;
+
+DateFormatter::DateFormatter()
+{
+ mDateFormatter = NULL;
+ mDateStyle = DateFormatStyleMedium;
+ mTimeStyle = DateFormatStyleMedium;
+ mDateFormat = NULL;
+ mTimezone = NULL;
+ mLocale = NULL;
+}
+
+DateFormatter::~DateFormatter()
+{
+ if (mDateFormatter != NULL) {
+ udat_close(mDateFormatter);
+ }
+ MC_SAFE_RELEASE(mDateFormat);
+ MC_SAFE_RELEASE(mTimezone);
+ MC_SAFE_RELEASE(mLocale);
+}
+
+DateFormatter * DateFormatter::dateFormatter()
+{
+ DateFormatter * result = new DateFormatter();
+ result->autorelease();
+ return result;
+}
+
+
+void DateFormatter::setDateStyle(DateFormatStyle style)
+{
+ mDateStyle = style;
+}
+
+DateFormatStyle DateFormatter::dateStyle()
+{
+ return mDateStyle;
+}
+
+void DateFormatter::setTimeStyle(DateFormatStyle style)
+{
+ mTimeStyle = style;
+}
+
+DateFormatStyle DateFormatter::timeStyle()
+{
+ return mTimeStyle;
+}
+
+void DateFormatter::setLocale(String * locale)
+{
+ MC_SAFE_REPLACE_COPY(String, mLocale, locale);
+}
+
+String * DateFormatter::locale()
+{
+ return mLocale;
+}
+
+void DateFormatter::setTimezone(String * timezone)
+{
+ MC_SAFE_REPLACE_COPY(String, mTimezone, timezone);
+}
+
+String * DateFormatter::timezone()
+{
+ return mTimezone;
+}
+
+void DateFormatter::setDateFormat(String * dateFormat)
+{
+ MC_SAFE_REPLACE_COPY(String, mDateFormat, dateFormat);
+}
+
+String * DateFormatter::dateFormat()
+{
+ return mDateFormat;
+}
+
+String * DateFormatter::stringFromDate(time_t date)
+{
+ prepare();
+ if (mDateFormatter == NULL)
+ return NULL;
+
+ UErrorCode err = U_ZERO_ERROR;
+ int32_t len = udat_format(mDateFormatter, ((double) date) * 1000., NULL, 0, NULL, &err);
+ if(err != U_BUFFER_OVERFLOW_ERROR) {
+ return NULL;
+ }
+
+ String * result;
+
+ err = U_ZERO_ERROR;
+ UChar * unichars = (UChar *) malloc((len + 1) * sizeof(unichars));
+ udat_format(mDateFormatter, ((double) date) * 1000., unichars, len + 1, NULL, &err);
+ result = new String(unichars, len);
+ free(unichars);
+
+ result->autorelease();
+ return result;
+}
+
+time_t DateFormatter::dateFromString(String * dateString)
+{
+ prepare();
+ if (mDateFormatter == NULL)
+ return (time_t) -1;
+
+ UErrorCode err = U_ZERO_ERROR;
+ UDate date = udat_parse(mDateFormatter, dateString->unicodeCharacters(), dateString->length(),
+ NULL, &err);
+ if (err != U_ZERO_ERROR) {
+ return (time_t) -1;
+ }
+
+ return date / 1000.;
+}
+
+void DateFormatter::prepare()
+{
+ if (mDateFormatter != NULL)
+ return;
+
+ const UChar * tzID = NULL;
+ int32_t tzIDLength = -1;
+ const UChar * pattern = NULL;
+ int32_t patternLength = -1;
+ UErrorCode err = U_ZERO_ERROR;
+ const char * locale = NULL;
+
+ if (mTimezone != NULL) {
+ tzID = mTimezone->unicodeCharacters();
+ tzIDLength = mTimezone->length();
+ }
+ if (mDateFormat != NULL) {
+ pattern = mDateFormat->unicodeCharacters();
+ patternLength = mDateFormat->length();
+ }
+ if (mLocale != NULL) {
+ locale = mLocale->UTF8Characters();
+ }
+
+ mDateFormatter = udat_open((UDateFormatStyle) mTimeStyle, (UDateFormatStyle) mDateStyle,
+ locale,
+ tzID, tzIDLength,
+ pattern, patternLength,
+ &err);
+}
diff --git a/src/core/renderer/MCDateFormatter.h b/src/core/renderer/MCDateFormatter.h
new file mode 100644
index 00000000..6467aae6
--- /dev/null
+++ b/src/core/renderer/MCDateFormatter.h
@@ -0,0 +1,69 @@
+//
+// MCDateFormatter.h
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/28/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __testUI__MCDateFormatter__
+#define __testUI__MCDateFormatter__
+
+#include <mailcore/MCBaseTypes.h>
+#include <unicode/udat.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class String;
+
+ enum DateFormatStyle {
+ DateFormatStyleFull = UDAT_FULL,
+ DateFormatStyleLong = UDAT_LONG,
+ DateFormatStyleMedium = UDAT_MEDIUM,
+ DateFormatStyleShort = UDAT_SHORT,
+ DateFormatStyleNone = UDAT_NONE,
+ };
+
+ class DateFormatter : public Object {
+ public:
+ DateFormatter();
+ virtual ~DateFormatter();
+
+ static DateFormatter * dateFormatter();
+
+ virtual void setDateStyle(DateFormatStyle style);
+ virtual DateFormatStyle dateStyle();
+
+ virtual void setTimeStyle(DateFormatStyle style);
+ virtual DateFormatStyle timeStyle();
+
+ virtual void setLocale(String * locale);
+ virtual String * locale();
+
+ virtual void setTimezone(String * timezone);
+ virtual String * timezone();
+
+ virtual void setDateFormat(String * dateFormat);
+ virtual String * dateFormat();
+
+ virtual String * stringFromDate(time_t date);
+ virtual time_t dateFromString(String * dateString);
+
+ private:
+ UDateFormat * mDateFormatter;
+ DateFormatStyle mDateStyle;
+ DateFormatStyle mTimeStyle;
+ String * mDateFormat;
+ String * mTimezone;
+ String * mLocale;
+
+ void prepare();
+ };
+
+}
+
+#endif
+
+#endif /* defined(__testUI__MCDateFormatter__) */
diff --git a/src/core/renderer/MCHTMLRenderer.cpp b/src/core/renderer/MCHTMLRenderer.cpp
new file mode 100644
index 00000000..ba78656b
--- /dev/null
+++ b/src/core/renderer/MCHTMLRenderer.cpp
@@ -0,0 +1,448 @@
+//
+// MCHTMLRenderer.cpp
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/23/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCHTMLRenderer.h"
+
+#include <ctemplate/template.h>
+#include "MCAddressDisplay.h"
+#include "MCDateFormatter.h"
+#include "MCSizeFormatter.h"
+#include "MCHTMLRendererCallback.h"
+
+using namespace mailcore;
+
+enum {
+ RENDER_STATE_NONE,
+ RENDER_STATE_HAD_ATTACHMENT,
+ RENDER_STATE_HAD_ATTACHMENT_THEN_TEXT,
+};
+
+struct htmlRendererContext {
+ HTMLRendererIMAPCallback * dataCallback;
+ HTMLRendererTemplateCallback * htmlCallback;
+ int firstRendered;
+ String * folder;
+ int state;
+ int pass;
+ bool hasMixedTextAndAttachments;
+ bool firstAttachment;
+ bool hasTextPart;
+};
+
+class DefaultTemplateCallback : public Object, public HTMLRendererTemplateCallback {
+};
+
+static bool partContainsMimeType(AbstractPart * part, String * mimeType);
+static bool singlePartContainsMimeType(AbstractPart * part, String * mimeType);
+static bool multipartContainsMimeType(AbstractMultipart * part, String * mimeType);
+static bool messagePartContainsMimeType(AbstractMessagePart * part, String * mimeType);
+
+static String * htmlForAbstractPart(AbstractPart * part, htmlRendererContext * context);
+
+static String * renderTemplate(String * templateContent, HashMap * values);
+
+static String * htmlForAbstractMessage(String * folder, AbstractMessage * message,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback);
+
+static bool isTextPart(AbstractPart * part, htmlRendererContext * context)
+{
+ String * mimeType = part->mimeType()->lowercaseString();
+ MCAssert(mimeType != NULL);
+
+ if (!part->isInlineAttachment()) {
+ if ((part->filename() != NULL) && context->firstRendered) {
+ return false;
+ }
+ }
+
+ if (mimeType->isEqual(MCSTR("text/plain"))) {
+ return true;
+ }
+ else if (mimeType->isEqual(MCSTR("text/html"))) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+static AbstractPart * preferredPartInMultipartAlternative(AbstractMultipart * part)
+{
+ int htmlPart = -1;
+ int textPart = -1;
+
+ for(unsigned int i = 0 ; i < part->parts()->count() ; i ++) {
+ AbstractPart * subpart = (AbstractPart *) part->parts()->objectAtIndex(i);
+ if (partContainsMimeType(subpart, MCSTR("text/html"))) {
+ htmlPart = i;
+ }
+ else if (partContainsMimeType(subpart, MCSTR("text/plain"))) {
+ textPart = i;
+ }
+ }
+ if (htmlPart != -1) {
+ return (AbstractPart *) part->parts()->objectAtIndex(htmlPart);
+ }
+ else if (textPart != -1) {
+ return (AbstractPart *) part->parts()->objectAtIndex(textPart);
+ }
+ else if (part->parts()->count() > 0) {
+ return (AbstractPart *) part->parts()->objectAtIndex(0);
+ }
+ else {
+ return NULL;
+ }
+}
+
+static bool partContainsMimeType(AbstractPart * part, String * mimeType)
+{
+ switch (part->partType()) {
+ case PartTypeSingle:
+ return singlePartContainsMimeType(part, mimeType);
+ case PartTypeMessage:
+ return messagePartContainsMimeType((AbstractMessagePart *) part, mimeType);
+ case PartTypeMultipartMixed:
+ case PartTypeMultipartRelated:
+ case PartTypeMultipartAlternative:
+ return multipartContainsMimeType((AbstractMultipart *) part, mimeType);
+ default:
+ return false;
+ }
+}
+
+static bool singlePartContainsMimeType(AbstractPart * part, String * mimeType)
+{
+ return part->mimeType()->lowercaseString()->isEqual(mimeType);
+}
+
+static bool multipartContainsMimeType(AbstractMultipart * part, String * mimeType)
+{
+ for(unsigned int i = 0 ; i < part->parts()->count() ; i ++) {
+ AbstractPart * subpart = (AbstractPart *) part->parts()->objectAtIndex(i);
+ if (partContainsMimeType(subpart, mimeType)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool messagePartContainsMimeType(AbstractMessagePart * part, String * mimeType)
+{
+ return partContainsMimeType(part->mainPart(), mimeType);
+}
+
+static String * htmlForAbstractMessage(String * folder, AbstractMessage * message,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback)
+{
+ AbstractPart * mainPart = NULL;
+
+ if (htmlCallback == NULL) {
+ htmlCallback = new DefaultTemplateCallback();
+ ((DefaultTemplateCallback *) htmlCallback)->autorelease();
+ }
+
+ if (message->className()->isEqual(MCSTR("mailcore::IMAPMessage"))) {
+ mainPart = ((IMAPMessage *) message)->mainPart();
+ }
+ else if (message->className()->isEqual(MCSTR("mailcore::MessageParser"))) {
+ mainPart = ((MessageParser *) message)->mainPart();
+ }
+ MCAssert(mainPart != NULL);
+
+ htmlRendererContext context;
+ context.dataCallback = dataCallback;
+ context.htmlCallback = htmlCallback;
+ context.firstRendered = 0;
+ context.folder = folder;
+ context.state = RENDER_STATE_NONE;
+
+ context.hasMixedTextAndAttachments = false;
+ context.pass = 0;
+ context.firstAttachment = false;
+ context.hasTextPart = false;
+ htmlForAbstractPart(mainPart, &context);
+
+ context.hasMixedTextAndAttachments = (context.state == RENDER_STATE_HAD_ATTACHMENT_THEN_TEXT);
+ context.pass = 1;
+ context.firstAttachment = false;
+ context.hasTextPart = false;
+ String * content = htmlForAbstractPart(mainPart, &context);
+ if (content == NULL)
+ return NULL;
+
+ content = htmlCallback->filterHTMLForMessage(content);
+
+ HashMap * values = htmlCallback->templateValuesForHeader(message->header());
+ String * headerString = renderTemplate(htmlCallback->templateForMainHeader(), values);
+
+ HashMap * msgValues = new HashMap();
+ msgValues->setObjectForKey(MCSTR("HEADER"), headerString);
+ msgValues->setObjectForKey(MCSTR("BODY"), content);
+ String * result = renderTemplate(htmlCallback->templateForMessage(), msgValues);
+ msgValues->release();
+
+ return result;
+}
+
+String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererContext * context);
+String * htmlForAbstractMessagePart(AbstractMessagePart * part, htmlRendererContext * context);
+String * htmlForAbstractMultipartRelated(AbstractMultipart * part, htmlRendererContext * context);
+String * htmlForAbstractMultipartMixed(AbstractMultipart * part, htmlRendererContext * context);
+String * htmlForAbstractMultipartAlternative(AbstractMultipart * part, htmlRendererContext * context);
+
+String * htmlForAbstractPart(AbstractPart * part, htmlRendererContext * context)
+{
+ switch (part->partType()) {
+ case PartTypeSingle:
+ return htmlForAbstractSinglePart((AbstractPart *) part, context);
+ case PartTypeMessage:
+ return htmlForAbstractMessagePart((AbstractMessagePart *) part, context);
+ case PartTypeMultipartMixed:
+ return htmlForAbstractMultipartMixed((AbstractMultipart *) part, context);
+ case PartTypeMultipartRelated:
+ return htmlForAbstractMultipartRelated((AbstractMultipart *) part, context);
+ case PartTypeMultipartAlternative:
+ return htmlForAbstractMultipartAlternative((AbstractMultipart *) part, context);
+ default:
+ MCAssert(0);
+ }
+ return NULL;
+}
+
+String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererContext * context)
+{
+ String * mimeType = part->mimeType()->lowercaseString();
+ MCAssert(mimeType != NULL);
+
+ if (isTextPart(part, context)) {
+ if (context->pass == 0) {
+ if (context->state == RENDER_STATE_HAD_ATTACHMENT) {
+ context->state = RENDER_STATE_HAD_ATTACHMENT_THEN_TEXT;
+ }
+ return NULL;
+ }
+
+ context->hasTextPart = true;
+
+ if (mimeType->isEqual(MCSTR("text/plain"))) {
+ String * charset = part->charset();
+ Data * data = NULL;
+ if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) {
+ data = context->dataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part);
+ }
+ else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) {
+ data = ((Attachment *) part)->data();
+ MCAssert(data != NULL);
+ }
+ if (data == NULL)
+ return NULL;
+
+ String * str = data->stringWithDetectedCharset(charset, false);
+ context->firstRendered = true;
+ return str->htmlEncodedString();
+ }
+ else if (mimeType->isEqual(MCSTR("text/html"))) {
+ String * charset = part->charset();
+ Data * data = NULL;
+ if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) {
+ data = context->dataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part);
+ }
+ else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) {
+ data = ((Attachment *) part)->data();
+ MCAssert(data != NULL);
+ }
+ if (data == NULL)
+ return NULL;
+
+ String * str = data->stringWithDetectedCharset(charset, true);
+ str = str->cleanedHTMLString();
+ str = context->htmlCallback->filterHTMLForPart(str);
+ context->firstRendered = true;
+ return str;
+ }
+ else {
+ MCAssert(0);
+ return NULL;
+ }
+ }
+ else {
+ if (context->pass == 0) {
+ if (context->state == RENDER_STATE_NONE) {
+ context->state = RENDER_STATE_HAD_ATTACHMENT;
+ }
+ return NULL;
+ }
+
+ if (part->uniqueID() == NULL) {
+ part->setUniqueID(String::uuidString());
+ }
+
+ String * result = String::string();
+ String * separatorString;
+ String * content;
+
+ if (!context->firstAttachment && context->hasTextPart) {
+ separatorString = context->htmlCallback->templateForAttachmentSeparator();
+ }
+ else {
+ separatorString = MCSTR("");
+ }
+
+ context->firstAttachment = true;
+
+ if (context->htmlCallback->canPreviewPart(part)) {
+ if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) {
+ context->dataCallback->prefetchImageIMAPPart(context->folder, (IMAPPart *) part);
+ }
+ String * url = String::stringWithUTF8Format("x-mailcore-image:%s",
+ part->uniqueID()->UTF8Characters());
+ HashMap * values = context->htmlCallback->templateValuesForPart(part);
+ values->setObjectForKey(MCSTR("URL"), url);
+ content = renderTemplate(context->htmlCallback->templateForImage(), values);
+ }
+ else {
+ if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) {
+ context->dataCallback->prefetchAttachmentIMAPPart(context->folder, (IMAPPart *) part);
+ }
+ HashMap * values = context->htmlCallback->templateValuesForPart(part);
+ content = renderTemplate(context->htmlCallback->templateForAttachment(), values);
+ }
+
+ result->appendString(separatorString);
+ result->appendString(content);
+
+ return result;
+ }
+}
+
+String * htmlForAbstractMessagePart(AbstractMessagePart * part, htmlRendererContext * context)
+{
+ String * substring = htmlForAbstractPart(part->mainPart(), context);
+ if (context->pass == 0) {
+ return NULL;
+ }
+ MCAssert(substring != NULL);
+
+ String * result = String::string();
+ HashMap * values = context->htmlCallback->templateValuesForHeader(part->header());
+ String * headerString = renderTemplate(context->htmlCallback->templateForMainHeader(), values);
+ result->appendString(headerString);
+ result->appendString(substring);
+ return result;
+}
+
+String * htmlForAbstractMultipartAlternative(AbstractMultipart * part, htmlRendererContext * context)
+{
+ AbstractPart * preferredAlternative = preferredPartInMultipartAlternative(part);
+ if (preferredAlternative == NULL)
+ return MCSTR("");
+
+ return htmlForAbstractPart(preferredAlternative, context);
+}
+
+String * htmlForAbstractMultipartMixed(AbstractMultipart * part, htmlRendererContext * context)
+{
+ String * result = String::string();
+ for(unsigned int i = 0 ; i < part->parts()->count() ; i ++) {
+ AbstractPart * subpart = (AbstractPart *) part->parts()->objectAtIndex(i);
+ String * substring = htmlForAbstractPart(subpart, context);
+ if (context->pass != 0) {
+ if (substring == NULL)
+ return NULL;
+
+ result->appendString(substring);
+ }
+ }
+ return result;
+}
+
+String * htmlForAbstractMultipartRelated(AbstractMultipart * part, htmlRendererContext * context)
+{
+ if (part->parts()->count() == 0) {
+ if (context->pass == 0) {
+ return NULL;
+ }
+ else {
+ return MCSTR("");
+ }
+ }
+
+ AbstractPart * subpart = (AbstractPart *) part->parts()->objectAtIndex(0);
+ return htmlForAbstractPart(subpart, context);
+}
+
+void fillTemplateDictionaryFromMCHashMap(ctemplate::TemplateDictionary * dict, HashMap * mcHashMap)
+{
+ Array * keys = mcHashMap->allKeys();
+
+ for(unsigned int i = 0 ; i < keys->count() ; i ++) {
+ String * key = (String *) keys->objectAtIndex(i);
+ Object * value;
+
+ value = mcHashMap->objectForKey(key);
+ if (value->className()->isEqual(MCSTR("mailcore::String"))) {
+ String * str;
+
+ str = (String *) value;
+ dict->SetValue(key->UTF8Characters(), str->UTF8Characters());
+ }
+ else if (value->className()->isEqual(MCSTR("mailcore::Array"))) {
+ Array * array;
+
+ array = (Array *) value;
+ for(unsigned int k = 0 ; k < array->count() ; k ++) {
+ HashMap * item = (HashMap *) array->objectAtIndex(k);
+ ctemplate::TemplateDictionary * subDict = dict->AddSectionDictionary(key->UTF8Characters());
+ fillTemplateDictionaryFromMCHashMap(subDict, item);
+ }
+ }
+ else if (value->className()->isEqual(MCSTR("mailcore::HashMap"))) {
+ ctemplate::TemplateDictionary * subDict;
+ HashMap * item;
+
+ item = (HashMap *) value;
+ subDict = dict->AddSectionDictionary(key->UTF8Characters());
+ fillTemplateDictionaryFromMCHashMap(subDict, item);
+ }
+ }
+}
+
+String * renderTemplate(String * templateContent, HashMap * values)
+{
+ ctemplate::TemplateDictionary dict("template dict");
+ std::string output;
+ Data * data;
+
+ fillTemplateDictionaryFromMCHashMap(&dict, values);
+ data = templateContent->dataUsingEncoding("utf-8");
+ ctemplate::Template * tpl = ctemplate::Template::StringToTemplate(data->bytes(), data->length(), ctemplate::DO_NOT_STRIP);
+ if (tpl == NULL)
+ return NULL;
+ if (!tpl->Expand(&output, &dict))
+ return NULL;
+ delete tpl;
+
+ return String::stringWithUTF8Characters(output.c_str());
+}
+
+String * HTMLRenderer::htmlForRFC822Message(MessageParser * message,
+ HTMLRendererTemplateCallback * htmlCallback)
+{
+ return htmlForAbstractMessage(NULL, message, NULL, htmlCallback);
+}
+
+String * HTMLRenderer::htmlForIMAPMessage(String * folder,
+ IMAPMessage * message,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback)
+{
+ return htmlForAbstractMessage(folder, message, dataCallback, htmlCallback);
+}
diff --git a/src/core/renderer/MCHTMLRenderer.h b/src/core/renderer/MCHTMLRenderer.h
new file mode 100644
index 00000000..042625cf
--- /dev/null
+++ b/src/core/renderer/MCHTMLRenderer.h
@@ -0,0 +1,38 @@
+//
+// MCHTMLRenderer.h
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/23/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __testUI__MCHTMLRenderer__
+#define __testUI__MCHTMLRenderer__
+
+#include <mailcore/MCAbstract.h>
+#include <mailcore/MCIMAP.h>
+#include <mailcore/MCRFC822.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class MessageParser;
+ class HTMLRendererTemplateCallback;
+ class HTMLRendererIMAPCallback;
+
+ class HTMLRenderer {
+ public:
+ static String * htmlForRFC822Message(MessageParser * message,
+ HTMLRendererTemplateCallback * htmlCallback);
+
+ static String * htmlForIMAPMessage(String * folder,
+ IMAPMessage * message,
+ HTMLRendererIMAPCallback * dataCallback,
+ HTMLRendererTemplateCallback * htmlCallback);
+ };
+};
+
+#endif
+
+#endif /* defined(__testUI__MCHTMLRenderer__) */
diff --git a/src/core/renderer/MCHTMLRendererCallback.cpp b/src/core/renderer/MCHTMLRendererCallback.cpp
new file mode 100644
index 00000000..3ceaeb40
--- /dev/null
+++ b/src/core/renderer/MCHTMLRendererCallback.cpp
@@ -0,0 +1,259 @@
+//
+// MCHTMLRendererCallback.cpp
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 2/2/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCHTMLRendererCallback.h"
+
+#include "MCAddressDisplay.h"
+#include "MCDateFormatter.h"
+#include "MCSizeFormatter.h"
+#include "MCAttachment.h"
+
+using namespace mailcore;
+
+mailcore::HashMap * HTMLRendererTemplateCallback::templateValuesForHeader(mailcore::MessageHeader * header)
+{
+ mailcore::HashMap * result = mailcore::HashMap::hashMap();
+
+ if (header->from() != NULL) {
+ result->setObjectForKey(MCSTR("HASFROM"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("FROM"), mailcore::AddressDisplay::displayStringForAddress(header->from())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTFROM"), mailcore::AddressDisplay::shortDisplayStringForAddress(header->from())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTFROM"), mailcore::AddressDisplay::veryShortDisplayStringForAddress(header->from())->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOFROM"), mailcore::HashMap::hashMap());
+ }
+
+ if ((header->to() != NULL) && (header->to()->count() > 0)) {
+ result->setObjectForKey(MCSTR("HASTO"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("TO"), mailcore::AddressDisplay::displayStringForAddresses(header->to())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTTO"), mailcore::AddressDisplay::shortDisplayStringForAddresses(header->to())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTTO"), mailcore::AddressDisplay::veryShortDisplayStringForAddresses(header->to())->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOTO"), mailcore::HashMap::hashMap());
+ }
+
+ if ((header->cc() != NULL) && (header->cc()->count() > 0)) {
+ result->setObjectForKey(MCSTR("HASCC"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("CC"), mailcore::AddressDisplay::displayStringForAddresses(header->cc())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTCC"), mailcore::AddressDisplay::shortDisplayStringForAddresses(header->cc())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTCC"), mailcore::AddressDisplay::veryShortDisplayStringForAddresses(header->cc())->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOCC"), mailcore::HashMap::hashMap());
+ }
+
+ if ((header->bcc() != NULL) && (header->bcc()->count() > 0)) {
+ result->setObjectForKey(MCSTR("HASBCC"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("BCC"), mailcore::AddressDisplay::displayStringForAddresses(header->bcc())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTBCC"), mailcore::AddressDisplay::shortDisplayStringForAddresses(header->bcc())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTBCC"), mailcore::AddressDisplay::veryShortDisplayStringForAddresses(header->bcc())->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOBCC"), mailcore::HashMap::hashMap());
+ }
+
+ mailcore::Array * recipient = new mailcore::Array();
+ recipient->addObjectsFromArray(header->to());
+ recipient->addObjectsFromArray(header->cc());
+ recipient->addObjectsFromArray(header->bcc());
+
+ if (recipient->count() > 0) {
+ result->setObjectForKey(MCSTR("HASRECIPIENT"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("RECIPIENT"), mailcore::AddressDisplay::displayStringForAddresses(recipient)->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTRECIPIENT"), mailcore::AddressDisplay::shortDisplayStringForAddresses(recipient)->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTRECIPIENT"), mailcore::AddressDisplay::veryShortDisplayStringForAddresses(recipient)->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NORECIPIENT"), mailcore::HashMap::hashMap());
+ }
+ recipient->release();
+
+ if ((header->replyTo() != NULL) && (header->replyTo()->count() > 0)) {
+ result->setObjectForKey(MCSTR("HASREPLYTO"), mailcore::HashMap::hashMap());
+ result->setObjectForKey(MCSTR("REPLYTO"), mailcore::AddressDisplay::displayStringForAddresses(header->replyTo())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SHORTREPLYTO"), mailcore::AddressDisplay::shortDisplayStringForAddresses(header->replyTo())->htmlEncodedString());
+ result->setObjectForKey(MCSTR("VERYSHORTREPLYTO"), mailcore::AddressDisplay::veryShortDisplayStringForAddresses(header->replyTo())->htmlEncodedString());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOREPLYTO"), mailcore::HashMap::hashMap());
+ }
+
+ if ((header->subject() != NULL) && (header->subject()->length() > 0)) {
+ result->setObjectForKey(MCSTR("EXTRACTEDSUBJECT"), header->partialExtractedSubject()->htmlEncodedString());
+ result->setObjectForKey(MCSTR("SUBJECT"), header->subject()->htmlEncodedString());
+ result->setObjectForKey(MCSTR("HASSUBJECT"), mailcore::HashMap::hashMap());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOSUBJECT"), mailcore::HashMap::hashMap());
+ }
+
+ mailcore::String * dateString;
+ static mailcore::DateFormatter * fullFormatter = NULL;
+ if (fullFormatter == NULL) {
+ fullFormatter = new mailcore::DateFormatter();
+ fullFormatter->setDateStyle(mailcore::DateFormatStyleFull);
+ fullFormatter->setTimeStyle(mailcore::DateFormatStyleFull);
+ }
+ dateString = fullFormatter->stringFromDate(header->date());
+ if (dateString != NULL) {
+ result->setObjectForKey(MCSTR("FULLDATE"), dateString->htmlEncodedString());
+ }
+ static mailcore::DateFormatter * longFormatter = NULL;
+ if (longFormatter == NULL) {
+ longFormatter = new mailcore::DateFormatter();
+ longFormatter->setDateStyle(mailcore::DateFormatStyleLong);
+ longFormatter->setTimeStyle(mailcore::DateFormatStyleLong);
+ }
+ dateString = longFormatter->stringFromDate(header->date());
+ if (dateString != NULL) {
+ result->setObjectForKey(MCSTR("LONGDATE"), dateString->htmlEncodedString());
+ }
+ static mailcore::DateFormatter * mediumFormatter = NULL;
+ if (mediumFormatter == NULL) {
+ mediumFormatter = new mailcore::DateFormatter();
+ mediumFormatter->setDateStyle(mailcore::DateFormatStyleMedium);
+ mediumFormatter->setTimeStyle(mailcore::DateFormatStyleMedium);
+ }
+ dateString = mediumFormatter->stringFromDate(header->date());
+ if (dateString != NULL) {
+ result->setObjectForKey(MCSTR("MEDIUMDATE"), dateString->htmlEncodedString());
+ }
+ static mailcore::DateFormatter * shortFormatter = NULL;
+ if (shortFormatter == NULL) {
+ shortFormatter = new mailcore::DateFormatter();
+ shortFormatter->setDateStyle(mailcore::DateFormatStyleShort);
+ shortFormatter->setTimeStyle(mailcore::DateFormatStyleShort);
+ }
+ dateString = shortFormatter->stringFromDate(header->date());
+ if (dateString != NULL) {
+ result->setObjectForKey(MCSTR("SHORTDATE"), dateString->htmlEncodedString());
+ }
+
+ return result;
+}
+
+mailcore::HashMap * HTMLRendererTemplateCallback::templateValuesForPart(mailcore::AbstractPart * part)
+{
+ mailcore::HashMap * result = mailcore::HashMap::hashMap();
+ mailcore::String * filename = NULL;
+
+ if (part->filename() != NULL) {
+ filename = part->filename()->lastPathComponent();
+ }
+
+ if (filename != NULL) {
+ result->setObjectForKey(MCSTR("FILENAME"), filename->htmlEncodedString());
+ }
+
+ if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) {
+ mailcore::IMAPPart * imapPart = (mailcore::IMAPPart *) part;
+ mailcore::String * value = mailcore::SizeFormatter::stringWithSize(imapPart->size());
+ result->setObjectForKey(MCSTR("SIZE"), value);
+ result->setObjectForKey(MCSTR("HASSIZE"), mailcore::HashMap::hashMap());
+ }
+ else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) {
+ mailcore::Attachment * attachment = (mailcore::Attachment *) part;
+ mailcore::String * value = mailcore::SizeFormatter::stringWithSize(attachment->data()->length());
+ result->setObjectForKey(MCSTR("SIZE"), value);
+ result->setObjectForKey(MCSTR("HASSIZE"), mailcore::HashMap::hashMap());
+ }
+ else {
+ result->setObjectForKey(MCSTR("NOSIZE"), mailcore::HashMap::hashMap());
+ }
+
+ if (part->contentID() != NULL) {
+ result->setObjectForKey(MCSTR("CONTENTID"), part->contentID());
+ }
+ if (part->uniqueID() != NULL) {
+ result->setObjectForKey(MCSTR("UNIQUEID"), part->uniqueID());
+ }
+
+ return result;
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForMainHeader()
+{
+ return MCSTR("<div style=\"background-color:#eee\">\
+ {{#HASFROM}}\
+ <div><b>From:</b> {{FROM}}</div>\
+ {{/HASFROM}}\
+ {{#HASTO}}\
+ <div><b>To:</b> {{TO}}</div>\
+ {{/HASTO}}\
+ {{#HASCC}}\
+ <div><b>Cc:</b> {{CC}}</div>\
+ {{/HASCC}}\
+ {{#HASBCC}}\
+ <div><b>Bcc:</b> {{BCC}}</div>\
+ {{/HASBCC}}\
+ {{#NORECIPIENT}}\
+ <div><b>To:</b> <i>Undisclosed recipient</i></div>\
+ {{/NORECIPIENT}}\
+ {{#HASSUBJECT}}\
+ <div><b>Subject:</b> {{EXTRACTEDSUBJECT}}</div>\
+ {{/HASSUBJECT}}\
+ {{#NOSUBJECT}}\
+ <div><b>Subject:</b> <i>No Subject</i></div>\
+ {{/NOSUBJECT}}\
+ <div><b>Date:</b> {{LONGDATE}}</div>\
+ </div>");
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForHeader()
+{
+ return templateForMainHeader();
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForImage()
+{
+ return MCSTR("");
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForAttachment()
+{
+ return MCSTR("{{#HASSIZE}}\
+ <div>- {{FILENAME}}, {{SIZE}}</div>\
+ {{/HASSIZE}}\
+ {{#NOSIZE}}\
+ <div>- {{FILENAME}}</div>\
+ {{/NOSIZE}}\
+ ");
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForMessage()
+{
+ return MCSTR("<div style=\"padding-bottom: 20px;\">{{HEADER}}</div><div>{{BODY}}</div>");
+}
+
+
+mailcore::String * HTMLRendererTemplateCallback::templateForEmbeddedMessage()
+{
+ return templateForMessage();
+}
+
+mailcore::String * HTMLRendererTemplateCallback::templateForAttachmentSeparator()
+{
+ return MCSTR("<hr/>");
+}
+
+mailcore::String * HTMLRendererTemplateCallback::filterHTMLForMessage(mailcore::String * html)
+{
+ return html;
+}
+
+mailcore::String * HTMLRendererTemplateCallback::filterHTMLForPart(mailcore::String * html)
+{
+ return html;
+}
+
+bool HTMLRendererTemplateCallback::canPreviewPart(AbstractPart * part)
+{
+ return false;
+}
diff --git a/src/core/renderer/MCHTMLRendererCallback.h b/src/core/renderer/MCHTMLRendererCallback.h
new file mode 100644
index 00000000..2972249e
--- /dev/null
+++ b/src/core/renderer/MCHTMLRendererCallback.h
@@ -0,0 +1,51 @@
+//
+// MCHTMLRendererCallback.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 2/2/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __mailcore2__MCHTMLRendererCallback__
+#define __mailcore2__MCHTMLRendererCallback__
+
+#include <mailcore/MCAbstract.h>
+#include <mailcore/MCIMAP.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class MessageParser;
+
+ class HTMLRendererIMAPCallback {
+ public:
+ virtual Data * dataForIMAPPart(String * folder, IMAPPart * part) { return NULL; }
+ virtual void prefetchAttachmentIMAPPart(String * folder, IMAPPart * part) {}
+ virtual void prefetchImageIMAPPart(String * folder, IMAPPart * part) {}
+ };
+
+ class HTMLRendererTemplateCallback {
+ public:
+ virtual bool canPreviewPart(AbstractPart * part);
+
+ virtual HashMap * templateValuesForHeader(MessageHeader * header);
+ virtual HashMap * templateValuesForPart(AbstractPart * part);
+
+ virtual String * templateForMainHeader();
+ virtual String * templateForHeader();
+ virtual String * templateForImage();
+ virtual String * templateForAttachment();
+ virtual String * templateForMessage();
+ virtual String * templateForEmbeddedMessage();
+ virtual String * templateForAttachmentSeparator();
+
+ virtual String * filterHTMLForPart(String * html);
+ virtual String * filterHTMLForMessage(String * html);
+ };
+
+}
+
+#endif
+
+#endif /* defined(__mailcore2__MCHTMLRendererCallback__) */
diff --git a/src/core/renderer/MCRenderer.h b/src/core/renderer/MCRenderer.h
new file mode 100644
index 00000000..65999f95
--- /dev/null
+++ b/src/core/renderer/MCRenderer.h
@@ -0,0 +1,14 @@
+//
+// MCRenderer.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 2/2/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef mailcore2_MCRenderer_h
+#define mailcore2_MCRenderer_h
+
+#include <mailcore/MCHTMLRendererCallback.h>
+
+#endif
diff --git a/src/core/renderer/MCSizeFormatter.cpp b/src/core/renderer/MCSizeFormatter.cpp
new file mode 100644
index 00000000..f0823075
--- /dev/null
+++ b/src/core/renderer/MCSizeFormatter.cpp
@@ -0,0 +1,43 @@
+//
+// MCSizeFormatter.cpp
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCSizeFormatter.h"
+
+#include <math.h>
+
+using namespace mailcore;
+
+String * SizeFormatter::stringWithSize(unsigned int size)
+{
+ double divider;
+ String * unit;
+
+ if (size >= 1024 * 1024 * 1024) {
+ divider = 1024 * 1024 * 1024;
+ unit = MCLOCALIZEDSTRING(MCSTR("GB"));
+ }
+ else if (size >= 1024 * 1024) {
+ divider = 1024 * 1024;
+ unit = MCLOCALIZEDSTRING(MCSTR("MB"));
+ }
+ else if (size >= 1024) {
+ divider = 1024;
+ unit = MCLOCALIZEDSTRING(MCSTR("KB"));
+ }
+ else {
+ divider = 1;
+ unit = MCLOCALIZEDSTRING(MCSTR("bytes"));
+ }
+
+ if ((size / divider) - round(size / divider) < 0.1) {
+ return String::stringWithUTF8Format("%.0f %s", size / divider, unit->UTF8Characters());
+ }
+ else {
+ return String::stringWithUTF8Format("%.1f %s", size / divider, unit->UTF8Characters());
+ }
+}
diff --git a/src/core/renderer/MCSizeFormatter.h b/src/core/renderer/MCSizeFormatter.h
new file mode 100644
index 00000000..a6c74010
--- /dev/null
+++ b/src/core/renderer/MCSizeFormatter.h
@@ -0,0 +1,28 @@
+//
+// MCSizeFormatter.h
+// testUI
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __testUI__MCSizeFormatter__
+#define __testUI__MCSizeFormatter__
+
+#include <mailcore/MCBaseTypes.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+ class String;
+
+ class SizeFormatter : public Object {
+ public:
+ static String * stringWithSize(unsigned int size);
+ };
+
+}
+
+#endif
+
+#endif /* defined(__testUI__MCSizeFormatter__) */
diff --git a/src/core/rfc822/MCAttachment.cc b/src/core/rfc822/MCAttachment.cc
index 91b8fde3..7926baa9 100644
--- a/src/core/rfc822/MCAttachment.cc
+++ b/src/core/rfc822/MCAttachment.cc
@@ -231,13 +231,6 @@ String * Attachment::description()
return result;
}
-#if 0
-String * Attachment::className()
-{
- return MCSTR("Attachment");
-}
-#endif
-
Object * Attachment::copy()
{
return new Attachment(this);
@@ -464,6 +457,8 @@ Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime)
MCAssert(mime->mm_type == MAILMIME_SINGLE);
result = new Attachment();
+ result->setUniqueID(mailcore::String::uuidString());
+
data = mime->mm_data.mm_single;
bytes = data->dt_data.dt_text.dt_data;
length = data->dt_data.dt_text.dt_length;
diff --git a/src/core/rfc822/MCAttachment.h b/src/core/rfc822/MCAttachment.h
index 0be168aa..ac12a5b5 100644
--- a/src/core/rfc822/MCAttachment.h
+++ b/src/core/rfc822/MCAttachment.h
@@ -27,13 +27,14 @@ namespace mailcore {
virtual void setData(Data * data);
virtual Data * data();
- static AbstractPart * attachmentsWithMIME(struct mailmime * mime);
-
public: // subclass behavior
Attachment(Attachment * other);
virtual String * description();
virtual Object * copy();
+ public: // private
+ static AbstractPart * attachmentsWithMIME(struct mailmime * mime);
+
private:
Data * mData;
void init();
diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc
index 62482564..07febfbb 100644
--- a/src/core/rfc822/MCMessageBuilder.cc
+++ b/src/core/rfc822/MCMessageBuilder.cc
@@ -524,13 +524,6 @@ String * MessageBuilder::description()
return result;
}
-#if 0
-String * MessageBuilder::className()
-{
- return MCSTR("MessageBuilder");
-}
-#endif
-
Object * MessageBuilder::copy()
{
return new MessageBuilder(this);
diff --git a/src/core/rfc822/MCMessageParser.cc b/src/core/rfc822/MCMessageParser.cc
index f301ce3e..a0dcf142 100644
--- a/src/core/rfc822/MCMessageParser.cc
+++ b/src/core/rfc822/MCMessageParser.cc
@@ -2,6 +2,7 @@
#include "MCAttachment.h"
#include "MCMessageHeader.h"
+#include "MCHTMLRenderer.h"
using namespace mailcore;
@@ -69,14 +70,23 @@ String * MessageParser::description()
return result;
}
-#if 0
-String * MessageParser::className()
+Object * MessageParser::copy()
{
- return MCSTR("MessageParser");
+ return new MessageParser(this);
}
-#endif
-Object * MessageParser::copy()
+AbstractPart * MessageParser::partForContentID(String * contentID)
{
- return new MessageParser(this);
+ return mainPart()->partForContentID(contentID);
}
+
+AbstractPart * MessageParser::partForUniqueID(String * uniqueID)
+{
+ return mainPart()->partForUniqueID(uniqueID);
+}
+
+String * MessageParser::htmlRendering(HTMLRendererTemplateCallback * htmlCallback)
+{
+ return HTMLRenderer::htmlForRFC822Message(this, htmlCallback);
+}
+
diff --git a/src/core/rfc822/MCMessageParser.h b/src/core/rfc822/MCMessageParser.h
index 06673ec4..ff2f1f50 100644
--- a/src/core/rfc822/MCMessageParser.h
+++ b/src/core/rfc822/MCMessageParser.h
@@ -10,6 +10,8 @@
namespace mailcore {
+ class HTMLRendererTemplateCallback;
+
class MessageParser : public AbstractMessage {
public:
static MessageParser * messageParserWithData(Data * data);
@@ -20,6 +22,11 @@ namespace mailcore {
virtual AbstractPart * mainPart();
virtual Data * data();
+ virtual AbstractPart * partForContentID(String * contentID);
+ virtual AbstractPart * partForUniqueID(String * uniqueID);
+
+ virtual String * htmlRendering(HTMLRendererTemplateCallback * htmlCallback = NULL);
+
public: // subclass behavior
MessageParser(MessageParser * other);
virtual String * description();
diff --git a/src/core/rfc822/MCMessagePart.cc b/src/core/rfc822/MCMessagePart.cc
index 8a2122c3..21d61181 100644
--- a/src/core/rfc822/MCMessagePart.cc
+++ b/src/core/rfc822/MCMessagePart.cc
@@ -14,13 +14,6 @@ MessagePart::~MessagePart()
{
}
-#if 0
-String * MessagePart::className()
-{
- return MCSTR("MessagePart");
-}
-#endif
-
Object * MessagePart::copy()
{
return new MessagePart(this);
diff --git a/src/core/rfc822/MCMultipart.cc b/src/core/rfc822/MCMultipart.cc
index 6ab1f0db..e048669e 100644
--- a/src/core/rfc822/MCMultipart.cc
+++ b/src/core/rfc822/MCMultipart.cc
@@ -14,13 +14,6 @@ Multipart::~Multipart()
{
}
-#if 0
-String * Multipart::className()
-{
- return MCSTR("Multipart");
-}
-#endif
-
Object * Multipart::copy()
{
return new Multipart(this);
diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc
index 12066146..96bd9787 100644
--- a/src/core/smtp/MCSMTPSession.cc
+++ b/src/core/smtp/MCSMTPSession.cc
@@ -51,13 +51,6 @@ SMTPSession::~SMTPSession()
MCLog("dealloc4");
}
-#if 0
-String * SMTPSession::className()
-{
- return MCSTR("SMTPSession");
-}
-#endif
-
void SMTPSession::setHostname(String * hostname)
{
MC_SAFE_REPLACE_COPY(String, mHostname, hostname);
diff --git a/src/objc/MCOConstants.h b/src/objc/MCOConstants.h
index 355fceb3..257b0d68 100644
--- a/src/objc/MCOConstants.h
+++ b/src/objc/MCOConstants.h
@@ -1,3 +1,7 @@
+#ifndef __MAILCORE_MCOCONSTANTS_H_
+
+#define __MAILCORE_MCOCONSTANTS_H_
+
typedef enum {
MCOConnectionTypeClear = 1 << 0,
MCOConnectionTypeStartTLS = 1 << 1,
@@ -15,3 +19,5 @@ typedef enum {
MCOAuthTypeSASLNTLM = 1 << 6,
MCOAuthTypeSASLKerberosV4 = 1 << 7,
} MCOAuthType;
+
+#endif
diff --git a/src/objc/MCObjC.h b/src/objc/MCObjC.h
index 364d5692..8468d298 100644
--- a/src/objc/MCObjC.h
+++ b/src/objc/MCObjC.h
@@ -14,11 +14,16 @@
#import <mailcore/MCOObjectWrapper.h>
#import <mailcore/NSData+MCO.h>
#import <mailcore/NSString+MCO.h>
+#import <mailcore/NSDictionary+MCO.h>
+#import <mailcore/NSArray+MCO.h>
+#import <mailcore/NSObject+MCO.h>
+#import <mailcore/MCOObjectWrapper.h>
#import <mailcore/NSError+MCO.h>
#import <mailcore/MCOIMAPSession.h>
#import <mailcore/MCOOperation.h>
#import <mailcore/MCOCheckAccountOperation.h>
-
+#import <mailcore/MCOFetchFoldersOperation.h>
+#import <mailcore/MCOConstants.h>
#endif
diff --git a/src/objc/imap/MCOCheckAccountOperation.mm b/src/objc/imap/MCOCheckAccountOperation.mm
index 47ea0fc8..4c9f5bca 100644
--- a/src/objc/imap/MCOCheckAccountOperation.mm
+++ b/src/objc/imap/MCOCheckAccountOperation.mm
@@ -6,7 +6,7 @@
// Copyright (c) 2013 __MyCompanyName__. All rights reserved.
//
-#import <mailcore/MCCore.h>
+#import <mailcore/MCAsync.h>
#import "MCOOperation+Internals.h"
#import "MCOCheckAccountOperation.h"
diff --git a/src/objc/imap/MCOOperation+Internals.h b/src/objc/imap/MCOOperation+Internals.h
index 58b10559..2862a929 100644
--- a/src/objc/imap/MCOOperation+Internals.h
+++ b/src/objc/imap/MCOOperation+Internals.h
@@ -13,6 +13,8 @@
@interface MCOOperation ()
- (id)initWithOperation:(mailcore::Operation *)op;
+#ifdef __cplusplus
- (mailcore::Operation *)operation;
+#endif
- (void)start;
@end \ No newline at end of file
diff --git a/src/objc/utils/MCOObjectWrapper.h b/src/objc/utils/MCOObjectWrapper.h
index eac1a457..6827bde9 100644
--- a/src/objc/utils/MCOObjectWrapper.h
+++ b/src/objc/utils/MCOObjectWrapper.h
@@ -8,7 +8,11 @@
#import <Foundation/Foundation.h>
-#include <mailcore/MCObject.h>
+#ifdef __cplusplus
+namespace mailcore {
+ class Object;
+}
+#endif
@interface MCOObjectWrapper : NSObject
diff --git a/src/objc/utils/MCOObjectWrapper.mm b/src/objc/utils/MCOObjectWrapper.mm
index 74a2afe7..e4fda2ae 100644
--- a/src/objc/utils/MCOObjectWrapper.mm
+++ b/src/objc/utils/MCOObjectWrapper.mm
@@ -9,6 +9,7 @@
#import "MCOObjectWrapper.h"
#include "MCUtils.h"
+#include "MCObject.h"
@implementation MCOObjectWrapper {
mailcore::Object * mObject;
diff --git a/src/objc/utils/NSArray+MCO.h b/src/objc/utils/NSArray+MCO.h
new file mode 100644
index 00000000..8d95acbc
--- /dev/null
+++ b/src/objc/utils/NSArray+MCO.h
@@ -0,0 +1,23 @@
+//
+// NSArray+MCO.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#ifdef __cplusplus
+namespace mailcore {
+ class Array;
+}
+#endif
+
+@interface NSArray (MCO)
+
+#ifdef __cplusplus
+- (mailcore::Array *) mco_mcArray;
+#endif
+
+@end
diff --git a/src/objc/utils/NSArray+MCO.mm b/src/objc/utils/NSArray+MCO.mm
new file mode 100644
index 00000000..1c4ef3e6
--- /dev/null
+++ b/src/objc/utils/NSArray+MCO.mm
@@ -0,0 +1,26 @@
+//
+// NSArray+MCO.cpp
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import "NSArray+MCO.h"
+
+#include "MCBaseTypes.h"
+
+#import "NSObject+MCO.h"
+
+@implementation NSArray (MCO)
+
+- (mailcore::Array *) mco_mcArray
+{
+ mailcore::Array * result = mailcore::Array::array();
+ for(NSObject * value in self) {
+ [value mco_mcObject];
+ }
+ return result;
+}
+
+@end
diff --git a/src/objc/utils/NSData+MCO.h b/src/objc/utils/NSData+MCO.h
index 105fd325..9a0b39cc 100644
--- a/src/objc/utils/NSData+MCO.h
+++ b/src/objc/utils/NSData+MCO.h
@@ -8,7 +8,11 @@
#import <Foundation/Foundation.h>
-#include <mailcore/MCData.h>
+#ifdef __cplusplus
+namespace mailcore {
+ class Data;
+}
+#endif
@interface NSData (MCO)
diff --git a/src/objc/utils/NSData+MCO.mm b/src/objc/utils/NSData+MCO.mm
index 70838280..dd279554 100644
--- a/src/objc/utils/NSData+MCO.mm
+++ b/src/objc/utils/NSData+MCO.mm
@@ -8,6 +8,8 @@
#import "NSData+MCO.h"
+#include "MCData.h"
+
@implementation NSData (MCO)
+ (NSData *) mco_dataWithMCData:(mailcore::Data *)cppData
diff --git a/src/objc/utils/NSDictionary+MCO.h b/src/objc/utils/NSDictionary+MCO.h
new file mode 100644
index 00000000..71812a46
--- /dev/null
+++ b/src/objc/utils/NSDictionary+MCO.h
@@ -0,0 +1,23 @@
+//
+// NSDictionary+MCO.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#ifdef __cplusplus
+namespace mailcore {
+ class HashMap;
+}
+#endif
+
+@interface NSDictionary (MCO)
+
+#ifdef __cplusplus
+- (mailcore::HashMap *) mco_mcHashMap;
+#endif
+
+@end
diff --git a/src/objc/utils/NSDictionary+MCO.mm b/src/objc/utils/NSDictionary+MCO.mm
new file mode 100644
index 00000000..a751f85b
--- /dev/null
+++ b/src/objc/utils/NSDictionary+MCO.mm
@@ -0,0 +1,27 @@
+//
+// NSDictionary+MCO.m
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import "NSDictionary+MCO.h"
+
+#include "MCBaseTypes.h"
+
+#import "NSObject+MCO.h"
+
+@implementation NSDictionary (MCO)
+
+- (mailcore::HashMap *) mco_mcHashMap
+{
+ mailcore::HashMap * result = mailcore::HashMap::hashMap();
+ for(NSObject * key in self) {
+ NSObject * value = [self objectForKey:key];
+ result->setObjectForKey([key mco_mcObject], [value mco_mcObject]);
+ }
+ return result;
+}
+
+@end
diff --git a/src/objc/utils/NSObject+MCO.h b/src/objc/utils/NSObject+MCO.h
new file mode 100644
index 00000000..349bd27a
--- /dev/null
+++ b/src/objc/utils/NSObject+MCO.h
@@ -0,0 +1,23 @@
+//
+// NSObject+MCO.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#ifdef __cplusplus
+namespace mailcore {
+ class Object;
+}
+#endif
+
+@interface NSObject (MCO)
+
+#ifdef __cplusplus
+- (mailcore::Object *) mco_mcObject;
+#endif
+
+@end
diff --git a/src/objc/utils/NSObject+MCO.mm b/src/objc/utils/NSObject+MCO.mm
new file mode 100644
index 00000000..e25db319
--- /dev/null
+++ b/src/objc/utils/NSObject+MCO.mm
@@ -0,0 +1,42 @@
+//
+// NSObject+MCO.m
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/29/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#import "NSObject+MCO.h"
+
+#import "NSData+MCO.h"
+#import "NSString+MCO.h"
+#import "NSDictionary+MCO.h"
+#import "NSArray+MCO.h"
+
+#include "MCBaseTypes.h"
+#include "MCUtils.h"
+
+@implementation NSObject (MCO)
+
+- (mailcore::Object *) mco_mcObject
+{
+ if ([self isKindOfClass:[NSData class]]) {
+ return [(NSData *) self mco_mcData];
+ }
+ else if ([self isKindOfClass:[NSString class]]) {
+ return [(NSString *) self mco_mcString];
+ }
+ else if ([self isKindOfClass:[NSArray class]]) {
+ return [(NSArray *) self mco_mcArray];
+ }
+ else if ([self isKindOfClass:[NSDictionary class]]) {
+ return [(NSDictionary *) self mco_mcHashMap];
+ }
+ else {
+ MCAssert(0);
+ return nil;
+ }
+
+}
+
+@end
diff --git a/src/objc/utils/NSString+MCO.h b/src/objc/utils/NSString+MCO.h
index e7057116..33cc0b67 100644
--- a/src/objc/utils/NSString+MCO.h
+++ b/src/objc/utils/NSString+MCO.h
@@ -8,7 +8,12 @@
#import <Foundation/Foundation.h>
-#include <mailcore/MCString.h>
+#ifdef __cplusplus
+namespace mailcore {
+ class String;
+ class Object;
+}
+#endif
@interface NSString (MCO)
diff --git a/src/objc/utils/NSString+MCO.mm b/src/objc/utils/NSString+MCO.mm
index 803e9f24..3d692b76 100644
--- a/src/objc/utils/NSString+MCO.mm
+++ b/src/objc/utils/NSString+MCO.mm
@@ -8,6 +8,8 @@
#import "NSString+MCO.h"
+#include "MCString.h"
+
@implementation NSString (MCO)
+ (NSString *) mco_stringWithMCString:(mailcore::String *)cppString