/ CFPlugIn_Instance.c
CFPlugIn_Instance.c
1 /* 2 * Copyright (c) 2015 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 /* CFPlugIn_Instance.c 25 Copyright (c) 1999-2014, Apple Inc. All rights reserved. 26 Responsibility: Tony Parker 27 */ 28 29 #include "CFBundle_Internal.h" 30 #include "CFInternal.h" 31 32 static CFTypeID __kCFPlugInInstanceTypeID = _kCFRuntimeNotATypeID; 33 34 struct __CFPlugInInstance { 35 CFRuntimeBase _base; 36 37 _CFPFactoryRef factory; 38 39 CFPlugInInstanceGetInterfaceFunction getInterfaceFunction; 40 CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction; 41 42 #ifdef _MSC_VER 43 #pragma warning(push) 44 #pragma warning(disable : 4200) 45 #endif //_MSC_VER 46 uint8_t _instanceData[0]; 47 #ifdef _MSC_VER 48 #pragma warning(pop) 49 #endif //_MSC_VER 50 }; 51 52 static CFStringRef __CFPlugInInstanceCopyDescription(CFTypeRef cf) { 53 /* MF:!!! Implement me */ 54 return CFSTR("Some CFPlugInInstance"); 55 } 56 57 static void __CFPlugInInstanceDeallocate(CFTypeRef cf) { 58 CFPlugInInstanceRef instance = (CFPlugInInstanceRef)cf; 59 60 __CFGenericValidateType(cf, CFPlugInInstanceGetTypeID()); 61 62 if (instance->deallocateInstanceDataFunction) { 63 FAULT_CALLBACK((void **)&(instance->deallocateInstanceDataFunction)); 64 (void)INVOKE_CALLBACK1(instance->deallocateInstanceDataFunction, (void *)(&instance->_instanceData[0])); 65 } 66 67 if (instance->factory) _CFPFactoryRemoveInstance(instance->factory); 68 } 69 70 static const CFRuntimeClass __CFPlugInInstanceClass = { 71 0, 72 "CFPlugInInstance", 73 NULL, // init 74 NULL, // copy 75 __CFPlugInInstanceDeallocate, 76 NULL, // equal 77 NULL, // hash 78 NULL, // 79 __CFPlugInInstanceCopyDescription 80 }; 81 82 CFTypeID CFPlugInInstanceGetTypeID(void) { 83 static dispatch_once_t initOnce; 84 dispatch_once(&initOnce, ^{ __kCFPlugInInstanceTypeID = _CFRuntimeRegisterClass(&__CFPlugInInstanceClass); }); 85 return __kCFPlugInInstanceTypeID; 86 } 87 88 CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction) { 89 CFPlugInInstanceRef instance; 90 UInt32 size; 91 size = sizeof(struct __CFPlugInInstance) + instanceDataSize - sizeof(CFRuntimeBase); 92 instance = (CFPlugInInstanceRef)_CFRuntimeCreateInstance(allocator, CFPlugInInstanceGetTypeID(), size, NULL); 93 if (!instance) return NULL; 94 95 instance->factory = _CFPFactoryFind((CFUUIDRef)factoryName, true); 96 if (instance->factory) _CFPFactoryAddInstance(instance->factory); 97 instance->getInterfaceFunction = getInterfaceFunction; 98 instance->deallocateInstanceDataFunction = deallocateInstanceFunction; 99 100 return instance; 101 } 102 103 CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl) { 104 void *myFtbl; 105 Boolean result = false; 106 107 if (instance->getInterfaceFunction) { 108 FAULT_CALLBACK((void **)&(instance->getInterfaceFunction)); 109 result = INVOKE_CALLBACK3(instance->getInterfaceFunction, instance, interfaceName, &myFtbl) ? true : false; 110 } 111 if (ftbl) *ftbl = (result ? myFtbl : NULL); 112 return result; 113 } 114 115 CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) { 116 // This function leaks, but it's the only safe way to access the factory name (on 10.8 or later). 117 // On 10.9 we added the CF_RETURNS_RETAINED annotation to the header. 118 CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(instance->factory); 119 return (CFStringRef)factoryId; 120 } 121 122 CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) { 123 return (void *)(&instance->_instanceData[0]); 124 } 125