1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/policy/core/common/mac_util.h"
9 #include "base/mac/foundation_util.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/values.h"
13 using base::mac::CFCast
;
19 // Callback function for CFDictionaryApplyFunction. |key| and |value| are an
20 // entry of the CFDictionary that should be converted into an equivalent entry
21 // in the DictionaryValue in |context|.
22 void DictionaryEntryToValue(const void* key
, const void* value
, void* context
) {
23 if (CFStringRef cf_key
= CFCast
<CFStringRef
>(key
)) {
24 scoped_ptr
<base::Value
> converted
=
25 PropertyToValue(static_cast<CFPropertyListRef
>(value
));
27 const std::string string
= base::SysCFStringRefToUTF8(cf_key
);
28 static_cast<base::DictionaryValue
*>(context
)->Set(
29 string
, converted
.release());
34 // Callback function for CFArrayApplyFunction. |value| is an entry of the
35 // CFArray that should be converted into an equivalent entry in the ListValue
37 void ArrayEntryToValue(const void* value
, void* context
) {
38 scoped_ptr
<base::Value
> converted
=
39 PropertyToValue(static_cast<CFPropertyListRef
>(value
));
41 static_cast<base::ListValue
*>(context
)->Append(converted
.release());
46 scoped_ptr
<base::Value
> PropertyToValue(CFPropertyListRef property
) {
47 if (CFCast
<CFNullRef
>(property
))
48 return scoped_ptr
<base::Value
>(base::Value::CreateNullValue());
50 if (CFBooleanRef boolean
= CFCast
<CFBooleanRef
>(property
)) {
51 return scoped_ptr
<base::Value
>(
52 base::Value::CreateBooleanValue(CFBooleanGetValue(boolean
)));
55 if (CFNumberRef number
= CFCast
<CFNumberRef
>(property
)) {
56 // CFNumberGetValue() converts values implicitly when the conversion is not
57 // lossy. Check the type before trying to convert.
58 if (CFNumberIsFloatType(number
)) {
59 double double_value
= 0.0;
60 if (CFNumberGetValue(number
, kCFNumberDoubleType
, &double_value
)) {
61 return scoped_ptr
<base::Value
>(
62 base::Value::CreateDoubleValue(double_value
));
66 if (CFNumberGetValue(number
, kCFNumberIntType
, &int_value
)) {
67 return scoped_ptr
<base::Value
>(
68 base::Value::CreateIntegerValue(int_value
));
73 if (CFStringRef string
= CFCast
<CFStringRef
>(property
)) {
74 return scoped_ptr
<base::Value
>(
75 base::Value::CreateStringValue(base::SysCFStringRefToUTF8(string
)));
78 if (CFDictionaryRef dict
= CFCast
<CFDictionaryRef
>(property
)) {
79 scoped_ptr
<base::DictionaryValue
> dict_value(new base::DictionaryValue());
80 CFDictionaryApplyFunction(dict
, DictionaryEntryToValue
, dict_value
.get());
81 return dict_value
.PassAs
<base::Value
>();
84 if (CFArrayRef array
= CFCast
<CFArrayRef
>(property
)) {
85 scoped_ptr
<base::ListValue
> list_value(new base::ListValue());
86 CFArrayApplyFunction(array
,
87 CFRangeMake(0, CFArrayGetCount(array
)),
90 return list_value
.PassAs
<base::Value
>();
93 return scoped_ptr
<base::Value
>();