/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2007 * the Initial Developer. All Rights Reserved. * * Contributor(s): * David Bienvenu * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ //============================================================================== // // DO NO MODIFY THE CONTENT OF THIS FILE // // This file contains the generic CFPlug-in code necessary for TB Spotlight // The actual importer is implemented in GetMetadataForFile.c // //============================================================================== #include #include #include // ----------------------------------------------------------------------------- // constants // ----------------------------------------------------------------------------- #define PLUGIN_ID "37401ADE-1058-42DB-BBE5-F2AAB9D7C13E" // // Below is the generic glue code for all plug-ins. // // You should not have to modify this code aside from changing // names if you decide to change the names defined in the Info.plist // // ----------------------------------------------------------------------------- // typedefs // ----------------------------------------------------------------------------- // The import function to be implemented in GetMetadataForFile.c Boolean GetMetadataForFile(void *thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile); // The layout for an instance of MetaDataImporterPlugIn typedef struct __MetadataImporterPluginType { MDImporterInterfaceStruct *conduitInterface; CFUUIDRef factoryID; UInt32 refCount; } MetadataImporterPluginType; // ----------------------------------------------------------------------------- // prototypes // ----------------------------------------------------------------------------- // Forward declaration for the IUnknown implementation. // MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID); void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance); HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); ULONG MetadataImporterPluginAddRef(void *thisInstance); ULONG MetadataImporterPluginRelease(void *thisInstance); // ----------------------------------------------------------------------------- // testInterfaceFtbl definition // ----------------------------------------------------------------------------- // The TestInterface function table. // static MDImporterInterfaceStruct testInterfaceFtbl = { NULL, MetadataImporterQueryInterface, MetadataImporterPluginAddRef, MetadataImporterPluginRelease, GetMetadataForFile }; // ----------------------------------------------------------------------------- // AllocMetadataImporterPluginType // ----------------------------------------------------------------------------- // Utility function that allocates a new instance. // You can do some initial setup for the importer here if you wish // like allocating globals etc... // MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID) { MetadataImporterPluginType *theNewInstance; theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType)); memset(theNewInstance,0,sizeof(MetadataImporterPluginType)); /* Point to the function table */ theNewInstance->conduitInterface = &testInterfaceFtbl; /* Retain and keep an open instance refcount for each factory. */ theNewInstance->factoryID = CFRetain(inFactoryID); CFPlugInAddInstanceForFactory(inFactoryID); /* This function returns the IUnknown interface so set the refCount to one. */ theNewInstance->refCount = 1; return theNewInstance; } // ----------------------------------------------------------------------------- // DeallocTBSpotlightMDImporterPluginType // ----------------------------------------------------------------------------- // Utility function that deallocates the instance when // the refCount goes to zero. // In the current implementation importer interfaces are never deallocated // but implement this as this might change in the future // void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance) { CFUUIDRef theFactoryID; theFactoryID = thisInstance->factoryID; free(thisInstance); if (theFactoryID){ CFPlugInRemoveInstanceForFactory(theFactoryID); CFRelease(theFactoryID); } } // ----------------------------------------------------------------------------- // MetadataImporterQueryInterface // ----------------------------------------------------------------------------- // Implementation of the IUnknown QueryInterface function. // HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) { CFUUIDRef interfaceID; interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); if (CFEqual(interfaceID,kMDImporterInterfaceID)){ /* If the Right interface was requested, bump the ref count, * set the ppv parameter equal to the instance, and * return good status. */ ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance); *ppv = thisInstance; CFRelease(interfaceID); return S_OK; }else{ if (CFEqual(interfaceID,IUnknownUUID)){ /* If the IUnknown interface was requested, same as above. */ ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance); *ppv = thisInstance; CFRelease(interfaceID); return S_OK; }else{ /* Requested interface unknown, bail with error. */ *ppv = NULL; CFRelease(interfaceID); return E_NOINTERFACE; } } } // ----------------------------------------------------------------------------- // MetadataImporterPluginAddRef // ----------------------------------------------------------------------------- // Implementation of reference counting for this type. Whenever an interface // is requested, bump the refCount for the instance. NOTE: returning the // refcount is a convention but is not required so don't rely on it. // ULONG MetadataImporterPluginAddRef(void *thisInstance) { ((MetadataImporterPluginType *)thisInstance )->refCount += 1; return ((MetadataImporterPluginType*) thisInstance)->refCount; } // ----------------------------------------------------------------------------- // SampleCMPluginRelease // ----------------------------------------------------------------------------- // When an interface is released, decrement the refCount. // If the refCount goes to zero, deallocate the instance. // ULONG MetadataImporterPluginRelease(void *thisInstance) { ((MetadataImporterPluginType*)thisInstance)->refCount -= 1; if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){ DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance ); return 0; }else{ return ((MetadataImporterPluginType*) thisInstance )->refCount; } } // ----------------------------------------------------------------------------- // TBSpotlightMDImporterPluginFactory // ----------------------------------------------------------------------------- // Implementation of the factory function for this type. // void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) { MetadataImporterPluginType *result; CFUUIDRef uuid; /* If correct type is being requested, allocate an * instance of TestType and return the IUnknown interface. */ if (CFEqual(typeID,kMDImporterTypeID)){ uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); result = AllocMetadataImporterPluginType(uuid); CFRelease(uuid); return result; } /* If the requested type is incorrect, return NULL. */ return NULL; }