/ 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