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" | |
17 | |
16 | 18 |
17 #if defined(__OBJC__) | 19 #if defined(__OBJC__) |
18 #import <Foundation/Foundation.h> | 20 #import <Foundation/Foundation.h> |
19 #else // __OBJC__ | 21 #else // __OBJC__ |
20 class NSBundle; | 22 class NSBundle; |
21 class NSString; | 23 class NSString; |
22 #endif // __OBJC__ | 24 #endif // __OBJC__ |
23 | 25 |
24 class FilePath; | 26 class FilePath; |
25 | 27 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 // Returns the ~/Library directory. | 91 // Returns the ~/Library directory. |
90 BASE_EXPORT FilePath GetUserLibraryPath(); | 92 BASE_EXPORT FilePath GetUserLibraryPath(); |
91 | 93 |
92 // Takes a path to an (executable) binary and tries to provide the path to an | 94 // 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 | 95 // 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"). | 96 // find (so for "/Foo/Bar.app/.../Baz.app/..." it produces "/Foo/Bar.app"). |
95 // |exec_name| - path to the binary | 97 // |exec_name| - path to the binary |
96 // returns - path to the application bundle, or empty on error | 98 // returns - path to the application bundle, or empty on error |
97 BASE_EXPORT FilePath GetAppBundlePath(const FilePath& exec_name); | 99 BASE_EXPORT FilePath GetAppBundlePath(const FilePath& exec_name); |
98 | 100 |
101 // Helper function for GetValueFromDictionary to create the error message | |
102 // that appears when a type mismatch is encountered. | |
103 std::string GetValueFromDictionaryErrorMessage(CFStringRef key, | |
104 CFStringRef expected_type_ref, | |
Mark Mentovai
2011/11/13 01:28:22
Bad alignment on the indent.
| |
105 CFTypeRef value); | |
106 | |
99 // Utility function to pull out a value from a dictionary, check its type, and | 107 // 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. | 108 // return it. Returns NULL if the key is not present or of the wrong type. |
101 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, | 109 BASE_EXPORT CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, |
102 CFStringRef key, | 110 CFStringRef key, |
103 CFTypeID expected_type); | 111 CFTypeID expected_type); |
104 | 112 |
113 // Utility function to pull out a value from a dictionary, check its type, and | |
114 // return it. Returns NULL if the key is not present or of the wrong type. | |
115 BASE_EXPORT template<class T> | |
Mark Mentovai
2011/11/13 01:28:22
Remember what I said? typename sounds better than
| |
116 T GetValueFromDictionary(CFDictionaryRef dict, CFStringRef key); | |
Mark Mentovai
2011/11/13 01:28:22
Why did you declare this here? You can just have t
KushalP
2011/11/13 12:30:27
Thought I'd killed this with the patch set.
| |
117 | |
105 // Retain/release calls for memory management in C++. | 118 // Retain/release calls for memory management in C++. |
106 BASE_EXPORT void NSObjectRetain(void* obj); | 119 BASE_EXPORT void NSObjectRetain(void* obj); |
107 BASE_EXPORT void NSObjectRelease(void* obj); | 120 BASE_EXPORT void NSObjectRelease(void* obj); |
108 | 121 |
109 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation | 122 // CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation |
110 // object (one derived from CFTypeRef) to the Foundation memory management | 123 // object (one derived from CFTypeRef) to the Foundation memory management |
111 // system. In a traditional managed-memory environment, cf_object is | 124 // system. In a traditional managed-memory environment, cf_object is |
112 // autoreleased and returned as an NSObject. In a garbage-collected | 125 // autoreleased and returned as an NSObject. In a garbage-collected |
113 // environment, cf_object is marked as eligible for garbage collection. | 126 // environment, cf_object is marked as eligible for garbage collection. |
114 // | 127 // |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 // triggering any DCHECK. | 224 // triggering any DCHECK. |
212 // | 225 // |
213 // Example usage: | 226 // Example usage: |
214 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( | 227 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( |
215 // CFArrayGetValueAtIndex(array, index)); | 228 // CFArrayGetValueAtIndex(array, index)); |
216 // | 229 // |
217 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( | 230 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>( |
218 // base::mac::GetValueFromDictionary(some_dict, | 231 // base::mac::GetValueFromDictionary(some_dict, |
219 // CFSTR("a_key"), | 232 // CFSTR("a_key"), |
220 // CFStringGetTypeID())); | 233 // CFStringGetTypeID())); |
221 BASE_EXPORT template<class T> | 234 BASE_EXPORT template<typename T> |
222 T CFCast(const CFTypeRef& cf_val); | 235 T CFCast(const CFTypeRef& cf_val); |
223 | 236 |
224 BASE_EXPORT template<class T> | 237 BASE_EXPORT template<typename T> |
225 T CFCastStrict(const CFTypeRef& cf_val); | 238 T CFCastStrict(const CFTypeRef& cf_val); |
226 | 239 |
227 #if defined(__OBJC__) | 240 #if defined(__OBJC__) |
228 | 241 |
229 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more | 242 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more |
230 // specific (NSObject-derived) type. The compatibility of the passed | 243 // specific (NSObject-derived) type. The compatibility of the passed |
231 // object is found by checking if it's a kind of the requested type | 244 // 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 | 245 // identifier. If the supplied object is not compatible with the |
233 // requested return type, ObjCCast<>() returns nil and | 246 // requested return type, ObjCCast<>() returns nil and |
234 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either | 247 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either |
235 // variant results in nil being returned without triggering any DCHECK. | 248 // variant results in nil being returned without triggering any DCHECK. |
236 // | 249 // |
237 // The strict variant is useful when retrieving a value from a | 250 // The strict variant is useful when retrieving a value from a |
238 // collection which only has values of a specific type, e.g. an | 251 // collection which only has values of a specific type, e.g. an |
239 // NSArray of NSStrings. The non-strict variant is useful when | 252 // NSArray of NSStrings. The non-strict variant is useful when |
240 // retrieving values from data that you can't fully control. For | 253 // retrieving values from data that you can't fully control. For |
241 // example, a plist read from disk may be beyond your exclusive | 254 // 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 | 255 // 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. | 256 // from it are of the expected types, but not crash if they're not. |
244 // | 257 // |
245 // Example usage: | 258 // Example usage: |
246 // NSString* version = base::mac::ObjCCast<NSString>( | 259 // NSString* version = base::mac::ObjCCast<NSString>( |
247 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); | 260 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); |
248 // | 261 // |
249 // NSString* str = base::mac::ObjCCastStrict<NSString>( | 262 // NSString* str = base::mac::ObjCCastStrict<NSString>( |
250 // [ns_arr_of_ns_strs objectAtIndex:0]); | 263 // [ns_arr_of_ns_strs objectAtIndex:0]); |
251 BASE_EXPORT template<class T> | 264 BASE_EXPORT template<typename T> |
252 T* ObjCCast(id objc_val) { | 265 T* ObjCCast(id objc_val) { |
253 if ([objc_val isKindOfClass:[T class]]) { | 266 if ([objc_val isKindOfClass:[T class]]) { |
254 return reinterpret_cast<T*>(objc_val); | 267 return reinterpret_cast<T*>(objc_val); |
255 } | 268 } |
256 return nil; | 269 return nil; |
257 } | 270 } |
258 | 271 |
259 BASE_EXPORT template<class T> | 272 BASE_EXPORT template<typename T> |
260 T* ObjCCastStrict(id objc_val) { | 273 T* ObjCCastStrict(id objc_val) { |
261 T* rv = ObjCCast<T>(objc_val); | 274 T* rv = ObjCCast<T>(objc_val); |
262 DCHECK(objc_val == nil || rv); | 275 DCHECK(objc_val == nil || rv); |
263 return rv; | 276 return rv; |
264 } | 277 } |
265 | 278 |
266 #endif // defined(__OBJC__) | 279 #endif // defined(__OBJC__) |
267 | 280 |
281 // Utility function to pull out a value from a dictionary, check its type, and | |
282 // return it. Returns NULL if the key is not present or of the wrong type. | |
283 // Is a cleaner implementation of base::mac::GetValueFromDictionary() above. | |
284 BASE_EXPORT template<typename T> | |
285 T GetValueFromDictionary(CFDictionaryRef dict, CFStringRef key) { | |
286 CFTypeRef value = CFDictionaryGetValue(dict, key); | |
287 T value_specific = CFCast<T>(value); | |
288 | |
289 if (!value) | |
Mark Mentovai
2011/11/13 01:28:22
Rid this entire function of early returns. Everyth
| |
290 // Can't return 'value' as it's a CFTypeRef. Provide a type T return. | |
291 return value_specific; | |
292 | |
293 if (!value_specific) { | |
294 // TODO: Get the string value of the type name T. | |
Mark Mentovai
2011/11/13 01:28:22
Can you think of a good way to do this?
KushalP
2011/11/13 12:30:27
If I'm honest I don't know "what" I'm looking for.
Mark Mentovai
2011/11/14 14:12:05
KushalP wrote:
| |
295 std::string type_name = "INSERT TYPE NAME"; | |
296 ScopedCFTypeRef<CFStringRef> expected_type_ref(CFStringCreateWithCString( | |
297 kCFAllocatorDefault, | |
298 type_name.c_str(), | |
299 kCFStringEncodingUTF8)); | |
300 DLOG(WARNING) << GetValueFromDictionaryErrorMessage(key, | |
301 expected_type_ref, | |
302 value); | |
303 return NULL; | |
304 } | |
305 return value_specific; | |
306 } | |
307 | |
268 } // namespace mac | 308 } // namespace mac |
269 } // namespace base | 309 } // namespace base |
270 | 310 |
271 // Stream operations for CFTypes. They can be used with NSTypes as well | 311 // Stream operations for CFTypes. They can be used with NSTypes as well |
272 // by using the NSToCFCast methods above. | 312 // by using the NSToCFCast methods above. |
273 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); | 313 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); |
274 // Operator << can not be overloaded for ObjectiveC types as the compiler | 314 // Operator << can not be overloaded for ObjectiveC types as the compiler |
275 // can not distinguish between overloads for id with overloads for void*. | 315 // can not distinguish between overloads for id with overloads for void*. |
276 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 316 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
277 const CFErrorRef err); | 317 const CFErrorRef err); |
278 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 318 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
279 const CFStringRef str); | 319 const CFStringRef str); |
280 | 320 |
281 #endif // BASE_MAC_FOUNDATION_UTIL_H_ | 321 #endif // BASE_MAC_FOUNDATION_UTIL_H_ |
OLD | NEW |