summaryrefslogtreecommitdiff
path: root/intl
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2022-04-26 09:34:34 -0500
committerBrian Smith <brian@dbsoft.org>2022-04-26 10:19:00 -0500
commit378738aaa9924d0b95e2c57f27cbad2b2e644282 (patch)
tree34ce9c4ce3995576604fb4bc47d9405e661daf39 /intl
parent82f11ad8aaeff395629c3a3f72ece43712fd8e72 (diff)
downloaduxp-378738aaa9924d0b95e2c57f27cbad2b2e644282.tar.gz
Issue #1829 - Revert “Issue #1751 - Remove Mac code behind MOZ_WIDGET_TOOLKIT == 'cocoa’”
This reverts commit 1fe9c19305dadf2d5bcaa0e589fcd250389dfa8a.
Diffstat (limited to 'intl')
-rw-r--r--intl/locale/mac/moz.build15
-rw-r--r--intl/locale/mac/nsCollationMacUC.cpp253
-rw-r--r--intl/locale/mac/nsCollationMacUC.h44
-rw-r--r--intl/locale/mac/nsDateTimeFormatMac.cpp266
-rw-r--r--intl/locale/mac/nsDateTimeFormatMac.h61
-rw-r--r--intl/locale/mac/nsMacCharset.cpp59
-rw-r--r--intl/locale/moz.build2
-rw-r--r--intl/lwbrk/moz.build4
-rw-r--r--intl/lwbrk/nsCarbonBreaker.cpp44
9 files changed, 748 insertions, 0 deletions
diff --git a/intl/locale/mac/moz.build b/intl/locale/mac/moz.build
new file mode 100644
index 0000000000..422fd3e3cd
--- /dev/null
+++ b/intl/locale/mac/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ 'nsCollationMacUC.cpp',
+ 'nsDateTimeFormatMac.cpp',
+ 'nsMacCharset.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
+LOCAL_INCLUDES += [
+ '..',
+]
diff --git a/intl/locale/mac/nsCollationMacUC.cpp b/intl/locale/mac/nsCollationMacUC.cpp
new file mode 100644
index 0000000000..d230f4d771
--- /dev/null
+++ b/intl/locale/mac/nsCollationMacUC.cpp
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCollationMacUC.h"
+#include "nsILocaleService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIServiceManager.h"
+#include "prmem.h"
+#include "nsString.h"
+
+NS_IMPL_ISUPPORTS(nsCollationMacUC, nsICollation)
+
+nsCollationMacUC::nsCollationMacUC()
+ : mInit(false)
+ , mHasCollator(false)
+ , mLocaleICU(nullptr)
+ , mLastStrength(-1)
+ , mCollatorICU(nullptr)
+{ }
+
+nsCollationMacUC::~nsCollationMacUC()
+{
+#ifdef DEBUG
+ nsresult res =
+#endif
+ CleanUpCollator();
+ NS_ASSERTION(NS_SUCCEEDED(res), "CleanUpCollator failed");
+ if (mLocaleICU) {
+ free(mLocaleICU);
+ mLocaleICU = nullptr;
+ }
+}
+
+nsresult nsCollationMacUC::ConvertStrength(const int32_t aNSStrength,
+ UCollationStrength* aICUStrength,
+ UColAttributeValue* aCaseLevelOut)
+{
+ NS_ENSURE_ARG_POINTER(aICUStrength);
+ NS_ENSURE_TRUE((aNSStrength < 4), NS_ERROR_FAILURE);
+
+ UCollationStrength strength = UCOL_DEFAULT;
+ UColAttributeValue caseLevel = UCOL_OFF;
+ switch (aNSStrength) {
+ case kCollationCaseInSensitive:
+ strength = UCOL_PRIMARY;
+ break;
+ case kCollationCaseInsensitiveAscii:
+ strength = UCOL_SECONDARY;
+ break;
+ case kCollationAccentInsenstive:
+ caseLevel = UCOL_ON;
+ strength = UCOL_PRIMARY;
+ break;
+ case kCollationCaseSensitive:
+ strength = UCOL_TERTIARY;
+ break;
+ default:
+ NS_WARNING("Bad aNSStrength passed to ConvertStrength.");
+ return NS_ERROR_FAILURE;
+ }
+
+ *aICUStrength = strength;
+ *aCaseLevelOut = caseLevel;
+
+ return NS_OK;
+}
+
+nsresult nsCollationMacUC::ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale)
+{
+ NS_ENSURE_ARG_POINTER(aNSLocale);
+ NS_ENSURE_ARG_POINTER(aICULocale);
+
+ nsAutoString localeString;
+ nsresult res = aNSLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString);
+ NS_ENSURE_TRUE(NS_SUCCEEDED(res) && !localeString.IsEmpty(),
+ NS_ERROR_FAILURE);
+ NS_LossyConvertUTF16toASCII tmp(localeString);
+ tmp.ReplaceChar('-', '_');
+ char* locale = (char*)malloc(tmp.Length() + 1);
+ if (!locale) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ strcpy(locale, tmp.get());
+
+ *aICULocale = locale;
+
+ return NS_OK;
+}
+
+nsresult nsCollationMacUC::EnsureCollator(const int32_t newStrength)
+{
+ NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
+ if (mHasCollator && (mLastStrength == newStrength))
+ return NS_OK;
+
+ nsresult res;
+ res = CleanUpCollator();
+ NS_ENSURE_SUCCESS(res, res);
+
+ NS_ENSURE_TRUE(mLocaleICU, NS_ERROR_NOT_INITIALIZED);
+
+ UErrorCode status;
+ status = U_ZERO_ERROR;
+ mCollatorICU = ucol_open(mLocaleICU, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+
+ UCollationStrength strength;
+ UColAttributeValue caseLevel;
+ res = ConvertStrength(newStrength, &strength, &caseLevel);
+ NS_ENSURE_SUCCESS(res, res);
+
+ status = U_ZERO_ERROR;
+ ucol_setAttribute(mCollatorICU, UCOL_STRENGTH, strength, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+ ucol_setAttribute(mCollatorICU, UCOL_CASE_LEVEL, caseLevel, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+ ucol_setAttribute(mCollatorICU, UCOL_ALTERNATE_HANDLING, UCOL_DEFAULT, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+ ucol_setAttribute(mCollatorICU, UCOL_NUMERIC_COLLATION, UCOL_OFF, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+ ucol_setAttribute(mCollatorICU, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+ ucol_setAttribute(mCollatorICU, UCOL_CASE_FIRST, UCOL_DEFAULT, &status);
+ NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
+
+ mHasCollator = true;
+
+ mLastStrength = newStrength;
+ return NS_OK;
+}
+
+nsresult nsCollationMacUC::CleanUpCollator(void)
+{
+ if (mHasCollator) {
+ ucol_close(mCollatorICU);
+ mHasCollator = false;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCollationMacUC::Initialize(nsILocale* locale)
+{
+ NS_ENSURE_TRUE((!mInit), NS_ERROR_ALREADY_INITIALIZED);
+ nsCOMPtr<nsILocale> appLocale;
+
+ nsresult rv;
+ if (!locale) {
+ nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
+ NS_ENSURE_SUCCESS(rv, rv);
+ locale = appLocale;
+ }
+
+ rv = ConvertLocaleICU(locale, &mLocaleICU);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mInit = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn,
+ uint8_t** key, uint32_t* outLen)
+{
+ NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
+ NS_ENSURE_ARG_POINTER(key);
+ NS_ENSURE_ARG_POINTER(outLen);
+
+ nsresult res = EnsureCollator(strength);
+ NS_ENSURE_SUCCESS(res, res);
+
+ uint32_t stringInLen = stringIn.Length();
+
+ const UChar* str = (const UChar*)stringIn.BeginReading();
+
+ int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0);
+ NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);
+
+ // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc.
+ uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1);
+ if (!newKey) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1);
+ NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);
+
+ *key = newKey;
+ *outLen = keyLength;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1,
+ const nsAString& string2, int32_t* result)
+{
+ NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
+ NS_ENSURE_ARG_POINTER(result);
+ *result = 0;
+
+ nsresult rv = EnsureCollator(strength);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ UCollationResult uresult;
+ uresult = ucol_strcoll(mCollatorICU,
+ (const UChar*)string1.BeginReading(),
+ string1.Length(),
+ (const UChar*)string2.BeginReading(),
+ string2.Length());
+ int32_t res;
+ switch (uresult) {
+ case UCOL_LESS:
+ res = -1;
+ break;
+ case UCOL_EQUAL:
+ res = 0;
+ break;
+ case UCOL_GREATER:
+ res = 1;
+ break;
+ default:
+ MOZ_CRASH("ucol_strcoll returned bad UCollationResult");
+ }
+ *result = res;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCollationMacUC::CompareRawSortKey(const uint8_t* key1, uint32_t len1,
+ const uint8_t* key2, uint32_t len2,
+ int32_t* result)
+{
+ NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
+ NS_ENSURE_ARG_POINTER(key1);
+ NS_ENSURE_ARG_POINTER(key2);
+ NS_ENSURE_ARG_POINTER(result);
+ *result = 0;
+
+ int32_t tmpResult = strcmp((const char*)key1, (const char*)key2);
+ int32_t res;
+ if (tmpResult < 0) {
+ res = -1;
+ } else if (tmpResult > 0) {
+ res = 1;
+ } else {
+ res = 0;
+ }
+ *result = res;
+ return NS_OK;
+}
diff --git a/intl/locale/mac/nsCollationMacUC.h b/intl/locale/mac/nsCollationMacUC.h
new file mode 100644
index 0000000000..46bb0145de
--- /dev/null
+++ b/intl/locale/mac/nsCollationMacUC.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsCollationMacUC_h_
+#define nsCollationMacUC_h_
+
+#include "nsICollation.h"
+#include "nsCollation.h"
+#include "mozilla/Attributes.h"
+
+#include "unicode/ucol.h"
+
+class nsCollationMacUC final : public nsICollation {
+
+public:
+ nsCollationMacUC();
+
+ // nsISupports interface
+ NS_DECL_ISUPPORTS
+
+ // nsICollation interface
+ NS_DECL_NSICOLLATION
+
+protected:
+ ~nsCollationMacUC();
+
+ nsresult ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale);
+ nsresult ConvertStrength(const int32_t aStrength,
+ UCollationStrength* aStrengthOut,
+ UColAttributeValue* aCaseLevelOut);
+ nsresult EnsureCollator(const int32_t newStrength);
+ nsresult CleanUpCollator(void);
+
+private:
+ bool mInit;
+ bool mHasCollator;
+ char* mLocaleICU;
+ int32_t mLastStrength;
+ UCollator* mCollatorICU;
+};
+
+#endif /* nsCollationMacUC_h_ */
diff --git a/intl/locale/mac/nsDateTimeFormatMac.cpp b/intl/locale/mac/nsDateTimeFormatMac.cpp
new file mode 100644
index 0000000000..6ee73292d7
--- /dev/null
+++ b/intl/locale/mac/nsDateTimeFormatMac.cpp
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include "nsIServiceManager.h"
+#include "nsDateTimeFormatMac.h"
+#include <CoreFoundation/CFDateFormatter.h>
+#include "nsIComponentManager.h"
+#include "nsILocaleService.h"
+#include "nsCRT.h"
+#include "plstr.h"
+#include "nsUnicharUtils.h"
+#include "nsTArray.h"
+
+
+NS_IMPL_ISUPPORTS(nsDateTimeFormatMac, nsIDateTimeFormat)
+
+nsresult nsDateTimeFormatMac::Initialize(nsILocale* locale)
+{
+ nsAutoString localeStr;
+ nsAutoString category(NS_LITERAL_STRING("NSILOCALE_TIME"));
+ nsresult res;
+
+ // use cached info if match with stored locale
+ if (nullptr == locale) {
+ if (!mLocale.IsEmpty() &&
+ mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
+ return NS_OK;
+ }
+ }
+ else {
+ res = locale->GetCategory(category, localeStr);
+ if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
+ if (!mLocale.IsEmpty() &&
+ mLocale.Equals(localeStr,
+ nsCaseInsensitiveStringComparator())) {
+ return NS_OK;
+ }
+ }
+ }
+
+ // get application locale
+ nsCOMPtr<nsILocaleService> localeService =
+ do_GetService(NS_LOCALESERVICE_CONTRACTID, &res);
+ if (NS_SUCCEEDED(res)) {
+ nsCOMPtr<nsILocale> appLocale;
+ res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
+ if (NS_SUCCEEDED(res)) {
+ res = appLocale->GetCategory(category, localeStr);
+ if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
+ mAppLocale = localeStr; // cache app locale name
+ }
+ }
+ }
+
+ // use app default if no locale specified
+ if (nullptr == locale) {
+ mUseDefaultLocale = true;
+ }
+ else {
+ mUseDefaultLocale = false;
+ res = locale->GetCategory(category, localeStr);
+ }
+
+ if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
+ mLocale.Assign(localeStr); // cache locale name
+ }
+
+ return res;
+}
+
+// performs a locale sensitive date formatting operation on the time_t parameter
+nsresult nsDateTimeFormatMac::FormatTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const time_t timetTime,
+ nsAString& stringOut)
+{
+ struct tm tmTime;
+ return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime_r(&timetTime, &tmTime), stringOut);
+}
+
+// performs a locale sensitive date formatting operation on the struct tm parameter
+nsresult nsDateTimeFormatMac::FormatTMTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const struct tm* tmTime,
+ nsAString& stringOut)
+{
+ nsresult res = NS_OK;
+
+ // set up locale data
+ (void) Initialize(locale);
+
+ // return, nothing to format
+ if (dateFormatSelector == kDateFormatNone && timeFormatSelector == kTimeFormatNone) {
+ stringOut.Truncate();
+ return NS_OK;
+ }
+
+ NS_ASSERTION(tmTime->tm_mon >= 0, "tm is not set correctly");
+ NS_ASSERTION(tmTime->tm_mday >= 1, "tm is not set correctly");
+ NS_ASSERTION(tmTime->tm_hour >= 0, "tm is not set correctly");
+ NS_ASSERTION(tmTime->tm_min >= 0, "tm is not set correctly");
+ NS_ASSERTION(tmTime->tm_sec >= 0, "tm is not set correctly");
+ NS_ASSERTION(tmTime->tm_wday >= 0, "tm is not set correctly");
+
+ // Got the locale for the formatter:
+ CFLocaleRef formatterLocale;
+ if (!locale) {
+ formatterLocale = CFLocaleCopyCurrent();
+ } else {
+ CFStringRef localeStr = CFStringCreateWithCharacters(nullptr,
+ reinterpret_cast<const UniChar*>(mLocale.get()),
+ mLocale.Length());
+ formatterLocale = CFLocaleCreate(nullptr, localeStr);
+ CFRelease(localeStr);
+ }
+
+ // Get the date style for the formatter:
+ CFDateFormatterStyle dateStyle;
+ switch (dateFormatSelector) {
+ case kDateFormatLong:
+ dateStyle = kCFDateFormatterLongStyle;
+ break;
+ case kDateFormatShort:
+ dateStyle = kCFDateFormatterShortStyle;
+ break;
+ case kDateFormatYearMonth:
+ case kDateFormatWeekday:
+ dateStyle = kCFDateFormatterNoStyle; // formats handled below
+ break;
+ case kDateFormatNone:
+ dateStyle = kCFDateFormatterNoStyle;
+ break;
+ default:
+ NS_ERROR("Unknown nsDateFormatSelector");
+ res = NS_ERROR_FAILURE;
+ dateStyle = kCFDateFormatterNoStyle;
+ }
+
+ // Get the time style for the formatter:
+ CFDateFormatterStyle timeStyle;
+ switch (timeFormatSelector) {
+ case kTimeFormatSeconds:
+ case kTimeFormatSecondsForce24Hour: // 24 hour part fixed below
+ timeStyle = kCFDateFormatterMediumStyle;
+ break;
+ case kTimeFormatNoSeconds:
+ case kTimeFormatNoSecondsForce24Hour: // 24 hour part fixed below
+ timeStyle = kCFDateFormatterShortStyle;
+ break;
+ case kTimeFormatNone:
+ timeStyle = kCFDateFormatterNoStyle;
+ break;
+ default:
+ NS_ERROR("Unknown nsTimeFormatSelector");
+ res = NS_ERROR_FAILURE;
+ timeStyle = kCFDateFormatterNoStyle;
+ }
+
+ // Create the formatter and fix up its formatting as necessary:
+ CFDateFormatterRef formatter =
+ CFDateFormatterCreate(nullptr, formatterLocale, dateStyle, timeStyle);
+
+ CFRelease(formatterLocale);
+
+ if (dateFormatSelector == kDateFormatYearMonth ||
+ dateFormatSelector == kDateFormatWeekday) {
+ CFStringRef dateFormat =
+ dateFormatSelector == kDateFormatYearMonth ? CFSTR("yyyy/MM ") : CFSTR("EEE ");
+
+ CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
+ CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
+ CFStringInsert(newFormat, 0, dateFormat);
+ CFDateFormatterSetFormat(formatter, newFormat);
+ CFRelease(newFormat); // note we don't own oldFormat
+ }
+
+ if (timeFormatSelector == kTimeFormatSecondsForce24Hour ||
+ timeFormatSelector == kTimeFormatNoSecondsForce24Hour) {
+ // Replace "h" with "H", and remove "a":
+ CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
+ CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
+ CFIndex replaceCount = CFStringFindAndReplace(newFormat,
+ CFSTR("h"), CFSTR("H"),
+ CFRangeMake(0, CFStringGetLength(newFormat)),
+ 0);
+ NS_ASSERTION(replaceCount <= 2, "Unexpected number of \"h\" occurrences");
+ replaceCount = CFStringFindAndReplace(newFormat,
+ CFSTR("a"), CFSTR(""),
+ CFRangeMake(0, CFStringGetLength(newFormat)),
+ 0);
+ NS_ASSERTION(replaceCount <= 1, "Unexpected number of \"a\" occurrences");
+ CFDateFormatterSetFormat(formatter, newFormat);
+ CFRelease(newFormat); // note we don't own oldFormat
+ }
+
+ // Now get the formatted date:
+ CFGregorianDate date;
+ date.second = tmTime->tm_sec;
+ date.minute = tmTime->tm_min;
+ date.hour = tmTime->tm_hour;
+ date.day = tmTime->tm_mday; // Mac is 1-based, tm is 1-based
+ date.month = tmTime->tm_mon + 1; // Mac is 1-based, tm is 0-based
+ date.year = tmTime->tm_year + 1900;
+
+ CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); // tmTime is in local time
+ CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
+ CFRelease(timeZone);
+
+ CFStringRef formattedDate = CFDateFormatterCreateStringWithAbsoluteTime(nullptr,
+ formatter,
+ absTime);
+
+ CFIndex stringLen = CFStringGetLength(formattedDate);
+
+ AutoTArray<UniChar, 256> stringBuffer;
+ stringBuffer.SetLength(stringLen + 1);
+ CFStringGetCharacters(formattedDate, CFRangeMake(0, stringLen), stringBuffer.Elements());
+ stringOut.Assign(reinterpret_cast<char16_t*>(stringBuffer.Elements()), stringLen);
+
+ CFRelease(formattedDate);
+ CFRelease(formatter);
+
+ return res;
+}
+
+// performs a locale sensitive date formatting operation on the PRTime parameter
+nsresult nsDateTimeFormatMac::FormatPRTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const PRTime prTime,
+ nsAString& stringOut)
+{
+ PRExplodedTime explodedTime;
+ PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
+
+ return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
+}
+
+// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
+nsresult nsDateTimeFormatMac::FormatPRExplodedTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const PRExplodedTime* explodedTime,
+ nsAString& stringOut)
+{
+ struct tm tmTime;
+ memset( &tmTime, 0, sizeof(tmTime) );
+
+ tmTime.tm_yday = explodedTime->tm_yday;
+ tmTime.tm_wday = explodedTime->tm_wday;
+ tmTime.tm_year = explodedTime->tm_year;
+ tmTime.tm_year -= 1900;
+ tmTime.tm_mon = explodedTime->tm_month;
+ tmTime.tm_mday = explodedTime->tm_mday;
+ tmTime.tm_hour = explodedTime->tm_hour;
+ tmTime.tm_min = explodedTime->tm_min;
+ tmTime.tm_sec = explodedTime->tm_sec;
+
+ return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
+}
+
diff --git a/intl/locale/mac/nsDateTimeFormatMac.h b/intl/locale/mac/nsDateTimeFormatMac.h
new file mode 100644
index 0000000000..dfdf703780
--- /dev/null
+++ b/intl/locale/mac/nsDateTimeFormatMac.h
@@ -0,0 +1,61 @@
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsDateTimeFormatMac_h__
+#define nsDateTimeFormatMac_h__
+
+
+#include "nsCOMPtr.h"
+#include "nsIDateTimeFormat.h"
+
+
+class nsDateTimeFormatMac : public nsIDateTimeFormat {
+
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ // performs a locale sensitive date formatting operation on the time_t parameter
+ NS_IMETHOD FormatTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const time_t timetTime,
+ nsAString& stringOut) override;
+
+ // performs a locale sensitive date formatting operation on the struct tm parameter
+ NS_IMETHOD FormatTMTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const struct tm* tmTime,
+ nsAString& stringOut) override;
+ // performs a locale sensitive date formatting operation on the PRTime parameter
+ NS_IMETHOD FormatPRTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const PRTime prTime,
+ nsAString& stringOut) override;
+
+ // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
+ NS_IMETHOD FormatPRExplodedTime(nsILocale* locale,
+ const nsDateFormatSelector dateFormatSelector,
+ const nsTimeFormatSelector timeFormatSelector,
+ const PRExplodedTime* explodedTime,
+ nsAString& stringOut) override;
+
+ nsDateTimeFormatMac() {}
+
+protected:
+ virtual ~nsDateTimeFormatMac() {}
+
+private:
+ // init this interface to a specified locale
+ NS_IMETHOD Initialize(nsILocale* locale);
+
+ nsString mLocale;
+ nsString mAppLocale;
+ bool mUseDefaultLocale;
+};
+
+#endif /* nsDateTimeFormatMac_h__ */
diff --git a/intl/locale/mac/nsMacCharset.cpp b/intl/locale/mac/nsMacCharset.cpp
new file mode 100644
index 0000000000..956560fba8
--- /dev/null
+++ b/intl/locale/mac/nsMacCharset.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <Carbon/Carbon.h>
+#include "nsIPlatformCharset.h"
+#include "nsCOMPtr.h"
+#include "nsIServiceManager.h"
+#include "nsReadableUtils.h"
+#include "nsPlatformCharset.h"
+#include "nsEncoderDecoderUtils.h"
+
+NS_IMPL_ISUPPORTS(nsPlatformCharset, nsIPlatformCharset)
+
+nsPlatformCharset::nsPlatformCharset()
+{
+}
+nsPlatformCharset::~nsPlatformCharset()
+{
+}
+
+NS_IMETHODIMP
+nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsACString& oResult)
+{
+ oResult.AssignLiteral("UTF-8");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACString &oResult)
+{
+ oResult.AssignLiteral("UTF-8");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPlatformCharset::Init()
+{
+ return NS_OK;
+}
+
+nsresult
+nsPlatformCharset::MapToCharset(nsAString& inANSICodePage, nsACString& outCharset)
+{
+ return NS_OK;
+}
+
+nsresult
+nsPlatformCharset::InitGetCharset(nsACString &oString)
+{
+ return NS_OK;
+}
+
+nsresult
+nsPlatformCharset::VerifyCharset(nsCString &aCharset)
+{
+ return NS_OK;
+}
diff --git a/intl/locale/moz.build b/intl/locale/moz.build
index 4b3b3c0b88..94a30873ba 100644
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -9,6 +9,8 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
if toolkit == 'windows':
DIRS += ['windows']
+elif toolkit == 'cocoa':
+ DIRS += ['mac']
else:
DIRS += ['unix']
diff --git a/intl/lwbrk/moz.build b/intl/lwbrk/moz.build
index dc7c2df1a2..da701be5e5 100644
--- a/intl/lwbrk/moz.build
+++ b/intl/lwbrk/moz.build
@@ -32,6 +32,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [
'nsUniscribeBreaker.cpp',
]
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ UNIFIED_SOURCES += [
+ 'nsCarbonBreaker.cpp',
+ ]
else:
SOURCES += [
'nsRuleBreaker.cpp',
diff --git a/intl/lwbrk/nsCarbonBreaker.cpp b/intl/lwbrk/nsCarbonBreaker.cpp
new file mode 100644
index 0000000000..1b37bc1298
--- /dev/null
+++ b/intl/lwbrk/nsCarbonBreaker.cpp
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <stdint.h>
+#include "nsDebug.h"
+#include "nscore.h"
+
+void
+NS_GetComplexLineBreaks(const char16_t* aText, uint32_t aLength,
+ uint8_t* aBreakBefore)
+{
+ NS_ASSERTION(aText, "aText shouldn't be null");
+
+ memset(aBreakBefore, 0, aLength * sizeof(uint8_t));
+
+ CFStringRef str = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(aText), aLength, kCFAllocatorNull);
+ if (!str) {
+ return;
+ }
+
+ CFStringTokenizerRef st = ::CFStringTokenizerCreate(kCFAllocatorDefault, str,
+ ::CFRangeMake(0, aLength),
+ kCFStringTokenizerUnitLineBreak,
+ nullptr);
+ if (!st) {
+ ::CFRelease(str);
+ return;
+ }
+
+ CFStringTokenizerTokenType tt = ::CFStringTokenizerAdvanceToNextToken(st);
+ while (tt != kCFStringTokenizerTokenNone) {
+ CFRange r = ::CFStringTokenizerGetCurrentTokenRange(st);
+ if (r.location != 0) { // Ignore leading edge
+ aBreakBefore[r.location] = true;
+ }
+ tt = CFStringTokenizerAdvanceToNextToken(st);
+ }
+
+ ::CFRelease(st);
+ ::CFRelease(str);
+}