| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 7 |
| 8 #include <CoreFoundation/CoreFoundation.h> | 8 #include <CoreFoundation/CoreFoundation.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 CF_TO_NS_CAST_DECL(CTFont, NSFont); | 245 CF_TO_NS_CAST_DECL(CTFont, NSFont); |
| 246 #endif | 246 #endif |
| 247 | 247 |
| 248 #undef CF_TO_NS_CAST_DECL | 248 #undef CF_TO_NS_CAST_DECL |
| 249 #undef CF_TO_NS_MUTABLE_CAST_DECL | 249 #undef CF_TO_NS_MUTABLE_CAST_DECL |
| 250 #undef OBJC_CPP_CLASS_DECL | 250 #undef OBJC_CPP_CLASS_DECL |
| 251 | 251 |
| 252 namespace base { | 252 namespace base { |
| 253 namespace mac { | 253 namespace mac { |
| 254 | 254 |
| 255 // CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more | 255 // CFCast<>(), CFCastStrict<>() and CFStaticCast<> cast a basic CFTypeRef to a |
| 256 // specific CoreFoundation type. The compatibility of the passed | 256 // more specific CoreFoundation type. The compatibility of the passed object is |
| 257 // object is found by comparing its opaque type against the | 257 // found by comparing its opaque type against the requested type identifier. If |
| 258 // requested type identifier. If the supplied object is not | 258 // the supplied object is not compatible with the requested return type: |
| 259 // compatible with the requested return type, CFCast<>() returns | 259 // - CFCast<>() returns null, similar to dynamic_cast<>; |
| 260 // NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer | 260 // - CFCastStrict<>() will DCHECK or return null in Release; and |
| 261 // to either variant results in NULL being returned without | 261 // - CFStaticCast<>() will DCHECK but always cast, similar to static_cast<>. |
| 262 // triggering any DCHECK. | 262 // Providing a null pointer to any variant results in null being returned |
| 263 // without triggering any DCHECK. |
| 263 // | 264 // |
| 264 // Example usage: | 265 // Example usage: |
| 265 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( | 266 // CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( |
| 266 // CFArrayGetValueAtIndex(array, index)); | 267 // CFArrayGetValueAtIndex(array, index)); |
| 267 // | 268 // |
| 268 // CFTypeRef hello = CFSTR("hello world"); | 269 // CFTypeRef hello = CFSTR("hello world"); |
| 269 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>(hello); | 270 // CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>(hello); |
| 270 | |
| 271 template<typename T> | 271 template<typename T> |
| 272 T CFCast(const CFTypeRef& cf_val); | 272 T CFCast(const CFTypeRef& cf_val); |
| 273 | 273 |
| 274 template<typename T> | 274 template<typename T> |
| 275 T CFCastStrict(const CFTypeRef& cf_val); | 275 T CFCastStrict(const CFTypeRef& cf_val); |
| 276 | 276 |
| 277 template<typename T> |
| 278 T CFStaticCast(const CFTypeRef& cf_val) { |
| 279 DCHECK(!cf_val || CFCast<T>(cf_val)); |
| 280 // Note: CFTypeRef is const void*, but CGColorRef and some others are non- |
| 281 // const. So this may also cast away a const qualifier. |
| 282 return (T)(cf_val); |
| 283 } |
| 284 |
| 277 #define CF_CAST_DECL(TypeCF) \ | 285 #define CF_CAST_DECL(TypeCF) \ |
| 278 template<> BASE_EXPORT TypeCF##Ref \ | 286 template<> BASE_EXPORT TypeCF##Ref \ |
| 279 CFCast<TypeCF##Ref>(const CFTypeRef& cf_val);\ | 287 CFCast<TypeCF##Ref>(const CFTypeRef& cf_val);\ |
| 280 \ | 288 \ |
| 281 template<> BASE_EXPORT TypeCF##Ref \ | 289 template<> BASE_EXPORT TypeCF##Ref \ |
| 282 CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val); | 290 CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val); |
| 283 | 291 |
| 284 CF_CAST_DECL(CFArray); | 292 CF_CAST_DECL(CFArray); |
| 285 CF_CAST_DECL(CFBag); | 293 CF_CAST_DECL(CFBag); |
| 286 CF_CAST_DECL(CFBoolean); | 294 CF_CAST_DECL(CFBoolean); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 300 CF_CAST_DECL(CTFontDescriptor); | 308 CF_CAST_DECL(CTFontDescriptor); |
| 301 CF_CAST_DECL(CTRun); | 309 CF_CAST_DECL(CTRun); |
| 302 | 310 |
| 303 CF_CAST_DECL(SecACL); | 311 CF_CAST_DECL(SecACL); |
| 304 CF_CAST_DECL(SecTrustedApplication); | 312 CF_CAST_DECL(SecTrustedApplication); |
| 305 | 313 |
| 306 #undef CF_CAST_DECL | 314 #undef CF_CAST_DECL |
| 307 | 315 |
| 308 #if defined(__OBJC__) | 316 #if defined(__OBJC__) |
| 309 | 317 |
| 310 // ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more | 318 // ObjCCast<>(), ObjCCastStrict<>() and ObjCStaticCast cast a basic id to a more |
| 311 // specific (NSObject-derived) type. The compatibility of the passed | 319 // specific (NSObject-derived) type. The compatibility of the passed object is |
| 312 // object is found by checking if it's a kind of the requested type | 320 // found by checking if it's a kind of the requested type identifier. If the |
| 313 // identifier. If the supplied object is not compatible with the | 321 // supplied object is not compatible with the requested return type: |
| 314 // requested return type, ObjCCast<>() returns nil and | 322 // - ObjCCast<>() returns nil, similar to dynamic_cast<>, |
| 315 // ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either | 323 // - ObjCCastStrict<>() will DCHECK or return nil in Release; and |
| 316 // variant results in nil being returned without triggering any DCHECK. | 324 // - ObjCStaticCast<>() will DCHECK but always cast, similar to static_cast<>. |
| 325 // Providing a nil pointer to any variant results in nil being returned without |
| 326 // triggering any DCHECK. |
| 317 // | 327 // |
| 318 // The strict variant is useful when retrieving a value from a | 328 // The strict variant is useful when retrieving a value from a collection which |
| 319 // collection which only has values of a specific type, e.g. an | 329 // only has values of a specific type, e.g. an NSArray of NSStrings. The non- |
| 320 // NSArray of NSStrings. The non-strict variant is useful when | 330 // strict variant is useful when retrieving values from data that you can't |
| 321 // retrieving values from data that you can't fully control. For | 331 // fully control. For example, a plist read from disk may be beyond your |
| 322 // example, a plist read from disk may be beyond your exclusive | 332 // exclusive control, so you'd only want to check that the values you retrieve |
| 323 // control, so you'd only want to check that the values you retrieve | |
| 324 // from it are of the expected types, but not crash if they're not. | 333 // from it are of the expected types, but not crash if they're not. |
| 334 // ObjCStaticCast should be preferred when you have a strong contract specifying |
| 335 // the type and good test coverage. |
| 325 // | 336 // |
| 326 // Example usage: | 337 // Example usage: |
| 327 // NSString* version = base::mac::ObjCCast<NSString>( | 338 // NSString* version = base::mac::ObjCCast<NSString>( |
| 328 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); | 339 // [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); |
| 329 // | 340 // |
| 330 // NSString* str = base::mac::ObjCCastStrict<NSString>( | 341 // NSString* str = base::mac::ObjCCastStrict<NSString>( |
| 331 // [ns_arr_of_ns_strs objectAtIndex:0]); | 342 // [ns_arr_of_ns_strs objectAtIndex:0]); |
| 332 template<typename T> | 343 template<typename T> |
| 333 T* ObjCCast(id objc_val) { | 344 T* ObjCCast(id objc_val) { |
| 334 if ([objc_val isKindOfClass:[T class]]) { | 345 if ([objc_val isKindOfClass:[T class]]) { |
| 335 return reinterpret_cast<T*>(objc_val); | 346 return reinterpret_cast<T*>(objc_val); |
| 336 } | 347 } |
| 337 return nil; | 348 return nil; |
| 338 } | 349 } |
| 339 | 350 |
| 340 template<typename T> | 351 template<typename T> |
| 341 T* ObjCCastStrict(id objc_val) { | 352 T* ObjCCastStrict(id objc_val) { |
| 342 T* rv = ObjCCast<T>(objc_val); | 353 T* rv = ObjCCast<T>(objc_val); |
| 343 DCHECK(objc_val == nil || rv); | 354 DCHECK(objc_val == nil || rv); |
| 344 return rv; | 355 return rv; |
| 345 } | 356 } |
| 346 | 357 |
| 358 template<typename T> |
| 359 T* ObjCStaticCast(id objc_val) { |
| 360 DCHECK(!objc_val || ObjCCast<T>(objc_val)); |
| 361 return reinterpret_cast<T*>(objc_val); |
| 362 } |
| 363 |
| 347 #endif // defined(__OBJC__) | 364 #endif // defined(__OBJC__) |
| 348 | 365 |
| 349 // Helper function for GetValueFromDictionary to create the error message | 366 // Helper function for GetValueFromDictionary to create the error message |
| 350 // that appears when a type mismatch is encountered. | 367 // that appears when a type mismatch is encountered. |
| 351 BASE_EXPORT std::string GetValueFromDictionaryErrorMessage( | 368 BASE_EXPORT std::string GetValueFromDictionaryErrorMessage( |
| 352 CFStringRef key, const std::string& expected_type, CFTypeRef value); | 369 CFStringRef key, const std::string& expected_type, CFTypeRef value); |
| 353 | 370 |
| 354 // Utility function to pull out a value from a dictionary, check its type, and | 371 // Utility function to pull out a value from a dictionary, check its type, and |
| 355 // return it. Returns NULL if the key is not present or of the wrong type. | 372 // return it. Returns NULL if the key is not present or of the wrong type. |
| 356 template<typename T> | 373 template<typename T> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 // by using the NSToCFCast methods above. | 406 // by using the NSToCFCast methods above. |
| 390 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); | 407 // e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); |
| 391 // Operator << can not be overloaded for ObjectiveC types as the compiler | 408 // Operator << can not be overloaded for ObjectiveC types as the compiler |
| 392 // can not distinguish between overloads for id with overloads for void*. | 409 // can not distinguish between overloads for id with overloads for void*. |
| 393 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 410 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
| 394 const CFErrorRef err); | 411 const CFErrorRef err); |
| 395 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, | 412 BASE_EXPORT extern std::ostream& operator<<(std::ostream& o, |
| 396 const CFStringRef str); | 413 const CFStringRef str); |
| 397 | 414 |
| 398 #endif // BASE_MAC_FOUNDATION_UTIL_H_ | 415 #endif // BASE_MAC_FOUNDATION_UTIL_H_ |
| OLD | NEW |