/* * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * IOFireWireUserClientIniter.cpp * IOFireWireFamily * * Created by NWG on Wed Jan 24 2001. * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. * */ #import "IOFireWireUserClientIniter.h" #import #import #import #import #undef super #define super IOService OSDefineMetaClassAndStructors(IOFireWireUserClientIniter, super); OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 0); OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 1); OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 2); OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 3); // init // // bool IOFireWireUserClientIniter::init(OSDictionary * propTable) { fPropTable = propTable ; fProvider = NULL ; return super::init(propTable) ; } // start // // bool IOFireWireUserClientIniter::start( IOService* provider) { if( provider == NULL ) { return false; } fProvider = provider ; fProvider->retain(); OSObject* dictObj = getProperty("IOProviderMergeProperties"); fProviderMergeProperties = OSDynamicCast(OSDictionary, dictObj); if ( !fProviderMergeProperties ) { fHasUCIniter = false; IOLog("%s %u: couldn't get fProviderMergeProperties\n", __FILE__, __LINE__ ) ; return false; } // // make sure the user client class object is an OSSymbol // OSObject * userClientClassObject = fProviderMergeProperties->getObject( gIOUserClientClassKey ); if( OSDynamicCast(OSString, userClientClassObject) != NULL ) { // if the the user client class object is an OSString, turn it into an OSSymbol const OSSymbol * userClientClassSymbol = OSSymbol::withString((const OSString *) userClientClassObject); if( userClientClassSymbol != NULL ) { fProviderMergeProperties->setObject(gIOUserClientClassKey, (OSObject *) userClientClassSymbol); userClientClassSymbol->release(); } } else if( OSDynamicCast(OSSymbol, userClientClassObject) == NULL ) { // if its not an OSString or an OSymbol remove it from the merge properties fProviderMergeProperties->removeObject(gIOUserClientClassKey); } OSDictionary* providerProps = fProvider->getPropertyTable() ; if (providerProps) { mergeProperties(providerProps, fProviderMergeProperties) ; // fProviderMergeProperties->flushCollection() ; } return true ; } // stop // // void IOFireWireUserClientIniter::stop(IOService* provider) { IOService::stop(provider) ; } // free // // void IOFireWireUserClientIniter::free() { if( fProvider != NULL ) { fProvider->release(); fProvider = NULL; } IOService::free(); } // mergeProperties // // recurively merge the properties of two dictionaries void IOFireWireUserClientIniter::mergeProperties(OSObject* inDest, OSObject* inSrc) { OSDictionary* dest = OSDynamicCast(OSDictionary, inDest); OSDictionary* src = OSDynamicCast(OSDictionary, inSrc); if (!src || !dest) return; OSCollectionIterator* srcIterator = OSCollectionIterator::withCollection(src); OSSymbol* keyObject = NULL; OSObject* destObject = NULL; OSObject* srcObject = NULL; while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject()))) { srcObject = src->getObject(keyObject); destObject = dest->getObject(keyObject); if (OSDynamicCast(OSDictionary, srcObject)) { srcObject = copyDictionaryProperty((OSDictionary*)srcObject); // if there's a already a dictionary with the same key as the // srcObject, we need to merge the new properties with that // dictionary, otherwise we can just add the srcObject to the // dest dictionary if( destObject ) mergeProperties(destObject, srcObject); else dest->setObject(keyObject, srcObject); // copyDictionaryProperty creates a new dictionary, so we should release // it after we add it to our dictionary srcObject->release(); } else { // if the property is not a dictionary, then we can simply add it to the // destination dictionary dest->setObject(keyObject, srcObject); } } // have to release this, or we'll leak. srcIterator->release(); } // copyDictionaryProperty // // recursively copy am OSDictionary OSDictionary* IOFireWireUserClientIniter::copyDictionaryProperty( OSDictionary* srcDictionary) { OSDictionary* result = NULL; OSObject* srcObject = NULL; OSCollectionIterator* srcIterator = NULL; OSSymbol* keyObject = NULL; result = OSDictionary::withCapacity(srcDictionary->getCount()); if (result) { srcIterator = OSCollectionIterator::withCollection(srcDictionary); if (srcIterator) { while ( (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())) ) { srcObject = srcDictionary->getObject(keyObject); if (OSDynamicCast(OSDictionary, srcObject)) { srcObject = copyDictionaryProperty((OSDictionary*)srcObject); result->setObject(keyObject, srcObject); // copyDictionaryProperty creates a new dictionary, so we should release // it after we add it to our dictionary srcObject->release(); } else { result->setObject(keyObject, srcObject); } } srcIterator->release(); } } return result; }