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