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) | |
Mark Mentovai
2011/11/14 22:11:37
Please finish this comment by referencing your new
| |
101 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, | 125 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, |
102 CFStringRef key, | 126 CFStringRef key, |
103 CFTypeID expected_type); | 127 CFTypeID expected_type); |
104 | 128 |
105 // Retain/release calls for memory management in C++. | 129 // Retain/release calls for memory management in C++. |
106 BASE_EXPORT void NSObjectRetain(void* obj); | 130 BASE_EXPORT void NSObjectRetain(void* obj); |
107 BASE_EXPORT void NSObjectRelease(void* obj); | 131 BASE_EXPORT void NSObjectRelease(void* obj); |
108 | 132 |
109 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation | 133 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation |
110 // object (one derived from CFTypeRef) to the Foundation memory management | 134 // 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); | 215 CF_TO_NS_CAST_DECL(CFLocale, NSLocale); |
192 CF_TO_NS_CAST_DECL(CFNumber, NSNumber); | 216 CF_TO_NS_CAST_DECL(CFNumber, NSNumber); |
193 CF_TO_NS_CAST_DECL(CFRunLoopTimer, NSTimer); | 217 CF_TO_NS_CAST_DECL(CFRunLoopTimer, NSTimer); |
194 CF_TO_NS_CAST_DECL(CFTimeZone, NSTimeZone); | 218 CF_TO_NS_CAST_DECL(CFTimeZone, NSTimeZone); |
195 CF_TO_NS_MUTABLE_CAST_DECL(Set); | 219 CF_TO_NS_MUTABLE_CAST_DECL(Set); |
196 CF_TO_NS_CAST_DECL(CFReadStream, NSInputStream); | 220 CF_TO_NS_CAST_DECL(CFReadStream, NSInputStream); |
197 CF_TO_NS_CAST_DECL(CFWriteStream, NSOutputStream); | 221 CF_TO_NS_CAST_DECL(CFWriteStream, NSOutputStream); |
198 CF_TO_NS_MUTABLE_CAST_DECL(String); | 222 CF_TO_NS_MUTABLE_CAST_DECL(String); |
199 CF_TO_NS_CAST_DECL(CFURL, NSURL); | 223 CF_TO_NS_CAST_DECL(CFURL, NSURL); |
200 | 224 |
225 #undef CF_TO_NS_CAST_DECL | |
226 #undef CF_TO_NS_MUTABLE_CAST_DECL | |
Mark Mentovai
2011/11/14 22:13:21
I said three, right?
How about OBJC_CPP_CLASS_DEC
KushalP
2011/11/14 22:20:47
Ah, thought you just mean this 10 line block here.
| |
227 | |
201 namespace base { | 228 namespace base { |
202 namespace mac { | 229 namespace mac { |
203 | 230 |
204 // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more | 231 // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more |
205 // specific CoreFoundation type. The compatibility of the passed | 232 // specific CoreFoundation type. The compatibility of the passed |
206 // object is found by comparing its opaque type against the | 233 // object is found by comparing its opaque type against the |
207 // requested type identifier. If the supplied object is not | 234 // requested type identifier. If the supplied object is not |
208 // compatible with the requested return type, CFCast<>() returns | 235 // compatible with the requested return type, CFCast<>() returns |
209 // NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer | 236 // NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer |
210 // to either variant results in NULL being returned without | 237 // to either variant results in NULL being returned without |
211 // triggering any DCHECK. | 238 // triggering any DCHECK. |
212 // | 239 // |
213 // Example usage: | 240 // Example usage: |
214 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( | 241 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( |
215 // CFArrayGetValueAtIndex(array, index)); | 242 // CFArrayGetValueAtIndex(array, index)); |
216 // | 243 // |
217 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( | 244 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( |
218 // base::mac::GetValueFromDictionary(some_dict, | 245 // base::mac::GetValueFromDictionary(some_dict, |
219 // CFSTR("a_key"), | 246 // CFSTR("a_key"), |
220 // CFStringGetTypeID())); | 247 // CFStringGetTypeID())); |
221 BASE_EXPORT template<class T> | 248 BASE_EXPORT template<typename T> |
222 T CFCast(const CFTypeRef& cf_val); | 249 T CFCast(const CFTypeRef& cf_val); |
223 | 250 |
224 BASE_EXPORT template<class T> | 251 BASE_EXPORT template<typename T> |
225 T CFCastStrict(const CFTypeRef& cf_val); | 252 T CFCastStrict(const CFTypeRef& cf_val); |
226 | 253 |
227 #if defined(__OBJC__) | 254 #if defined(__OBJC__) |
228 | 255 |
229 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more | 256 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more |
230 // specific (NSObject-derived) type. The compatibility of the passed | 257 // specific (NSObject-derived) type. The compatibility of the passed |
231 // object is found by checking if it's a kind of the requested type | 258 // 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 | 259 // identifier. If the supplied object is not compatible with the |
233 // requested return type, ObjCCast<>() returns nil and | 260 // requested return type, ObjCCast<>() returns nil and |
234 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either | 261 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either |
235 // variant results in nil being returned without triggering any DCHECK. | 262 // variant results in nil being returned without triggering any DCHECK. |
236 // | 263 // |
237 // The strict variant is useful when retrieving a value from a | 264 // The strict variant is useful when retrieving a value from a |
238 // collection which only has values of a specific type, e.g. an | 265 // collection which only has values of a specific type, e.g. an |
239 // NSArray of NSStrings. The non-strict variant is useful when | 266 // NSArray of NSStrings. The non-strict variant is useful when |
240 // retrieving values from data that you can't fully control. For | 267 // retrieving values from data that you can't fully control. For |
241 // example, a plist read from disk may be beyond your exclusive | 268 // 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 | 269 // 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. | 270 // from it are of the expected types, but not crash if they're not. |
244 // | 271 // |
245 // Example usage: | 272 // Example usage: |
246 // NSString* version = base::mac::ObjCCast<NSString>( | 273 // NSString* version = base::mac::ObjCCast<NSString>( |
247 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); | 274 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); |
248 // | 275 // |
249 // NSString* str = base::mac::ObjCCastStrict<NSString>( | 276 // NSString* str = base::mac::ObjCCastStrict<NSString>( |
250 // [ns_arr_of_ns_strs objectAtIndex:0]); | 277 // [ns_arr_of_ns_strs objectAtIndex:0]); |
251 BASE_EXPORT template<class T> | 278 BASE_EXPORT template<typename T> |
252 T* ObjCCast(id objc_val) { | 279 T* ObjCCast(id objc_val) { |
253 if ([objc_val isKindOfClass:[T class]]) { | 280 if ([objc_val isKindOfClass:[T class]]) { |
254 return reinterpret_cast<T*>(objc_val); | 281 return reinterpret_cast<T*>(objc_val); |
255 } | 282 } |
256 return nil; | 283 return nil; |
257 } | 284 } |
258 | 285 |
259 BASE_EXPORT template<class T> | 286 BASE_EXPORT template<typename T> |
260 T* ObjCCastStrict(id objc_val) { | 287 T* ObjCCastStrict(id objc_val) { |
261 T* rv = ObjCCast<T>(objc_val); | 288 T* rv = ObjCCast<T>(objc_val); |
262 DCHECK(objc_val == nil || rv); | 289 DCHECK(objc_val == nil || rv); |
263 return rv; | 290 return rv; |
264 } | 291 } |
265 | 292 |
266 #endif // defined(__OBJC__) | 293 #endif // defined(__OBJC__) |
267 | 294 |
295 // Utility function to pull out a value from a dictionary, check its type, and | |
296 // return it. Returns NULL if the key is not present or of the wrong type. | |
297 BASE_EXPORT template<typename T> | |
298 T GetValueFromDictionary(CFDictionaryRef dict, CFStringRef key) { | |
299 CFTypeRef value = CFDictionaryGetValue(dict, key); | |
300 T value_specific = CFCast<T>(value); | |
301 | |
302 if (value && !value_specific) { | |
303 std::string expected_type = TypeNameForCFType(value_specific); | |
304 DLOG(WARNING) << GetValueFromDictionaryErrorMessage(key, | |
305 expected_type, | |
306 value); | |
307 } | |
308 | |
309 return value_specific; | |
310 } | |
311 | |
268 } // namespace mac | 312 } // namespace mac |
269 } // namespace base | 313 } // namespace base |
270 | 314 |
271 // Stream operations for CFTypes. They can be used with NSTypes as well | 315 // Stream operations for CFTypes. They can be used with NSTypes as well |
272 // by using the NSToCFCast methods above. | 316 // by using the NSToCFCast methods above. |
273 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); | 317 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); |
274 // Operator << can not be overloaded for ObjectiveC types as the compiler | 318 // Operator << can not be overloaded for ObjectiveC types as the compiler |
275 // can not distinguish between overloads for id with overloads for void*. | 319 // can not distinguish between overloads for id with overloads for void*. |
276 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 320 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
277 const CFErrorRef err); | 321 const CFErrorRef err); |
278 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 322 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
279 const CFStringRef str); | 323 const CFStringRef str); |
280 | 324 |
281 #endif // BASE_MAC_FOUNDATION_UTIL_H_ | 325 #endif // BASE_MAC_FOUNDATION_UTIL_H_ |
OLD | NEW |