UtilitiesCFPrettyPrint.c [plain text]
#include "UtilitiesCFPrettyPrint.h"
typedef struct TAOCFDepth_Counter {
int depth;
int arrayIndex;
char *indent;
FILE *out;
} TAOCFDepth_Counter;
static void _TAOCFLabelPrettyPrint(char *label, CFTypeRef value, void *context);
static void _TAOCFDictionaryPrettyPrint(const void *key, const void *value, void *context);
static void _TAOCFArrayPrettyPrint(const void *value, void *context);
static void _TAOCFTreePrettyPrint(const void *value, void *context);
static void _TAOCFBagPrettyPrint(const void *value, void *context);
static void _TAOCFScalarPrettyPrint(const void *value, void *context);
static void _TAOCFPrettyPrint_recurse(CFTypeRef inRef, void *h);
static char * _TAOCFGetDescriptionAsCString(CFTypeRef typeRef);
static void _TAOCFLabelPrettyPrint(char *label, CFTypeRef value, void *context) {
TAOCFDepth_Counter *h = (TAOCFDepth_Counter *)context;
int i;
char *desc;
for(i=0; i< h->depth; i++) {
fprintf(h->out, h->indent);
}
fprintf(h->out, "%s", label);
if(value == NULL) {
fprintf(h->out, "\n");
return;
}
if(label && label[0]) {
fprintf(h->out, ":");
}
if(CFGetTypeID(value) == CFDictionaryGetTypeID()
|| CFGetTypeID(value) == CFArrayGetTypeID()
|| CFGetTypeID(value) == CFTreeGetTypeID()
|| CFGetTypeID(value) == CFBagGetTypeID() ) {
TAOCFDepth_Counter newhelper;
fprintf(h->out, "\n");
newhelper.depth = h->depth + 1;
newhelper.out = h->out;
newhelper.arrayIndex = 0;
newhelper.indent = h->indent;
_TAOCFPrettyPrint_recurse((CFTypeRef) value, &newhelper);
} else {
desc = _TAOCFGetDescriptionAsCString((CFTypeRef)value);
if(label && label[0]) {
fprintf(h->out, " ");
}
if(desc) {
fprintf(h->out, "%s\n", desc);
free(desc);
} else {
fprintf(h->out, "(NULL)\n");
}
}
}
static void _TAOCFDictionaryPrettyPrint(const void *key, const void *value, void *context) {
char *desc;
desc = _TAOCFGetDescriptionAsCString((CFTypeRef)key);
_TAOCFLabelPrettyPrint(desc, (CFTypeRef) value, context);
if(desc) {
free(desc);
}
}
static void _TAOCFArrayPrettyPrint(const void *value, void *context) {
char desc[256];
snprintf(desc, 256, "%d", ((TAOCFDepth_Counter *)context)->arrayIndex++);
_TAOCFLabelPrettyPrint(desc, (CFTypeRef)value, context);
}
static void _TAOCFBagPrettyPrint(const void *value, void *context) {
_TAOCFLabelPrettyPrint("", (CFTypeRef)value, context);
}
static void _TAOCFTreePrettyPrint(const void *value, void *context) {
CFTreeContext treeContext;
TAOCFDepth_Counter newhelper;
newhelper.depth = ((TAOCFDepth_Counter *)context)->depth + 1;
newhelper.out = ((TAOCFDepth_Counter *)context)->out;
newhelper.indent = ((TAOCFDepth_Counter *)context)->indent;
newhelper.arrayIndex = 0;
CFTreeGetContext((CFTreeRef)value, &treeContext);
_TAOCFLabelPrettyPrint("", (CFTypeRef)treeContext.info, context);
CFTreeApplyFunctionToChildren((CFTreeRef)value,
_TAOCFTreePrettyPrint, &newhelper);
}
static void _TAOCFScalarPrettyPrint(const void *value, void *context) {
char *desc;
desc = _TAOCFGetDescriptionAsCString((CFTypeRef)value);
_TAOCFLabelPrettyPrint(desc, NULL, context);
if(desc) {
free(desc);
}
}
static void _TAOCFPrettyPrint_recurse(CFTypeRef inRef, void *h) {
if(inRef == NULL) {
_TAOCFScalarPrettyPrint(inRef, h);
} else if(CFGetTypeID(inRef) == CFDictionaryGetTypeID()) {
CFDictionaryApplyFunction((CFDictionaryRef)inRef,
_TAOCFDictionaryPrettyPrint, h);
} else if(CFGetTypeID(inRef) == CFArrayGetTypeID()) {
CFArrayApplyFunction((CFArrayRef)inRef,
CFRangeMake(0, CFArrayGetCount((CFArrayRef)inRef)),
_TAOCFArrayPrettyPrint, h);
} else if(CFGetTypeID(inRef) == CFTreeGetTypeID()) {
_TAOCFTreePrettyPrint(inRef, h);
} else if(CFGetTypeID(inRef) == CFBagGetTypeID()) {
CFBagApplyFunction(inRef, _TAOCFBagPrettyPrint, h);
} else {
_TAOCFScalarPrettyPrint(inRef, h);
}
}
void TAOCFPrettyPrint(CFTypeRef inRef) {
TAOCFPrettyPrintToFile(inRef, stdout);
}
void TAOCFPrettyPrintWithIndenter(CFTypeRef inRef, char *indent) {
TAOCFPrettyPrintToFileWithIndenter(inRef, stdout, indent);
}
void TAOCFPrettyPrintToFile(CFTypeRef inRef, FILE *out) {
TAOCFPrettyPrintToFileWithIndenter(inRef, out, "\t");
}
void TAOCFPrettyPrintToFileWithIndenter(CFTypeRef inRef, FILE *out, char *indent) {
TAOCFDepth_Counter helper;
helper.depth = 0;
helper.out = out;
helper.arrayIndex = 0;
helper.indent = indent;
_TAOCFPrettyPrint_recurse(inRef, &helper);
}
static char * _TAOCFGetDescriptionAsCString(CFTypeRef typeRef)
{
char *str = NULL;
CFStringRef cfstr = NULL;
CFIndex len;
cfstr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), typeRef);
if(cfstr == NULL && typeRef != NULL) cfstr = CFSTR("<error getting string representation>");
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8) + 1;
str = malloc(len);
if (str) {
if (!CFStringGetCString(cfstr, str, len, kCFStringEncodingUTF8)) {
free(str);
str = NULL;
}
}
return str;
}