aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/renderer
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-04-28 15:57:20 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-04-28 15:57:51 -0700
commit3e01b4e601a509aa54fa59f6391dcb99d9286de3 (patch)
treee4d0c1ad80071fc8af144f44d8584cff81861a5b /src/core/renderer
parent7960dcf785f9e3db796c2029e1900a0b065ff6dd (diff)
Workaround ICU issue on iOS by implementing date formatter using CoreFoundation on Apple platforms
Diffstat (limited to 'src/core/renderer')
-rw-r--r--src/core/renderer/MCDateFormatter.cpp89
-rw-r--r--src/core/renderer/MCDateFormatter.h5
2 files changed, 92 insertions, 2 deletions
diff --git a/src/core/renderer/MCDateFormatter.cpp b/src/core/renderer/MCDateFormatter.cpp
index 5d4ab2fb..065224d3 100644
--- a/src/core/renderer/MCDateFormatter.cpp
+++ b/src/core/renderer/MCDateFormatter.cpp
@@ -10,6 +10,14 @@
#include <stdlib.h>
#include <unicode/udat.h>
+#if defined(__APPLE__)
+#define USE_COREFOUNDATION 1
+#endif
+
+#if USE_COREFOUNDATION
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
using namespace mailcore;
DateFormatter::DateFormatter()
@@ -20,10 +28,16 @@ DateFormatter::DateFormatter()
mDateFormat = NULL;
mTimezone = NULL;
mLocale = NULL;
+ mAppleDateFormatter = NULL;
}
DateFormatter::~DateFormatter()
{
+#if USE_COREFOUNDATION
+ if (mAppleDateFormatter != NULL) {
+ CFRelease(mAppleDateFormatter);
+ }
+#endif
if (mDateFormatter != NULL) {
udat_close(mDateFormatter);
}
@@ -93,6 +107,21 @@ String * DateFormatter::dateFormat()
String * DateFormatter::stringFromDate(time_t date)
{
prepare();
+#if USE_COREFOUNDATION
+ if (mAppleDateFormatter == NULL)
+ return NULL;
+
+ CFDateRef dateRef = CFDateCreate(NULL, (CFAbsoluteTime) date - kCFAbsoluteTimeIntervalSince1970);
+ CFStringRef string = CFDateFormatterCreateStringWithDate(NULL, (CFDateFormatterRef) mAppleDateFormatter, dateRef);
+ CFIndex len = CFStringGetLength(string);
+ UniChar * buffer = (UniChar *) malloc(sizeof(* buffer) * len);
+ CFStringGetCharacters(string, CFRangeMake(0, len), buffer);
+ String * result = String::stringWithCharacters(buffer, (unsigned int) len);
+ free(buffer);
+ CFRelease(string);
+ CFRelease(dateRef);
+ return result;
+#else
if (mDateFormatter == NULL)
return NULL;
@@ -112,11 +141,31 @@ String * DateFormatter::stringFromDate(time_t date)
result->autorelease();
return result;
+#endif
}
time_t DateFormatter::dateFromString(String * dateString)
{
prepare();
+#if USE_COREFOUNDATION
+ if (mAppleDateFormatter == NULL)
+ return (time_t) -1;
+
+ CFAbsoluteTime absoluteTime;
+ bool r;
+ time_t result;
+ CFStringRef dateCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) dateString->unicodeCharacters(),
+ dateString->length());
+ r = CFDateFormatterGetAbsoluteTimeFromString((CFDateFormatterRef) mAppleDateFormatter, dateCFString,
+ NULL, &absoluteTime);
+ result = (time_t) -1;
+ if (r) {
+ result = (time_t) absoluteTime + kCFAbsoluteTimeIntervalSince1970;
+ }
+ CFRelease(dateCFString);
+
+ return result;
+#else
if (mDateFormatter == NULL)
return (time_t) -1;
@@ -128,7 +177,27 @@ time_t DateFormatter::dateFromString(String * dateString)
}
return date / 1000.;
+#endif
+}
+
+#if USE_COREFOUNDATION
+static CFDateFormatterStyle toAppleStyle(DateFormatStyle style)
+{
+ switch (style) {
+ case DateFormatStyleFull:
+ return kCFDateFormatterFullStyle;
+ case DateFormatStyleLong:
+ return kCFDateFormatterLongStyle;
+ case DateFormatStyleMedium:
+ return kCFDateFormatterMediumStyle;
+ case DateFormatStyleShort:
+ return kCFDateFormatterShortStyle;
+ case DateFormatStyleNone:
+ return kCFDateFormatterNoStyle;
+ }
+ return kCFDateFormatterMediumStyle;
}
+#endif
void DateFormatter::prepare()
{
@@ -154,9 +223,29 @@ void DateFormatter::prepare()
locale = mLocale->UTF8Characters();
}
+#if USE_COREFOUNDATION
+ CFStringRef localeIdentifier = NULL;
+ CFLocaleRef localeRef = NULL;
+ if (mLocale != NULL) {
+ localeIdentifier = CFStringCreateWithCharacters(NULL, (const UniChar *) mLocale->unicodeCharacters(),
+ mLocale->length());
+ localeRef = CFLocaleCreate(NULL, localeIdentifier);
+ }
+ if (localeRef == NULL) {
+ localeRef = CFLocaleCopyCurrent();
+ }
+ mAppleDateFormatter = CFDateFormatterCreate(NULL, localeRef, toAppleStyle(mDateStyle), toAppleStyle(mTimeStyle));
+ if (localeIdentifier != NULL) {
+ CFRelease(localeIdentifier);
+ }
+ if (locale != NULL) {
+ CFRelease(locale);
+ }
+#else
mDateFormatter = udat_open((UDateFormatStyle) mTimeStyle, (UDateFormatStyle) mDateStyle,
locale,
tzID, tzIDLength,
pattern, patternLength,
&err);
+#endif
}
diff --git a/src/core/renderer/MCDateFormatter.h b/src/core/renderer/MCDateFormatter.h
index eb33fe52..4c5a7140 100644
--- a/src/core/renderer/MCDateFormatter.h
+++ b/src/core/renderer/MCDateFormatter.h
@@ -6,8 +6,8 @@
// Copyright (c) 2013 MailCore. All rights reserved.
//
-#ifndef __testUI__MCDateFormatter__
-#define __testUI__MCDateFormatter__
+#ifndef __MAILCORE_MCDATEFORMATTER_H_
+#define __MAILCORE_MCDATEFORMATTER_H_
#include <MailCore/MCBaseTypes.h>
@@ -62,6 +62,7 @@ namespace mailcore {
String * mDateFormat;
String * mTimezone;
String * mLocale;
+ void * mAppleDateFormatter;
void prepare();
};