1void printPlist(OSObject * plist, UInt32 indent = 0) {
2    const OSMetaClass * typeID;
3    OSCollectionIterator * iterator;
4    OSString * key;
5    OSObject * value;
6    unsigned int i;
7
8    if (!plist) {
9        IOLog("error! null plist\n");
10        return;
11    }
12
13    typeID = OSTypeIDInst(plist);
14
15    if (typeID ==  OSTypeID(OSDictionary)) {
16
17        IOLog("{\n");
18        OSDictionary * dict = OSDynamicCast(OSDictionary, plist);
19        iterator = OSCollectionIterator::withCollection(dict);
20        while ( (key = OSDynamicCast(OSString, iterator->getNextObject())) ) {
21            for (i = 0; i < indent + 4; i++) {
22                IOLog(" ");
23            }
24            IOLog("%s = ", key->getCStringNoCopy());
25            value = dict->getObject(key);
26            printPlist(value, indent + 4);
27        }
28
29        for (i = 0; i < indent; i++) {
30            IOLog(" ");
31        }
32        IOLog("}\n");
33
34    } else if (typeID == OSTypeID(OSArray)) {
35
36        IOLog("(\n");
37
38        OSArray * array = OSDynamicCast(OSArray, plist);
39        iterator = OSCollectionIterator::withCollection(array);
40        while ( (value = iterator->getNextObject()) ) {
41            for (i = 0; i < indent + 4; i++) {
42                IOLog(" ");
43            }
44            printPlist(value, indent + 4);
45        }
46
47        for (i = 0; i < indent; i++) {
48            IOLog(" ");
49        }
50        IOLog(")\n");
51
52    } else if (typeID == OSTypeID(OSString) || typeID == OSTypeID(OSSymbol)) {
53
54        OSString * string = OSDynamicCast(OSString, plist);
55        IOLog("\"%s\"\n", string->getCStringNoCopy());
56
57    } else if (typeID == OSTypeID(OSNumber)) {
58
59        OSNumber * number = OSDynamicCast(OSNumber, plist);
60        UInt32 numberValue = number->unsigned32BitValue();
61        IOLog("0x%lx (%ld base 10)\n", numberValue, numberValue);
62
63    } else if (typeID == OSTypeID(OSBoolean)) {
64
65        OSBoolean * boolObj = OSDynamicCast(OSBoolean, plist);
66        IOLog("%s\n", boolObj->isTrue() ? "true" : "false");
67
68    } else if (typeID == OSTypeID(OSData)) {
69
70        IOLog("(binary data)\n");
71
72    } else {
73
74        IOLog("(object of class %s)\n", plist->getMetaClass()->getClassName());
75
76    }
77
78    IODelay(150000);
79    return;
80}
81