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