Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2604)

Unified Diff: base/mac/mac_util.h

Issue 6594096: Clean up CF To NS Casts and make them slightly safer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/mac/mac_util.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/mac/mac_util.h
diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h
index d75fb6e792a8fca003b43b8572e4d20f744e5f1d..7f0a899e8fc4855bd127fdce0556870e31ad9354 100644
--- a/base/mac/mac_util.h
+++ b/base/mac/mac_util.h
@@ -110,14 +110,22 @@ void RemoveFromLoginItems();
// 'Login Item' with 'hide on startup' flag. Used to suppress opening windows.
bool WasLaunchedAsHiddenLoginItem();
-#if defined(__OBJC__)
+} // namespace mac
+} // namespace base
-// Convert toll-free bridged CFTypes to NSTypes. This does not autorelease
-// |cf_val|. This is useful for the case where there is a CFType in a call that
-// expects an NSType and the compiler is complaining about const casting
-// problems.
-// The call is used like this:
+#if !defined(__OBJC__)
+#define OBJC_CPP_CLASS_DEFN(x) class x;
+#else // __OBJC__
+#define OBJC_CPP_CLASS_DEFN(x)
+#endif // __OBJC__
+
+// Convert toll-free bridged CFTypes to NSTypes and vice-versa. This does not
+// autorelease |cf_val|. This is useful for the case where there is a CFType in
+// a call that expects an NSType and the compiler is complaining about const
+// casting problems.
+// The calls are used like this:
// NSString *foo = CFToNSCast(CFSTR("Hello"));
+// CFStringRef foo2 = NSToCFCast(@"Hello");
// The macro magic below is to enforce safe casting. It could possibly have
// been done using template function specialization, but template function
// specialization doesn't always work intuitively,
@@ -125,42 +133,72 @@ bool WasLaunchedAsHiddenLoginItem();
// of macros and function overloading is used instead.
#define CF_TO_NS_CAST(TypeCF, TypeNS) \
-inline TypeNS* CFToNSCast(TypeCF cf_val) { \
+OBJC_CPP_CLASS_DEFN(TypeNS); \
+\
+namespace base { \
+namespace mac { \
+inline TypeNS* CFToNSCast(TypeCF##Ref cf_val) { \
+ DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
TypeNS* ns_val = \
const_cast<TypeNS*>(reinterpret_cast<const TypeNS*>(cf_val)); \
- DCHECK(!ns_val || [ns_val isKindOfClass:[TypeNS class]]); \
return ns_val; \
-}
-
+} \
+\
+inline TypeCF##Ref NSToCFCast(TypeNS* ns_val) { \
+ TypeCF##Ref cf_val = reinterpret_cast<TypeCF##Ref>(ns_val); \
+ DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \
+ return cf_val; \
+} \
+} \
+} \
+
+#define CF_TO_NS_MUTABLE_CAST(name) \
+CF_TO_NS_CAST(CF##name, NS##name) \
+OBJC_CPP_CLASS_DEFN(NSMutable##name) \
+\
+namespace base { \
+namespace mac { \
+inline NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val) { \
Nico 2011/03/02 02:21:22 I guess Elliot would be happier if all these funct
dmac 2011/03/02 22:20:09 Done.
+ DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
+ NSMutable##name* ns_val = reinterpret_cast<NSMutable##name*>(cf_val); \
+ return ns_val; \
+} \
+\
+inline CFMutable##name##Ref NSToCFCast(NSMutable##name* ns_val) { \
+ CFMutable##name##Ref cf_val = \
+ reinterpret_cast<CFMutable##name##Ref>(ns_val); \
+ DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
+ return cf_val; \
+} \
+} \
+} \
// List of toll-free bridged types taken from:
// http://www.cocoadev.com/index.pl?TollFreeBridged
-CF_TO_NS_CAST(CFArrayRef, NSArray);
-CF_TO_NS_CAST(CFMutableArrayRef, NSMutableArray);
-CF_TO_NS_CAST(CFAttributedStringRef, NSAttributedString);
-CF_TO_NS_CAST(CFMutableAttributedStringRef, NSMutableAttributedString);
-CF_TO_NS_CAST(CFCalendarRef, NSCalendar);
-CF_TO_NS_CAST(CFCharacterSetRef, NSCharacterSet);
-CF_TO_NS_CAST(CFMutableCharacterSetRef, NSMutableCharacterSet);
-CF_TO_NS_CAST(CFDataRef, NSData);
-CF_TO_NS_CAST(CFMutableDataRef, NSMutableData);
-CF_TO_NS_CAST(CFDateRef, NSDate);
-CF_TO_NS_CAST(CFDictionaryRef, NSDictionary);
-CF_TO_NS_CAST(CFMutableDictionaryRef, NSMutableDictionary);
-CF_TO_NS_CAST(CFNumberRef, NSNumber);
-CF_TO_NS_CAST(CFRunLoopTimerRef, NSTimer);
-CF_TO_NS_CAST(CFSetRef, NSSet);
-CF_TO_NS_CAST(CFMutableSetRef, NSMutableSet);
-CF_TO_NS_CAST(CFStringRef, NSString);
-CF_TO_NS_CAST(CFMutableStringRef, NSMutableString);
-CF_TO_NS_CAST(CFURLRef, NSURL);
-CF_TO_NS_CAST(CFTimeZoneRef, NSTimeZone);
-CF_TO_NS_CAST(CFReadStreamRef, NSInputStream);
-CF_TO_NS_CAST(CFWriteStreamRef, NSOutputStream);
-
-#endif // __OBJC__
-
-} // namespace mac
-} // namespace base
+CF_TO_NS_MUTABLE_CAST(Array);
+CF_TO_NS_MUTABLE_CAST(AttributedString);
+CF_TO_NS_CAST(CFCalendar, NSCalendar);
+CF_TO_NS_MUTABLE_CAST(CharacterSet);
+CF_TO_NS_MUTABLE_CAST(Data);
+CF_TO_NS_CAST(CFDate, NSDate);
+CF_TO_NS_MUTABLE_CAST(Dictionary);
+CF_TO_NS_CAST(CFError, NSError);
+CF_TO_NS_CAST(CFLocale, NSLocale);
+CF_TO_NS_CAST(CFNumber, NSNumber);
+CF_TO_NS_CAST(CFRunLoopTimer, NSTimer);
+CF_TO_NS_CAST(CFTimeZone, NSTimeZone);
+CF_TO_NS_MUTABLE_CAST(Set);
+CF_TO_NS_CAST(CFReadStream, NSInputStream);
+CF_TO_NS_CAST(CFWriteStream, NSOutputStream);
+CF_TO_NS_MUTABLE_CAST(String);
+CF_TO_NS_CAST(CFURL, NSURL);
+
+// Stream operations for CFTypes. They can be used with NSTypes as well
+// by using the NSToCFCast methods above.
+// e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo");
+// Operator << can not be overloaded for ObjectiveC types as the compiler
+// can not distinguish between overloads for id with overloads for void*.
+extern std::ostream& operator<<(std::ostream& o, const CFErrorRef err);
+extern std::ostream& operator<<(std::ostream& o, const CFStringRef str);
#endif // BASE_MAC_MAC_UTIL_H_
« no previous file with comments | « no previous file | base/mac/mac_util.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698