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