From f7de41c770be1bc6c45e825ff0fbdd6bfb799fae Mon Sep 17 00:00:00 2001 From: Tobias Markmann <tm@ayena.de> Date: Wed, 9 Mar 2016 14:38:57 +0000 Subject: Explicitly convert between nullable and non-nullable on OS X Clang was complaining about implicit conversions between nullable and non-nullable NSString pointers. Adjusted our std::string -> NSString* conversion utilities to check for nil and return an empty std::string in that case. Replaced uses of [NSString stringWithUTF8String] with our STD2NSSTRING macro. Turned std::string <-> NSString* conversion macros into functions. Test-Information: Builds without the warning on OS X 10.11.3 and Swift runs without issues. Change-Id: I949f2f3332018391aead58ef362764f4b7955b01 diff --git a/Slimber/Cocoa/CocoaMenulet.mm b/Slimber/Cocoa/CocoaMenulet.mm index 6013b05..f62da80 100644 --- a/Slimber/Cocoa/CocoaMenulet.mm +++ b/Slimber/Cocoa/CocoaMenulet.mm @@ -1,15 +1,15 @@ /* - * Copyright (c) 2012-2013 Isode Limited. + * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include "Slimber/Cocoa/CocoaMenulet.h" - -#pragma GCC diagnostic ignored "-Wold-style-cast" +#include <Slimber/Cocoa/CocoaMenulet.h> #include <boost/function.hpp> +#include <SwifTools/Cocoa/CocoaUtil.h> + CocoaMenulet::CocoaMenulet() { restartAction = [[CocoaAction alloc] initWithFunction: new boost::function<void()>(boost::ref(onRestartClicked))]; @@ -19,7 +19,7 @@ CocoaMenulet::CocoaMenulet() { statusItemWithLength: NSVariableStatusItemLength] retain]; [statusItem setHighlightMode: YES]; [statusItem setEnabled: YES]; - [statusItem setToolTip: @"Slimber"]; + [statusItem setToolTip: @"Slimber"]; [statusItem setMenu: menu]; } @@ -30,8 +30,7 @@ CocoaMenulet::~CocoaMenulet() { } void CocoaMenulet::setIcon(const std::string& icon) { - NSString* path = [[NSBundle mainBundle] pathForResource: - [NSString stringWithUTF8String: icon.c_str()] ofType:@"png"]; + NSString* path = [[NSBundle mainBundle] pathForResource: std2NSString(icon) ofType:@"png"]; NSImage* image = [[NSImage alloc] initWithContentsOfFile: path]; [statusItem setImage: image]; [image release]; @@ -44,12 +43,10 @@ void CocoaMenulet::clear() { } void CocoaMenulet::addItem(const std::string& name, const std::string& icon) { - NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: - [NSString stringWithUTF8String: name.c_str()] + NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: std2NSString(name) action: NULL keyEquivalent: @""]; if (!icon.empty()) { - NSString* path = [[NSBundle mainBundle] pathForResource: - [NSString stringWithUTF8String: icon.c_str()] ofType:@"png"]; + NSString* path = [[NSBundle mainBundle] pathForResource: std2NSString(icon) ofType:@"png"]; NSImage* image = [[NSImage alloc] initWithContentsOfFile: path]; [item setImage: image]; [image release]; diff --git a/Sluift/ITunesInterface.mm b/Sluift/ITunesInterface.mm index 0843aad..a11be20 100644 --- a/Sluift/ITunesInterface.mm +++ b/Sluift/ITunesInterface.mm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Isode Limited. + * Copyright (c) 2014-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -40,9 +40,9 @@ boost::optional<ITunesInterface::Track> ITunesInterface::getCurrentTrack() const return boost::optional<ITunesInterface::Track>(); } ITunesInterface::Track result; - result.name = NS2STDSTRING(currentTrack.name); - result.artist = NS2STDSTRING(currentTrack.artist); - result.album = NS2STDSTRING(currentTrack.album); + result.name = ns2StdString(currentTrack.name); + result.artist = ns2StdString(currentTrack.artist); + result.album = ns2StdString(currentTrack.album); result.trackNumber = currentTrack.trackNumber; result.duration = currentTrack.duration; result.rating = currentTrack.rating; diff --git a/SwifTools/Cocoa/CocoaUtil.h b/SwifTools/Cocoa/CocoaUtil.h index 49ed682..83d95b6 100644 --- a/SwifTools/Cocoa/CocoaUtil.h +++ b/SwifTools/Cocoa/CocoaUtil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Isode Limited. + * Copyright (c) 2011-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -7,16 +7,36 @@ #pragma once // Conversion utilities -#define NS2STDSTRING(a) (a == nil ? std::string() : std::string([a cStringUsingEncoding:NSUTF8StringEncoding])) -#define STD2NSSTRING(a) [NSString stringWithCString:a.c_str() encoding:NSUTF8StringEncoding] +namespace { + +inline std::string ns2StdString(NSString* _Nullable nsString); +inline std::string ns2StdString(NSString* _Nullable nsString) { + std::string stdString; + if (nsString != nil) { + stdString = std::string([nsString cStringUsingEncoding:NSUTF8StringEncoding]); + } + return stdString; +} + +inline NSString* _Nonnull std2NSString(const std::string& stdString); +inline NSString* _Nonnull std2NSString(const std::string& stdString) { + NSString* _Nullable nsString = [NSString stringWithUTF8String:stdString.c_str()]; + if (nsString == nil) { + nsString = @""; + } + // At this point nsString is guaranteed to be not null/nil. + return static_cast<NSString* _Nonnull>(nsString); +} + +} // Intrusive pointer for NSObjects namespace boost { - inline void intrusive_ptr_add_ref(NSObject* object) { + inline void intrusive_ptr_add_ref(NSObject* _Nonnull object) { [object retain]; } - inline void intrusive_ptr_release(NSObject* object) { + inline void intrusive_ptr_release(NSObject* _Nonnull object) { [object release]; } } diff --git a/SwifTools/Notifier/GrowlNotifier.mm b/SwifTools/Notifier/GrowlNotifier.mm index acaf45c..d5bdf6f 100644 --- a/SwifTools/Notifier/GrowlNotifier.mm +++ b/SwifTools/Notifier/GrowlNotifier.mm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2011 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -36,16 +36,16 @@ GrowlNotifier::GrowlNotifier(const std::string& name) { p = boost::make_shared<Private>(); p->delegate = boost::intrusive_ptr<GrowlNotifierDelegate>([[GrowlNotifierDelegate alloc] init], false); p->delegate.get().notifier = this; - p->delegate.get().name = STD2NSSTRING(name); + p->delegate.get().name = std2NSString(name); NSMutableArray* allNotifications = [[NSMutableArray alloc] init]; foreach(Type type, getAllTypes()) { - [allNotifications addObject: STD2NSSTRING(typeToString(type))]; + [allNotifications addObject: std2NSString(typeToString(type))]; } NSMutableArray* defaultNotifications = [[NSMutableArray alloc] init]; foreach(Type type, getDefaultTypes()) { - [defaultNotifications addObject: STD2NSSTRING(typeToString(type))]; + [defaultNotifications addObject: std2NSString(typeToString(type))]; } p->delegate.get().registrationDictionary = [[[NSDictionary alloc] @@ -73,9 +73,9 @@ void GrowlNotifier::showMessage(Type type, const std::string& subject, const std p->pendingNotifications.insert(context); [GrowlApplicationBridge - notifyWithTitle: STD2NSSTRING(subject) - description: STD2NSSTRING(description) - notificationName: STD2NSSTRING(typeToString(type)) + notifyWithTitle: std2NSString(subject) + description: std2NSString(description) + notificationName: std2NSString(typeToString(type)) iconData: [NSData dataWithBytes: vecptr(picture) length: picture.size()] priority: 0 isSticky: NO diff --git a/SwifTools/Notifier/NotificationCenterNotifier.mm b/SwifTools/Notifier/NotificationCenterNotifier.mm index 10319c8..01e6368 100644 --- a/SwifTools/Notifier/NotificationCenterNotifier.mm +++ b/SwifTools/Notifier/NotificationCenterNotifier.mm @@ -57,11 +57,11 @@ void NotificationCenterNotifier::showMessage(Type type, const std::string& subje if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) { return; } - NSImage* image = [[NSImage alloc] initWithContentsOfFile: STD2NSSTRING(picture.string())]; + NSImage* image = [[NSImage alloc] initWithContentsOfFile: std2NSString(picture.string())]; NSUserNotification* notification = [[NSUserNotification alloc] init]; - [notification setTitle:STD2NSSTRING(typeToString(type))]; - [notification setSubtitle:STD2NSSTRING(subject)]; - [notification setInformativeText:STD2NSSTRING(description)]; + [notification setTitle:std2NSString(typeToString(type))]; + [notification setSubtitle:std2NSString(subject)]; + [notification setInformativeText:std2NSString(description)]; [notification setContentImage: image]; [image release]; @@ -73,7 +73,7 @@ void NotificationCenterNotifier::showMessage(Type type, const std::string& subje /// \todo Currently the elements are only removed on application exit. Ideally the notifications not required anymore /// are removed from the map; e.g. when visiting a chat view, all notifications from that view can be removed from /// the map and the NSUserNotificationCenter. - p->callbacksForNotifications[NS2STDSTRING(notification.identifier)] = boost::make_shared<Context>(callback); + p->callbacksForNotifications[ns2StdString(notification.identifier)] = boost::make_shared<Context>(callback); [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; [notification release]; } diff --git a/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm b/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm index 617619c..2b1c2a4 100644 --- a/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm +++ b/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Isode Limited. + * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -19,7 +19,7 @@ using namespace Swift; - (void)userNotificationCenter:(NSUserNotificationCenter *) center didActivateNotification:(NSUserNotification *)notification { (void)center; - std::string identifier = NS2STDSTRING(notification.identifier); + std::string identifier = ns2StdString(notification.identifier); notifier->handleUserNotificationActivated(identifier); } diff --git a/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm b/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm index ed409bd..6f8e158 100644 --- a/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm +++ b/Swiften/TLS/SecureTransport/SecureTransportCertificate.mm @@ -25,6 +25,19 @@ T bridge_cast(S source) { } +namespace { + +inline std::string ns2StdString(NSString* _Nullable nsString); +inline std::string ns2StdString(NSString* _Nullable nsString) { + std::string stdString; + if (nsString != nil) { + stdString = std::string([nsString cStringUsingEncoding:NSUTF8StringEncoding]); + } + return stdString; +} + +} + namespace Swift { SecureTransportCertificate::SecureTransportCertificate(SecCertificateRef certificate) { @@ -49,9 +62,6 @@ SecureTransportCertificate::~SecureTransportCertificate() { } -#define NS2STDSTRING(a) (a == nil ? std::string() : std::string([a cStringUsingEncoding:NSUTF8StringEncoding])) - - void SecureTransportCertificate::parse() { assert(certificateHandle_); CFErrorRef error = NULL; @@ -63,7 +73,7 @@ void SecureTransportCertificate::parse() { CFStringRef subject = SecCertificateCopySubjectSummary(certificateHandle_.get()); if (subject) { NSString* subjectStr = bridge_cast<NSString*>(subject); - subjectName_ = NS2STDSTRING(subjectStr); + subjectName_ = ns2StdString(subjectStr); CFRelease(subject); } @@ -72,7 +82,7 @@ void SecureTransportCertificate::parse() { OSStatus error = SecCertificateCopyCommonName(certificateHandle_.get(), &commonName); if (!error && commonName) { NSString* commonNameStr = bridge_cast<NSString*>(commonName); - commonNames_.push_back(NS2STDSTRING(commonNameStr)); + commonNames_.push_back(ns2StdString(commonNameStr)); } if (commonName) { CFRelease(commonName); @@ -83,14 +93,14 @@ void SecureTransportCertificate::parse() { NSDictionary* subjectAltNamesDict = certDict[@"2.5.29.17"][@"value"]; for (NSDictionary* entry in subjectAltNamesDict) { - if ([entry[@"label"] isEqualToString:[NSString stringWithUTF8String:ID_ON_XMPPADDR_OID]]) { - xmppAddresses_.push_back(NS2STDSTRING(entry[@"value"])); + if ([entry[@"label"] isEqualToString:static_cast<NSString * _Nonnull>([NSString stringWithUTF8String:ID_ON_XMPPADDR_OID])]) { + xmppAddresses_.push_back(ns2StdString(entry[@"value"])); } - else if ([entry[@"label"] isEqualToString:[NSString stringWithUTF8String:ID_ON_DNSSRV_OID]]) { - srvNames_.push_back(NS2STDSTRING(entry[@"value"])); + else if ([entry[@"label"] isEqualToString:static_cast<NSString * _Nonnull>([NSString stringWithUTF8String:ID_ON_DNSSRV_OID])]) { + srvNames_.push_back(ns2StdString(entry[@"value"])); } else if ([entry[@"label"] isEqualToString:@"DNS Name"]) { - dnsNames_.push_back(NS2STDSTRING(entry[@"value"])); + dnsNames_.push_back(ns2StdString(entry[@"value"])); } } CFRelease(valueDict); -- cgit v0.10.2-6-g49f6