CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, CFStringRef key, CFStringRef value) { CF_OBJC_FUNCDISPATCH2(CFLocaleGetTypeID(), CFStringRef, displayLocale, "_copyDisplayNameForKey:value:", key, value); CFIndex idx, slot = -1; for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { if (__CFLocaleKeyTable[idx].key == key) { slot = idx; break; } } if (-1 == slot && NULL != key) { for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { if (CFEqual(__CFLocaleKeyTable[idx].key, key)) { slot = idx; break; } } } if (-1 == slot || !value) { return NULL; } // Get the locale ID as a C string char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY]; char cValue[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY]; if (CFStringGetCString(displayLocale->_identifier, localeID, sizeof(localeID)/sizeof(localeID[0]), kCFStringEncodingASCII) && CFStringGetCString(value, cValue, sizeof(cValue)/sizeof(char), kCFStringEncodingASCII)) { CFStringRef result; if ((NULL == displayLocale->_prefs) && __CFLocaleKeyTable[slot].name(localeID, cValue, &result)) { return result; } // We could not find a result using the requested language. Fall back through all preferred languages. CFArrayRef langPref; if (displayLocale->_prefs) { langPref = (CFArrayRef)CFDictionaryGetValue(displayLocale->_prefs, CFSTR("AppleLanguages")); if (langPref) CFRetain(langPref); } else { langPref = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication); } if (langPref != NULL) { CFIndex count = CFArrayGetCount(langPref); CFIndex i; bool success = false; for (i = 0; i < count && !success; ++i) { CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(langPref, i); CFStringRef cleanLanguage = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorSystemDefault, language); if (CFStringGetCString(cleanLanguage, localeID, sizeof(localeID)/sizeof(localeID[0]), kCFStringEncodingASCII)) { success = __CFLocaleKeyTable[slot].name(localeID, cValue, &result); } CFRelease(cleanLanguage); } CFRelease(langPref); if (success) return result; } } return NULL; }
void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) { CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, setLocale:locale); __CFGenericValidateType(calendar, CFCalendarGetTypeID()); __CFGenericValidateType(locale, CFLocaleGetTypeID()); CFStringRef localeID = CFLocaleGetIdentifier(locale); if (localeID != calendar->_localeID) { CFRelease(calendar->_localeID); CFRetain(localeID); calendar->_localeID = localeID; if (calendar->_cal) __CFCalendarZapCal(calendar); } }
CFLocaleRef CFLocaleCreate(CFAllocatorRef allocator, CFStringRef identifier) { if (allocator == NULL) allocator = __CFGetDefaultAllocator(); __CFGenericValidateType(allocator, CFAllocatorGetTypeID()); __CFGenericValidateType(identifier, CFStringGetTypeID()); CFStringRef localeIdentifier = NULL; if (identifier) { localeIdentifier = CFLocaleCreateCanonicalLocaleIdentifierFromString(allocator, identifier); } if (NULL == localeIdentifier) return NULL; CFStringRef old = localeIdentifier; localeIdentifier = (CFStringRef)CFStringCreateCopy(allocator, localeIdentifier); CFRelease(old); __CFLocaleLockGlobal(); // Look for cases where we can return a cached instance. // We only use cached objects if the allocator is the system // default allocator. if (!allocator) allocator = __CFGetDefaultAllocator(); Boolean canCache = (kCFAllocatorSystemDefault == allocator); if (canCache && __CFLocaleCache) { CFLocaleRef locale = (CFLocaleRef)CFDictionaryGetValue(__CFLocaleCache, localeIdentifier); if (locale) { CFRetain(locale); __CFLocaleUnlockGlobal(); CFRelease(localeIdentifier); return locale; } } struct __CFLocale *locale = NULL; uint32_t size = sizeof(struct __CFLocale) - sizeof(CFRuntimeBase); locale = (struct __CFLocale *)_CFRuntimeCreateInstance(allocator, CFLocaleGetTypeID(), size, NULL); if (NULL == locale) { return NULL; } __CFLocaleSetType(locale, __kCFLocaleOrdinary); locale->_identifier = localeIdentifier; locale->_cache = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks); locale->_overrides = NULL; locale->_prefs = NULL; CF_SPINLOCK_INIT_FOR_STRUCTS(locale->_lock); if (canCache) { if (NULL == __CFLocaleCache) { __CFLocaleCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(__CFLocaleCache, localeIdentifier, locale); } __CFLocaleUnlockGlobal(); return (CFLocaleRef)locale; }
CFTypeRef CFLocaleGetValue(CFLocaleRef locale, CFStringRef key) { CF_OBJC_FUNCDISPATCH1(CFLocaleGetTypeID(), CFTypeRef, locale, "objectForKey:", key); CFIndex idx, slot = -1; for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { if (__CFLocaleKeyTable[idx].key == key) { slot = idx; break; } } if (-1 == slot && NULL != key) { for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) { if (CFEqual(__CFLocaleKeyTable[idx].key, key)) { slot = idx; break; } } } if (-1 == slot) { return NULL; } CFTypeRef value; if (NULL != locale->_overrides && CFDictionaryGetValueIfPresent(locale->_overrides, __CFLocaleKeyTable[slot].key, &value)) { return value; } __CFLocaleLock(locale); if (CFDictionaryGetValueIfPresent(locale->_cache, __CFLocaleKeyTable[slot].key, &value)) { __CFLocaleUnlock(locale); return value; } if (__kCFLocaleUser == __CFLocaleGetType(locale) && __CFLocaleKeyTable[slot].get(locale, true, &value, __CFLocaleKeyTable[slot].context)) { if (value) CFDictionarySetValue(locale->_cache, __CFLocaleKeyTable[idx].key, value); if (value) CFRelease(value); __CFLocaleUnlock(locale); return value; } if (__CFLocaleKeyTable[slot].get(locale, false, &value, __CFLocaleKeyTable[slot].context)) { if (value) CFDictionarySetValue(locale->_cache, __CFLocaleKeyTable[idx].key, value); if (value) CFRelease(value); __CFLocaleUnlock(locale); return value; } __CFLocaleUnlock(locale); return NULL; }
CFStringRef CFLocaleGetIdentifier(CFLocaleRef locale) { CF_OBJC_FUNCDISPATCH0(CFLocaleGetTypeID(), CFStringRef, locale, "localeIdentifier"); return locale->_identifier; }
CFLocaleRef CFLocaleCopyCurrent(void) { __CFLocaleLockGlobal(); if (__CFLocaleCurrent) { CFRetain(__CFLocaleCurrent); __CFLocaleUnlockGlobal(); return __CFLocaleCurrent; } __CFLocaleUnlockGlobal(); CFDictionaryRef prefs = NULL; CFStringRef identifier = NULL; #ifdef DEPLOYMENT_TARGET_WINDOWS identifier = __CFLocaleWindowsLCIDToISOLocaleName(LOCALE_USER_DEFAULT); #endif struct __CFLocale *locale; uint32_t size = sizeof(struct __CFLocale) - sizeof(CFRuntimeBase); locale = (struct __CFLocale *)_CFRuntimeCreateInstance(kCFAllocatorSystemDefault, CFLocaleGetTypeID(), size, NULL); if (NULL == locale) { return NULL; } __CFLocaleSetType(locale, __kCFLocaleUser); if (NULL == identifier) identifier = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME); locale->_identifier = identifier; locale->_cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); locale->_overrides = NULL; locale->_prefs = prefs; CF_SPINLOCK_INIT_FOR_STRUCTS(locale->_lock); __CFLocaleLockGlobal(); if (NULL == __CFLocaleCurrent) { __CFLocaleCurrent = locale; } else { CFRelease(locale); } locale = (struct __CFLocale *)CFRetain(__CFLocaleCurrent); __CFLocaleUnlockGlobal(); return locale; }