Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
ComponentDispatchHelper.c
/* |
File: ComponentDispatchHelper.c |
Copyright: © 1995-2001 by Apple Computer, Inc., all rights reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
// **** BEGIN: Error Checking the Required Macros |
// Make sure BASENAME is defined |
#ifndef COMPONENT_BASENAME |
#ifdef CALLCOMPONENT_BASENAME |
#define COMPONENT_BASENAME() CALLCOMPONENT_BASENAME() |
#else |
#error "COMPONENT_BASENAME or CALLCOMPONENT_BASENAME must be defined for ComponentDispatchHelper.c" |
#endif |
#endif |
// Make sure GLOBALS is defined |
#ifndef COMPONENT_GLOBALS |
#ifdef CALLCOMPONENT_GLOBALS |
#define COMPONENT_GLOBALS() CALLCOMPONENT_GLOBALS() |
#else |
#error "COMPONENT_GLOBALS or CALLCOMPONENT_GLOBALS must be defined for ComponentDispatchHelper.c" |
#endif |
#endif |
// Make sure DISPATCH_FILE is defined |
#ifndef COMPONENT_DISPATCH_FILE |
#error "COMPONENT_DISPATCH_FILE must be defined for ComponentDispatchHelper.c" |
#endif |
// Make sure UPP_PREFIX and SELECT_PREFIX are defined |
#if !defined(COMPONENT_UPP_SELECT_ROOT) && !defined(COMPONENT_UPP_PREFIX) && !defined(COMPONENT_SELECT_PREFIX) |
#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c" |
#endif |
#ifdef COMPONENT_UPP_SELECT_ROOT |
#if defined(COMPONENT_UPP_PREFIX) || defined(COMPONENT_SELECT_PREFIX) |
#error "use only COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) for ComponentDispatchHelper.c" |
#endif |
#else |
#if !defined(COMPONENT_UPP_PREFIX) || !defined(COMPONENT_SELECT_PREFIX) |
#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c" |
#endif |
#endif |
#ifndef COMPONENT_UPP_PREFIX |
#ifndef COMPONENT_UPP_SELECT_ROOT |
#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c" |
#else |
#define COMPONENT_UPP_PREFIX() cdh_GLUE2(upp,COMPONENT_UPP_SELECT_ROOT()) |
#endif |
#endif |
#ifndef COMPONENT_SELECT_PREFIX |
#ifndef COMPONENT_UPP_SELECT_ROOT |
#error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c" |
#else |
#define COMPONENT_SELECT_PREFIX() cdh_GLUE2(k,COMPONENT_UPP_SELECT_ROOT()) |
#endif |
#endif |
// Make sure SUBTYPE UPP_PREFIX and SELECT_PREFIX are defined correctly if they are used at all |
#if defined(COMPONENT_SUBTYPE_UPP_SELECT_ROOT) || defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX) |
#ifdef COMPONENT_SUBTYPE_UPP_SELECT_ROOT |
#if defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX) |
#error "use only COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT for ComponentDispatchHelper.c" |
#endif |
#else |
#if !defined(COMPONENT_SUBTYPE_UPP_PREFIX) || !defined(COMPONENT_SUBTYPE_SELECT_PREFIX) |
#error "COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c" |
#endif |
#endif |
#ifndef COMPONENT_SUBTYPE_UPP_PREFIX |
#ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT |
#error "COMPONENT_SUBTYPE_UPP_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c" |
#else |
#define COMPONENT_SUBTYPE_UPP_PREFIX() cdh_GLUE2(upp,COMPONENT_SUBTYPE_UPP_SELECT_ROOT()) |
#endif |
#endif |
#ifndef COMPONENT_SUBTYPE_SELECT_PREFIX |
#ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT |
#error "COMPONENT_SUBTYPE_SELECT_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c" |
#else |
#define COMPONENT_SUBTYPE_SELECT_PREFIX() cdh_GLUE2(k,COMPONENT_SUBTYPE_UPP_SELECT_ROOT()) |
#endif |
#endif |
#endif |
// **** END: Error Checking the Required Macros |
#if TARGET_API_MAC_OSX |
#define CDHCONST const |
#else |
#define CDHCONST |
#endif |
#if TARGET_OS_MAC |
#define PASCAL_RTN pascal |
#else |
#define PASCAL_RTN |
#endif |
#if !TARGET_OS_MAC || TARGET_CPU_PPC |
#define C_DISPATCH_WITH_GLOBALS 1 |
#define C_DISPATCH_WITH_SWITCH 0 |
#elif TARGET_CPU_68K |
#ifdef COMPONENT_C_DISPATCHER |
#define C_DISPATCH_WITH_GLOBALS 0 |
#define C_DISPATCH_WITH_SWITCH 1 |
#else |
#define C_DISPATCH_WITH_GLOBALS 0 |
#define C_DISPATCH_WITH_SWITCH 0 |
#endif |
#else |
#error "I have no idea what kind of machine you are using" |
#endif |
/* |
C_DISPATCH_WITH_GLOBALS implies global storage for dispatch information |
and procinfos returned by COMPONENTSELECTORLOOKUP |
C_DISPATCH_WITH_SWITCH implies no global storage, dispatch by switch |
and no procinfos returned by COMPONENTSELECTORLOOKUP |
*/ |
#define COMPONENTSELECTORLOOKUP ADD_BASENAME(FindRoutineUPP) |
#ifdef COMPONENT_DISPATCH_MAIN |
#define COMPONENT_DISPATCH_ENTRY main |
#else |
#define COMPONENT_DISPATCH_ENTRY ADD_BASENAME(ComponentDispatch) |
#endif |
#ifndef __COMPONENTS_K__ |
#include "Components.k.h" |
#endif |
#define kCOMPONENT_NOERROR ((ComponentFunctionUPP)-2) |
#define kCOMPONENT_ERROR ((ComponentFunctionUPP)-1) |
#define kCOMPONENT_DELEGATE ((ComponentFunctionUPP)0) |
#ifndef cdh_GLUE |
#define cdh_GLUE(a,b) a##b |
#endif |
#ifndef cdh_GLUE2 |
#define cdh_GLUE2(a,b) cdh_GLUE(a,b) |
#endif |
#ifndef cdh_GLUE3 |
#define cdh_GLUE3(a,b,c) cdh_GLUE2(cdh_GLUE2(a,b),c) |
#endif |
#if TARGET_RT_LITTLE_ENDIAN |
#define ComponentCallLittleEndian ComponentCall |
#else |
#define ComponentCallLittleEndian ComponentDelegate |
#endif |
#ifdef forPublicQTiRelease |
#define ComponentQTiCall(procName) ComponentCall(procName) |
#define QTIComponentCall(procName) ComponentCall(procName) |
#endif |
#define ADD_BASENAME(name) cdh_GLUE2(COMPONENT_BASENAME(),name) |
#if C_DISPATCH_WITH_GLOBALS |
PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS()); |
static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo); |
#if TARGET_OS_MAC && TARGET_CPU_PPC && !TARGET_API_MAC_CARBON |
// entry point for PowerPC native components |
struct RoutineDescriptor ADD_BASENAME(ComponentDispatchRD) = |
BUILD_ROUTINE_DESCRIPTOR((kPascalStackBased | RESULT_SIZE (kFourByteCode) | |
STACK_ROUTINE_PARAMETER (1, kFourByteCode) | |
STACK_ROUTINE_PARAMETER (2, kFourByteCode)),COMPONENT_DISPATCH_ENTRY); |
#endif |
PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params,COMPONENT_GLOBALS()) |
{ |
ComponentFunctionUPP theProc; |
ComponentResult result = badComponentSelector; |
ProcInfoType theProcInfo; |
theProc = COMPONENTSELECTORLOOKUP(params->what, &theProcInfo); |
if (theProc) { |
if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) { |
if (theProcInfo != 0) { |
result = CallComponentFunctionWithStorageProcInfo((Handle) storage, params, (ProcPtr)theProc, theProcInfo); |
} |
} |
else if ( theProc == kCOMPONENT_NOERROR ) { |
result = noErr; |
} |
} |
#ifdef GET_DELEGATE_COMPONENT |
else |
return DelegateComponentCall(params, GET_DELEGATE_COMPONENT()); |
#endif |
return result; |
} |
#elif C_DISPATCH_WITH_SWITCH |
PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS()); |
static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num); |
PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY( ComponentParameters *params, COMPONENT_GLOBALS() ) |
{ |
ComponentFunctionUPP theProc; |
ComponentResult result = badComponentSelector; |
theProc = COMPONENTSELECTORLOOKUP(params->what); |
if (theProc) { |
if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) { |
result = CallComponentFunctionWithStorage((Handle) storage, params, theProc); |
} |
else if ( theProc == kCOMPONENT_NOERROR ) { |
result = noErr; |
} |
} |
#ifdef GET_DELEGATE_COMPONENT |
else |
result = DelegateComponentCall(params, GET_DELEGATE_COMPONENT()); |
#endif |
return result; |
} |
#endif |
#if C_DISPATCH_WITH_GLOBALS |
typedef struct { |
ComponentFunctionUPP theProc; |
ProcInfoType theProcInfo; |
} cdhDispatchInfoRecord; |
typedef struct { |
short rangeMax; |
CDHCONST cdhDispatchInfoRecord *cdhDispatchInfoP; |
} cdhRangeDispatchInfoRecord; |
#define ComponentSelectorOffset(theOffset) enum {SelOffset = theOffset}; |
#define ComponentRangeCount(theCount) enum {RangeCount = theCount}; |
#define ComponentRangeShift(theShift) enum {RangeShift = theShift}; |
#define ComponentRangeMask(theMask) enum {RangeMask = cdh_GLUE2(0x0,theMask)}; |
#define ComponentStorageType(theType) |
#define ComponentDelegateByteOffset(theOffset) |
#define StdComponentCall(procName) \ |
{ (ComponentFunctionUPP) ADD_BASENAME(procName), cdh_GLUE3(uppCallComponent,procName,ProcInfo) }, |
#define ComponentCall(procName) \ |
{ (ComponentFunctionUPP) ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_UPP_PREFIX(),procName,ProcInfo) }, |
#define ComponentSubTypeCall(procName) \ |
{ (ComponentFunctionUPP) ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_SUBTYPE_UPP_PREFIX(),procName,ProcInfo) }, |
#define ComponentError(procName) { kCOMPONENT_ERROR, 0 }, |
#define StdComponentNoError(procName) { kCOMPONENT_NOERROR, 0 }, |
#define ComponentNoError(procName) { kCOMPONENT_NOERROR, 0 }, |
#define ComponentSubTypeNoError(procName) { kCOMPONENT_NOERROR, 0 }, |
#define ComponentDelegate(procName) { kCOMPONENT_DELEGATE, 0 }, |
#define ComponentRangeUnused(rangeNum) \ |
static CDHCONST cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[1] = { { 0, 0 } }; \ |
enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = 0}; |
#define ComponentRangeBegin(rangeNum) \ |
static CDHCONST cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[] = { |
#define ComponentRangeEnd(rangeNum) \ |
}; \ |
enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = sizeof(cdh_GLUE2(cdhDispatchInfo,rangeNum)) / sizeof(cdhDispatchInfoRecord)}; |
#define ComponentComment(theComment) |
// define the static dispatch tables |
#include COMPONENT_DISPATCH_FILE |
#undef ComponentSelectorOffset |
#undef ComponentRangeCount |
#undef ComponentRangeShift |
#undef ComponentRangeMask |
#undef StdComponentCall |
#undef ComponentCall |
#undef ComponentSubTypeCall |
#undef ComponentError |
#undef StdComponentNoError |
#undef ComponentNoError |
#undef ComponentSubTypeNoError |
#undef ComponentDelegate |
#undef ComponentRangeUnused |
#undef ComponentRangeBegin |
#undef ComponentRangeEnd |
#define ComponentSelectorOffset(theOffset) |
#define ComponentRangeCount(theCount) |
#define ComponentRangeShift(theShift) |
#define ComponentRangeMask(theMask) |
#define StdComponentCall(procName) |
#define ComponentCall(procName) |
#define ComponentSubTypeCall(procName) |
#define ComponentError(procName) |
#define StdComponentNoError(procName) |
#define ComponentNoError(procName) |
#define ComponentSubTypeNoError(procName) |
#define ComponentDelegate(procName) |
#define ComponentRangeUnused(rangeNum) \ |
{ 0, nil }, |
#define ComponentRangeBegin(rangeNum) \ |
{ cdh_GLUE2(cdhDispatchMax,rangeNum), cdh_GLUE2(cdhDispatchInfo,rangeNum) }, |
#define ComponentRangeEnd(rangeNum) |
// define the static range tables (max per range and point to dispatch tables) |
static CDHCONST cdhRangeDispatchInfoRecord cdhRangeDispatch[RangeCount+1] = { |
#include COMPONENT_DISPATCH_FILE |
}; |
ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo) |
{ |
//ProcInfoType pinfo = 0; |
ComponentFunctionUPP result = kCOMPONENT_DELEGATE; |
CDHCONST cdhDispatchInfoRecord *infoP = nil; |
short theRange; |
theRange = selector_num >> RangeShift; |
if (theRange < 0) { |
selector_num += SelOffset; |
if (selector_num >= 0) { |
infoP = &(cdhRangeDispatch[0].cdhDispatchInfoP)[selector_num]; |
} |
} else { |
if (theRange < RangeCount) { |
selector_num &= RangeMask; |
if (selector_num < cdhRangeDispatch[theRange+1].rangeMax) |
infoP = &(cdhRangeDispatch[theRange+1].cdhDispatchInfoP)[selector_num]; |
} |
} |
if (infoP) { |
*procInfo = infoP->theProcInfo; |
result = infoP->theProc; |
} |
return result; |
} |
#elif C_DISPATCH_WITH_SWITCH |
ComponentFunctionUPP COMPONENTSELECTORLOOKUP( short selector_num ) |
{ |
ComponentFunctionUPP aProc = (ComponentFunctionUPP) kCOMPONENT_DELEGATE; |
#define ComponentSelectorOffset(theOffset) |
#define case_ComponentCall(kPrefix,procName) case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)ADD_BASENAME(procName); break; |
#define StdComponentCall(procName) case_ComponentCall(kComponent,procName) |
#define ComponentCall(procName) case_ComponentCall(COMPONENT_SELECT_PREFIX(),procName) |
#define ComponentSubTypeCall(procName) case_ComponentCall(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName) |
#define case_ComponentNoError(kPrefix,procName) case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)kCOMPONENT_NOERROR; break; |
#define StdComponentNoError(procName) case_ComponentNoError(kComponent,procName) |
#define ComponentNoError(procName) case_ComponentNoError(COMPONENT_SELECT_PREFIX(),procName) |
#define ComponentSubTypeNoError(procName) case_ComponentNoError(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName) |
#define ComponentError(procName) //ComponentError for C_DISPATCH_WITH_SWITCH uses default case (delegate if we can) |
#define ComponentDelegate(procName) //The default case for C_DISPATCH_WITH_SWITCH is to delegate if we can, error if we can't |
#define ComponentRangeCount(theCount) |
#define ComponentRangeShift(theShift) |
#define ComponentRangeMask(theMask) |
#define ComponentRangeBegin(rangeNum) |
#define ComponentRangeEnd(rangeNum) |
#define ComponentRangeUnused(rangeNum) |
#define ComponentStorageType(theType) |
#define ComponentDelegateByteOffset(theOffset) |
#define ComponentComment(theComment) |
switch (selector_num) { |
#include COMPONENT_DISPATCH_FILE |
} |
return aProc; |
} |
#endif |
#ifdef OVERRIDE_CANDO |
ComponentResult OVERRIDE_CANDO( COMPONENT_GLOBALS(), short ftnNumber, ComponentResult result); |
#endif |
#ifndef TOUCH_UNUSED_ARG |
// a macro to avoid "unused variable" warnings |
#define TOUCH_UNUSED_ARG(arg) ((void)arg) |
#endif |
PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber ); |
PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber ) |
{ |
ComponentResult result; |
#if C_DISPATCH_WITH_GLOBALS |
ProcInfoType ignore; |
result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber, &ignore); |
#else |
result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber); |
#endif |
/* check for a ComponentError */ |
if ( result == (ComponentResult) kCOMPONENT_ERROR ) |
result = false; |
else if ( result == (ComponentResult) kCOMPONENT_DELEGATE ) |
result = false; |
else |
result = true; |
#ifdef GET_DELEGATE_COMPONENT |
/* if we're delegated, then keep looking */ |
if (!result) |
{ |
if (GET_DELEGATE_COMPONENT()) |
result = CallComponentCanDo( GET_DELEGATE_COMPONENT(), ftnNumber ); |
} |
#endif |
#ifdef OVERRIDE_CANDO |
result = OVERRIDE_CANDO( storage, ftnNumber, result); |
#else |
TOUCH_UNUSED_ARG(storage); |
#endif |
return result; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-04-21