1/* 2 * Copyright (c) 2003, 2004, 2006, 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Modification History 26 * 27 * May 1, 2003 Allan Nathanson <ajn@apple.com> 28 * - initial revision 29 */ 30 31 32#include <CoreFoundation/CoreFoundation.h> 33#include <SystemConfiguration/SystemConfiguration.h> 34#include <SystemConfiguration/SCPrivate.h> // for SCLog() 35 36#include "cache.h" 37 38 39static CFMutableDictionaryRef cached_keys = NULL; 40static CFMutableDictionaryRef cached_set = NULL; 41static CFMutableArrayRef cached_removals = NULL; 42static CFMutableArrayRef cached_notifys = NULL; 43 44 45__private_extern__ 46void 47cache_open(void) 48{ 49 cached_keys = CFDictionaryCreateMutable(NULL, 50 0, 51 &kCFTypeDictionaryKeyCallBacks, 52 &kCFTypeDictionaryValueCallBacks); 53 cached_set = CFDictionaryCreateMutable(NULL, 54 0, 55 &kCFTypeDictionaryKeyCallBacks, 56 &kCFTypeDictionaryValueCallBacks); 57 cached_removals = CFArrayCreateMutable(NULL, 58 0, 59 &kCFTypeArrayCallBacks); 60 cached_notifys = CFArrayCreateMutable(NULL, 61 0, 62 &kCFTypeArrayCallBacks); 63 64 return; 65} 66 67 68__private_extern__ 69CFPropertyListRef 70cache_SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key) 71{ 72 CFPropertyListRef value; 73 74 value = CFDictionaryGetValue(cached_set, key); 75 if (value) { 76 // if we have "set" a new value 77 return (CFRetain(value)); 78 } 79 80 if (CFArrayContainsValue(cached_removals, 81 CFRangeMake(0, CFArrayGetCount(cached_removals)), 82 key)) { 83 // if we have "removed" the key 84 _SCErrorSet(kSCStatusNoKey); 85 return NULL; 86 } 87 88 value = CFDictionaryGetValue(cached_keys, key); 89 if (value) { 90 // if we have a cached value 91 return (CFRetain(value)); 92 } 93 94 value = SCDynamicStoreCopyValue(store, key); 95 if (value) { 96 CFDictionarySetValue(cached_keys, key, value); 97 } 98 99 return value; 100} 101 102 103__private_extern__ 104void 105cache_SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value) 106{ 107 CFIndex i; 108 109 i = CFArrayGetFirstIndexOfValue(cached_removals, 110 CFRangeMake(0, CFArrayGetCount(cached_removals)), 111 key); 112 if (i != kCFNotFound) { 113 // if previously "removed" 114 CFArrayRemoveValueAtIndex(cached_removals, i); 115 } 116 117 CFDictionarySetValue(cached_set, key, value); 118 119 return; 120} 121 122__private_extern__ 123void 124cache_SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key) 125{ 126 CFDictionaryRemoveValue(cached_set, key); 127 128 if (!CFArrayContainsValue(cached_removals, 129 CFRangeMake(0, CFArrayGetCount(cached_removals)), 130 key)) { 131 CFArrayAppendValue(cached_removals, key); 132 } 133 134 return; 135} 136 137 138__private_extern__ 139void 140cache_SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key) 141{ 142 if (!CFArrayContainsValue(cached_notifys, 143 CFRangeMake(0, CFArrayGetCount(cached_notifys)), 144 key)) { 145 CFArrayAppendValue(cached_notifys, key); 146 } 147 148 return; 149} 150 151 152__private_extern__ 153void 154cache_write(SCDynamicStoreRef store) 155{ 156 if ((CFDictionaryGetCount(cached_set) > 0) || 157 (CFArrayGetCount(cached_removals) > 0) || 158 (CFArrayGetCount(cached_notifys) > 0)) { 159 if (!SCDynamicStoreSetMultiple(store, 160 cached_set, 161 cached_removals, 162 cached_notifys)) { 163 SCLog(TRUE, 164 LOG_ERR, 165 CFSTR("SCDynamicStoreSetMultiple() failed: %s"), 166 SCErrorString(SCError())); 167 } 168 } 169 170 return; 171} 172 173 174__private_extern__ 175void 176cache_close(void) 177{ 178 CFRelease(cached_keys); 179 CFRelease(cached_set); 180 CFRelease(cached_removals); 181 CFRelease(cached_notifys); 182 183 return; 184} 185