| /* |
| * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>. All rights reserved. |
| * |
| * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under |
| * the terms of the APSL version 2.0 (see below). |
| * |
| * For information about changes from the original Apple source release can be found by reviewing the |
| * source control system for the project at https://sourceforge.net/svn/?group_id=246198. |
| * |
| * The original license information is as follows: |
| * |
| * Copyright (c) 2008 Apple Inc. All rights reserved. |
| * |
| * @APPLE_LICENSE_HEADER_START@ |
| * |
| * This file contains Original Code and/or Modifications of Original Code |
| * as defined in and that are subject to the Apple Public Source License |
| * Version 2.0 (the 'License'). You may not use this file except in |
| * compliance with the License. Please obtain a copy of the License at |
| * http://www.opensource.apple.com/apsl/ and read it before using this |
| * file. |
| * |
| * The Original Code and all software distributed under the License are |
| * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| * Please see the License for the specific language governing rights and |
| * limitations under the License. |
| * |
| * @APPLE_LICENSE_HEADER_END@ |
| */ |
| /* CFDateFormatter.c |
| Copyright 2002-2003, Apple, Inc. All rights reserved. |
| Responsibility: Christopher Kane |
| */ |
| |
| #include <CoreFoundation/CFDateFormatter.h> |
| #include <CoreFoundation/CFDate.h> |
| #include <CoreFoundation/CFTimeZone.h> |
| #include <CoreFoundation/CFCalendar.h> |
| #include <CoreFoundation/CFNumber.h> |
| #include "CFInternal.h" |
| #include <unicode/udat.h> |
| #include <math.h> |
| #include <float.h> |
| |
| extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz); |
| #ifdef DEPLOYMENT_TARGET_WINDOWS |
| extern CFAbsoluteTime __CFDateWindowsSystemTimeToAbsoluteTime(SYSTEMTIME *time); |
| #endif |
| static void __CFDateFormatterCustomize(CFDateFormatterRef formatter); |
| |
| CF_EXPORT const CFStringRef kCFDateFormatterCalendarIdentifier; |
| |
| #define BUFFER_SIZE 768 |
| |
| struct __CFDateFormatter { |
| CFRuntimeBase _base; |
| UDateFormat *_df; |
| CFLocaleRef _locale; |
| CFDateFormatterStyle _timeStyle; |
| CFDateFormatterStyle _dateStyle; |
| CFStringRef _format; |
| CFStringRef _defformat; |
| CFStringRef _calendarName; |
| CFTimeZoneRef _tz; |
| CFDateRef _defaultDate; |
| }; |
| |
| static CFStringRef __CFDateFormatterCopyDescription(CFTypeRef cf) { |
| CFDateFormatterRef formatter = (CFDateFormatterRef)cf; |
| return CFStringCreateWithFormat(CFGetAllocator(formatter), NULL, CFSTR("<CFDateFormatter %p [%p]>"), cf, CFGetAllocator(formatter)); |
| } |
| |
| static void __CFDateFormatterDeallocate(CFTypeRef cf) { |
| CFDateFormatterRef formatter = (CFDateFormatterRef)cf; |
| if (formatter->_df) udat_close(formatter->_df); |
| if (formatter->_locale) CFRelease(formatter->_locale); |
| if (formatter->_format) CFRelease(formatter->_format); |
| if (formatter->_defformat) CFRelease(formatter->_defformat); |
| if (formatter->_calendarName) CFRelease(formatter->_calendarName); |
| if (formatter->_tz) CFRelease(formatter->_tz); |
| if (formatter->_defaultDate) CFRelease(formatter->_defaultDate); |
| } |
| |
| static CFTypeID __kCFDateFormatterTypeID = _kCFRuntimeNotATypeID; |
| |
| static const CFRuntimeClass __CFDateFormatterClass = { |
| 0, |
| "CFDateFormatter", |
| NULL, // init |
| NULL, // copy |
| __CFDateFormatterDeallocate, |
| NULL, |
| NULL, |
| NULL, // |
| __CFDateFormatterCopyDescription |
| }; |
| |
| static void __CFDateFormatterInitialize(void) { |
| __kCFDateFormatterTypeID = _CFRuntimeRegisterClass(&__CFDateFormatterClass); |
| } |
| |
| CFTypeID CFDateFormatterGetTypeID(void) { |
| if (_kCFRuntimeNotATypeID == __kCFDateFormatterTypeID) __CFDateFormatterInitialize(); |
| return __kCFDateFormatterTypeID; |
| } |
| |
| CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef locale, CFDateFormatterStyle dateStyle, CFDateFormatterStyle timeStyle) { |
| struct __CFDateFormatter *memory; |
| uint32_t size = sizeof(struct __CFDateFormatter) - sizeof(CFRuntimeBase); |
| if (allocator == NULL) allocator = __CFGetDefaultAllocator(); |
| __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); |
| if (locale) __CFGenericValidateType(locale, CFLocaleGetTypeID()); |
| memory = (struct __CFDateFormatter *)_CFRuntimeCreateInstance(allocator, CFDateFormatterGetTypeID(), size, NULL); |
| if (NULL == memory) { |
| return NULL; |
| } |
| memory->_df = NULL; |
| memory->_locale = NULL; |
| memory->_format = NULL; |
| memory->_defformat = NULL; |
| memory->_calendarName = NULL; |
| memory->_tz = NULL; |
| memory->_defaultDate = NULL; |
| if (NULL == locale) locale = CFLocaleGetSystem(); |
| memory->_dateStyle = dateStyle; |
| memory->_timeStyle = timeStyle; |
| int32_t udstyle, utstyle; |
| switch (dateStyle) { |
| case kCFDateFormatterNoStyle: udstyle = UDAT_NONE; break; |
| case kCFDateFormatterShortStyle: udstyle = UDAT_SHORT; break; |
| case kCFDateFormatterMediumStyle: udstyle = UDAT_MEDIUM; break; |
| case kCFDateFormatterLongStyle: udstyle = UDAT_LONG; break; |
| case kCFDateFormatterFullStyle: udstyle = UDAT_FULL; break; |
| default: |
| CFAssert2(0, __kCFLogAssertion, "%s(): unknown date style %d", __PRETTY_FUNCTION__, dateStyle); |
| udstyle = UDAT_MEDIUM; |
| memory->_dateStyle = kCFDateFormatterMediumStyle; |
| break; |
| } |
| switch (timeStyle) { |
| case kCFDateFormatterNoStyle: utstyle = UDAT_NONE; break; |
| case kCFDateFormatterShortStyle: utstyle = UDAT_SHORT; break; |
| case kCFDateFormatterMediumStyle: utstyle = UDAT_MEDIUM; break; |
| case kCFDateFormatterLongStyle: utstyle = UDAT_LONG; break; |
| case kCFDateFormatterFullStyle: utstyle = UDAT_FULL; break; |
| default: |
| CFAssert2(0, __kCFLogAssertion, "%s(): unknown time style %d", __PRETTY_FUNCTION__, timeStyle); |
| utstyle = UDAT_MEDIUM; |
| memory->_timeStyle = kCFDateFormatterMediumStyle; |
| break; |
| } |
| CFStringRef localeName = locale ? CFLocaleGetIdentifier(locale) : CFSTR(""); |
| char buffer[BUFFER_SIZE]; |
| const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII); |
| if (NULL == cstr) { |
| if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer; |
| } |
| if (NULL == cstr) { |
| CFRelease(memory); |
| return NULL; |
| } |
| UChar ubuffer[BUFFER_SIZE]; |
| memset(ubuffer, 0x00, sizeof(UChar) * BUFFER_SIZE); |
| memory->_tz = CFTimeZoneCopyDefault(); |
| #ifdef DEPLOYMENT_TARGET_WINDOWS |
| // ICU doesn't know about Windows Time Zone names. It'll understand the abbreviation for the non-daylight saving time, though |
| TIME_ZONE_INFORMATION *tzi = (TIME_ZONE_INFORMATION *)CFDataGetBytePtr(CFTimeZoneGetData(memory->_tz)); |
| CFAbsoluteTime at = __CFDateWindowsSystemTimeToAbsoluteTime(&tzi->DaylightDate); |
| // subtract a day to get us off the time change boundary |
| at -= (60 * 60 * 24); |
| CFStringRef tznam = CFTimeZoneCopyAbbreviation(memory->_tz, at); |
| #else |
| CFStringRef tznam = CFTimeZoneGetName(memory->_tz); |
| #endif |
| CFIndex cnt = CFStringGetLength(tznam); |
| if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE; |
| CFStringGetCharacters(tznam, CFRangeMake(0, cnt), (UniChar *)ubuffer); |
| UErrorCode status = U_ZERO_ERROR; |
| memory->_df = udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, cstr, ubuffer, cnt, NULL, 0, &status); |
| CFAssert2(memory->_df, __kCFLogAssertion, "%s(): error (%d) creating date formatter", __PRETTY_FUNCTION__, status); |
| if (NULL == memory->_df) { |
| CFRelease(memory->_tz); |
| CFRelease(memory); |
| return NULL; |
| } |
| udat_setLenient(memory->_df, 0); |
| if (kCFDateFormatterNoStyle == dateStyle && kCFDateFormatterNoStyle == timeStyle) { |
| udat_applyPattern(memory->_df, false, NULL, 0); |
| } |
| CFTypeRef calident = CFLocaleGetValue(locale, kCFLocaleCalendarIdentifier); |
| if (calident && CFEqual(calident, kCFGregorianCalendar)) { |
| status = U_ZERO_ERROR; |
| udat_set2DigitYearStart(memory->_df, -631152000000.0, &status); // 1950-01-01 00:00:00 GMT |
| } |
| memory->_locale = locale ? CFLocaleCreateCopy(allocator, locale) : CFLocaleGetSystem(); |
| __CFDateFormatterCustomize(memory); |
| status = U_ZERO_ERROR; |
| int32_t ret = udat_toPattern(memory->_df, false, ubuffer, BUFFER_SIZE, &status); |
| if (U_SUCCESS(status) && ret <= BUFFER_SIZE) { |
| memory->_format = CFStringCreateWithCharacters(allocator, (const UniChar *)ubuffer, ret); |
| } |
| memory->_defformat = memory->_format ? (CFStringRef)CFRetain(memory->_format) : NULL; |
| return (CFDateFormatterRef)memory; |
| } |
| |
| extern CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale); |
| |
| static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bool doTime) { |
| CFIndex formatStyle = doTime ? formatter->_timeStyle : formatter->_dateStyle; |
| CFStringRef prefName = doTime ? CFSTR("AppleICUTimeFormatStrings") : CFSTR("AppleICUDateFormatStrings"); |
| if (kCFDateFormatterNoStyle != formatStyle) { |
| CFStringRef pref = NULL; |
| CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale); |
| CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, prefName) : NULL; |
| if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { |
| CFStringRef key; |
| switch (formatStyle) { |
| case kCFDateFormatterShortStyle: key = CFSTR("1"); break; |
| case kCFDateFormatterMediumStyle: key = CFSTR("2"); break; |
| case kCFDateFormatterLongStyle: key = CFSTR("3"); break; |
| case kCFDateFormatterFullStyle: key = CFSTR("4"); break; |
| default: key = CFSTR("0"); break; |
| } |
| pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key); |
| } |
| if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) { |
| int32_t icustyle = UDAT_NONE; |
| switch (formatStyle) { |
| case kCFDateFormatterShortStyle: icustyle = UDAT_SHORT; break; |
| case kCFDateFormatterMediumStyle: icustyle = UDAT_MEDIUM; break; |
| case kCFDateFormatterLongStyle: icustyle = UDAT_LONG; break; |
| case kCFDateFormatterFullStyle: icustyle = UDAT_FULL; break; |
| } |
| CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale); |
| char buffer[BUFFER_SIZE]; |
| const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII); |
| if (NULL == cstr) { |
| if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer; |
| } |
| UErrorCode status = U_ZERO_ERROR; |
| UDateFormat *df = udat_open((UDateFormatStyle)(doTime ? icustyle : UDAT_NONE), (UDateFormatStyle)(doTime ? UDAT_NONE : icustyle), cstr, NULL, 0, NULL, 0, &status); |
| if (NULL != df) { |
| UChar ubuffer[BUFFER_SIZE]; |
| status = U_ZERO_ERROR; |
| int32_t date_len = udat_toPattern(df, false, ubuffer, BUFFER_SIZE, &status); |
| if (U_SUCCESS(status) && date_len <= BUFFER_SIZE) { |
| CFStringRef dateString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)ubuffer, date_len); |
| status = U_ZERO_ERROR; |
| int32_t formatter_len = udat_toPattern(formatter->_df, false, ubuffer, BUFFER_SIZE, &status); |
| if (U_SUCCESS(status) && formatter_len <= BUFFER_SIZE) { |
| CFMutableStringRef formatString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); |
| CFStringAppendCharacters(formatString, (UniChar *)ubuffer, formatter_len); |
| // find dateString inside formatString, substitute the pref in that range |
| CFRange result; |
| if (CFStringFindWithOptions(formatString, dateString, CFRangeMake(0, formatter_len), 0, &result)) { |
| CFStringReplace(formatString, result, pref); |
| int32_t new_len = CFStringGetLength(formatString); |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, new_buffer, new_len); |
| #else |
| UChar new_buffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific |
| #endif |
| const UChar *new_ustr = (UChar *)CFStringGetCharactersPtr(formatString); |
| if (NULL == new_ustr) { |
| CFStringGetCharacters(formatString, CFRangeMake(0, new_len), (UniChar *)new_buffer); |
| new_ustr = new_buffer; |
| } |
| status = U_ZERO_ERROR; |
| // udat_applyPattern(formatter->_df, false, new_ustr, new_len, &status); |
| udat_applyPattern(formatter->_df, false, new_ustr, new_len); |
| } |
| CFRelease(formatString); |
| } |
| CFRelease(dateString); |
| } |
| udat_close(df); |
| } |
| } |
| } |
| } |
| |
| static void __CFDateFormatterApplySymbolPrefs(const void *key, const void *value, void *context) { |
| if (CFGetTypeID(key) == CFStringGetTypeID() && CFGetTypeID(value) == CFArrayGetTypeID()) { |
| CFDateFormatterRef formatter = (CFDateFormatterRef)context; |
| UDateFormatSymbolType sym = (UDateFormatSymbolType)CFStringGetIntValue((CFStringRef)key); |
| CFArrayRef array = (CFArrayRef)value; |
| CFIndex idx, cnt = CFArrayGetCount(array); |
| for (idx = 0; idx < cnt; idx++) { |
| CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx); |
| if (CFGetTypeID(item) != CFStringGetTypeID()) continue; |
| CFIndex item_cnt = CFStringGetLength(item); |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt)); |
| #else |
| UChar item_buffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific |
| #endif |
| UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); |
| if (NULL == item_ustr) { |
| item_cnt = __CFMin(BUFFER_SIZE, item_cnt); |
| CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); |
| item_ustr = item_buffer; |
| } |
| UErrorCode status = U_ZERO_ERROR; |
| udat_setSymbols(formatter->_df, sym, idx, item_ustr, item_cnt, &status); |
| } |
| } |
| } |
| |
| static void __CFDateFormatterCustomize(CFDateFormatterRef formatter) { |
| __substituteFormatStringFromPrefsDF(formatter, false); |
| __substituteFormatStringFromPrefsDF(formatter, true); |
| CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale); |
| CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateTimeSymbols")) : NULL; |
| if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) { |
| CFDictionaryApplyFunction((CFDictionaryRef)metapref, __CFDateFormatterApplySymbolPrefs, formatter); |
| } |
| } |
| |
| CFLocaleRef CFDateFormatterGetLocale(CFDateFormatterRef formatter) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| return formatter->_locale; |
| } |
| |
| CFDateFormatterStyle CFDateFormatterGetDateStyle(CFDateFormatterRef formatter) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| return formatter->_dateStyle; |
| } |
| |
| CFDateFormatterStyle CFDateFormatterGetTimeStyle(CFDateFormatterRef formatter) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| return formatter->_timeStyle; |
| } |
| |
| CFStringRef CFDateFormatterGetFormat(CFDateFormatterRef formatter) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| return formatter->_format; |
| } |
| |
| void CFDateFormatterSetFormat(CFDateFormatterRef formatter, CFStringRef formatString) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(formatString, CFStringGetTypeID()); |
| CFIndex cnt = CFStringGetLength(formatString); |
| CFAssert1(cnt <= 1024, __kCFLogAssertion, "%s(): format string too long", __PRETTY_FUNCTION__); |
| if (formatter->_format != formatString && cnt <= 1024) { |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, ubuffer, cnt); |
| #else |
| UChar ubuffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific |
| #endif |
| const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)formatString); |
| if (NULL == ustr) { |
| CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)ubuffer); |
| ustr = ubuffer; |
| } |
| UErrorCode status = U_ZERO_ERROR; |
| // udat_applyPattern(formatter->_df, false, ustr, cnt, &status); |
| udat_applyPattern(formatter->_df, false, ustr, cnt); |
| if (U_SUCCESS(status)) { |
| if (formatter->_format) CFRelease(formatter->_format); |
| formatter->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(formatter), formatString); |
| } |
| } |
| } |
| |
| CFStringRef CFDateFormatterCreateStringWithDate(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFDateRef date) { |
| if (allocator == NULL) allocator = __CFGetDefaultAllocator(); |
| __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(date, CFDateGetTypeID()); |
| return CFDateFormatterCreateStringWithAbsoluteTime(allocator, formatter, CFDateGetAbsoluteTime(date)); |
| } |
| |
| CFStringRef CFDateFormatterCreateStringWithAbsoluteTime(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFAbsoluteTime at) { |
| if (allocator == NULL) allocator = __CFGetDefaultAllocator(); |
| __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| UChar *ustr = NULL, ubuffer[BUFFER_SIZE]; |
| UErrorCode status = U_ZERO_ERROR; |
| CFIndex used, cnt = BUFFER_SIZE; |
| UDate ud = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0 + 0.5; |
| used = udat_format(formatter->_df, ud, ubuffer, cnt, NULL, &status); |
| if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) { |
| cnt = used + 1; |
| ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0); |
| status = U_ZERO_ERROR; |
| used = udat_format(formatter->_df, ud, ustr, cnt, NULL, &status); |
| } |
| CFStringRef string = NULL; |
| if (U_SUCCESS(status)) { |
| string = CFStringCreateWithCharacters(allocator, (const UniChar *)(ustr ? ustr : ubuffer), used); |
| } |
| if (ustr) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ustr); |
| return string; |
| } |
| |
| CFDateRef CFDateFormatterCreateDateFromString(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFStringRef string, CFRange *rangep) { |
| if (allocator == NULL) allocator = __CFGetDefaultAllocator(); |
| __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(string, CFStringGetTypeID()); |
| CFAbsoluteTime at; |
| if (CFDateFormatterGetAbsoluteTimeFromString(formatter, string, rangep, &at)) { |
| return CFDateCreate(allocator, at); |
| } |
| return NULL; |
| } |
| |
| Boolean CFDateFormatterGetAbsoluteTimeFromString(CFDateFormatterRef formatter, CFStringRef string, CFRange *rangep, CFAbsoluteTime *atp) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(string, CFStringGetTypeID()); |
| CFRange range = {0, 0}; |
| if (rangep) { |
| range = *rangep; |
| } else { |
| range.length = CFStringGetLength(string); |
| } |
| if (1024 < range.length) range.length = 1024; |
| const UChar *ustr = (UChar *)CFStringGetCharactersPtr(string); |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, ubuffer, (NULL == ustr) ? range.length : 1); |
| #else |
| UChar ubuffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific |
| #endif |
| if (NULL == ustr) { |
| CFStringGetCharacters(string, range, (UniChar *)ubuffer); |
| ustr = ubuffer; |
| } else { |
| ustr += range.location; |
| } |
| UDate udate; |
| int32_t dpos = 0; |
| UErrorCode status = U_ZERO_ERROR; |
| if (formatter->_defaultDate) { |
| CFAbsoluteTime at = CFDateGetAbsoluteTime(formatter->_defaultDate); |
| udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; |
| UDateFormat *df2 = udat_clone(formatter->_df, &status); |
| UCalendar *cal2 = (UCalendar *)udat_getCalendar(df2); |
| ucal_setMillis(cal2, udate, &status); |
| udat_parseCalendar(formatter->_df, cal2, ustr, range.length, &dpos, &status); |
| udate = ucal_getMillis(cal2, &status); |
| udat_close(df2); |
| } else { |
| udate = udat_parse(formatter->_df, ustr, range.length, &dpos, &status); |
| } |
| if (rangep) rangep->length = dpos; |
| if (U_FAILURE(status)) { |
| return false; |
| } |
| if (atp) { |
| *atp = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970; |
| } |
| return true; |
| } |
| |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| #define SET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \ |
| __CFGenericValidateType(value, CFArrayGetTypeID()); \ |
| CFArrayRef array = (CFArrayRef)value; \ |
| CFIndex idx, cnt = CFArrayGetCount(array); \ |
| for (idx = 0; idx < cnt; idx++) { \ |
| CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx); \ |
| __CFGenericValidateType(item, CFStringGetTypeID()); \ |
| CFIndex item_cnt = CFStringGetLength(item); \ |
| STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt)); \ |
| UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); \ |
| if (NULL == item_ustr) { \ |
| item_cnt = __CFMin(BUFFER_SIZE, item_cnt); \ |
| CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); \ |
| item_ustr = item_buffer; \ |
| } \ |
| status = U_ZERO_ERROR; \ |
| udat_setSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, item_ustr, item_cnt, &status); \ |
| } |
| #else |
| #define SET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \ |
| __CFGenericValidateType(value, CFArrayGetTypeID()); \ |
| CFArrayRef array = (CFArrayRef)value; \ |
| CFIndex idx, cnt = CFArrayGetCount(array); \ |
| for (idx = 0; idx < cnt; idx++) { \ |
| CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx); \ |
| __CFGenericValidateType(item, CFStringGetTypeID()); \ |
| CFIndex item_cnt = CFStringGetLength(item); \ |
| UChar item_buffer[BUFFER_SIZE]; \ |
| UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); \ |
| if (NULL == item_ustr) { \ |
| item_cnt = __CFMin(BUFFER_SIZE, item_cnt); \ |
| CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); \ |
| item_ustr = item_buffer; \ |
| } \ |
| status = U_ZERO_ERROR; \ |
| udat_setSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, item_ustr, item_cnt, &status); \ |
| } |
| #endif |
| |
| |
| void CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringRef key, CFTypeRef value) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(key, CFStringGetTypeID()); |
| UErrorCode status = U_ZERO_ERROR; |
| UChar ubuffer[BUFFER_SIZE]; |
| |
| if (kCFDateFormatterIsLenient == key) { |
| __CFGenericValidateType(value, CFBooleanGetTypeID()); |
| udat_setLenient(formatter->_df, (kCFBooleanTrue == value)); |
| } else if (kCFDateFormatterCalendar == key) { |
| __CFGenericValidateType(value, CFCalendarGetTypeID()); |
| CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale); |
| CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeName); |
| CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components); |
| CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, CFCalendarGetIdentifier((CFCalendarRef)value)); |
| localeName = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents); |
| CFRelease(mcomponents); |
| CFRelease(components); |
| CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName); |
| CFRelease(localeName); |
| CFRelease(formatter->_locale); |
| formatter->_locale = newLocale; |
| UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_tz); |
| if (cal) udat_setCalendar(formatter->_df, cal); |
| if (cal) ucal_close(cal); |
| } else if (kCFDateFormatterCalendarIdentifier == key || kCFDateFormatterCalendarName == key) { |
| __CFGenericValidateType(value, CFStringGetTypeID()); |
| CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale); |
| CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeName); |
| CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components); |
| CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, value); |
| localeName = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents); |
| CFRelease(mcomponents); |
| CFRelease(components); |
| CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName); |
| CFRelease(localeName); |
| CFRelease(formatter->_locale); |
| formatter->_locale = newLocale; |
| UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_tz); |
| if (cal) udat_setCalendar(formatter->_df, cal); |
| if (cal) ucal_close(cal); |
| } else if (kCFDateFormatterTimeZone == key) { |
| __CFGenericValidateType(value, CFTimeZoneGetTypeID()); |
| CFTimeZoneRef old = formatter->_tz; |
| formatter->_tz = value ? (CFTimeZoneRef)CFRetain(value) : CFTimeZoneCopyDefault(); |
| if (old) CFRelease(old); |
| CFStringRef tznam = CFTimeZoneGetName(formatter->_tz); |
| UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df); |
| CFIndex ucnt = CFStringGetLength(tznam); |
| if (BUFFER_SIZE < ucnt) ucnt = BUFFER_SIZE; |
| CFStringGetCharacters(tznam, CFRangeMake(0, ucnt), (UniChar *)ubuffer); |
| ucal_setTimeZone(cal, ubuffer, ucnt, &status); |
| } else if (kCFDateFormatterDefaultFormat == key) { |
| // read-only attribute |
| } else if (kCFDateFormatterTwoDigitStartDate == key) { |
| __CFGenericValidateType(value, CFDateGetTypeID()); |
| CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value); |
| UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; |
| udat_set2DigitYearStart(formatter->_df, udate, &status); |
| } else if (kCFDateFormatterDefaultDate == key) { |
| __CFGenericValidateType(value, CFDateGetTypeID()); |
| CFDateRef old = formatter->_defaultDate; |
| formatter->_defaultDate = value ? (CFDateRef)CFRetain(value) : NULL; |
| if (old) CFRelease(old); |
| } else if (kCFDateFormatterEraSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_ERAS, 0) |
| } else if (kCFDateFormatterMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_MONTHS, 0) |
| } else if (kCFDateFormatterShortMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_SHORT_MONTHS, 0) |
| } else if (kCFDateFormatterWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterShortWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_SHORT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterAMSymbol == key) { |
| __CFGenericValidateType(value, CFStringGetTypeID()); |
| CFIndex item_cnt = CFStringGetLength((CFStringRef)value); |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt)); |
| #else |
| UChar item_buffer[BUFFER_SIZE]; |
| #endif |
| UChar *item_ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)value); |
| if (NULL == item_ustr) { |
| item_cnt = __CFMin(BUFFER_SIZE, item_cnt); |
| CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); |
| item_ustr = item_buffer; |
| } |
| udat_setSymbols(formatter->_df, UDAT_AM_PMS, 0, item_ustr, item_cnt, &status); |
| } else if (kCFDateFormatterPMSymbol == key) { |
| __CFGenericValidateType(value, CFStringGetTypeID()); |
| CFIndex item_cnt = CFStringGetLength((CFStringRef)value); |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt)); |
| #else |
| UChar item_buffer[BUFFER_SIZE]; |
| #endif |
| UChar *item_ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)value); |
| if (NULL == item_ustr) { |
| item_cnt = __CFMin(BUFFER_SIZE, item_cnt); |
| CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); |
| item_ustr = item_buffer; |
| } |
| udat_setSymbols(formatter->_df, UDAT_AM_PMS, 1, item_ustr, item_cnt, &status); |
| } else if (kCFDateFormatterGregorianStartDate == key) { |
| __CFGenericValidateType(value, CFDateGetTypeID()); |
| CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value); |
| UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; |
| UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df); |
| ucal_setGregorianChange(cal, udate, &status); |
| } else if (kCFDateFormatterLongEraSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_ERA_NAMES, 0) |
| } else if (kCFDateFormatterVeryShortMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_NARROW_MONTHS, 0) |
| } else if (kCFDateFormatterStandaloneMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_MONTHS, 0) |
| } else if (kCFDateFormatterShortStandaloneMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_MONTHS, 0) |
| } else if (kCFDateFormatterVeryShortStandaloneMonthSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_MONTHS, 0) |
| } else if (kCFDateFormatterVeryShortWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_NARROW_WEEKDAYS, 1) |
| } else if (kCFDateFormatterStandaloneWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_WEEKDAYS, 1) |
| } else if (kCFDateFormatterShortStandaloneWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterVeryShortStandaloneWeekdaySymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_WEEKDAYS, 1) |
| } else if (kCFDateFormatterQuarterSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_QUARTERS, 1) |
| } else if (kCFDateFormatterShortQuarterSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_SHORT_QUARTERS, 1) |
| } else if (kCFDateFormatterStandaloneQuarterSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_QUARTERS, 1) |
| } else if (kCFDateFormatterShortStandaloneQuarterSymbols == key) { |
| SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_QUARTERS, 1) |
| } else { |
| CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key); |
| } |
| } |
| |
| #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX |
| #define GET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \ |
| CFIndex idx, cnt = udat_countSymbols(formatter->_df, ICU_CODE) - INDEX_BASE; \ |
| STACK_BUFFER_DECL(CFStringRef, strings, cnt); \ |
| for (idx = 0; idx < cnt; idx++) { \ |
| CFStringRef str = NULL; \ |
| status = U_ZERO_ERROR; \ |
| CFIndex ucnt = udat_getSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, ubuffer, BUFFER_SIZE, &status); \ |
| if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { \ |
| str = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ucnt); \ |
| } \ |
| strings[idx] = !str ? (CFStringRef)CFRetain(CFSTR("<error>")) : str; \ |
| } \ |
| CFArrayRef array = CFArrayCreate(CFGetAllocator(formatter), (const void **)strings, cnt, &kCFTypeArrayCallBacks); \ |
| while (cnt--) { \ |
| CFRelease(strings[cnt]); \ |
| } \ |
| return array; |
| #else |
| #define GET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \ |
| CFIndex idx, cnt = udat_countSymbols(formatter->_df, ICU_CODE) - INDEX_BASE; \ |
| CFStringRef strings[BUFFER_SIZE]; \ |
| for (idx = 0; idx < cnt; idx++) { \ |
| CFStringRef str = NULL; \ |
| status = U_ZERO_ERROR; \ |
| CFIndex ucnt = udat_getSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, ubuffer, BUFFER_SIZE, &status); \ |
| if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { \ |
| str = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ucnt); \ |
| } \ |
| strings[idx] = !str ? (CFStringRef)CFRetain(CFSTR("<error>")) : str; \ |
| } \ |
| CFArrayRef array = CFArrayCreate(CFGetAllocator(formatter), (const void **)strings, cnt, &kCFTypeArrayCallBacks); \ |
| while (cnt--) { \ |
| CFRelease(strings[cnt]); \ |
| } \ |
| return array; |
| #endif |
| |
| CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef key) { |
| __CFGenericValidateType(formatter, CFDateFormatterGetTypeID()); |
| __CFGenericValidateType(key, CFStringGetTypeID()); |
| UErrorCode status = U_ZERO_ERROR; |
| UChar ubuffer[BUFFER_SIZE]; |
| |
| if (kCFDateFormatterIsLenient == key) { |
| return CFRetain(udat_isLenient(formatter->_df) ? kCFBooleanTrue : kCFBooleanFalse); |
| } else if (kCFDateFormatterCalendar == key) { |
| CFCalendarRef calendar = (CFCalendarRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendar); |
| return calendar ? CFRetain(calendar) : NULL; |
| } else if (kCFDateFormatterCalendarIdentifier == key || kCFDateFormatterCalendarName == key) { |
| CFStringRef ident = (CFStringRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendarIdentifier); |
| return ident ? CFRetain(ident) : NULL; |
| } else if (kCFDateFormatterTimeZone == key) { |
| return CFRetain(formatter->_tz); |
| } else if (kCFDateFormatterDefaultFormat == key) { |
| return formatter->_defformat ? CFRetain(formatter->_defformat) : NULL; |
| } else if (kCFDateFormatterTwoDigitStartDate == key) { |
| UDate udate = udat_get2DigitYearStart(formatter->_df, &status); |
| if (U_SUCCESS(status)) { |
| CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970; |
| return CFDateCreate(CFGetAllocator(formatter), at); |
| } |
| } else if (kCFDateFormatterDefaultDate == key) { |
| return formatter->_defaultDate ? CFRetain(formatter->_defaultDate) : NULL; |
| } else if (kCFDateFormatterEraSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_ERAS, 0) |
| } else if (kCFDateFormatterMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_MONTHS, 0) |
| } else if (kCFDateFormatterShortMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_SHORT_MONTHS, 0) |
| } else if (kCFDateFormatterWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterShortWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_SHORT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterAMSymbol == key) { |
| CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS); |
| if (2 <= cnt) { |
| CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 0, ubuffer, BUFFER_SIZE, &status); |
| if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { |
| return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt); |
| } |
| } |
| } else if (kCFDateFormatterPMSymbol == key) { |
| CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS); |
| if (2 <= cnt) { |
| CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 1, ubuffer, BUFFER_SIZE, &status); |
| if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { |
| return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt); |
| } |
| } |
| } else if (kCFDateFormatterGregorianStartDate == key) { |
| UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df); |
| UDate udate = ucal_getGregorianChange(cal, &status); |
| if (U_SUCCESS(status)) { |
| CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970; |
| return CFDateCreate(CFGetAllocator(formatter), at); |
| } |
| } else if (kCFDateFormatterLongEraSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_ERA_NAMES, 0) |
| } else if (kCFDateFormatterVeryShortMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_NARROW_MONTHS, 0) |
| } else if (kCFDateFormatterStandaloneMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_MONTHS, 0) |
| } else if (kCFDateFormatterShortStandaloneMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_MONTHS, 0) |
| } else if (kCFDateFormatterVeryShortStandaloneMonthSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_MONTHS, 0) |
| } else if (kCFDateFormatterVeryShortWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_NARROW_WEEKDAYS, 1) |
| } else if (kCFDateFormatterStandaloneWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_WEEKDAYS, 1) |
| } else if (kCFDateFormatterShortStandaloneWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_WEEKDAYS, 1) |
| } else if (kCFDateFormatterVeryShortStandaloneWeekdaySymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_WEEKDAYS, 1) |
| } else if (kCFDateFormatterQuarterSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_QUARTERS, 1) |
| } else if (kCFDateFormatterShortQuarterSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_SHORT_QUARTERS, 1) |
| } else if (kCFDateFormatterStandaloneQuarterSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_QUARTERS, 1) |
| } else if (kCFDateFormatterShortStandaloneQuarterSymbols == key) { |
| GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_QUARTERS, 1) |
| } else { |
| CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key); |
| } |
| return NULL; |
| } |
| |
| CONST_STRING_DECL(kCFDateFormatterIsLenient, "kCFDateFormatterIsLenient") |
| CONST_STRING_DECL(kCFDateFormatterTimeZone, "kCFDateFormatterTimeZone") |
| CONST_STRING_DECL(kCFDateFormatterCalendarName, "kCFDateFormatterCalendarName") |
| CONST_STRING_DECL(kCFDateFormatterCalendarIdentifier, "kCFDateFormatterCalendarIdentifier") |
| CONST_STRING_DECL(kCFDateFormatterCalendar, "kCFDateFormatterCalendar") |
| CONST_STRING_DECL(kCFDateFormatterDefaultFormat, "kCFDateFormatterDefaultFormat") |
| |
| CONST_STRING_DECL(kCFDateFormatterTwoDigitStartDate, "kCFDateFormatterTwoDigitStartDate") |
| CONST_STRING_DECL(kCFDateFormatterDefaultDate, "kCFDateFormatterDefaultDate") |
| CONST_STRING_DECL(kCFDateFormatterEraSymbols, "kCFDateFormatterEraSymbols") |
| CONST_STRING_DECL(kCFDateFormatterMonthSymbols, "kCFDateFormatterMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortMonthSymbols, "kCFDateFormatterShortMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterWeekdaySymbols, "kCFDateFormatterWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortWeekdaySymbols, "kCFDateFormatterShortWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterAMSymbol, "kCFDateFormatterAMSymbol") |
| CONST_STRING_DECL(kCFDateFormatterPMSymbol, "kCFDateFormatterPMSymbol") |
| |
| CONST_STRING_DECL(kCFDateFormatterLongEraSymbols, "kCFDateFormatterLongEraSymbols") |
| CONST_STRING_DECL(kCFDateFormatterVeryShortMonthSymbols, "kCFDateFormatterVeryShortMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterStandaloneMonthSymbols, "kCFDateFormatterStandaloneMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortStandaloneMonthSymbols, "kCFDateFormatterShortStandaloneMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneMonthSymbols, "kCFDateFormatterVeryShortStandaloneMonthSymbols") |
| CONST_STRING_DECL(kCFDateFormatterVeryShortWeekdaySymbols, "kCFDateFormatterVeryShortWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterStandaloneWeekdaySymbols, "kCFDateFormatterStandaloneWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortStandaloneWeekdaySymbols, "kCFDateFormatterShortStandaloneWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneWeekdaySymbols, "kCFDateFormatterVeryShortStandaloneWeekdaySymbols") |
| CONST_STRING_DECL(kCFDateFormatterQuarterSymbols, "kCFDateFormatterQuarterSymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortQuarterSymbols, "kCFDateFormatterShortQuarterSymbols") |
| CONST_STRING_DECL(kCFDateFormatterStandaloneQuarterSymbols, "kCFDateFormatterStandaloneQuarterSymbols") |
| CONST_STRING_DECL(kCFDateFormatterShortStandaloneQuarterSymbols, "kCFDateFormatterShortStandaloneQuarterSymbols") |
| CONST_STRING_DECL(kCFDateFormatterGregorianStartDate, "kCFDateFormatterGregorianStartDate") |
| |
| #undef BUFFER_SIZE |
| |