#import <IOKit/firewire/IOLocalConfigDirectory.h>
#import "FWDebugging.h"
#import <libkern/c++/OSIterator.h>
#import <libkern/c++/OSData.h>
#import <libkern/c++/OSArray.h>
#import "IOConfigEntry.h"
OSDefineMetaClassAndStructors(IOConfigEntry, OSObject);
void IOConfigEntry::free()
{
if (fData) {
fData->release();
fData = NULL;
}
OSObject::free();
}
IOConfigEntry* IOConfigEntry::create(UInt32 key, IOConfigKeyType type, OSObject *obj)
{
IOConfigEntry* entry;
entry = OSTypeAlloc( IOConfigEntry );
if(!entry)
return NULL;
if(!entry->init()) {
entry->release();
return NULL;
}
assert(type == kConfigLeafKeyType ||
type == kConfigDirectoryKeyType);
entry->fKey = key;
entry->fType = type;
obj->retain() ;
entry->fData = obj;
return entry;
}
IOConfigEntry* IOConfigEntry::create(UInt32 key, UInt32 value)
{
IOConfigEntry* entry;
if(value > kConfigEntryValue)
return NULL; entry = OSTypeAlloc( IOConfigEntry );
if(!entry)
return NULL;
if(!entry->init()) {
entry->release();
return NULL;
}
entry->fKey = key;
entry->fType = kConfigImmediateKeyType;
entry->fValue = value;
return entry;
}
IOConfigEntry* IOConfigEntry::create(UInt32 key, FWAddress address)
{
IOConfigEntry* entry;
entry = OSTypeAlloc( IOConfigEntry );
if(!entry)
return NULL;
if(!entry->init()) {
entry->release();
return NULL;
}
entry->fKey = key;
entry->fType = kConfigOffsetKeyType;
entry->fAddr = address;
return entry;
}
unsigned int IOConfigEntry::totalSize()
{
unsigned int size = 0;
switch(fType) {
default:
break;
case kConfigLeafKeyType:
{
OSData *data = OSDynamicCast(OSData, fData);
if(!data)
return 0;
size = (data->getLength()-1) / sizeof(UInt32) + 2;
break;
}
case kConfigDirectoryKeyType:
{
IOLocalConfigDirectory *dir = OSDynamicCast(IOLocalConfigDirectory,
fData);
if(!dir)
return 0; const OSArray *entries = dir->getEntries();
unsigned int i;
size = 1 + entries->getCount();
for(i=0; i<entries->getCount(); i++) {
IOConfigEntry *entry = OSDynamicCast(IOConfigEntry, entries->getObject(i));
if(!entry)
return 0; size += entry->totalSize();
}
break;
}
}
return size;
}