PageRenderTime 49ms CodeModel.GetById 34ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/SpotlightPlugins/Common/main.c

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