]>
Commit | Line | Data |
---|---|---|
9ce05555 | 1 | /* |
d8925383 | 2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. |
9ce05555 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
9ce05555 A |
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 | /* CFPlugIn.c | |
24 | Copyright 1999-2002, Apple, Inc. All rights reserved. | |
25 | Responsibility: Doug Davidson | |
26 | */ | |
27 | ||
28 | #include "CFBundle_Internal.h" | |
29 | #include "CFInternal.h" | |
30 | ||
31 | CONST_STRING_DECL(kCFPlugInDynamicRegistrationKey, "CFPlugInDynamicRegistration") | |
32 | CONST_STRING_DECL(kCFPlugInDynamicRegisterFunctionKey, "CFPlugInDynamicRegisterFunction") | |
33 | CONST_STRING_DECL(kCFPlugInUnloadFunctionKey, "CFPlugInUnloadFunction") | |
34 | CONST_STRING_DECL(kCFPlugInFactoriesKey, "CFPlugInFactories") | |
35 | CONST_STRING_DECL(kCFPlugInTypesKey, "CFPlugInTypes") | |
36 | ||
37 | __private_extern__ void __CFPlugInInitialize(void) { | |
38 | } | |
39 | ||
40 | /* ===================== Finding factories and creating instances ===================== */ | |
41 | /* For plugIn hosts. */ | |
42 | /* Functions for finding factories to create specific types and actually creating instances of a type. */ | |
43 | ||
44 | CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeID) { | |
45 | CFArrayRef array = _CFPFactoryFindForType(typeID); | |
46 | CFMutableArrayRef result = NULL; | |
47 | ||
48 | if (array) { | |
49 | SInt32 i, c = CFArrayGetCount(array); | |
50 | ||
51 | // Use default allocator | |
52 | result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | |
53 | ||
54 | for (i=0; i<c; i++) { | |
55 | CFArrayAppendValue(result, _CFPFactoryGetFactoryID((_CFPFactory *)CFArrayGetValueAtIndex(array, i))); | |
56 | } | |
57 | } | |
58 | return result; | |
59 | } | |
60 | ||
61 | CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeID, CFPlugInRef plugIn) { | |
62 | CFArrayRef array = _CFPFactoryFindForType(typeID); | |
63 | CFMutableArrayRef result = NULL; | |
64 | ||
65 | if (array) { | |
66 | SInt32 i, c = CFArrayGetCount(array); | |
67 | _CFPFactory *factory; | |
68 | ||
69 | // Use default allocator | |
70 | result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); | |
71 | ||
72 | for (i=0; i<c; i++) { | |
73 | factory = (_CFPFactory *)CFArrayGetValueAtIndex(array, i); | |
74 | if (_CFPFactoryGetPlugIn(factory) == plugIn) { | |
75 | CFArrayAppendValue(result, _CFPFactoryGetFactoryID(factory)); | |
76 | } | |
77 | } | |
78 | } | |
79 | return result; | |
80 | } | |
81 | ||
82 | CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFUUIDRef typeID) { | |
83 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
84 | void *result = NULL; | |
85 | if (!factory) { | |
86 | /* MF:!!! No such factory. */ | |
87 | CFLog(__kCFLogPlugIn, CFSTR("Cannot find factory %@"), factoryID); | |
88 | } else { | |
89 | if (!_CFPFactorySupportsType(factory, typeID)) { | |
90 | /* MF:!!! Factory does not support type. */ | |
91 | CFLog(__kCFLogPlugIn, CFSTR("Factory %@ does not support type %@"), factoryID, typeID); | |
92 | } else { | |
93 | result = _CFPFactoryCreateInstance(allocator, factory, typeID); | |
94 | } | |
95 | } | |
96 | return result; | |
97 | } | |
98 | ||
99 | /* ===================== Registering factories and types ===================== */ | |
100 | /* For plugIn writers who must dynamically register things. */ | |
101 | /* Functions to register factory functions and to associate factories with types. */ | |
102 | ||
103 | CF_EXPORT Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryID, CFPlugInFactoryFunction func) { | |
104 | // Create factories without plugIns from default allocator | |
105 | // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists | |
106 | // _CFPFactory *factory = | |
107 | (void)_CFPFactoryCreate(NULL, factoryID, func); | |
108 | return true; | |
109 | } | |
110 | ||
111 | CF_EXPORT Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef functionName) { | |
112 | // Create factories with plugIns from plugIn's allocator | |
113 | // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists | |
114 | // _CFPFactory *factory = | |
115 | (void)_CFPFactoryCreateByName(CFGetAllocator(plugIn), factoryID, plugIn, functionName); | |
116 | return true; | |
117 | } | |
118 | ||
119 | CF_EXPORT Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryID) { | |
120 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
121 | ||
122 | if (!factory) { | |
123 | /* MF:!!! Error. No factory registered for this ID. */ | |
124 | } else { | |
125 | _CFPFactoryDisable(factory); | |
126 | } | |
127 | return true; | |
128 | } | |
129 | ||
130 | CF_EXPORT Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) { | |
131 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
132 | ||
133 | if (!factory) { | |
134 | /* MF:!!! Error. Factory must be registered (and not disabled) before types can be associated with it. */ | |
135 | } else { | |
136 | _CFPFactoryAddType(factory, typeID); | |
137 | } | |
138 | return true; | |
139 | } | |
140 | ||
141 | CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) { | |
142 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
143 | ||
144 | if (!factory) { | |
145 | /* MF:!!! Error. Could not find factory. */ | |
146 | } else { | |
147 | _CFPFactoryRemoveType(factory, typeID); | |
148 | } | |
149 | return true; | |
150 | } | |
151 | ||
152 | ||
153 | /* ================= Registering instances ================= */ | |
154 | /* When a new instance of a type is created, the instance is responsible for registering itself with the factory that created it and unregistering when it deallocates. */ | |
155 | /* This means that an instance must keep track of the CFUUIDRef of the factory that created it so it can unregister when it goes away. */ | |
156 | ||
157 | CF_EXPORT void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID) { | |
158 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
159 | ||
160 | if (!factory) { | |
161 | /* MF:!!! Error. Could not find factory. */ | |
162 | } else { | |
163 | _CFPFactoryAddInstance(factory); | |
164 | } | |
165 | } | |
166 | ||
167 | CF_EXPORT void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID) { | |
168 | _CFPFactory *factory = _CFPFactoryFind(factoryID, true); | |
169 | ||
170 | if (!factory) { | |
171 | /* MF:!!! Error. Could not find factory. */ | |
172 | } else { | |
173 | _CFPFactoryRemoveInstance(factory); | |
174 | } | |
175 | } |