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

Unified Diff: util/mac/launchd.mm

Issue 438673003: Add CFPropertyToLaunchData() and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rebase Created 6 years, 4 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 | « util/mac/launchd.h ('k') | util/mac/launchd_test.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/mac/launchd.mm
diff --git a/util/mac/launchd.mm b/util/mac/launchd.mm
new file mode 100644
index 0000000000000000000000000000000000000000..a621f791432fe743987684abbc15811790f441ab
--- /dev/null
+++ b/util/mac/launchd.mm
@@ -0,0 +1,137 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/mac/launchd.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_launch_data.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/strings/sys_string_conversions.h"
+
+namespace crashpad {
+
+launch_data_t CFPropertyToLaunchData(CFPropertyListRef property_cf) {
+ // This function mixes Foundation and Core Foundation access to property list
+ // elements according to which is more convenient and correct for any specific
+ // task.
+
+ launch_data_t data_launch = NULL;
+ CFTypeID type_id_cf = CFGetTypeID(property_cf);
+
+ if (type_id_cf == CFDictionaryGetTypeID()) {
+ NSDictionary* dictionary_ns = base::mac::CFToNSCast(
+ base::mac::CFCastStrict<CFDictionaryRef>(property_cf));
+ base::mac::ScopedLaunchData dictionary_launch(
+ launch_data_alloc(LAUNCH_DATA_DICTIONARY));
+
+ for (NSString* key in dictionary_ns) {
+ if (![key isKindOfClass:[NSString class]]) {
+ return NULL;
+ }
+
+ CFPropertyListRef value_cf =
+ static_cast<CFPropertyListRef>([dictionary_ns objectForKey:key]);
+ launch_data_t value_launch = CFPropertyToLaunchData(value_cf);
+ if (!value_launch) {
+ return NULL;
+ }
+
+ launch_data_dict_insert(
+ dictionary_launch, value_launch, [key UTF8String]);
+ }
+
+ data_launch = dictionary_launch.release();
+
+ } else if (type_id_cf == CFArrayGetTypeID()) {
+ NSArray* array_ns =
+ base::mac::CFToNSCast(base::mac::CFCastStrict<CFArrayRef>(property_cf));
+ base::mac::ScopedLaunchData array_launch(
+ launch_data_alloc(LAUNCH_DATA_ARRAY));
+ size_t index = 0;
+
+ for (id element_ns in array_ns) {
+ CFPropertyListRef element_cf = static_cast<CFPropertyListRef>(element_ns);
+ launch_data_t element_launch = CFPropertyToLaunchData(element_cf);
+ if (!element_launch) {
+ return NULL;
+ }
+
+ launch_data_array_set_index(array_launch, element_launch, index++);
+ }
+
+ data_launch = array_launch.release();
+
+ } else if (type_id_cf == CFNumberGetTypeID()) {
+ CFNumberRef number_cf = base::mac::CFCastStrict<CFNumberRef>(property_cf);
+ NSNumber* number_ns = base::mac::CFToNSCast(number_cf);
+ switch (CFNumberGetType(number_cf)) {
+ case kCFNumberSInt8Type:
+ case kCFNumberSInt16Type:
+ case kCFNumberSInt32Type:
+ case kCFNumberSInt64Type:
+ case kCFNumberCharType:
+ case kCFNumberShortType:
+ case kCFNumberIntType:
+ case kCFNumberLongType:
+ case kCFNumberLongLongType:
+ case kCFNumberCFIndexType:
+ case kCFNumberNSIntegerType: {
+ data_launch = launch_data_new_integer([number_ns longLongValue]);
+ break;
+ }
+
+ case kCFNumberFloat32Type:
+ case kCFNumberFloat64Type:
+ case kCFNumberFloatType:
+ case kCFNumberDoubleType: {
+ data_launch = launch_data_new_real([number_ns doubleValue]);
+ break;
+ }
+
+ default: { return NULL; }
+ }
+
+ } else if (type_id_cf == CFBooleanGetTypeID()) {
+ CFBooleanRef boolean_cf =
+ base::mac::CFCastStrict<CFBooleanRef>(property_cf);
+ data_launch = launch_data_new_bool(CFBooleanGetValue(boolean_cf));
+
+ } else if (type_id_cf == CFStringGetTypeID()) {
+ NSString* string_ns = base::mac::CFToNSCast(
+ base::mac::CFCastStrict<CFStringRef>(property_cf));
+
+ // -fileSystemRepresentation might be more correct than -UTF8String, because
+ // these strings can hold paths. The analogous function in launchctl,
+ // CF2launch_data (10.9.2 launchd-842.90.1/support/launchctl.c), uses UTF-8
+ // instead of filesystem encoding, so do the same here. Note that there’s
+ // another occurrence of -UTF8String above, used for dictionary keys.
+ data_launch = launch_data_new_string([string_ns UTF8String]);
+
+ } else if (type_id_cf == CFDataGetTypeID()) {
+ NSData* data_ns =
+ base::mac::CFToNSCast(base::mac::CFCastStrict<CFDataRef>(property_cf));
+ data_launch = launch_data_new_opaque([data_ns bytes], [data_ns length]);
+ } else {
+ base::ScopedCFTypeRef<CFStringRef> type_name_cf(
+ CFCopyTypeIDDescription(type_id_cf));
+ DLOG(ERROR) << "unable to convert CFTypeID " << type_id_cf << " ("
+ << base::SysCFStringRefToUTF8(type_name_cf) << ")";
+ }
+
+ return data_launch;
+}
+
+} // namespace crashpad
« no previous file with comments | « util/mac/launchd.h ('k') | util/mac/launchd_test.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698