git.fiddlerwoaroof.com
Source/main.c
0c532ca4
 //  main.c
 //
 //  Lisp Metadata Importer
 //
 //  Created by John Wiseman on 9/1/05.
 //  Copyright 2005 John Wiseman.
 //
 //  Licensed under the MIT license--see the accompanying LICENSE.txt
 //  file.
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFPlugInCOM.h>
 #include <CoreServices/CoreServices.h>
 
 // Constants
 
 
 #define PLUGIN_ID "12C869B3-3D4B-4DED-B156-5D55D1C64354"
 
 //
 // 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, 
0223e6a6
                            CFMutableDictionaryRef attributes, 
                            CFStringRef contentTypeUTI,
                            CFStringRef pathToFile);
 
0c532ca4
 // 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;
0223e6a6
     
0c532ca4
     theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
     memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
0223e6a6
     
     /* Point to the function table */
0c532ca4
     theNewInstance->conduitInterface = &testInterfaceFtbl;
0223e6a6
     
     /*  Retain and keep an open instance refcount for each factory. */
0c532ca4
     theNewInstance->factoryID = CFRetain(inFactoryID);
     CFPlugInAddInstanceForFactory(inFactoryID);
0223e6a6
     
     /* This function returns the IUnknown interface so set the refCount to one. */
0c532ca4
     theNewInstance->refCount = 1;
     return theNewInstance;
 }
 
 // -----------------------------------------------------------------------------
 //	DeallocPython_Metadata_ImporterMDImporterPluginType
 // -----------------------------------------------------------------------------
 //	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;
0223e6a6
     
0c532ca4
     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;
0223e6a6
     
0c532ca4
     interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
0223e6a6
     
0c532ca4
     if (CFEqual(interfaceID,kMDImporterInterfaceID)){
0223e6a6
         /* If the Right interface was requested, bump the ref count,
          * set the ppv parameter equal to the instance, and
          * return good status.
          */
0c532ca4
         ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
         *ppv = thisInstance;
         CFRelease(interfaceID);
         return S_OK;
     }else{
         if (CFEqual(interfaceID,IUnknownUUID)){
0223e6a6
             /* If the IUnknown interface was requested, same as above. */
0c532ca4
             ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
             *ppv = thisInstance;
             CFRelease(interfaceID);
             return S_OK;
         }else{
0223e6a6
             /* Requested interface unknown, bail with error. */
0c532ca4
             *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;
     }
 }
 
 // -----------------------------------------------------------------------------
 //	Python_Metadata_ImporterMDImporterPluginFactory
 // -----------------------------------------------------------------------------
 //	Implementation of the factory function for this type.
 //
 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
 {
     MetadataImporterPluginType *result;
     CFUUIDRef                 uuid;
     
0223e6a6
     
     /* If correct type is being requested, allocate an
      * instance of TestType and return the IUnknown interface.
      */
0c532ca4
     if (CFEqual(typeID,kMDImporterTypeID)){
         uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
         result = AllocMetadataImporterPluginType(uuid);
         CFRelease(uuid);
         return result;
     }
0223e6a6
     /* If the requested type is incorrect, return NULL. */
0c532ca4
     return NULL;
 }