diff options
author | Matt Ellis <matell@microsoft.com> | 2015-10-14 15:45:03 -0700 |
---|---|---|
committer | Matt Ellis <matell@microsoft.com> | 2015-10-21 13:48:59 -0700 |
commit | 894c6cc94929b2ea842c1b256678ae97855da961 (patch) | |
tree | 9327ed33817873dadf191e3193e255c9ff2b2b8a /src/corefx | |
parent | 4c64b92b4adb277d7e88cdacbc71b2545071847a (diff) | |
download | coreclr-894c6cc94929b2ea842c1b256678ae97855da961.tar.gz coreclr-894c6cc94929b2ea842c1b256678ae97855da961.tar.bz2 coreclr-894c6cc94929b2ea842c1b256678ae97855da961.zip |
Convert DateTimePatternGenerator usage to C
Part of the effort to remove our usage of C++ ICU APIs. The major issue
here was that the C++ API used char*'s for some things whereas the C API
used UChar*'s so we needed to define our own copies of some constants.
We also need to manage a buffer ourselves, instead of being able to use
the underlying buffer of a retured UnicodeString.
Diffstat (limited to 'src/corefx')
-rw-r--r-- | src/corefx/System.Globalization.Native/calendarData.cpp | 42 | ||||
-rw-r--r-- | src/corefx/System.Globalization.Native/holders.h | 11 |
2 files changed, 40 insertions, 13 deletions
diff --git a/src/corefx/System.Globalization.Native/calendarData.cpp b/src/corefx/System.Globalization.Native/calendarData.cpp index 21808f7053..9a9307e855 100644 --- a/src/corefx/System.Globalization.Native/calendarData.cpp +++ b/src/corefx/System.Globalization.Native/calendarData.cpp @@ -26,6 +26,10 @@ #define JAPANESE_LOCALE_AND_CALENDAR "ja_JP@calendar=japanese" +const UChar UDAT_MONTH_DAY_UCHAR[] = {'M', 'M', 'M', 'M', 'd', '\0'}; +const UChar UDAT_YEAR_NUM_MONTH_DAY_UCHAR[] = {'y', 'M', 'd', '\0'}; +const UChar UDAT_YEAR_MONTH_UCHAR[] = {'y', 'M', 'M', 'M', 'M', '\0'}; + /* * These values should be kept in sync with System.Globalization.CalendarId */ @@ -247,15 +251,13 @@ Gets the Month-Day DateTime pattern for the specified locale. CalendarDataResult GetMonthDayPattern(Locale& locale, UChar* sMonthDay, int32_t stringCapacity) { UErrorCode err = U_ZERO_ERROR; - LocalPointer<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(locale, err)); - if (U_FAILURE(err)) - return GetCalendarDataResult(err); + UDateTimePatternGenerator* pGenerator = udatpg_open(locale.getName(), &err); + UDateTimePatternGeneratorHolder generatorHolder(pGenerator, err); - UnicodeString monthDayPattern = generator->getBestPattern(UnicodeString(UDAT_MONTH_DAY), err); if (U_FAILURE(err)) return GetCalendarDataResult(err); - monthDayPattern.extract(sMonthDay, stringCapacity, err); + udatpg_getBestPattern(pGenerator, UDAT_MONTH_DAY_UCHAR, -1, sMonthDay, stringCapacity, &err); return GetCalendarDataResult(err); } @@ -342,23 +344,37 @@ Gets the DateTime pattern for the specified skeleton and invokes the callback with the retrieved value. */ bool InvokeCallbackForDateTimePattern(Locale& locale, - const char* patternSkeleton, + const UChar* patternSkeleton, EnumCalendarInfoCallback callback, const void* context) { UErrorCode err = U_ZERO_ERROR; - LocalPointer<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(locale, err)); + UDateTimePatternGenerator* pGenerator = udatpg_open(locale.getName(), &err); + UDateTimePatternGeneratorHolder generatorHolder(pGenerator, err); + if (U_FAILURE(err)) return false; - UnicodeString pattern = generator->getBestPattern(UnicodeString(patternSkeleton), err); + UErrorCode ignore = U_ZERO_ERROR; + int32_t patternLen = udatpg_getBestPattern(pGenerator, patternSkeleton, -1, nullptr, 0, &ignore); + + UChar* bestPattern = (UChar*)calloc(patternLen + 1, sizeof(UChar)); + + if (bestPattern == nullptr) + { + return false; + } + + udatpg_getBestPattern(pGenerator, patternSkeleton, -1, bestPattern, patternLen + 1, &err); + if (U_SUCCESS(err)) { - callback(pattern.getTerminatedBuffer(), context); - return true; + callback(bestPattern, context); } - return false; + free(bestPattern); + + return U_SUCCESS(err); } /* @@ -504,7 +520,7 @@ extern "C" int32_t EnumCalendarInfo(EnumCalendarInfoCallback callback, // ShortDates to map kShort and kMedium in ICU, but also adding the "yMd" // skeleton as well, as this // closely matches what is used on Windows - return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_NUM_MONTH_DAY, callback, context) && + return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_NUM_MONTH_DAY_UCHAR, callback, context) && InvokeCallbackForDatePattern(locale, DateFormat::kShort, callback, context) && InvokeCallbackForDatePattern(locale, DateFormat::kMedium, callback, context); case LongDates: @@ -512,7 +528,7 @@ extern "C" int32_t EnumCalendarInfo(EnumCalendarInfoCallback callback, return InvokeCallbackForDatePattern(locale, DateFormat::kFull, callback, context) && InvokeCallbackForDatePattern(locale, DateFormat::kLong, callback, context); case YearMonths: - return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_MONTH, callback, context); + return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_MONTH_UCHAR, callback, context); case DayNames: return EnumWeekdays( locale, calendarId, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE, callback, context); diff --git a/src/corefx/System.Globalization.Native/holders.h b/src/corefx/System.Globalization.Native/holders.h index ea757fc30d..4c2f7c71d3 100644 --- a/src/corefx/System.Globalization.Native/holders.h +++ b/src/corefx/System.Globalization.Native/holders.h @@ -5,6 +5,7 @@ #include "unicode/ucal.h" #include "unicode/uenum.h" +#include "unicode/udatpg.h" // IcuHolder is a template that can manage the lifetime of a raw pointer to ensure that it is cleaned up at the correct // time. The general usage pattern is to aquire some ICU resource via an _open call, then construct a holder using the @@ -51,5 +52,15 @@ struct UEnumerationCloser } }; +struct UDateTimePatternGeneratorCloser +{ + public: + void operator()(UDateTimePatternGenerator* pGenerator) const + { + udatpg_close(pGenerator); + } +}; + typedef IcuHolder<UCalendar, UCalendarCloser> UCalendarHolder; typedef IcuHolder<UEnumeration, UEnumerationCloser> UEnumerationHolder; +typedef IcuHolder<UDateTimePatternGenerator, UDateTimePatternGeneratorCloser> UDateTimePatternGeneratorHolder; |