/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFPlugIn_Instance.c
	Copyright (c) 1999-2007 Apple Inc.  All rights reserved.
	Responsibility: Doug Davidson
*/

#include "CFBundle_Internal.h"
#include "CFInternal.h"

static CFTypeID __kCFPlugInInstanceTypeID = _kCFRuntimeNotATypeID;

struct __CFPlugInInstance {
    CFRuntimeBase _base;
    
    _CFPFactory *factory;
    
    CFPlugInInstanceGetInterfaceFunction getInterfaceFunction;
    CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction;

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4200)
#endif //_MSC_VER
    uint8_t _instanceData[0];
#ifdef _MSC_VER
#pragma warning(pop)
#endif //_MSC_VER
};

static CFStringRef __CFPlugInInstanceCopyDescription(CFTypeRef cf) {
    /* MF:!!! Implement me */
    return CFSTR("Some CFPlugInInstance");
}

static void __CFPlugInInstanceDeallocate(CFTypeRef cf) {
    CFPlugInInstanceRef instance = (CFPlugInInstanceRef)cf;
    
    __CFGenericValidateType(cf, __kCFPlugInInstanceTypeID);

    if (instance->deallocateInstanceDataFunction) {
        FAULT_CALLBACK((void **)&(instance->deallocateInstanceDataFunction));
        (void)INVOKE_CALLBACK1(instance->deallocateInstanceDataFunction, (void *)(&instance->_instanceData[0]));
    }

    if (instance->factory) {
        _CFPFactoryRemoveInstance(instance->factory);
    }
}

static const CFRuntimeClass __CFPlugInInstanceClass = {
    0,
    "CFPlugInInstance",
    NULL,      // init
    NULL,      // copy
    __CFPlugInInstanceDeallocate,
    NULL,      // equal
    NULL,      // hash
    NULL,      // 
    __CFPlugInInstanceCopyDescription
};

__private_extern__ void __CFPlugInInstanceInitialize(void) {
    __kCFPlugInInstanceTypeID = _CFRuntimeRegisterClass(&__CFPlugInInstanceClass);
}

CFTypeID CFPlugInInstanceGetTypeID(void) {
    return __kCFPlugInInstanceTypeID;
}
CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction) {
    CFPlugInInstanceRef instance;
    UInt32 size;
    size = sizeof(struct __CFPlugInInstance) + instanceDataSize - sizeof(CFRuntimeBase);
    instance = (CFPlugInInstanceRef)_CFRuntimeCreateInstance(allocator, __kCFPlugInInstanceTypeID, size, NULL);
    if (NULL == instance) {
        return NULL;
    }

    instance->factory = _CFPFactoryFind((CFUUIDRef)factoryName, true);
    if (instance->factory) {
        _CFPFactoryAddInstance(instance->factory);
    }
    instance->getInterfaceFunction = getInterfaceFunction;
    instance->deallocateInstanceDataFunction = deallocateInstanceFunction;

    return instance;
}

CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl) {
    void *myFtbl;
    Boolean result = false;

    if (instance->getInterfaceFunction) {
        FAULT_CALLBACK((void **)&(instance->getInterfaceFunction));
        result = INVOKE_CALLBACK3(instance->getInterfaceFunction, instance, interfaceName, &myFtbl) ? true : false;
    }
    if (ftbl) {
        *ftbl = (result ? myFtbl : NULL);
    }
    return result;
}

CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) {
    return (CFStringRef)_CFPFactoryGetFactoryID(instance->factory);
}

CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) {
    return (void *)(&instance->_instanceData[0]);
}

