1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/policy/core/common/mac_util.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <string> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/mac/foundation_util.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/sys_string_conversions.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/values.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::mac::CFCast; 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace policy { 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Callback function for CFDictionaryApplyFunction. |key| and |value| are an 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// entry of the CFDictionary that should be converted into an equivalent entry 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in the DictionaryValue in |context|. 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DictionaryEntryToValue(const void* key, const void* value, void* context) { 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFStringRef cf_key = CFCast<CFStringRef>(key)) { 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::Value> converted = 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PropertyToValue(static_cast<CFPropertyListRef>(value)); 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (converted) { 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string string = base::SysCFStringRefToUTF8(cf_key); 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<base::DictionaryValue*>(context)->Set( 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string, converted.release()); 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Callback function for CFArrayApplyFunction. |value| is an entry of the 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// CFArray that should be converted into an equivalent entry in the ListValue 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in |context|. 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ArrayEntryToValue(const void* value, void* context) { 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::Value> converted = 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PropertyToValue(static_cast<CFPropertyListRef>(value)); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (converted) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<base::ListValue *>(context)->Append(converted.release()); 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<base::Value> PropertyToValue(CFPropertyListRef property) { 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFCast<CFNullRef>(property)) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<base::Value>(base::Value::CreateNullValue()); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFBooleanRef boolean = CFCast<CFBooleanRef>(property)) { 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return scoped_ptr<base::Value>(new base::FundamentalValue( 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<bool>(CFBooleanGetValue(boolean)))); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFNumberRef number = CFCast<CFNumberRef>(property)) { 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // CFNumberGetValue() converts values implicitly when the conversion is not 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // lossy. Check the type before trying to convert. 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFNumberIsFloatType(number)) { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) double double_value = 0.0; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFNumberGetValue(number, kCFNumberDoubleType, &double_value)) { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<base::Value>( 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new base::FundamentalValue(double_value)); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int int_value = 0; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) { 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return scoped_ptr<base::Value>(new base::FundamentalValue(int_value)); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFStringRef string = CFCast<CFStringRef>(property)) { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<base::Value>( 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new base::StringValue(base::SysCFStringRefToUTF8(string))); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFDictionaryRef dict = CFCast<CFDictionaryRef>(property)) { 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue()); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CFDictionaryApplyFunction(dict, DictionaryEntryToValue, dict_value.get()); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return dict_value.PassAs<base::Value>(); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CFArrayRef array = CFCast<CFArrayRef>(property)) { 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::ListValue> list_value(new base::ListValue()); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CFArrayApplyFunction(array, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CFRangeMake(0, CFArrayGetCount(array)), 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ArrayEntryToValue, 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) list_value.get()); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return list_value.PassAs<base::Value>(); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<base::Value>(); 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace policy 96