OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_MAC_FOUNDATION_UTIL_H_ | 5 #ifndef BASE_MAC_FOUNDATION_UTIL_H_ |
6 #define BASE_MAC_FOUNDATION_UTIL_H_ | 6 #define BASE_MAC_FOUNDATION_UTIL_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <CoreFoundation/CoreFoundation.h> | 9 #include <CoreFoundation/CoreFoundation.h> |
10 | 10 |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/base_export.h" | 14 #include "base/base_export.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/mac/scoped_cftyperef.h" |
16 | 17 |
17 #if defined(__OBJC__) | 18 #if defined(__OBJC__) |
18 #import <Foundation/Foundation.h> | 19 #import <Foundation/Foundation.h> |
19 #else // __OBJC__ | 20 #else // __OBJC__ |
20 class NSBundle; | 21 class NSBundle; |
21 class NSString; | 22 class NSString; |
22 #endif // __OBJC__ | 23 #endif // __OBJC__ |
23 | 24 |
24 class FilePath; | 25 class FilePath; |
25 | 26 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 // Returns the ~/Library directory. | 90 // Returns the ~/Library directory. |
90 BASE_EXPORT FilePath GetUserLibraryPath(); | 91 BASE_EXPORT FilePath GetUserLibraryPath(); |
91 | 92 |
92 // Takes a path to an (executable) binary and tries to provide the path to an | 93 // Takes a path to an (executable) binary and tries to provide the path to an |
93 // application bundle containing it. It takes the outermost bundle that it can | 94 // application bundle containing it. It takes the outermost bundle that it can |
94 // find (so for "/Foo/Bar.app/.../Baz.app/..." it produces "/Foo/Bar.app"). | 95 // find (so for "/Foo/Bar.app/.../Baz.app/..." it produces "/Foo/Bar.app"). |
95 // |exec_name| - path to the binary | 96 // |exec_name| - path to the binary |
96 // returns - path to the application bundle, or empty on error | 97 // returns - path to the application bundle, or empty on error |
97 BASE_EXPORT FilePath GetAppBundlePath(const FilePath& exec_name); | 98 BASE_EXPORT FilePath GetAppBundlePath(const FilePath& exec_name); |
98 | 99 |
| 100 #define TYPE_NAME_FOR_CF_TYPE_DECL(TypeCF) \ |
| 101 std::string TypeNameForCFType(TypeCF##Ref); |
| 102 |
| 103 TYPE_NAME_FOR_CF_TYPE_DECL(CFArray); |
| 104 TYPE_NAME_FOR_CF_TYPE_DECL(CFBag); |
| 105 TYPE_NAME_FOR_CF_TYPE_DECL(CFBoolean); |
| 106 TYPE_NAME_FOR_CF_TYPE_DECL(CFData); |
| 107 TYPE_NAME_FOR_CF_TYPE_DECL(CFDate); |
| 108 TYPE_NAME_FOR_CF_TYPE_DECL(CFDictionary); |
| 109 TYPE_NAME_FOR_CF_TYPE_DECL(CFNull); |
| 110 TYPE_NAME_FOR_CF_TYPE_DECL(CFNumber); |
| 111 TYPE_NAME_FOR_CF_TYPE_DECL(CFSet); |
| 112 TYPE_NAME_FOR_CF_TYPE_DECL(CFString); |
| 113 |
| 114 #undef TYPE_NAME_FOR_CF_TYPE_DECL |
| 115 |
| 116 // Helper function for GetValueFromDictionary to create the error message |
| 117 // that appears when a type mismatch is encountered. |
| 118 std::string GetValueFromDictionaryErrorMessage( |
| 119 CFStringRef key, const std::string& expected_type, CFTypeRef value); |
| 120 |
99 // Utility function to pull out a value from a dictionary, check its type, and | 121 // Utility function to pull out a value from a dictionary, check its type, and |
100 // return it. Returns NULL if the key is not present or of the wrong type. | 122 // return it. Returns NULL if the key is not present or of the wrong type. |
| 123 // This is now deprecated in favor of the two-argument form below. |
| 124 // TODO(kushi.p): Remove this function once all cases of it have been |
| 125 // replaced with the two-argument form below. See: crbug.com/104200. |
101 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, | 126 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, |
102 CFStringRef key, | 127 CFStringRef key, |
103 CFTypeID expected_type); | 128 CFTypeID expected_type); |
104 | 129 |
105 // Retain/release calls for memory management in C++. | 130 // Retain/release calls for memory management in C++. |
106 BASE_EXPORT void NSObjectRetain(void* obj); | 131 BASE_EXPORT void NSObjectRetain(void* obj); |
107 BASE_EXPORT void NSObjectRelease(void* obj); | 132 BASE_EXPORT void NSObjectRelease(void* obj); |
108 | 133 |
109 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation | 134 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation |
110 // object (one derived from CFTypeRef) to the Foundation memory management | 135 // object (one derived from CFTypeRef) to the Foundation memory management |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 CF_TO_NS_CAST_DECL(CFLocale, NSLocale); | 216 CF_TO_NS_CAST_DECL(CFLocale, NSLocale); |
192 CF_TO_NS_CAST_DECL(CFNumber, NSNumber); | 217 CF_TO_NS_CAST_DECL(CFNumber, NSNumber); |
193 CF_TO_NS_CAST_DECL(CFRunLoopTimer, NSTimer); | 218 CF_TO_NS_CAST_DECL(CFRunLoopTimer, NSTimer); |
194 CF_TO_NS_CAST_DECL(CFTimeZone, NSTimeZone); | 219 CF_TO_NS_CAST_DECL(CFTimeZone, NSTimeZone); |
195 CF_TO_NS_MUTABLE_CAST_DECL(Set); | 220 CF_TO_NS_MUTABLE_CAST_DECL(Set); |
196 CF_TO_NS_CAST_DECL(CFReadStream, NSInputStream); | 221 CF_TO_NS_CAST_DECL(CFReadStream, NSInputStream); |
197 CF_TO_NS_CAST_DECL(CFWriteStream, NSOutputStream); | 222 CF_TO_NS_CAST_DECL(CFWriteStream, NSOutputStream); |
198 CF_TO_NS_MUTABLE_CAST_DECL(String); | 223 CF_TO_NS_MUTABLE_CAST_DECL(String); |
199 CF_TO_NS_CAST_DECL(CFURL, NSURL); | 224 CF_TO_NS_CAST_DECL(CFURL, NSURL); |
200 | 225 |
| 226 #undef CF_TO_NS_CAST_DECL |
| 227 #undef CF_TO_NS_MUTABLE_CAST_DECL |
| 228 #undef OBJC_CPP_CLASS_DECL |
| 229 |
201 namespace base { | 230 namespace base { |
202 namespace mac { | 231 namespace mac { |
203 | 232 |
204 // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more | 233 // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more |
205 // specific CoreFoundation type. The compatibility of the passed | 234 // specific CoreFoundation type. The compatibility of the passed |
206 // object is found by comparing its opaque type against the | 235 // object is found by comparing its opaque type against the |
207 // requested type identifier. If the supplied object is not | 236 // requested type identifier. If the supplied object is not |
208 // compatible with the requested return type, CFCast<>() returns | 237 // compatible with the requested return type, CFCast<>() returns |
209 // NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer | 238 // NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer |
210 // to either variant results in NULL being returned without | 239 // to either variant results in NULL being returned without |
211 // triggering any DCHECK. | 240 // triggering any DCHECK. |
212 // | 241 // |
213 // Example usage: | 242 // Example usage: |
214 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( | 243 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( |
215 // CFArrayGetValueAtIndex(array, index)); | 244 // CFArrayGetValueAtIndex(array, index)); |
216 // | 245 // |
217 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( | 246 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( |
218 // base::mac::GetValueFromDictionary(some_dict, | 247 // base::mac::GetValueFromDictionary(some_dict, |
219 // CFSTR("a_key"), | 248 // CFSTR("a_key"), |
220 // CFStringGetTypeID())); | 249 // CFStringGetTypeID())); |
221 BASE_EXPORT template<class T> | 250 BASE_EXPORT template<typename T> |
222 T CFCast(const CFTypeRef& cf_val); | 251 T CFCast(const CFTypeRef& cf_val); |
223 | 252 |
224 BASE_EXPORT template<class T> | 253 BASE_EXPORT template<typename T> |
225 T CFCastStrict(const CFTypeRef& cf_val); | 254 T CFCastStrict(const CFTypeRef& cf_val); |
226 | 255 |
227 #if defined(__OBJC__) | 256 #if defined(__OBJC__) |
228 | 257 |
229 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more | 258 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more |
230 // specific (NSObject-derived) type. The compatibility of the passed | 259 // specific (NSObject-derived) type. The compatibility of the passed |
231 // object is found by checking if it's a kind of the requested type | 260 // object is found by checking if it's a kind of the requested type |
232 // identifier. If the supplied object is not compatible with the | 261 // identifier. If the supplied object is not compatible with the |
233 // requested return type, ObjCCast<>() returns nil and | 262 // requested return type, ObjCCast<>() returns nil and |
234 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either | 263 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either |
235 // variant results in nil being returned without triggering any DCHECK. | 264 // variant results in nil being returned without triggering any DCHECK. |
236 // | 265 // |
237 // The strict variant is useful when retrieving a value from a | 266 // The strict variant is useful when retrieving a value from a |
238 // collection which only has values of a specific type, e.g. an | 267 // collection which only has values of a specific type, e.g. an |
239 // NSArray of NSStrings. The non-strict variant is useful when | 268 // NSArray of NSStrings. The non-strict variant is useful when |
240 // retrieving values from data that you can't fully control. For | 269 // retrieving values from data that you can't fully control. For |
241 // example, a plist read from disk may be beyond your exclusive | 270 // example, a plist read from disk may be beyond your exclusive |
242 // control, so you'd only want to check that the values you retrieve | 271 // control, so you'd only want to check that the values you retrieve |
243 // from it are of the expected types, but not crash if they're not. | 272 // from it are of the expected types, but not crash if they're not. |
244 // | 273 // |
245 // Example usage: | 274 // Example usage: |
246 // NSString* version = base::mac::ObjCCast<NSString>( | 275 // NSString* version = base::mac::ObjCCast<NSString>( |
247 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); | 276 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); |
248 // | 277 // |
249 // NSString* str = base::mac::ObjCCastStrict<NSString>( | 278 // NSString* str = base::mac::ObjCCastStrict<NSString>( |
250 // [ns_arr_of_ns_strs objectAtIndex:0]); | 279 // [ns_arr_of_ns_strs objectAtIndex:0]); |
251 BASE_EXPORT template<class T> | 280 BASE_EXPORT template<typename T> |
252 T* ObjCCast(id objc_val) { | 281 T* ObjCCast(id objc_val) { |
253 if ([objc_val isKindOfClass:[T class]]) { | 282 if ([objc_val isKindOfClass:[T class]]) { |
254 return reinterpret_cast<T*>(objc_val); | 283 return reinterpret_cast<T*>(objc_val); |
255 } | 284 } |
256 return nil; | 285 return nil; |
257 } | 286 } |
258 | 287 |
259 BASE_EXPORT template<class T> | 288 BASE_EXPORT template<typename T> |
260 T* ObjCCastStrict(id objc_val) { | 289 T* ObjCCastStrict(id objc_val) { |
261 T* rv = ObjCCast<T>(objc_val); | 290 T* rv = ObjCCast<T>(objc_val); |
262 DCHECK(objc_val == nil || rv); | 291 DCHECK(objc_val == nil || rv); |
263 return rv; | 292 return rv; |
264 } | 293 } |
265 | 294 |
266 #endif // defined(__OBJC__) | 295 #endif // defined(__OBJC__) |
267 | 296 |
| 297 // Utility function to pull out a value from a dictionary, check its type, and |
| 298 // return it. Returns NULL if the key is not present or of the wrong type. |
| 299 BASE_EXPORT template<typename T> |
| 300 T GetValueFromDictionary(CFDictionaryRef dict, CFStringRef key) { |
| 301 CFTypeRef value = CFDictionaryGetValue(dict, key); |
| 302 T value_specific = CFCast<T>(value); |
| 303 |
| 304 if (value && !value_specific) { |
| 305 std::string expected_type = TypeNameForCFType(value_specific); |
| 306 DLOG(WARNING) << GetValueFromDictionaryErrorMessage(key, |
| 307 expected_type, |
| 308 value); |
| 309 } |
| 310 |
| 311 return value_specific; |
| 312 } |
| 313 |
268 } // namespace mac | 314 } // namespace mac |
269 } // namespace base | 315 } // namespace base |
270 | 316 |
271 // Stream operations for CFTypes. They can be used with NSTypes as well | 317 // Stream operations for CFTypes. They can be used with NSTypes as well |
272 // by using the NSToCFCast methods above. | 318 // by using the NSToCFCast methods above. |
273 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); | 319 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); |
274 // Operator << can not be overloaded for ObjectiveC types as the compiler | 320 // Operator << can not be overloaded for ObjectiveC types as the compiler |
275 // can not distinguish between overloads for id with overloads for void*. | 321 // can not distinguish between overloads for id with overloads for void*. |
276 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 322 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
277 const CFErrorRef err); | 323 const CFErrorRef err); |
278 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 324 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
279 const CFStringRef str); | 325 const CFStringRef str); |
280 | 326 |
281 #endif // BASE_MAC_FOUNDATION_UTIL_H_ | 327 #endif // BASE_MAC_FOUNDATION_UTIL_H_ |
OLD | NEW |