1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sal.hxx" 26 27 #include <sal/types.h> 28 #include <assert.h> 29 30 #include <premac.h> 31 #include <CoreServices/CoreServices.h> 32 #include <CoreFoundation/CoreFoundation.h> 33 #include <postmac.h> 34 35 namespace /* private */ 36 { 37 template <typename T> 38 class CFGuard 39 { 40 public: 41 explicit CFGuard(T& rT) : rT_(rT) {} 42 ~CFGuard() { if (rT_) CFRelease(rT_); } 43 private: 44 T& rT_; 45 }; 46 47 typedef CFGuard<CFArrayRef> CFArrayGuard; 48 typedef CFGuard<CFStringRef> CFStringGuard; 49 typedef CFGuard<CFPropertyListRef> CFPropertyListGuard; 50 51 /** Get the current process locale from system 52 */ 53 CFStringRef getProcessLocale() 54 { 55 CFPropertyListRef pref = CFPreferencesCopyAppValue(CFSTR("AppleLocale"), kCFPreferencesCurrentApplication); 56 CFPropertyListGuard proplGuard(pref); 57 58 if (pref == NULL) // return fallback value 'en_US' 59 return CFStringCreateWithCString(kCFAllocatorDefault, "en_US", kCFStringEncodingASCII); 60 61 CFStringRef sref = (CFGetTypeID(pref) == CFArrayGetTypeID()) ? (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)pref, 0) : (CFStringRef)pref; 62 63 // NOTE: this API is only available with Mac OS X >=10.3. We need to use it because 64 // Apple used non-ISO values on systems <10.2 like "German" for instance but didn't 65 // upgrade those values during upgrade to newer Mac OS X versions. See also #i54337# 66 return CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, sref); 67 } 68 } // namespace private 69 70 /** Grab current locale from system. 71 */ 72 extern "C" { 73 int macosx_getLocale(char *locale, sal_uInt32 bufferLen) 74 { 75 CFStringRef sref = getProcessLocale(); 76 CFStringGuard sGuard(sref); 77 78 assert(sref != NULL && "osxlocale.cxx: getProcessLocale must return a non-NULL value"); 79 80 // split the string into substrings; the first two (if there are two) substrings 81 // are language and country 82 CFArrayRef subs = CFStringCreateArrayBySeparatingStrings(NULL, sref, CFSTR("_")); 83 CFArrayGuard arrGuard(subs); 84 85 CFStringRef lang = (CFStringRef)CFArrayGetValueAtIndex(subs, 0); 86 CFStringGetCString(lang, locale, bufferLen, kCFStringEncodingASCII); 87 88 // country also available? Assumption: if the array contains more than one 89 // value the second value is always the country! 90 if (CFArrayGetCount(subs) > 1) 91 { 92 strlcat(locale, "_", bufferLen - strlen(locale)); 93 94 CFStringRef country = (CFStringRef)CFArrayGetValueAtIndex(subs, 1); 95 CFStringGetCString(country, locale + strlen(locale), bufferLen - strlen(locale), kCFStringEncodingASCII); 96 } 97 // Append 'UTF-8' to the locale because the Mac OS X file 98 // system interface is UTF-8 based and sal tries to determine 99 // the file system locale from the locale information 100 strlcat(locale, ".UTF-8", bufferLen - strlen(locale)); 101 102 return noErr; 103 } 104 } 105 106 107 108 /* 109 * macxp_OSXConvertCFEncodingToIANACharSetName 110 * 111 * Convert a CoreFoundation text encoding to an IANA charset name. 112 */ 113 extern "C" int macxp_OSXConvertCFEncodingToIANACharSetName( char *buffer, unsigned int bufferLen, CFStringEncoding cfEncoding ) 114 { 115 CFStringRef sCFEncodingName; 116 117 sCFEncodingName = CFStringConvertEncodingToIANACharSetName( cfEncoding ); 118 CFStringGetCString( sCFEncodingName, buffer, bufferLen, cfEncoding ); 119 120 if ( sCFEncodingName ) 121 CFRelease( sCFEncodingName ); 122 123 return( noErr ); 124 } 125 126