#if !__LP64__
#include "printPList.h"
static void _indent(CFMutableStringRef string, unsigned indentLevel)
{
unsigned int i;
for (i = 0; i < indentLevel; i++) {
CFStringAppendCString(string, " ", kCFStringEncodingUTF8);
}
return;
}
static void _appendCFString(CFMutableStringRef string, CFStringRef aString, Boolean withQuotes)
{
char * quote = "";
if (withQuotes) quote = "\"";
CFStringAppendFormat(string, NULL, CFSTR("%s%@%s"), quote, aString, quote);
return;
}
static void _appendCFURL(CFMutableStringRef string, CFURLRef anURL)
{
CFURLRef absURL = NULL; CFStringRef absPath = NULL;
absURL = CFURLCopyAbsoluteURL(anURL);
if (!absURL) {
goto finish;
}
absPath = CFURLCopyFileSystemPath(anURL, kCFURLPOSIXPathStyle);
if (!absPath) {
goto finish;
}
CFStringAppendCString(string, "[URL]", kCFStringEncodingUTF8);
_appendCFString(string, absPath, false);
finish:
if (absURL) CFRelease(absURL);
if (absPath) CFRelease(absPath);
return;
}
void _appendPlist(CFMutableStringRef string, CFTypeRef plist, unsigned indentLevel)
{
CFTypeID typeID = 0;
if (!plist) {
return;
}
typeID = CFGetTypeID(plist);
if (typeID == CFDictionaryGetTypeID()) {
CFDictionaryRef dict = (CFDictionaryRef)plist;
CFIndex count, i;
CFStringRef * keys = NULL; CFStringRef * values = NULL; count = CFDictionaryGetCount(dict);
keys = (CFStringRef *)malloc(count * sizeof(CFStringRef));
values = (CFStringRef *)malloc(count * sizeof(CFTypeRef));
CFDictionaryGetKeysAndValues(dict, (const void **)keys,
(const void **)values);
CFStringAppendCString(string, "{\n", kCFStringEncodingUTF8);
for (i = 0; i < count; i++) {
_indent(string, indentLevel + 4);
_appendCFString(string, keys[i], true);
CFStringAppendCString(string, " = ", kCFStringEncodingUTF8);
if (CFGetTypeID(values[i]) == CFStringGetTypeID()) {
CFIndex keyLength = CFStringGetLength(keys[i]);
CFIndex valueLength = CFStringGetLength(values[i]);
if (indentLevel + 4 + keyLength + valueLength > 72) {
CFStringAppendCString(string, "\n", kCFStringEncodingUTF8);
_indent(string, indentLevel + 8);
}
}
_appendPlist(string, values[i], indentLevel + 4);
}
_indent(string, indentLevel);
CFStringAppendCString(string, "}\n", kCFStringEncodingUTF8);
free(keys);
free(values);
} else if (typeID == CFArrayGetTypeID()) {
CFArrayRef array = (CFArrayRef)plist;
CFIndex count, i;
count = CFArrayGetCount(array);
CFStringAppendCString(string, "(\n", kCFStringEncodingUTF8);
for (i = 0; i < count; i++) {
_indent(string, indentLevel + 4);
_appendPlist(string, CFArrayGetValueAtIndex(array, i), indentLevel + 4);
}
_indent(string, indentLevel);
CFStringAppendCString(string, ")\n", kCFStringEncodingUTF8);
} else if (typeID == CFStringGetTypeID()) {
_appendCFString(string, (CFStringRef)plist, indentLevel > 0);
CFStringAppendCString(string, "\n", kCFStringEncodingUTF8);
} else if (typeID == CFURLGetTypeID()) {
_appendCFURL(string, (CFURLRef)plist);
CFStringAppendCString(string, "\n", kCFStringEncodingUTF8);
} else if (typeID == CFDataGetTypeID()) {
CFStringAppendCString(string, "(data object)\n", kCFStringEncodingUTF8);
} else if (typeID == CFNumberGetTypeID()) {
CFStringAppendFormat(string, NULL, CFSTR("%@"), (CFNumberRef)plist);
CFStringAppendCString(string, "\n", kCFStringEncodingUTF8);
} else if (typeID == CFBooleanGetTypeID()) {
CFBooleanRef booleanValue = (CFBooleanRef)plist;
CFStringAppendFormat(string, NULL, CFSTR("%s\n"),
CFBooleanGetValue(booleanValue) ? "true" : "false");
} else if (typeID == CFDateGetTypeID()) {
CFStringAppendCString(string, "(date object)\n", kCFStringEncodingUTF8);
} else {
CFStringAppendCString(string, "(unknown object)\n", kCFStringEncodingUTF8);
}
return;
}
void printPList(FILE * stream, CFTypeRef plist)
{
CFMutableStringRef string = NULL; CFIndex bufSize;
char * c_string = NULL;
string = createCFStringForPlist(plist);
if (!string) {
goto finish;
}
bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string),
kCFStringEncodingUTF8) + sizeof('\0');
c_string = (char *)malloc(bufSize);
if (!c_string) {
goto finish;
}
if (CFStringGetCString(string, c_string, bufSize, kCFStringEncodingUTF8)) {
fprintf(stream, c_string);
}
finish:
if (string) CFRelease(string);
if (c_string) free(c_string);
return;
}
void showPList(CFPropertyListRef plist)
{
printPList(stdout, plist);
return;
}
CFMutableStringRef createCFStringForPlist(CFTypeRef plist)
{
CFMutableStringRef string = NULL;
string = CFStringCreateMutable(kCFAllocatorDefault, 0);
if (!string) {
goto finish;
}
_appendPlist(string, plist, 0);
finish:
return string;
}
#endif // !__LP64__