#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h> // for SCLog()
#include "cache.h"
static CFMutableDictionaryRef cached_keys = NULL;
static CFMutableDictionaryRef cached_set = NULL;
static CFMutableArrayRef cached_removals = NULL;
static CFMutableArrayRef cached_notifys = NULL;
__private_extern__
void
cache_open()
{
cached_keys = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
cached_set = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
cached_removals = CFArrayCreateMutable(NULL,
0,
&kCFTypeArrayCallBacks);
cached_notifys = CFArrayCreateMutable(NULL,
0,
&kCFTypeArrayCallBacks);
return;
}
__private_extern__
CFPropertyListRef
cache_SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key)
{
CFPropertyListRef value;
value = CFDictionaryGetValue(cached_set, key);
if (value) {
return (CFRetain(value));
}
if (CFArrayContainsValue(cached_removals,
CFRangeMake(0, CFArrayGetCount(cached_removals)),
key)) {
return NULL;
}
value = CFDictionaryGetValue(cached_keys, key);
if (value) {
return (CFRetain(value));
}
value = SCDynamicStoreCopyValue(store, key);
if (value) {
CFDictionarySetValue(cached_keys, key, value);
}
return value;
}
__private_extern__
void
cache_SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
{
CFIndex i;
i = CFArrayGetFirstIndexOfValue(cached_removals,
CFRangeMake(0, CFArrayGetCount(cached_removals)),
key);
if (i != kCFNotFound) {
CFArrayRemoveValueAtIndex(cached_removals, i);
}
CFDictionarySetValue(cached_set, key, value);
return;
}
__private_extern__
void
cache_SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key)
{
CFDictionaryRemoveValue(cached_set, key);
if (!CFArrayContainsValue(cached_removals,
CFRangeMake(0, CFArrayGetCount(cached_removals)),
key)) {
CFArrayAppendValue(cached_removals, key);
}
return;
}
__private_extern__
void
cache_SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key)
{
if (!CFArrayContainsValue(cached_notifys,
CFRangeMake(0, CFArrayGetCount(cached_notifys)),
key)) {
CFArrayAppendValue(cached_notifys, key);
}
return;
}
__private_extern__
void
cache_write(SCDynamicStoreRef store)
{
if ((CFDictionaryGetCount(cached_set) > 0) ||
(CFArrayGetCount(cached_removals) > 0) ||
(CFArrayGetCount(cached_notifys) > 0)) {
if (!SCDynamicStoreSetMultiple(store,
cached_set,
cached_removals,
cached_notifys)) {
SCLog(TRUE,
LOG_ERR,
CFSTR("SCDynamicStoreSetMultiple() failed: %s"),
SCErrorString(SCError()));
}
}
return;
}
__private_extern__
void
cache_close()
{
CFRelease(cached_keys);
CFRelease(cached_set);
CFRelease(cached_removals);
CFRelease(cached_notifys);
return;
}