1*cdf0e10cSrcweir//
2*cdf0e10cSrcweir//  main.c
3*cdf0e10cSrcweir//  SpotlightTester
4*cdf0e10cSrcweir//
5*cdf0e10cSrcweir//  Created by Florian Heckl on 10.07.07.
6*cdf0e10cSrcweir//  Copyright (c) 2007 __MyCompanyName__. All rights reserved.
7*cdf0e10cSrcweir//
8*cdf0e10cSrcweir
9*cdf0e10cSrcweir
10*cdf0e10cSrcweir
11*cdf0e10cSrcweir
12*cdf0e10cSrcweir
13*cdf0e10cSrcweir//==============================================================================
14*cdf0e10cSrcweir//
15*cdf0e10cSrcweir//	DO NO MODIFY THE CONTENT OF THIS FILE
16*cdf0e10cSrcweir//
17*cdf0e10cSrcweir//	This file contains the generic CFPlug-in code necessary for your importer
18*cdf0e10cSrcweir//	To complete your importer implement the function in GetMetadataForFile.c
19*cdf0e10cSrcweir//
20*cdf0e10cSrcweir//==============================================================================
21*cdf0e10cSrcweir
22*cdf0e10cSrcweir
23*cdf0e10cSrcweir
24*cdf0e10cSrcweir
25*cdf0e10cSrcweir
26*cdf0e10cSrcweir
27*cdf0e10cSrcweir#include <CoreFoundation/CoreFoundation.h>
28*cdf0e10cSrcweir#include <CoreFoundation/CFPlugInCOM.h>
29*cdf0e10cSrcweir#include <CoreServices/CoreServices.h>
30*cdf0e10cSrcweir
31*cdf0e10cSrcweir// -----------------------------------------------------------------------------
32*cdf0e10cSrcweir//	constants
33*cdf0e10cSrcweir// -----------------------------------------------------------------------------
34*cdf0e10cSrcweir
35*cdf0e10cSrcweir
36*cdf0e10cSrcweir#define PLUGIN_ID "A3FCC88D-B9A6-4364-8B93-92123C8A2D18"
37*cdf0e10cSrcweir
38*cdf0e10cSrcweir//
39*cdf0e10cSrcweir// Below is the generic glue code for all plug-ins.
40*cdf0e10cSrcweir//
41*cdf0e10cSrcweir// You should not have to modify this code aside from changing
42*cdf0e10cSrcweir// names if you decide to change the names defined in the Info.plist
43*cdf0e10cSrcweir//
44*cdf0e10cSrcweir
45*cdf0e10cSrcweir
46*cdf0e10cSrcweir// -----------------------------------------------------------------------------
47*cdf0e10cSrcweir//	typedefs
48*cdf0e10cSrcweir// -----------------------------------------------------------------------------
49*cdf0e10cSrcweir
50*cdf0e10cSrcweir// The import function to be implemented in GetMetadataForFile.c
51*cdf0e10cSrcweirBoolean GetMetadataForFile(void *thisInterface,
52*cdf0e10cSrcweir			   CFMutableDictionaryRef attributes,
53*cdf0e10cSrcweir			   CFStringRef contentTypeUTI,
54*cdf0e10cSrcweir			   CFStringRef pathToFile);
55*cdf0e10cSrcweir
56*cdf0e10cSrcweir// The layout for an instance of MetaDataImporterPlugIn
57*cdf0e10cSrcweirtypedef struct __MetadataImporterPluginType
58*cdf0e10cSrcweir{
59*cdf0e10cSrcweir    MDImporterInterfaceStruct *conduitInterface;
60*cdf0e10cSrcweir    CFUUIDRef                 factoryID;
61*cdf0e10cSrcweir    UInt32                    refCount;
62*cdf0e10cSrcweir} MetadataImporterPluginType;
63*cdf0e10cSrcweir
64*cdf0e10cSrcweir// -----------------------------------------------------------------------------
65*cdf0e10cSrcweir//	prototypes
66*cdf0e10cSrcweir// -----------------------------------------------------------------------------
67*cdf0e10cSrcweir//	Forward declaration for the IUnknown implementation.
68*cdf0e10cSrcweir//
69*cdf0e10cSrcweir
70*cdf0e10cSrcweirMetadataImporterPluginType  *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
71*cdf0e10cSrcweirvoid                      DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
72*cdf0e10cSrcweirHRESULT                   MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
73*cdf0e10cSrcweirvoid                     *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
74*cdf0e10cSrcweirULONG                     MetadataImporterPluginAddRef(void *thisInstance);
75*cdf0e10cSrcweirULONG                     MetadataImporterPluginRelease(void *thisInstance);
76*cdf0e10cSrcweir// -----------------------------------------------------------------------------
77*cdf0e10cSrcweir//	testInterfaceFtbl	definition
78*cdf0e10cSrcweir// -----------------------------------------------------------------------------
79*cdf0e10cSrcweir//	The TestInterface function table.
80*cdf0e10cSrcweir//
81*cdf0e10cSrcweir
82*cdf0e10cSrcweirstatic MDImporterInterfaceStruct testInterfaceFtbl = {
83*cdf0e10cSrcweir    NULL,
84*cdf0e10cSrcweir    MetadataImporterQueryInterface,
85*cdf0e10cSrcweir    MetadataImporterPluginAddRef,
86*cdf0e10cSrcweir    MetadataImporterPluginRelease,
87*cdf0e10cSrcweir    GetMetadataForFile
88*cdf0e10cSrcweir};
89*cdf0e10cSrcweir
90*cdf0e10cSrcweir
91*cdf0e10cSrcweir// -----------------------------------------------------------------------------
92*cdf0e10cSrcweir//	AllocMetadataImporterPluginType
93*cdf0e10cSrcweir// -----------------------------------------------------------------------------
94*cdf0e10cSrcweir//	Utility function that allocates a new instance.
95*cdf0e10cSrcweir//      You can do some initial setup for the importer here if you wish
96*cdf0e10cSrcweir//      like allocating globals etc...
97*cdf0e10cSrcweir//
98*cdf0e10cSrcweirMetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
99*cdf0e10cSrcweir{
100*cdf0e10cSrcweir    MetadataImporterPluginType *theNewInstance;
101*cdf0e10cSrcweir
102*cdf0e10cSrcweir    theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
103*cdf0e10cSrcweir    memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
104*cdf0e10cSrcweir
105*cdf0e10cSrcweir        /* Point to the function table */
106*cdf0e10cSrcweir    theNewInstance->conduitInterface = &testInterfaceFtbl;
107*cdf0e10cSrcweir
108*cdf0e10cSrcweir        /*  Retain and keep an open instance refcount for each factory. */
109*cdf0e10cSrcweir    theNewInstance->factoryID = CFRetain(inFactoryID);
110*cdf0e10cSrcweir    CFPlugInAddInstanceForFactory(inFactoryID);
111*cdf0e10cSrcweir
112*cdf0e10cSrcweir        /* This function returns the IUnknown interface so set the refCount to one. */
113*cdf0e10cSrcweir    theNewInstance->refCount = 1;
114*cdf0e10cSrcweir    return theNewInstance;
115*cdf0e10cSrcweir}
116*cdf0e10cSrcweir
117*cdf0e10cSrcweir// -----------------------------------------------------------------------------
118*cdf0e10cSrcweir//	DeallocSpotlightTesterMDImporterPluginType
119*cdf0e10cSrcweir// -----------------------------------------------------------------------------
120*cdf0e10cSrcweir//	Utility function that deallocates the instance when
121*cdf0e10cSrcweir//	the refCount goes to zero.
122*cdf0e10cSrcweir//      In the current implementation importer interfaces are never deallocated
123*cdf0e10cSrcweir//      but implement this as this might change in the future
124*cdf0e10cSrcweir//
125*cdf0e10cSrcweirvoid DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
126*cdf0e10cSrcweir{
127*cdf0e10cSrcweir    CFUUIDRef theFactoryID;
128*cdf0e10cSrcweir
129*cdf0e10cSrcweir    theFactoryID = thisInstance->factoryID;
130*cdf0e10cSrcweir    free(thisInstance);
131*cdf0e10cSrcweir    if (theFactoryID){
132*cdf0e10cSrcweir        CFPlugInRemoveInstanceForFactory(theFactoryID);
133*cdf0e10cSrcweir        CFRelease(theFactoryID);
134*cdf0e10cSrcweir    }
135*cdf0e10cSrcweir}
136*cdf0e10cSrcweir
137*cdf0e10cSrcweir// -----------------------------------------------------------------------------
138*cdf0e10cSrcweir//	MetadataImporterQueryInterface
139*cdf0e10cSrcweir// -----------------------------------------------------------------------------
140*cdf0e10cSrcweir//	Implementation of the IUnknown QueryInterface function.
141*cdf0e10cSrcweir//
142*cdf0e10cSrcweirHRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
143*cdf0e10cSrcweir{
144*cdf0e10cSrcweir    CFUUIDRef interfaceID;
145*cdf0e10cSrcweir
146*cdf0e10cSrcweir    interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
147*cdf0e10cSrcweir
148*cdf0e10cSrcweir    if (CFEqual(interfaceID,kMDImporterInterfaceID)){
149*cdf0e10cSrcweir            /* If the Right interface was requested, bump the ref count,
150*cdf0e10cSrcweir             * set the ppv parameter equal to the instance, and
151*cdf0e10cSrcweir             * return good status.
152*cdf0e10cSrcweir             */
153*cdf0e10cSrcweir        ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
154*cdf0e10cSrcweir        *ppv = thisInstance;
155*cdf0e10cSrcweir        CFRelease(interfaceID);
156*cdf0e10cSrcweir        return S_OK;
157*cdf0e10cSrcweir    }else{
158*cdf0e10cSrcweir        if (CFEqual(interfaceID,IUnknownUUID)){
159*cdf0e10cSrcweir                /* If the IUnknown interface was requested, same as above. */
160*cdf0e10cSrcweir            ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
161*cdf0e10cSrcweir            *ppv = thisInstance;
162*cdf0e10cSrcweir            CFRelease(interfaceID);
163*cdf0e10cSrcweir            return S_OK;
164*cdf0e10cSrcweir        }else{
165*cdf0e10cSrcweir                /* Requested interface unknown, bail with error. */
166*cdf0e10cSrcweir            *ppv = NULL;
167*cdf0e10cSrcweir            CFRelease(interfaceID);
168*cdf0e10cSrcweir            return E_NOINTERFACE;
169*cdf0e10cSrcweir        }
170*cdf0e10cSrcweir    }
171*cdf0e10cSrcweir}
172*cdf0e10cSrcweir
173*cdf0e10cSrcweir// -----------------------------------------------------------------------------
174*cdf0e10cSrcweir//	MetadataImporterPluginAddRef
175*cdf0e10cSrcweir// -----------------------------------------------------------------------------
176*cdf0e10cSrcweir//	Implementation of reference counting for this type. Whenever an interface
177*cdf0e10cSrcweir//	is requested, bump the refCount for the instance. NOTE: returning the
178*cdf0e10cSrcweir//	refcount is a convention but is not required so don't rely on it.
179*cdf0e10cSrcweir//
180*cdf0e10cSrcweirULONG MetadataImporterPluginAddRef(void *thisInstance)
181*cdf0e10cSrcweir{
182*cdf0e10cSrcweir    ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
183*cdf0e10cSrcweir    return ((MetadataImporterPluginType*) thisInstance)->refCount;
184*cdf0e10cSrcweir}
185*cdf0e10cSrcweir
186*cdf0e10cSrcweir// -----------------------------------------------------------------------------
187*cdf0e10cSrcweir// SampleCMPluginRelease
188*cdf0e10cSrcweir// -----------------------------------------------------------------------------
189*cdf0e10cSrcweir//	When an interface is released, decrement the refCount.
190*cdf0e10cSrcweir//	If the refCount goes to zero, deallocate the instance.
191*cdf0e10cSrcweir//
192*cdf0e10cSrcweirULONG MetadataImporterPluginRelease(void *thisInstance)
193*cdf0e10cSrcweir{
194*cdf0e10cSrcweir    ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
195*cdf0e10cSrcweir    if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
196*cdf0e10cSrcweir        DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
197*cdf0e10cSrcweir        return 0;
198*cdf0e10cSrcweir    }else{
199*cdf0e10cSrcweir        return ((MetadataImporterPluginType*) thisInstance )->refCount;
200*cdf0e10cSrcweir    }
201*cdf0e10cSrcweir}
202*cdf0e10cSrcweir
203*cdf0e10cSrcweir// -----------------------------------------------------------------------------
204*cdf0e10cSrcweir//	SpotlightTesterMDImporterPluginFactory
205*cdf0e10cSrcweir// -----------------------------------------------------------------------------
206*cdf0e10cSrcweir//	Implementation of the factory function for this type.
207*cdf0e10cSrcweir//
208*cdf0e10cSrcweirvoid *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
209*cdf0e10cSrcweir{
210*cdf0e10cSrcweir    MetadataImporterPluginType *result;
211*cdf0e10cSrcweir    CFUUIDRef                 uuid;
212*cdf0e10cSrcweir
213*cdf0e10cSrcweir        /* If correct type is being requested, allocate an
214*cdf0e10cSrcweir         * instance of TestType and return the IUnknown interface.
215*cdf0e10cSrcweir         */
216*cdf0e10cSrcweir    if (CFEqual(typeID,kMDImporterTypeID)){
217*cdf0e10cSrcweir        uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
218*cdf0e10cSrcweir        result = AllocMetadataImporterPluginType(uuid);
219*cdf0e10cSrcweir        CFRelease(uuid);
220*cdf0e10cSrcweir        return result;
221*cdf0e10cSrcweir    }
222*cdf0e10cSrcweir        /* If the requested type is incorrect, return NULL. */
223*cdf0e10cSrcweir    return NULL;
224*cdf0e10cSrcweir}
225*cdf0e10cSrcweir
226