summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/mac/mac_util.h99
-rw-r--r--base/mac/mac_util.mm72
-rw-r--r--chrome/app/chrome_main.cc2
-rw-r--r--chrome/browser/cocoa/install_from_dmg.mm4
-rw-r--r--chrome/browser/cocoa/keystone_glue.mm2
-rw-r--r--chrome/browser/importer/safari_importer.mm3
-rw-r--r--chrome/browser/ui/cocoa/file_metadata.mm4
-rw-r--r--ui/gfx/canvas_skia_mac.mm3
8 files changed, 141 insertions, 48 deletions
diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h
index d75fb6e..990197d 100644
--- a/base/mac/mac_util.h
+++ b/base/mac/mac_util.h
@@ -110,57 +110,76 @@ void RemoveFromLoginItems();
// 'Login Item' with 'hide on startup' flag. Used to suppress opening windows.
bool WasLaunchedAsHiddenLoginItem();
-#if defined(__OBJC__)
+} // namespace mac
+} // namespace base
+
+#if !defined(__OBJC__)
+#define OBJC_CPP_CLASS_DECL(x) class x;
+#else // __OBJC__
+#define OBJC_CPP_CLASS_DECL(x)
+#endif // __OBJC__
-// 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:
+// 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,
// (http://www.gotw.ca/publications/mill17.htm) so the trusty combination
// of macros and function overloading is used instead.
-#define CF_TO_NS_CAST(TypeCF, TypeNS) \
-inline TypeNS* CFToNSCast(TypeCF 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; \
-}
+#define CF_TO_NS_CAST_DECL(TypeCF, TypeNS) \
+OBJC_CPP_CLASS_DECL(TypeNS) \
+\
+namespace base { \
+namespace mac { \
+TypeNS* CFToNSCast(TypeCF##Ref cf_val); \
+TypeCF##Ref NSToCFCast(TypeNS* ns_val); \
+} \
+} \
+
+#define CF_TO_NS_MUTABLE_CAST_DECL(name) \
+CF_TO_NS_CAST_DECL(CF##name, NS##name) \
+OBJC_CPP_CLASS_DECL(NSMutable##name) \
+\
+namespace base { \
+namespace mac { \
+NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val); \
+CFMutable##name##Ref NSToCFCast(NSMutable##name* ns_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_DECL(Array);
+CF_TO_NS_MUTABLE_CAST_DECL(AttributedString);
+CF_TO_NS_CAST_DECL(CFCalendar, NSCalendar);
+CF_TO_NS_MUTABLE_CAST_DECL(CharacterSet);
+CF_TO_NS_MUTABLE_CAST_DECL(Data);
+CF_TO_NS_CAST_DECL(CFDate, NSDate);
+CF_TO_NS_MUTABLE_CAST_DECL(Dictionary);
+CF_TO_NS_CAST_DECL(CFError, NSError);
+CF_TO_NS_CAST_DECL(CFLocale, NSLocale);
+CF_TO_NS_CAST_DECL(CFNumber, NSNumber);
+CF_TO_NS_CAST_DECL(CFRunLoopTimer, NSTimer);
+CF_TO_NS_CAST_DECL(CFTimeZone, NSTimeZone);
+CF_TO_NS_MUTABLE_CAST_DECL(Set);
+CF_TO_NS_CAST_DECL(CFReadStream, NSInputStream);
+CF_TO_NS_CAST_DECL(CFWriteStream, NSOutputStream);
+CF_TO_NS_MUTABLE_CAST_DECL(String);
+CF_TO_NS_CAST_DECL(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_
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm
index 7f3be18..2eddeae 100644
--- a/base/mac/mac_util.mm
+++ b/base/mac/mac_util.mm
@@ -480,5 +480,77 @@ bool WasLaunchedAsHiddenLoginItem() {
return IsHiddenLoginItem(item);
}
+// Definitions for the corresponding CF_TO_NS_CAST_DECL macros in mac_util.h.
+#define CF_TO_NS_CAST_DEFN(TypeCF, TypeNS) \
+\
+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)); \
+ return ns_val; \
+} \
+\
+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_DEFN(name) \
+CF_TO_NS_CAST_DEFN(CF##name, NS##name) \
+\
+NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val) { \
+ DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \
+ NSMutable##name* ns_val = reinterpret_cast<NSMutable##name*>(cf_val); \
+ return ns_val; \
+} \
+\
+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; \
+} \
+
+CF_TO_NS_MUTABLE_CAST_DEFN(Array);
+CF_TO_NS_MUTABLE_CAST_DEFN(AttributedString);
+CF_TO_NS_CAST_DEFN(CFCalendar, NSCalendar);
+CF_TO_NS_MUTABLE_CAST_DEFN(CharacterSet);
+CF_TO_NS_MUTABLE_CAST_DEFN(Data);
+CF_TO_NS_CAST_DEFN(CFDate, NSDate);
+CF_TO_NS_MUTABLE_CAST_DEFN(Dictionary);
+CF_TO_NS_CAST_DEFN(CFError, NSError);
+CF_TO_NS_CAST_DEFN(CFLocale, NSLocale);
+CF_TO_NS_CAST_DEFN(CFNumber, NSNumber);
+CF_TO_NS_CAST_DEFN(CFRunLoopTimer, NSTimer);
+CF_TO_NS_CAST_DEFN(CFTimeZone, NSTimeZone);
+CF_TO_NS_MUTABLE_CAST_DEFN(Set);
+CF_TO_NS_CAST_DEFN(CFReadStream, NSInputStream);
+CF_TO_NS_CAST_DEFN(CFWriteStream, NSOutputStream);
+CF_TO_NS_MUTABLE_CAST_DEFN(String);
+CF_TO_NS_CAST_DEFN(CFURL, NSURL);
+
} // namespace mac
} // namespace base
+
+std::ostream& operator<<(std::ostream& o, const CFStringRef string) {
+ return o << base::SysCFStringRefToUTF8(string);
+}
+
+std::ostream& operator<<(std::ostream& o, const CFErrorRef err) {
+ base::mac::ScopedCFTypeRef<CFStringRef> desc(CFErrorCopyDescription(err));
+ base::mac::ScopedCFTypeRef<CFDictionaryRef> user_info(
+ CFErrorCopyUserInfo(err));
+ CFStringRef errorDesc = NULL;
+ if (user_info.get()) {
+ errorDesc = reinterpret_cast<CFStringRef>(
+ CFDictionaryGetValue(user_info.get(), kCFErrorDescriptionKey));
+ }
+ o << "Code: " << CFErrorGetCode(err)
+ << " Domain: " << CFErrorGetDomain(err)
+ << " Desc: " << desc.get();
+ if(errorDesc) {
+ o << "(" << errorDesc << ")";
+ }
+ return o;
+}
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index eeee4e4..71bb4c2 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -268,7 +268,7 @@ void SetMacProcessName(const std::string& process_type) {
}
if (name_id) {
NSString* app_name = l10n_util::GetNSString(name_id);
- base::mac::SetProcessName(reinterpret_cast<CFStringRef>(app_name));
+ base::mac::SetProcessName(base::mac::NSToCFCast(app_name));
}
}
diff --git a/chrome/browser/cocoa/install_from_dmg.mm b/chrome/browser/cocoa/install_from_dmg.mm
index 8af44f3..1c56927 100644
--- a/chrome/browser/cocoa/install_from_dmg.mm
+++ b/chrome/browser/cocoa/install_from_dmg.mm
@@ -239,7 +239,7 @@ AuthorizationRef MaybeShowAuthorizationDialog(NSString* application_directory) {
IDS_INSTALL_FROM_DMG_AUTHENTICATION_PROMPT,
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
return authorization_util::AuthorizationCreateToRunAsRoot(
- reinterpret_cast<CFStringRef>(prompt));
+ base::mac::NSToCFCast(prompt));
}
// Invokes the installer program at installer_path to copy source_path to
@@ -339,7 +339,7 @@ bool LaunchInstalledApp(NSString* app_path) {
struct LSApplicationParameters parameters = {0};
parameters.flags = kLSLaunchDefaults;
parameters.application = &app_fsref;
- parameters.argv = reinterpret_cast<CFArrayRef>(arguments);
+ parameters.argv = base::mac::NSToCFCast(arguments);
err = LSOpenApplication(&parameters, NULL);
if (err != noErr) {
diff --git a/chrome/browser/cocoa/keystone_glue.mm b/chrome/browser/cocoa/keystone_glue.mm
index 562d74a..8addcdb 100644
--- a/chrome/browser/cocoa/keystone_glue.mm
+++ b/chrome/browser/cocoa/keystone_glue.mm
@@ -757,7 +757,7 @@ NSString* const kBrandKey = @"KSBrandID";
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
scoped_AuthorizationRef authorization(
authorization_util::AuthorizationCreateToRunAsRoot(
- reinterpret_cast<CFStringRef>(prompt)));
+ base::mac::NSToCFCast(prompt)));
if (!authorization.get()) {
return;
}
diff --git a/chrome/browser/importer/safari_importer.mm b/chrome/browser/importer/safari_importer.mm
index de40655..e65a41d 100644
--- a/chrome/browser/importer/safari_importer.mm
+++ b/chrome/browser/importer/safari_importer.mm
@@ -10,6 +10,7 @@
#include <vector>
#include "base/file_util.h"
+#include "base/mac/mac_util.h"
#include "base/message_loop.h"
#include "base/scoped_nsobject.h"
#include "base/string16.h"
@@ -326,7 +327,7 @@ double SafariImporter::HistoryTimeToEpochTime(NSString* history_time) {
// Add Difference between Unix epoch and CFAbsoluteTime epoch in seconds.
// Unix epoch is 1970-01-01 00:00:00.0 UTC,
// CF epoch is 2001-01-01 00:00:00.0 UTC.
- return CFStringGetDoubleValue(reinterpret_cast<CFStringRef>(history_time)) +
+ return CFStringGetDoubleValue(base::mac::NSToCFCast(history_time)) +
kCFAbsoluteTimeIntervalSince1970;
}
diff --git a/chrome/browser/ui/cocoa/file_metadata.mm b/chrome/browser/ui/cocoa/file_metadata.mm
index ca199a5..c069f09 100644
--- a/chrome/browser/ui/cocoa/file_metadata.mm
+++ b/chrome/browser/ui/cocoa/file_metadata.mm
@@ -70,7 +70,7 @@ void AddOriginMetadataToFile(const FilePath& file, const GURL& source,
return;
base::mac::ScopedCFTypeRef<MDItemRef> md_item(
- MDItemCreate(NULL, reinterpret_cast<CFStringRef>(file_path)));
+ MDItemCreate(NULL, base::mac::NSToCFCast(file_path)));
if (!md_item)
return;
@@ -88,7 +88,7 @@ void AddOriginMetadataToFile(const FilePath& file, const GURL& source,
[list addObject:referrer_url];
md_item_set_attribute_func(md_item, kMDItemWhereFroms,
- reinterpret_cast<CFArrayRef>(list));
+ base::mac::NSToCFCast(list));
}
// The OS will automatically quarantine files due to the
diff --git a/ui/gfx/canvas_skia_mac.mm b/ui/gfx/canvas_skia_mac.mm
index c82e1aa..c6fb031 100644
--- a/ui/gfx/canvas_skia_mac.mm
+++ b/ui/gfx/canvas_skia_mac.mm
@@ -6,6 +6,7 @@
#include "ui/gfx/canvas_skia.h"
+#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/sys_string_conversions.h"
#include "third_party/skia/include/core/SkShader.h"
@@ -72,7 +73,7 @@ void CanvasSkia::DrawStringInt(const string16& text,
attributes:attributes] autorelease];
base::mac::ScopedCFTypeRef<CTFramesetterRef> framesetter(
CTFramesetterCreateWithAttributedString(
- reinterpret_cast<CFAttributedStringRef>(ns_string)));
+ base::mac::NSToCFCast(ns_string)));
CGRect text_bounds = CGRectMake(x, y, w, h);
CGMutablePathRef path = CGPathCreateMutable();