CFBundle_Strings.c [plain text]
#include "CFBundle_Internal.h"
#if DEPLOYMENT_TARGET_MACOSX
#endif
#include <CoreFoundation/CFPreferences.h>
#include <CoreFoundation/CFURLAccess.h>
#pragma mark -
#pragma mark Localized Strings
CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName) {
return CFBundleCopyLocalizedStringForLocalization(bundle, key, value, tableName, NULL);
}
CF_EXPORT CFStringRef CFBundleCopyLocalizedStringForLocalization(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName, CFStringRef localizationName) {
CFStringRef result = NULL;
CFDictionaryRef stringTable = NULL;
if (!key) return (value ? (CFStringRef)CFRetain(value) : (CFStringRef)CFRetain(CFSTR("")));
(void)CFBundleAllowMixedLocalizations();
if (!tableName || CFEqual(tableName, CFSTR(""))) tableName = _CFBundleDefaultStringTableName;
__CFLock(&bundle->_lock);
if (!localizationName && bundle->_stringTable) {
stringTable = (CFDictionaryRef)CFDictionaryGetValue(bundle->_stringTable, tableName);
if (stringTable) CFRetain(stringTable);
}
if (!stringTable) {
__CFUnlock(&bundle->_lock);
CFURLRef tableURL = NULL;
if (localizationName) {
tableURL = CFBundleCopyResourceURLForLocalization(bundle, tableName, _CFBundleStringTableType, NULL, localizationName);
} else {
tableURL = CFBundleCopyResourceURL(bundle, tableName, _CFBundleStringTableType, NULL);
}
if (tableURL) {
CFStringRef nameForSharing = NULL;
if (!stringTable) {
CFDataRef tableData = NULL;
SInt32 errCode;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tableURL, &tableData, NULL, NULL, &errCode)) {
#pragma GCC diagnostic pop
CFErrorRef error = NULL;
stringTable = (CFDictionaryRef)CFPropertyListCreateWithData(CFGetAllocator(bundle), tableData, kCFPropertyListImmutable, NULL, &error);
if (stringTable && CFDictionaryGetTypeID() != CFGetTypeID(stringTable)) {
CFRelease(stringTable);
stringTable = NULL;
}
if (!stringTable && error) {
CFLog(kCFLogLevelError, CFSTR("Unable to load string table file: %@ / %@: %@"), bundle, tableName, error);
CFRelease(error);
error = NULL;
}
CFRelease(tableData);
}
}
if (nameForSharing) CFRelease(nameForSharing);
if (tableURL) CFRelease(tableURL);
}
if (!stringTable) stringTable = CFDictionaryCreate(CFGetAllocator(bundle), NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if ((!CFStringHasSuffix(tableName, CFSTR(".nocache")) || !_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) && localizationName == NULL) {
__CFLock(&bundle->_lock);
if (!bundle->_stringTable) bundle->_stringTable = CFDictionaryCreateMutable(CFGetAllocator(bundle), 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(bundle->_stringTable, tableName, stringTable);
} else {
__CFLock(&bundle->_lock);
}
}
result = (CFStringRef)CFDictionaryGetValue(stringTable, key);
if (result) {
CFRetain(result);
}
__CFUnlock(&bundle->_lock);
CFRelease(stringTable);
if (!result) {
if (!value) {
result = (CFStringRef)CFRetain(key);
} else if (CFEqual(value, CFSTR(""))) {
result = (CFStringRef)CFRetain(key);
} else {
result = (CFStringRef)CFRetain(value);
}
static Boolean capitalize = false;
if (capitalize) {
CFMutableStringRef capitalizedResult = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, result);
CFLog(__kCFLogBundle, CFSTR("Localizable string \"%@\" not found in strings table \"%@\" of bundle %@."), key, tableName, bundle);
CFStringUppercase(capitalizedResult, NULL);
CFRelease(result);
result = capitalizedResult;
}
}
return result;
}