aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/basetypes
diff options
context:
space:
mode:
authorGravatar George Nachman <georgen@google.com>2014-07-24 12:04:10 -0700
committerGravatar George Nachman <georgen@google.com>2014-07-24 12:04:10 -0700
commit108bb69dab1a0e6fcc17115c0e94feadaf820216 (patch)
tree26ac82f97fb499ae8624047b2643f11b6bbde0dd /src/core/basetypes
parent1f243bb124f03e2b8710dc70f31010ab42cdf964 (diff)
parentdfc73dd7ad39d13e2cb06b2a308dbab38105c786 (diff)
Merge branch 'master' of https://github.com/MailCore/mailcore2 into iOS8AndLibCpp
Diffstat (limited to 'src/core/basetypes')
-rw-r--r--src/core/basetypes/MCArray.cc1
-rw-r--r--src/core/basetypes/MCHTMLCleaner.cc2
-rw-r--r--src/core/basetypes/MCLibetpan.cc202
-rw-r--r--src/core/basetypes/MCLibetpan.h12
-rw-r--r--src/core/basetypes/MCOperationQueue.cc12
-rw-r--r--src/core/basetypes/MCOperationQueue.h1
6 files changed, 226 insertions, 4 deletions
diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc
index 15e9a2be..43ee6bd4 100644
--- a/src/core/basetypes/MCArray.cc
+++ b/src/core/basetypes/MCArray.cc
@@ -212,7 +212,6 @@ static int sortCompare(Object ** pa, Object ** pb, struct sortData * data)
Array * Array::sortedArray(int (* compare)(void * a, void * b, void * context), void * context)
{
- struct sortData data;
Array * result = (Array *) this->copy()->autorelease();
result->sortArray(compare, context);
return result;
diff --git a/src/core/basetypes/MCHTMLCleaner.cc b/src/core/basetypes/MCHTMLCleaner.cc
index 079163bf..81145c9e 100644
--- a/src/core/basetypes/MCHTMLCleaner.cc
+++ b/src/core/basetypes/MCHTMLCleaner.cc
@@ -43,6 +43,8 @@ String * HTMLCleaner::cleanHTML(String * input)
tidyOptSetBool(tdoc, TidyDropEmptyElems, no);
#endif
tidyOptSetBool(tdoc, TidyXhtmlOut, yes);
+ tidyOptSetInt(tdoc, TidyDoctypeMode, TidyDoctypeUser);
+
tidyOptSetBool(tdoc, TidyMark, no);
tidySetCharEncoding(tdoc, "utf8");
tidyOptSetBool(tdoc, TidyForceOutput, yes);
diff --git a/src/core/basetypes/MCLibetpan.cc b/src/core/basetypes/MCLibetpan.cc
index fcc1b772..1779d605 100644
--- a/src/core/basetypes/MCLibetpan.cc
+++ b/src/core/basetypes/MCLibetpan.cc
@@ -10,9 +10,211 @@
#include <libetpan/libetpan.h>
+using namespace mailcore;
+
+static time_t mkgmtime(struct tm * tmp);
+static int tmcomp(struct tm * atmp, struct tm * btmp);
+
__attribute__((constructor))
static void initialize()
{
// It will enable CFStream on platforms that supports it.
mailstream_cfstream_enabled = 1;
}
+
+time_t mailcore::timestampFromDate(struct mailimf_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+struct mailimf_date_time * mailcore::dateFromTimestamp(time_t timeval)
+{
+ struct tm gmt;
+ struct tm lt;
+ int off;
+ struct mailimf_date_time * date_time;
+ int sign;
+ int hour;
+ int min;
+
+ gmtime_r(&timeval, &gmt);
+ localtime_r(&timeval, &lt);
+
+ off = (int) ((mkgmtime(&lt) - mkgmtime(&gmt)) / 60);
+ if (off < 0) {
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ off = off * sign;
+ min = off % 60;
+ hour = off / 60;
+ off = hour * 100 + min;
+ off = off * sign;
+
+ date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1,
+ lt.tm_year + 1900,
+ lt.tm_hour, lt.tm_min, lt.tm_sec,
+ off);
+
+ return date_time;
+}
+
+struct mailimap_date_time * mailcore::imapDateFromTimestamp(time_t timeval)
+{
+ struct tm gmt;
+ struct tm lt;
+ int off;
+ struct mailimap_date_time * date_time;
+ int sign;
+ int hour;
+ int min;
+
+ gmtime_r(&timeval, &gmt);
+ localtime_r(&timeval, &lt);
+
+ off = (int) ((mkgmtime(&lt) - mkgmtime(&gmt)) / 60);
+ if (off < 0) {
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ off = off * sign;
+ min = off % 60;
+ hour = off / 60;
+ off = hour * 100 + min;
+ off = off * sign;
+
+ date_time = mailimap_date_time_new(lt.tm_mday, lt.tm_mon + 1,
+ lt.tm_year + 1900,
+ lt.tm_hour, lt.tm_min, lt.tm_sec,
+ off);
+
+ return date_time;
+}
+
+time_t mailcore::timestampFromIMAPDate(struct mailimap_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+#define INVALID_TIMESTAMP (-1)
+
+static int tmcomp(struct tm * atmp, struct tm * btmp)
+{
+ int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t mkgmtime(struct tm * tmp)
+{
+ int dir;
+ int bits;
+ int saved_seconds;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ yourtm = *tmp;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ /*
+ ** Calculate the number of magnitude bits in a time_t
+ ** (this works regardless of whether time_t is
+ ** signed or unsigned, though lint complains if unsigned).
+ */
+ for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+ ;
+ /*
+ ** If time_t is signed, then 0 is the median value,
+ ** if time_t is unsigned, then 1 << bits is median.
+ */
+ if(bits > 40) bits = 40;
+ t = (t < 0) ? 0 : ((time_t) 1 << bits);
+ for ( ; ; ) {
+ gmtime_r(&t, &mytm);
+ dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0) {
+ if (bits-- < 0) {
+ return INVALID_TIMESTAMP;
+ }
+ if (bits < 0)
+ --t;
+ else if (dir > 0)
+ t -= (time_t) 1 << bits;
+ else t += (time_t) 1 << bits;
+ continue;
+ }
+ break;
+ }
+ t += saved_seconds;
+ return t;
+}
diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h
index 9670a47b..41024137 100644
--- a/src/core/basetypes/MCLibetpan.h
+++ b/src/core/basetypes/MCLibetpan.h
@@ -10,6 +10,16 @@
#define MAILCORE_MCLIBETPAN_H
-// No API in this file.
+#include <time.h>
+#include <libetpan/libetpan.h>
+
+namespace mailcore {
+
+ time_t timestampFromDate(struct mailimf_date_time * date_time);
+ time_t timestampFromIMAPDate(struct mailimap_date_time * date_time);
+ struct mailimf_date_time * dateFromTimestamp(time_t timeval);
+ struct mailimap_date_time * imapDateFromTimestamp(time_t timeval);
+
+}
#endif
diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc
index 9a740ef6..e45f04ee 100644
--- a/src/core/basetypes/MCOperationQueue.cc
+++ b/src/core/basetypes/MCOperationQueue.cc
@@ -28,6 +28,7 @@ OperationQueue::OperationQueue()
#if __APPLE__
mDispatchQueue = dispatch_get_main_queue();
#endif
+ _pendingCheckRunning = false;
}
OperationQueue::~OperationQueue()
@@ -175,12 +176,19 @@ void OperationQueue::callbackOnMainThread(Operation * op)
void OperationQueue::checkRunningOnMainThread(void * context)
{
- cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL);
+ retain(); // (4)
+ if (_pendingCheckRunning) {
+ cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL);
+ release(); // (4)
+ }
+ _pendingCheckRunning = true;
performMethodAfterDelay((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, 1);
+ release(); // (1)
}
void OperationQueue::checkRunningAfterDelay(void * context)
{
+ _pendingCheckRunning = false;
pthread_mutex_lock(&mLock);
if (!mQuitting) {
if (mOperations->count() == 0) {
@@ -194,7 +202,7 @@ void OperationQueue::checkRunningAfterDelay(void * context)
// Number of operations can't be changed because it runs on main thread.
// And addOperation() should also be called from main thread.
- release(); // (1)
+ release(); // (4)
}
void OperationQueue::stoppedOnMainThread(void * context)
diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h
index b5f29143..119befcc 100644
--- a/src/core/basetypes/MCOperationQueue.h
+++ b/src/core/basetypes/MCOperationQueue.h
@@ -48,6 +48,7 @@ namespace mailcore {
#if __APPLE__
dispatch_queue_t mDispatchQueue;
#endif
+ bool _pendingCheckRunning;
void startThread();
static void runOperationsOnThread(OperationQueue * queue);