Blame macosx/mdimporter/main.c

Packit df99a1
//
Packit df99a1
//  main.c
Packit df99a1
//  DjVu
Packit df99a1
//
Packit df99a1
//  Created by Jeff Sickel on 9/6/06.
Packit df99a1
//  Copyright (c) 2006 Corpus Callosum Corporation. All rights reserved.
Packit df99a1
//
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//==============================================================================
Packit df99a1
//
Packit df99a1
//	DO NO MODIFY THE CONTENT OF THIS FILE
Packit df99a1
//
Packit df99a1
//	This file contains the generic CFPlug-in code necessary for your importer
Packit df99a1
//	To complete your importer implement the function in GetMetadataForFile.c
Packit df99a1
//
Packit df99a1
//==============================================================================
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
#include <CoreFoundation/CoreFoundation.h>
Packit df99a1
#include <CoreFoundation/CFPlugInCOM.h>
Packit df99a1
#include <CoreServices/CoreServices.h>
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	constants
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
Packit df99a1
Packit df99a1
#define PLUGIN_ID "200A2D97-B602-4FAB-84DA-18DE40383D7C"
Packit df99a1
Packit df99a1
//
Packit df99a1
// Below is the generic glue code for all plug-ins.
Packit df99a1
//
Packit df99a1
// You should not have to modify this code aside from changing
Packit df99a1
// names if you decide to change the names defined in the Info.plist
Packit df99a1
//
Packit df99a1
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	typedefs
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
Packit df99a1
// The import function to be implemented in GetMetadataForFile.c
Packit df99a1
Boolean GetMetadataForFile(void *thisInterface, 
Packit df99a1
			   CFMutableDictionaryRef attributes, 
Packit df99a1
			   CFStringRef contentTypeUTI,
Packit df99a1
			   CFStringRef pathToFile);
Packit df99a1
			   
