File indexing completed on 2025-05-11 07:37:43

0001 /*
0002  * This file is part of Krita
0003  *
0004  * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 /* clang-format off */
0010 
0011 
0012 
0013 
0014 //==============================================================================
0015 //
0016 //  DO NO MODIFY THE CONTENT OF THIS FILE
0017 //
0018 //  This file contains the generic CFPlug-in code necessary for your importer
0019 //  To complete your importer implement the function in GetMetadataForFile.c
0020 //
0021 //==============================================================================
0022 
0023 
0024 
0025 
0026 
0027 #import <CoreFoundation/CoreFoundation.h>
0028 #import <CoreFoundation/CFPlugInCOM.h>
0029 #import <CoreServices/CoreServices.h>
0030 
0031 // -----------------------------------------------------------------------------
0032 //  constants
0033 // -----------------------------------------------------------------------------
0034 
0035 
0036 #define PLUGIN_ID "23FE92B0-6256-49C0-B1A6-942FB9B86A82"
0037 
0038 //
0039 // Below is the generic glue code for all plug-ins.
0040 //
0041 // You should not have to modify this code aside from changing
0042 // names if you decide to change the names defined in the Info.plist
0043 //
0044 
0045 
0046 // -----------------------------------------------------------------------------
0047 //  typedefs
0048 // -----------------------------------------------------------------------------
0049 
0050 // The import function to be implemented in GetMetadataForFile.c
0051 Boolean GetMetadataForFile(void *thisInterface,
0052                CFMutableDictionaryRef attributes,
0053                CFStringRef contentTypeUTI,
0054                CFStringRef pathToFile);
0055 
0056 // The layout for an instance of MetaDataImporterPlugIn
0057 typedef struct __MetadataImporterPluginType
0058 {
0059     MDImporterInterfaceStruct *conduitInterface;
0060     CFUUIDRef                 factoryID;
0061     UInt32                    refCount;
0062 } MetadataImporterPluginType;
0063 
0064 // -----------------------------------------------------------------------------
0065 //  prototypes
0066 // -----------------------------------------------------------------------------
0067 //  Forward declaration for the IUnknown implementation.
0068 //
0069 
0070 MetadataImporterPluginType  *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
0071 void                      DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
0072 HRESULT                   MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
0073 void                     *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
0074 ULONG                     MetadataImporterPluginAddRef(void *thisInstance);
0075 ULONG                     MetadataImporterPluginRelease(void *thisInstance);
0076 // -----------------------------------------------------------------------------
0077 //  testInterfaceFtbl    definition
0078 // -----------------------------------------------------------------------------
0079 //  The TestInterface function table.
0080 //
0081 
0082 static MDImporterInterfaceStruct testInterfaceFtbl = {
0083     NULL,
0084     MetadataImporterQueryInterface,
0085     MetadataImporterPluginAddRef,
0086     MetadataImporterPluginRelease,
0087     GetMetadataForFile
0088 };
0089 
0090 
0091 // -----------------------------------------------------------------------------
0092 //  AllocMetadataImporterPluginType
0093 // -----------------------------------------------------------------------------
0094 //  Utility function that allocates a new instance.
0095 //      You can do some initial setup for the importer here if you wish
0096 //      like allocating globals etc...
0097 //
0098 MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
0099 {
0100     MetadataImporterPluginType *theNewInstance;
0101 
0102     theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
0103     memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
0104 
0105         /* Point to the function table */
0106     theNewInstance->conduitInterface = &testInterfaceFtbl;
0107 
0108         /*  Retain and keep an open instance refcount for each factory. */
0109     theNewInstance->factoryID = CFRetain(inFactoryID);
0110     CFPlugInAddInstanceForFactory(inFactoryID);
0111 
0112         /* This function returns the IUnknown interface so set the refCount to one. */
0113     theNewInstance->refCount = 1;
0114     return theNewInstance;
0115 }
0116 
0117 // -----------------------------------------------------------------------------
0118 //    DeallockritaspotlightMDImporterPluginType
0119 // -----------------------------------------------------------------------------
0120 //  Utility function that deallocates the instance when
0121 //  the refCount goes to zero.
0122 //      In the current implementation importer interfaces are never deallocated
0123 //      but implement this as this might change in the future
0124 //
0125 void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
0126 {
0127     CFUUIDRef theFactoryID;
0128 
0129     theFactoryID = thisInstance->factoryID;
0130     free(thisInstance);
0131     if (theFactoryID){
0132         CFPlugInRemoveInstanceForFactory(theFactoryID);
0133         CFRelease(theFactoryID);
0134     }
0135 }
0136 
0137 // -----------------------------------------------------------------------------
0138 //  MetadataImporterQueryInterface
0139 // -----------------------------------------------------------------------------
0140 //  Implementation of the IUnknown QueryInterface function.
0141 //
0142 HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
0143 {
0144     CFUUIDRef interfaceID;
0145 
0146     interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
0147 
0148     if (CFEqual(interfaceID,kMDImporterInterfaceID)){
0149             /* If the Right interface was requested, bump the ref count,
0150              * set the ppv parameter equal to the instance, and
0151              * return good status.
0152              */
0153         ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
0154         *ppv = thisInstance;
0155         CFRelease(interfaceID);
0156         return S_OK;
0157     }else{
0158         if (CFEqual(interfaceID,IUnknownUUID)){
0159                 /* If the IUnknown interface was requested, same as above. */
0160             ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
0161             *ppv = thisInstance;
0162             CFRelease(interfaceID);
0163             return S_OK;
0164         }else{
0165                 /* Requested interface unknown, bail with error. */
0166             *ppv = NULL;
0167             CFRelease(interfaceID);
0168             return E_NOINTERFACE;
0169         }
0170     }
0171 }
0172 
0173 // -----------------------------------------------------------------------------
0174 //  MetadataImporterPluginAddRef
0175 // -----------------------------------------------------------------------------
0176 //  Implementation of reference counting for this type. Whenever an interface
0177 //  is requested, bump the refCount for the instance. NOTE: returning the
0178 //  refcount is a convention but is not required so don't rely on it.
0179 //
0180 ULONG MetadataImporterPluginAddRef(void *thisInstance)
0181 {
0182     ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
0183     return ((MetadataImporterPluginType*) thisInstance)->refCount;
0184 }
0185 
0186 // -----------------------------------------------------------------------------
0187 // SampleCMPluginRelease
0188 // -----------------------------------------------------------------------------
0189 //  When an interface is released, decrement the refCount.
0190 //  If the refCount goes to zero, deallocate the instance.
0191 //
0192 ULONG MetadataImporterPluginRelease(void *thisInstance)
0193 {
0194     ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
0195     if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
0196         DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
0197         return 0;
0198     }else{
0199         return ((MetadataImporterPluginType*) thisInstance )->refCount;
0200     }
0201 }
0202 
0203 // -----------------------------------------------------------------------------
0204 //  kritaspotlightMDImporterPluginFactory
0205 // -----------------------------------------------------------------------------
0206 //  Implementation of the factory function for this type.
0207 //
0208 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
0209 {
0210     MetadataImporterPluginType *result;
0211     CFUUIDRef                 uuid;
0212 
0213         /* If correct type is being requested, allocate an
0214          * instance of TestType and return the IUnknown interface.
0215          */
0216     if (CFEqual(typeID,kMDImporterTypeID)){
0217         uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
0218         result = AllocMetadataImporterPluginType(uuid);
0219         CFRelease(uuid);
0220         return result;
0221     }
0222         /* If the requested type is incorrect, return NULL. */
0223     return NULL;
0224 }
0225