Packit df99a1
// The layout for an instance of MetaDataImporterPlugIn 
Packit df99a1
typedef struct __MetadataImporterPluginType
Packit df99a1
{
Packit df99a1
    MDImporterInterfaceStruct *conduitInterface;
Packit df99a1
    CFUUIDRef                 factoryID;
Packit df99a1
    UInt32                    refCount;
Packit df99a1
} MetadataImporterPluginType;
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	prototypes
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Forward declaration for the IUnknown implementation.
Packit df99a1
//
Packit df99a1
Packit df99a1
MetadataImporterPluginType  *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
Packit df99a1
void                      DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
Packit df99a1
HRESULT                   MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
Packit df99a1
void                     *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
Packit df99a1
ULONG                     MetadataImporterPluginAddRef(void *thisInstance);
Packit df99a1
ULONG                     MetadataImporterPluginRelease(void *thisInstance);
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	testInterfaceFtbl	definition
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	The TestInterface function table.
Packit df99a1
//
Packit df99a1
Packit df99a1
static MDImporterInterfaceStruct testInterfaceFtbl = {
Packit df99a1
    NULL,
Packit df99a1
    MetadataImporterQueryInterface,
Packit df99a1
    MetadataImporterPluginAddRef,
Packit df99a1
    MetadataImporterPluginRelease,
Packit df99a1
    GetMetadataForFile
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	AllocMetadataImporterPluginType
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Utility function that allocates a new instance.
Packit df99a1
//      You can do some initial setup for the importer here if you wish
Packit df99a1
//      like allocating globals etc...
Packit df99a1
//
Packit df99a1
MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
Packit df99a1
{
Packit df99a1
    MetadataImporterPluginType *theNewInstance;
Packit df99a1
Packit df99a1
    theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
Packit df99a1
    memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
Packit df99a1
Packit df99a1
        /* Point to the function table */
Packit df99a1
    theNewInstance->conduitInterface = &testInterfaceFtbl;
Packit df99a1
Packit df99a1
        /*  Retain and keep an open instance refcount for each factory. */
Packit df99a1
    theNewInstance->factoryID = CFRetain(inFactoryID);
Packit df99a1
    CFPlugInAddInstanceForFactory(inFactoryID);
Packit df99a1
Packit df99a1
        /* This function returns the IUnknown interface so set the refCount to one. */
Packit df99a1
    theNewInstance->refCount = 1;
Packit df99a1
    return theNewInstance;
Packit df99a1
}
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	DeallocDjVuMDImporterPluginType
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Utility function that deallocates the instance when
Packit df99a1
//	the refCount goes to zero.
Packit df99a1
//      In the current implementation importer interfaces are never deallocated
Packit df99a1
//      but implement this as this might change in the future
Packit df99a1
//
Packit df99a1
void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
Packit df99a1
{
Packit df99a1
    CFUUIDRef theFactoryID;
Packit df99a1
Packit df99a1
    theFactoryID = thisInstance->factoryID;
Packit df99a1
    free(thisInstance);
Packit df99a1
    if (theFactoryID){
Packit df99a1
        CFPlugInRemoveInstanceForFactory(theFactoryID);
Packit df99a1
        CFRelease(theFactoryID);
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	MetadataImporterQueryInterface
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Implementation of the IUnknown QueryInterface function.
Packit df99a1
//
Packit df99a1
HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
Packit df99a1
{
Packit df99a1
    CFUUIDRef interfaceID;
Packit df99a1
Packit df99a1
    interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
Packit df99a1
Packit df99a1
    if (CFEqual(interfaceID,kMDImporterInterfaceID)){
Packit df99a1
            /* If the Right interface was requested, bump the ref count,
Packit df99a1
             * set the ppv parameter equal to the instance, and
Packit df99a1
             * return good status.
Packit df99a1
             */
Packit df99a1
        ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
Packit df99a1
        *ppv = thisInstance;
Packit df99a1
        CFRelease(interfaceID);
Packit df99a1
        return S_OK;
Packit df99a1
    }else{
Packit df99a1
        if (CFEqual(interfaceID,IUnknownUUID)){
Packit df99a1
                /* If the IUnknown interface was requested, same as above. */
Packit df99a1
            ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
Packit df99a1
            *ppv = thisInstance;
Packit df99a1
            CFRelease(interfaceID);
Packit df99a1
            return S_OK;
Packit df99a1
        }else{
Packit df99a1
                /* Requested interface unknown, bail with error. */
Packit df99a1
            *ppv = NULL;
Packit df99a1
            CFRelease(interfaceID);
Packit df99a1
            return E_NOINTERFACE;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	MetadataImporterPluginAddRef
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Implementation of reference counting for this type. Whenever an interface
Packit df99a1
//	is requested, bump the refCount for the instance. NOTE: returning the
Packit df99a1
//	refcount is a convention but is not required so don't rely on it.
Packit df99a1
//
Packit df99a1
ULONG MetadataImporterPluginAddRef(void *thisInstance)
Packit df99a1
{
Packit df99a1
    ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
Packit df99a1
    return ((MetadataImporterPluginType*) thisInstance)->refCount;
Packit df99a1
}
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
// SampleCMPluginRelease
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	When an interface is released, decrement the refCount.
Packit df99a1
//	If the refCount goes to zero, deallocate the instance.
Packit df99a1
//
Packit df99a1
ULONG MetadataImporterPluginRelease(void *thisInstance)
Packit df99a1
{
Packit df99a1
    ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
Packit df99a1
    if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
Packit df99a1
        DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
Packit df99a1
        return 0;
Packit df99a1
    }else{
Packit df99a1
        return ((MetadataImporterPluginType*) thisInstance )->refCount;
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	DjVuMDImporterPluginFactory
Packit df99a1
// -----------------------------------------------------------------------------
Packit df99a1
//	Implementation of the factory function for this type.
Packit df99a1
//
Packit df99a1
void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
Packit df99a1
{
Packit df99a1
    MetadataImporterPluginType *result;
Packit df99a1
    CFUUIDRef                 uuid;
Packit df99a1
Packit df99a1
        /* If correct type is being requested, allocate an
Packit df99a1
         * instance of TestType and return the IUnknown interface.
Packit df99a1
         */
Packit df99a1
    if (CFEqual(typeID,kMDImporterTypeID)){
Packit df99a1
        uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
Packit df99a1
        result = AllocMetadataImporterPluginType(uuid);
Packit df99a1
        CFRelease(uuid);
Packit df99a1
        return result;
Packit df99a1
    }
Packit df99a1
        /* If the requested type is incorrect, return NULL. */
Packit df99a1
    return NULL;
Packit df99a1
}
Packit df99a1