home *** CD-ROM | disk | FTP | other *** search
- /*==================================================================
- File: MacOS_AppleEventUtils.cpp
-
- Contains: AppleEvent utility routines.
-
- Written by: Ed Reed
-
- Copyright: © 1999 Connectix Corporation
- ==================================================================*/
-
- #include "MacOS_AppleEventUtils.h"
-
- #include "MacOS_Exceptions.h"
- #include "MacOS_ConnectixUtils.h"
- #include "MacOS_Namespaces.h"
- #include "MacOS_UMemory.h"
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #ifndef __AEPACKOBJECT__
- #include <AEPackObject.h>
- #endif
-
- #ifndef __FINDERREGISTRY__
- #include <FinderRegistry.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
-
- CTX_Begin_Namespace_MacOS
-
-
- /*------------------------------------------------------------------
- ResolveAEParameterList [internal]
-
- This function resolves a list objects contained within in
- AEListDesc into a list of tokens representing the objects.
-
- Parameters:
- In: inList - the source list
- ioResolvedList - a NULL descriptor or a list
- descriptor to which the token
- descriptors will be added
- Out: ioResolvedList - the list of resolved token
- descriptors
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- static OSErr
- ResolveAEParameterList(
- const AEDescList * inList,
- AEDescList * ioResolvedList,
- SInt16 inFlags)
- {
- OSErr status = noErr;
-
- /*
- ** If ioResolvedList is not a list, create a list. (This should only happen
- ** the first time that this function is called to process a list of object
- ** specifiers.) By using one list during the recursive traversal of the
- ** object specifier list we flatten {obj1, {obj2, obj3}} into {tok1, tok2,
- ** tok3} where obj1, obj2 & obj3 are object specifiers and tok1, tok2 &
- ** tok3 are the corresponding object tokens.
- */
- if (ioResolvedList->descriptorType != typeAEList)
- {
- check (ioResolvedList->descriptorType == typeNull);
- status = ::AECreateList(NULL, 0L, false, ioResolvedList);
- check (status == noErr);
- }
-
- if (status == noErr)
- {
- AEDesc theItemDesc;
- SInt16 theIndex = 0;
- AEKeyword theKeyword;
-
- /*
- ** Resolve and add every item of inList to outResolvedList.
- ** (ResolveAEParameter will take care of adding the resolve object
- ** specifier to the list.)
- */
- while ((status = ::AEGetNthDesc(inList, ++theIndex,
- typeWildCard, &theKeyword, &theItemDesc)) == noErr)
- {
- status = CTX_MacOS::ResolveAEParameter(&theItemDesc, ioResolvedList, inFlags);
- ::AEDisposeDesc(&theItemDesc);
- if (status != noErr)
- break;
- }
- if (status == errAEDescNotFound)
- status = noErr;
- }
-
- return status;
- }
-
- /*------------------------------------------------------------------
- ResolveAEParameter
-
- This function resolves a an object contained within in
- AEDesc into a token representing the object.
-
- Parameters:
- In: inParam - the source descriptor
- ioResolvedParam - a NULL descriptor or a list
- descriptor to which the token
- descriptors will be added
- Out: ioResolvedParam - the [list of] resolved token
- descriptor
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- ResolveAEParameter(
- const AEDesc * inParam,
- AEDesc * ioResolvedParam,
- SInt16 inFlags)
- {
- OSErr status = noErr;
- AEDesc resolvedParam;
-
- /*
- ** If inParam is an object specifier, call AEResolve() to resolve it
- ** into the appropriate type. If ioResolvedParam is a list, add the
- ** resolved parameter to the list. Otherwise, just return the resolved
- ** parameter in ioResolvedParam.
- **
- ** If inParam is a list, call ResolveAEParamterList() to recursively
- ** resolve every item of the list.
- **
- ** If inParam is neither a list nor an object specifier, copy inParam
- ** to ioResovledParam.
- */
- switch (inParam->descriptorType)
- {
- case typeObjectSpecifier:
- status = ::AEResolve(inParam, inFlags, &resolvedParam);
- if (ioResolvedParam->descriptorType != typeAEList)
- *ioResolvedParam = resolvedParam;
- else
- {
- status = ::AEPutDesc(ioResolvedParam, 0, &resolvedParam);
- check (status == noErr);
- ::AEDisposeDesc(&resolvedParam);
- }
- break;
-
- case typeAEList:
- status = CTX_MacOS::ResolveAEParameterList(inParam, ioResolvedParam, inFlags);
- break;
-
- default:
- if (ioResolvedParam->descriptorType == typeAEList)
- status = ::AEPutDesc(ioResolvedParam, 0, inParam);
- else
- {
- check (ioResolvedParam->descriptorType == typeNull);
- status = ::AEDuplicateDesc(inParam, ioResolvedParam);
- }
- check (status == noErr);
- break;
- }
-
- return status;
- }
-
-
- /*------------------------------------------------------------------
- CheckRequiredParams
-
- This function checks for the missed keyword attribute and
- returns errAEParamMissed if it is present.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- Out: (return) - errAEParamMissed if missed keyword
- attribute is present; noErr otherwise
- ------------------------------------------------------------------*/
-
- OSErr
- CheckRequiredParams(
- const AppleEvent * inEvent)
- {
- DescType returnedType;
- long size;
-
- return (::AEGetAttributePtr(inEvent, keyMissedKeywordAttr,
- typeWildCard, &returnedType, NULL, 0, &size) == errAEDescNotFound)
- ? noErr
- : errAEParamMissed;
- }
-
-
- /*------------------------------------------------------------------
- GetAEErrorNumber
-
- This function checks for the error number attribute and returns
- the attribute's value if present. GetAEErrorNumber returns noErr
- if the error number attribute is not present.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- Out: (return) - value of error number attribute if it
- is present; noErr otherwise
- ------------------------------------------------------------------*/
-
- SInt32
- GetAEErrorNumber(
- const AppleEvent * inEvent)
- {
- DescType typeCode;
- Size actualSize;
- SInt32 theErrNumber = 0;
-
- ::AEGetKeyPtr(inEvent, keyErrorNumber, typeLongInteger, &typeCode,
- &theErrNumber, sizeof(theErrNumber), &actualSize);
- return theErrNumber;
- }
-
-
- /*------------------------------------------------------------------
- GetAEParameter
-
- This function returns the resolved descriptor of the specified
- parameter.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- inKeyword - parameter keyword
- Out: outParam - resolve parameter descriptor
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAEParameter(
- const AppleEvent * inEvent,
- AEKeyword inKeyword,
- AEDesc * outParam)
- {
- /*
- ** Retrieve the parameter specified by inKeyword from inEvent and resolve
- ** any object specifiers.
- */
- OSErr status;
- AEDesc theDesc;
-
- outParam->descriptorType = typeNull;
- outParam->dataHandle = NULL;
-
- status = ::AEGetParamDesc(inEvent, inKeyword, typeWildCard, &theDesc);
- if (status == noErr)
- {
- status = CTX_MacOS::ResolveAEParameter(&theDesc, outParam);
- ::AEDisposeDesc(&theDesc);
- }
-
- return status;
- }
-
- /*------------------------------------------------------------------
- GetAEBoolean
-
- This function returns the boolean value of the specified
- parameter.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- inKeyword - parameter keyword
- Out: outBoolean - boolean value of parameter
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAEBoolean(
- const AppleEvent * inEvent,
- AEKeyword inKeyword,
- Boolean * outBoolean)
- {
- OSErr status;
- DescType theTypeCode;
- Size theActualSize;
-
- status = ::AEGetParamPtr(inEvent, inKeyword, typeWildCard,
- &theTypeCode, NULL, 0L, &theActualSize);
- if (status == noErr)
- {
- *outBoolean = theTypeCode == typeTrue;
- }
- return status;
- }
-
-
- /*------------------------------------------------------------------
- GetAppleEventClassAndID
-
- This function returns AppleEvent class and event IDs.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- Out: outClass - the AppleEvent class
- outID - the AppleEvent event ID
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAppleEventClassAndID(
- const AppleEvent * inEvent,
- AEEventClass * outClass,
- AEEventID * outID)
- {
- OSErr status;
- DescType typeCode;
- Size actualSize;
-
- status = ::AEGetAttributePtr(inEvent, keyEventClassAttr,
- typeType, &typeCode, outClass, sizeof(AEEventClass), &actualSize);
- require (status == noErr, FailedToGetClass);
-
- status = ::AEGetAttributePtr(inEvent, keyEventIDAttr,
- typeType, &typeCode, outID, sizeof(AEEventID), &actualSize);
- require (status == noErr, FailedToGetEventID);
-
- FailedToGetEventID:
- FailedToGetClass:
- return status;
- }
-
- /*------------------------------------------------------------------
- Get1AEEventHandler
-
- This function returns AppleEvent handler from the specified
- handler table given the class and event IDs.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- inClass - the AppleEvent class
- inID - the AppleEvent event ID
- inSysHandler- if true, get the handler from the
- system table
- Out: outProc - the event handler UPP
- outRefCon - the event handler reference constant
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- Get1AEEventHandler(
- AEEventClass inClass,
- AEEventID inID,
- AEEventHandlerUPP * outProc,
- UInt32 * outRefCon,
- Boolean inSysHandler)
- {
- OSErr status;
-
- if ((status = ::AEGetEventHandler(inClass, inID,
- outProc, (SInt32*) outRefCon, inSysHandler)) != noErr)
- {
- if ((status = ::AEGetEventHandler(typeWildCard, inID,
- outProc, (SInt32*) outRefCon, inSysHandler)) != noErr)
- {
- if ((status = ::AEGetEventHandler(inClass, typeWildCard,
- outProc, (SInt32*) outRefCon, inSysHandler)) != noErr)
- {
- status = ::AEGetEventHandler(typeWildCard, typeWildCard,
- outProc, (SInt32*) outRefCon, inSysHandler);
- }
- }
- }
- return status;
- }
-
- /*------------------------------------------------------------------
- GetAEEventHandler
-
- This function returns an AppleEvent handler given the class and
- event IDs. If a handler has not been installed in the
- application handler table, then the system handler table will be
- searched.
-
- Parameter:
- In: inEvent - AppleEvent descriptor
- inClass - the AppleEvent class
- inID - the AppleEvent event ID
- Out: outProc - the event handler UPP
- outRefCon - the event handler reference constant
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAEEventHandler(
- AEEventClass inClass,
- AEEventID inID,
- AEEventHandlerUPP * outProc,
- UInt32 * outRefCon)
- {
- OSErr status;
-
- if ((status = CTX_MacOS::Get1AEEventHandler(inClass, inID, outProc, outRefCon, false)) != noErr)
- status = CTX_MacOS::Get1AEEventHandler(inClass, inID, outProc, outRefCon, true);
-
- return status;
- }
-
-
- /*------------------------------------------------------------------
- Call1AEEventHandler
-
- This function searches for and calls the handler for the given
- AppleEvent class and event ID. Only the system or application
- handler table is searched.
-
- Parameter:
- In: inClass - the AppleEvent class
- inID - the AppleEvent event ID
- inEvent - AppleEvent descriptor
- ioReply - a NULL descriptor indicates no reply
- is desired; otherwise this should
- point to a kAEAnswer AppleEvent
- inSysHandler- if true, get the handler from the
- system table
- Out: ioReply - the reply from the event handler
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- Call1AEEventHandler(
- AEEventClass inClass,
- AEEventID inID,
- const AppleEvent * inEvent,
- AppleEvent * ioReply,
- Boolean inSysHandler)
- {
- OSErr status;
-
- AEEventHandlerUPP handlerUPP;
- UInt32 handlerRefCon;
-
- status = CTX_MacOS::Get1AEEventHandler(inClass, inID, &handlerUPP, &handlerRefCon, inSysHandler);
- if (status == noErr)
- {
- status = InvokeAEEventHandlerUPP(inEvent, ioReply, handlerRefCon, handlerUPP);
- }
- return status;
- }
-
-
- /*------------------------------------------------------------------
- CallAEEventHandler
-
- This function searches for and calls the handler for the given
- AppleEvent class and event ID. If the handler is not found in
- the application handler table, the system handler table is
- searched.
-
- Parameter:
- In: inClass - the AppleEvent class
- inID - the AppleEvent event ID
- inEvent - AppleEvent descriptor
- ioReply - a NULL descriptor indicates no reply
- is desired; otherwise this should
- point to a kAEAnswer AppleEvent
- Out: ioReply - the reply from the event handler
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CallAEEventHandler(
- AEEventClass inClass,
- AEEventID inID,
- const AppleEvent * inEvent,
- AppleEvent * ioReply)
- {
- OSErr status;
-
- status = CTX_MacOS::Call1AEEventHandler(inClass, inID, inEvent, ioReply, false);
- if (status == errAEHandlerNotFound || status == errAEEventNotHandled)
- status = CTX_MacOS::Call1AEEventHandler(inClass, inID, inEvent, ioReply, true);
- return status;
- }
-
-
- /*------------------------------------------------------------------
- CopyAppleEventParameters
-
- This function copies the parameters from one AppleEvent to
- another.
-
- Parameter:
- In: inOriginal - the source AppleEvent
- Out: outCopy - the newly created AppleEvent
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CopyAppleEventParameters(
- const AppleEvent * inOriginal,
- AppleEvent * outCopy)
- {
- OSErr status;
- AEDesc theDesc;
- AEKeyword theKeyword;
- SInt16 index = 1;
-
- while ((status = ::AEGetNthDesc(inOriginal, index++,
- typeWildCard, &theKeyword, &theDesc)) == noErr)
- {
- status = ::AEPutParamDesc(outCopy, theKeyword, &theDesc);
- check (status == noErr);
- ::AEDisposeDesc(&theDesc);
- if (status != noErr)
- break;
- }
- if (status == errAEDescNotFound)
- status = noErr;
-
- return noErr;
- }
-
- /*------------------------------------------------------------------
- CreateNamedObjectSpecifier
-
- This function creates an object specifier using the name key
- form.
-
- Parameter:
- In: inDesiredClass - the class of the object
- inContainer - the object container descriptor
- inName - the name of the object
- Out: outSpecifier - an object specifier of formName
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreateNamedObjectSpecifier(
- DescType inDesiredClass,
- const AEDesc * inContainer,
- ConstStr255Param inName,
- AEDesc * outSpecifier)
- {
- OSErr status;
- AEDesc theNameKeyDesc;
-
- status = ::AECreateDesc(typeChar, inName + 1, StrLength(inName), &theNameKeyDesc);
- require (status == noErr, FailedToCreateNameDesc);
-
- status = ::CreateObjSpecifier(inDesiredClass,
- (AEDesc*) inContainer, formName, &theNameKeyDesc, false, outSpecifier);
- check (status == noErr);
-
- ::AEDisposeDesc(&theNameKeyDesc);
-
- FailedToCreateNameDesc:
- return status;
- }
-
- /*------------------------------------------------------------------
- CreateIndexObjectSpecifier
-
- This function creates an object specifier using the absolute
- position key form.
-
- Parameter:
- In: inDesiredClass - the class of the object
- inContainer - the object container descriptor
- inIndex - the index of the object
- Out: outSpecifier - an object specifier of formAbsolutePosition
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreateIndexObjectSpecifier(
- DescType inDesiredClass,
- const AEDesc * inContainer,
- SInt32 inIndex,
- AEDesc * outSpecifier)
- {
- OSErr status;
- AEDesc theIndexKeyDesc;
-
- status = ::AECreateDesc(typeSInt32, &inIndex, sizeof(inIndex), &theIndexKeyDesc);
- require (status == noErr, FailedToCreateNameDesc);
-
- status = ::CreateObjSpecifier(inDesiredClass,
- (AEDesc*) inContainer, formAbsolutePosition, &theIndexKeyDesc, false, outSpecifier);
- check (status == noErr);
-
- ::AEDisposeDesc(&theIndexKeyDesc);
-
- FailedToCreateNameDesc:
- return status;
- }
-
- /*------------------------------------------------------------------
- CreateUniqueIDObjectSpecifier
-
- This function creates an object specifier using the unique ID
- key form.
-
- Parameter:
- In: inDesiredClass - the class of the object
- inContainer - the object container descriptor
- inUniqueID - the unique ID of the object
- Out: outSpecifier - an object specifier of formName
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreateUniqueIDObjectSpecifier(
- DescType inDesiredClass,
- const AEDesc * inContainer,
- SInt32 inUniqueID,
- AEDesc * outSpecifier)
- {
- OSErr status;
- AEDesc theUniqueIDKeyDesc;
-
- status = ::AECreateDesc(typeSInt32, &inUniqueID, sizeof(inUniqueID), &theUniqueIDKeyDesc);
- require (status == noErr, FailedToCreateUniqueIDDesc);
-
- status = ::CreateObjSpecifier(inDesiredClass,
- (AEDesc*) inContainer, formUniqueID, &theUniqueIDKeyDesc, false, outSpecifier);
- check (status == noErr);
-
- ::AEDisposeDesc(&theUniqueIDKeyDesc);
-
- FailedToCreateUniqueIDDesc:
- return status;
- }
-
- /*------------------------------------------------------------------
- FSMakeFSSpecAndGetInfo [internal]
-
- This function creates a file system specification record and
- returns a boolean value indicating if this item is a directory.
-
- Parameter:
- In: inVRefNum - the volume reference number
- inParID - the item's parent directory ID
- inName - the item's name
- Out: outSpec - the file system specification record
- outIsFolder - if true, the item is a folder
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- static OSErr
- FSMakeFSSpecAndGetInfo(
- SInt16 inVRefNum,
- SInt32 inParID,
- ConstStr255Param inName,
- FSSpec * outSpec,
- Boolean * outIsFolder)
- {
- CInfoPBRec catInfo;
- OSErr status;
-
- if ((status = ::MakeFSSpec(inVRefNum, inParID, inName, outSpec)) == noErr
- && (status = ::FSpGetCatInfo(outSpec, &catInfo)) == noErr)
- {
- *outIsFolder = (catInfo.hFileInfo.ioFlAttrib&ioDirMask) != 0;
- }
- return status;
- }
-
- /*------------------------------------------------------------------
- CreateFSSpecObjectSpecifier
-
- This function creates an object specifier for the specified file
- system object.
-
- Parameter:
- In: inDesiredClass - the class of the object or
- typeWildcard
- inContainer - the object container descriptor
- inFSSpec - the FSSpec of the object
- Out: outSpecifier - an object specifier of formName
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreateFSSpecObjectSpecifier(
- DescType inDesiredClass,
- const AEDesc * inContainer,
- const FSSpec * inFSSpec,
- AEDesc * outSpecifier)
- {
- OSErr status;
-
- if (inFSSpec->parID == fsRtParID)
- {
- status = CTX_MacOS::CreateNamedObjectSpecifier(
- inDesiredClass == typeWildCard
- ? cDisk
- : inDesiredClass,
- inContainer,
- inFSSpec->name,
- outSpecifier);
- }
- else
- {
- FSSpec theParentSpec;
- AEDesc theParentDesc;
- Boolean isFolder;
-
- *theParentSpec.name = 0;
- status = CTX_MacOS::FSMakeFSSpecAndGetInfo(inFSSpec->vRefNum,
- inFSSpec->parID,
- theParentSpec.name,
- &theParentSpec,
- &isFolder);
- require (status == noErr, FailedToCreateParentFSSpec);
-
- status = CTX_MacOS::CreateFSSpecObjectSpecifier(
- theParentSpec.parID != fsRtParID ? cFolder : cDisk,
- inContainer,
- &theParentSpec,
- &theParentDesc);
- require (status == noErr, FailedToCreateParentDesc);
-
- status = CTX_MacOS::CreateNamedObjectSpecifier(
- inDesiredClass == typeWildCard
- ? (isFolder
- ? cFolder
- : cFile)
- : inDesiredClass,
- &theParentDesc, inFSSpec->name, outSpecifier);
-
- ::AEDisposeDesc(&theParentDesc);
-
- FailedToCreateParentDesc:
- FailedToCreateParentFSSpec:
- ;
- }
- return status;
- }
-
- /*------------------------------------------------------------------
- CreatePropertyObjectSpecifier
-
- This function creates an object specifier for the specified
- property.
-
- Parameter:
- In: inDesiredClass - the class of the object
- inContainer - the object container descriptor
- inPropertyType - the property ID
- Out: outSpecifier - an object specifier of
- formPropertyID
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreatePropertyObjectSpecifier(
- DescType inDesiredClass,
- const AEDesc * inContainer,
- DescType inPropertyType,
- AEDesc * outSpecifier)
- {
- OSErr status;
- AEDesc thePropertyKeyDesc;
-
- status = ::AECreateDesc(typeType, &inPropertyType,
- sizeof(inPropertyType), &thePropertyKeyDesc);
- require (status == noErr, FailedToCreatePropertyDesc);
-
- status = ::CreateObjSpecifier(inDesiredClass,
- (AEDesc*) inContainer, formPropertyID, &thePropertyKeyDesc, false, outSpecifier);
- check (status == noErr);
- ::AEDisposeDesc(&thePropertyKeyDesc);
-
- FailedToCreatePropertyDesc:
- return status;
- }
-
-
- /*------------------------------------------------------------------
- AECreateHandleDesc
-
- This function creates an AEDesc of the specified type from the
- data in a handle.
-
- Parameter:
- In: inType - the type of descriptor
- inData - the descriptor data in a handle
- Out: outDesc - the resulting descriptor
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- AECreateHandleDesc(
- DescType inType,
- const Handle inData,
- AEDesc * outDesc)
- {
- OSErr status;
- char hState;
-
- hState = ::HGetState(inData);
- HLock(inData);
-
- status = ::AECreateDesc(inType, *inData, GetHandleSize(inData), outDesc);
- check (status == noErr);
-
- ::HSetState(inData, hState);
-
- return status;
- }
-
- /*------------------------------------------------------------------
- CreateAliasDescriptorFromFSSpec
-
- This function creates an alias descriptor given a file system
- specification record.
-
- Parameter:
- In: inFSSpec - the target file system object
- Out: outDesc - an alias descriptor
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CreateAliasDescriptorFromFSSpec(
- const FSSpec * inFSSpec,
- AEDesc * outDesc)
- {
- AliasHandle alias;
- OSErr status;
-
- status = ::NewAliasMinimal(inFSSpec, &alias);
- require (status == noErr, NewAliasMinimalFailed);
-
- status = CTX_MacOS::CreateAliasDescriptorFromAlias(alias, outDesc);
- require (status == noErr, CreateAliasDescriptorFailed);
-
- return noErr;
-
- CreateAliasDescriptorFailed:
- ::DisposeHandle(reinterpret_cast<Handle>(alias));
-
- NewAliasMinimalFailed:
- return status;
- }
-
-
- /*------------------------------------------------------------------
- CoerceDescList [internal]
-
- This function coerces every element of a list to the specfied
- type.
-
- Parameter:
- In: inDescList - the list of objects
- inDesiredType - the type to which to coerce
- Out: outResult - the list of coerced objects
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- static OSErr
- CoerceDescList(
- const AEDesc * inDescList,
- DescType inDesiredType,
- AEDesc * outResult)
- {
- OSErr status = noErr;
- AEDesc theDesc;
- SInt16 theIndex = 1;
- AEKeyword theKeyword;
-
- status = ::AECreateList(NULL, 0L, false, outResult);
- require (status == noErr, FailedToCreateList);
-
- while ((status = ::AEGetNthDesc(inDescList, theIndex++,
- typeWildCard, &theKeyword, &theDesc)) == noErr)
- {
- AEDesc theCoercedDesc = { typeNull, NULL };
-
- status = CTX_MacOS::CoerceDesc(&theDesc, inDesiredType, &theCoercedDesc);
- ::AEDisposeDesc(&theDesc);
- if (status != noErr)
- break;
-
- status = ::AEPutDesc(outResult, 0, &theCoercedDesc);
- check (status == noErr);
- ::AEDisposeDesc(&theCoercedDesc);
- if (status != noErr)
- break;
- }
- if (status == errAEDescNotFound)
- status = noErr;
- else if (status != noErr)
- AEDisposeDesc(outResult);
-
- FailedToCreateList:
- return status;
- }
-
- /*------------------------------------------------------------------
- CoerceDesc
-
- This function coerce the specified descriptor to the specfied
- type. If the initial coercion fails and the descriptor is list,
- the function coerces each item of the list.
-
- Parameter:
- In: inDesc - the descriptor to coerce
- inDesiredType - the type to which to coerce
- Out: outResult - the coerced object or list of
- coerced objects
- (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- CoerceDesc(
- const AEDesc * inDesc,
- DescType inDesiredType,
- AEDesc * outResult)
- {
- OSErr status;
-
- status = ::AECoerceDesc(inDesc, inDesiredType, outResult);
- if (status == errAECoercionFail)
- {
- if (inDesc->descriptorType == typeAEList)
- status = CTX_MacOS::CoerceDescList(inDesc, inDesiredType, outResult);
- }
- check (status == noErr);
-
- return status;
- }
-
- /*------------------------------------------------------------------
- CompareDescs
-
- This function compares two blocks of bytes. If the first block
- is greater than the second, the result is positive. If the
- converse is true. the result is negative. If the blocks are
- equal, the result is zero.
-
- Parameters:
- In: inSource - the source descriptor
- inDest - the destination descriptor
- Out: outResult - positive if 1st > 2nd;
- negative if 1st < 2nd;
- zero if equal
- (return) - non-zero if descs are not
- comparable; noErr otherwise
- ------------------------------------------------------------------*/
-
- OSErr
- CompareDescs(
- const AEDesc * inSource,
- const AEDesc * inDest,
- SInt32 * outResult)
- {
- OSErr status = noErr;
- AEKeyword keyword;
-
- // If the descriptor types are not the same, first attempt to coerce
- // the destination descriptor to the source descriptor type and then
- // compare the two descriptors. If this coercion fails attempt to
- // coerce the source descriptor to the destination descriptor type
- // and then compare the two descriptors. We do this because many
- // coercions are unidirectional. E.g. typeBoolean --> typeTrue only
- // if the boolean value is 1; typeTrue --> typeBoolean always succeeds.
- if (inSource->descriptorType != inDest->descriptorType)
- {
- AEDesc coercedDesc = {typeNull, NULL};
-
- status = ::AECoerceDesc(inDest, inSource->descriptorType, &coercedDesc);
- if (status == noErr)
- status = CTX_MacOS::CompareDescs(inSource, &coercedDesc, outResult);
- else
- {
- require (status == errAECoercionFail, FatalError);
-
- status = ::AECoerceDesc(inSource, inDest->descriptorType, &coercedDesc);
- if (status == noErr)
- status = CTX_MacOS::CompareDescs(&coercedDesc, inDest, outResult);
- else
- {
- require (status == errAECoercionFail, FatalError);
-
- // Since we can't coerce descriptors typeTrue <==> typeFalse
- // but we can make a valid comparison with these two, special
- // case the comparison here.
- if ((inSource->descriptorType == typeTrue || inSource->descriptorType == typeFalse)
- && (inDest->descriptorType == typeTrue || inDest->descriptorType == typeFalse))
- {
- // Always false because we can only get here if the descriptor
- // types are not equal to begin with.
- *outResult = false;
- status = noErr;
- }
- }
- }
-
- ::AEDisposeDesc(&coercedDesc);
- }
- else
- {
- switch (inSource->descriptorType)
- {
- case typeAEList:
- {
- SInt32 sourceCount;
- SInt32 destCount;
- SInt32 count;
-
- status = ::AECountItems(inSource, &sourceCount);
- require (status == noErr, CantGetItemCount);
- status = ::AECountItems(inDest, &destCount);
- require (status == noErr, CantGetItemCount);
-
- count = ::Min32(sourceCount, destCount);
- for (SInt32 index = 1; index <= count; index++)
- {
- AEDesc sourceItem;
- AEDesc destItem;
-
- status = ::AEGetNthDesc(inSource, index, typeWildCard, &keyword, &sourceItem);
- require (status == noErr, CantGetItemDesc);
-
- status = ::AEGetNthDesc(inSource, index, typeWildCard, &keyword, &destItem);
- require_action (status == noErr, CantGetItemDesc, ::AEDisposeDesc(&sourceItem););
-
- status = CTX_MacOS::CompareDescs(&sourceItem, &destItem, outResult);
- ::AEDisposeDesc(&sourceItem);
- ::AEDisposeDesc(&destItem);
- require (status == noErr, CantCompareItemDescs);
- if (*outResult != 0)
- break;
- }
- if (*outResult == 0)
- *outResult = sourceCount - destCount;
-
- CantCompareItemDescs:
- CantGetItemDesc:
- CantGetItemCount:
- break;
- }
-
- case typeAERecord:
- {
- SInt32 sourceKeys;
- SInt32 destKeys;
- SInt32 count;
-
- status = ::AECountItems(inSource, &sourceKeys);
- require (status == noErr, CantGetKeyCount);
- status = ::AECountItems(inDest, &destKeys);
- require (status == noErr, CantGetKeyCount);
-
- count = ::Min32(sourceKeys, destKeys);
- for (SInt32 index = 1; index <= count; index++)
- {
- AEDesc sourceKey;
- AEDesc destKey;
-
- status = ::AEGetNthDesc(inSource, index, typeWildCard, &keyword, &sourceKey);
- require (status == noErr, CantGetKeyDesc);
-
- status = ::AEGetKeyDesc(inDest, keyword, typeWildCard, &destKey);
- require_action (status == noErr, CantGetKeyDesc, ::AEDisposeDesc(&sourceKey););
-
- status = CTX_MacOS::CompareDescs(&sourceKey, &destKey, outResult);
- ::AEDisposeDesc(&sourceKey);
- ::AEDisposeDesc(&destKey);
- require (status == noErr, CantCompareKeyDescs);
- if (*outResult != 0)
- break;
- }
- if (*outResult == 0)
- *outResult = sourceKeys - destKeys;
-
- CantCompareKeyDescs:
- CantGetKeyDesc:
- CantGetKeyCount:
- break;
- }
-
- default:
- {
- // If the data handles are both NULL, compare the descriptor types
- if (inSource->dataHandle == NULL && inDest->dataHandle == NULL)
- {
- // Always true because we can only get here if the types are equal
- *outResult = true;
- }
- else
- {
- StHandleDisposer source(::NewHandle(0));
- StHandleDisposer dest(::NewHandle(0));
-
- require_action(inSource->dataHandle != NULL, FatalError, status = errAENotAEDesc;);
- require_action(inDest->dataHandle != NULL, FatalError, status = errAENotAEDesc;);
-
- CTX_MacOS::GetAEDescData(*inSource, source);
- CTX_MacOS::GetAEDescData(*inDest, dest);
-
- StHandleLocker lockSource(source);
- StHandleLocker lockDest(dest);
-
- *outResult = ::CompareBytes(*source, *dest,
- ::Min32(::GetHandleSize(source), ::GetHandleSize(dest)));
- if (*outResult == 0)
- *outResult = ::GetHandleSize(source) - ::GetHandleSize(dest);
- }
- break;
- }
- }
- }
-
- FatalError:
- return status;
- }
-
- /*------------------------------------------------------------------
- AEStartsWith
-
- This function determines if the source descriptor starts with
- the destination descriptor.
-
- Parameters:
- In: inSource - the source descriptor
- inDest - the destination descriptor
- Out: outResult - positive if 1st > 2nd;
- negative if 1st < 2nd;
- zero if equal
- (return) - non-zero if descs are not
- comparable; noErr otherwise
- ------------------------------------------------------------------*/
-
- OSErr
- AEStartsWith(
- const AEDesc * inSource,
- const AEDesc * inDest,
- Boolean * outResult)
- {
- OSErr status = noErr;
- AEKeyword keyword;
- SInt32 comparisonResult;
-
- *outResult = false;
-
- switch (inSource->descriptorType)
- {
- case typeAEList:
- {
- AEDesc sourceItem;
-
- status = ::AEGetNthDesc(inSource, 1, typeWildCard, &keyword, &sourceItem);
- require (status == noErr, CantGetItemDesc);
-
- status = CTX_MacOS::CompareDescs(&sourceItem, inDest, &comparisonResult);
- ::AEDisposeDesc(&sourceItem);
- require (status == noErr, CantCompareItemDescs);
-
- *outResult = comparisonResult == 0;
-
- CantCompareItemDescs:
- CantGetItemDesc:
- break;
- }
- break;
-
- case typeChar:
- {
- StHandleDisposer source(::NewHandle(0));
- StHandleDisposer dest(::NewHandle(0));
-
- require_action (inSource->descriptorType == inDest->descriptorType, CantCompareDescs, status = errAEEventNotHandled;);
-
- CTX_MacOS::GetAEDescData(*inSource, source);
- CTX_MacOS::GetAEDescData(*inDest, dest);
-
- if (::GetHandleSize(dest) <= ::GetHandleSize(source))
- {
- StHandleLocker lockSource(source);
- StHandleLocker lockDest(dest);
-
- comparisonResult = ::CompareBytes(*source, *dest, ::GetHandleSize(dest));
- *outResult = comparisonResult == 0;
- }
-
- CantCompareDescs:
- break;
- }
-
- default:
- debug_unexpected_value();
- status = errAEEventNotHandled;
- break;
- }
-
- return status;
- }
-
- /*------------------------------------------------------------------
- AEStartsWith
-
- This function determines if the source descriptor ends with
- the destination descriptor.
-
- Parameters:
- In: inSource - the source descriptor
- inDest - the destination descriptor
- Out: outResult - positive if 1st > 2nd;
- negative if 1st < 2nd;
- zero if equal
- (return) - non-zero if descs are not
- comparable; noErr otherwise
- ------------------------------------------------------------------*/
-
- OSErr
- AEEndsWith(
- const AEDesc * inSource,
- const AEDesc * inDest,
- Boolean * outResult)
- {
- OSErr status = noErr;
- AEKeyword keyword;
- SInt32 comparisonResult;
-
- *outResult = false;
-
- switch (inSource->descriptorType)
- {
- case typeAEList:
- {
- AEDesc sourceItem;
- SInt32 sourceCount;
-
- status = ::AECountItems(inSource, &sourceCount);
- require (status == noErr, CantGetItemCount);
-
- status = ::AEGetNthDesc(inSource, sourceCount, typeWildCard, &keyword, &sourceItem);
- require (status == noErr, CantGetItemDesc);
-
- status = CTX_MacOS::CompareDescs(&sourceItem, inDest, &comparisonResult);
- ::AEDisposeDesc(&sourceItem);
- require (status == noErr, CantCompareItemDescs);
-
- *outResult = comparisonResult == 0;
-
- CantCompareItemDescs:
- CantGetItemDesc:
- CantGetItemCount:
- break;
- }
-
- case typeChar:
- {
- StHandleDisposer source(::NewHandle(0));
- StHandleDisposer dest(::NewHandle(0));
-
- require_action (inSource->descriptorType == inDest->descriptorType, CantCompareDescs, status = errAEEventNotHandled;);
-
- if (CTX_MacOS::GetAEDescDataSize(*inDest) <= CTX_MacOS::GetAEDescDataSize(*inSource))
- {
- CTX_MacOS::GetAEDescData(*inSource, source);
- CTX_MacOS::GetAEDescData(*inDest, dest);
-
- *outResult = ::BytesMatch(source + (::GetHandleSize(source) - ::GetHandleSize(dest)),
- dest, ::GetHandleSize(dest));
- }
-
- CantCompareDescs:
- break;
- }
- break;
-
- default:
- debug_unexpected_value();
- status = errAEEventNotHandled;
- break;
- }
-
- return status;
- }
-
- /*------------------------------------------------------------------
- AEContains
-
- This function determines if the source descriptor contains with
- the destination descriptor.
-
- Parameters:
- In: inSource - the source descriptor
- inDest - the destination descriptor
- Out: outResult - positive if 1st > 2nd;
- negative if 1st < 2nd;
- zero if equal
- (return) - non-zero if descs are not
- comparable; noErr otherwise
- ------------------------------------------------------------------*/
-
- OSErr
- AEContains(
- const AEDesc * inSource,
- const AEDesc * inDest,
- Boolean * outResult)
- {
- OSErr status = noErr;
- AEKeyword keyword;
- SInt32 comparisonResult;
-
- *outResult = false;
-
- switch (inSource->descriptorType)
- {
- case typeAEList:
- {
- SInt32 sourceCount;
-
- status = ::AECountItems(inSource, &sourceCount);
- require (status == noErr, CantGetItemCount);
-
- for (SInt32 index = 1; index <= sourceCount; index++)
- {
- AEDesc sourceItem;
-
- status = ::AEGetNthDesc(inSource, index, typeWildCard, &keyword, &sourceItem);
- require (status == noErr, CantGetItemDesc);
-
- status = CTX_MacOS::CompareDescs(&sourceItem, inDest, &comparisonResult);
- ::AEDisposeDesc(&sourceItem);
- require (status == noErr, CantCompareItemDescs);
-
- *outResult = comparisonResult == 0;
- if (*outResult)
- break;
- }
-
- CantCompareItemDescs:
- CantGetItemDesc:
- CantGetItemCount:
- break;
- }
-
- case typeChar:
- {
- StHandleDisposer source;
- StHandleDisposer dest;
-
- require_action (inSource->descriptorType == inDest->descriptorType, CantCompareDescs, status = errAEEventNotHandled;);
-
- if (CTX_MacOS::GetAEDescDataSize(*inDest) <= CTX_MacOS::GetAEDescDataSize(*inSource))
- {
- SInt32 count = CTX_MacOS::GetAEDescDataSize(*inSource) - CTX_MacOS::GetAEDescDataSize(*inDest);
-
- CTX_MacOS::GetAEDescData(*inSource, source);
- CTX_MacOS::GetAEDescData(*inDest, dest);
-
- for (SInt32 offset = 0; offset <= count; offset++)
- {
- *outResult = ::BytesMatch(source + offset, dest, ::GetHandleSize(dest));
- if (*outResult)
- break;
- }
- }
-
- CantCompareDescs:
- break;
- }
- break;
-
- default:
- debug_unexpected_value();
- status = errAEEventNotHandled;
- break;
- }
-
- return status;
- }
-
- /*------------------------------------------------------------------
- SetReplyError
-
- This function sets the keyErrorNumber and keyErrorString keyword
- values in the specified Apple Event reply.
-
- Parameters:
- In: inReply - a reply Apple Event
- inErrorNumber - the error number
- inErrorStrID - the error message STR# or STR ID
- inErrorIndex - the error index (0 if resource is
- a STR resource)
- Out: (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- SetReplyError(
- AppleEvent * inReply,
- SInt32 inErrorNumber,
- SInt16 inErrorStrID,
- SInt16 inErrorIndex)
- {
- Str255 message;
-
- if (inErrorIndex != 0)
- ::GetIndString(message, inErrorStrID, inErrorIndex);
- else
- {
- Handle resource = ::GetResource('STR ', inErrorStrID);
- if (resource == NULL)
- {
- message[0] = 0;
- }
- else
- {
- ::BlockMoveData(*resource, message, StrLength(reinterpret_cast<StringPtr>(*resource)) + 1);
- ::ReleaseResource(resource);
- }
- }
-
- return SetReplyError(inReply, inErrorNumber, message);
- }
-
- /*------------------------------------------------------------------
- SetReplyError
-
- This function sets the keyErrorNumber and keyErrorString keyword
- values in the specified Apple Event reply.
-
- Parameters:
- In: inReply - a reply Apple Event
- inErrorNumber - the error number
- inErrorStr - the error string
- Out: (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- SetReplyError(
- AppleEvent * inReply,
- SInt32 inErrorNumber,
- ConstStr255Param inErrorStr)
- {
- OSErr status;
-
- status = ::AEPutKeyPtr(inReply, keyErrorNumber, typeSInt32, &inErrorNumber, sizeof(inErrorNumber));
- require (status == noErr, FatalError);
-
- if (StrLength(inErrorStr) != 0)
- {
- status = ::AEPutKeyPtr(inReply, keyErrorString, typeChar, &inErrorStr[1], StrLength(inErrorStr));
- require (status == noErr, FatalError);
- }
-
- FatalError:
- return status;
- }
-
-
- /*------------------------------------------------------------------
- GetAEDescData
-
- This function retrieves the data from an AEDesc (the dataHandle
- pre-Carbon). The caller must pass in a valid handle, which will
- be resized as necessary.
-
- Parameters:
- In: inDesc - an AEDesc
- ioData - the data buffer
- Out: (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAEDescData(
- const AEDesc & inDesc,
- Handle ioData)
- {
- ::SetHandleSize(ioData, CTX_MacOS::GetAEDescDataSize(inDesc));
- return CTX_MacOS::GetAEDescData(inDesc, *ioData, ::GetHandleSize(ioData));
- }
-
-
- /*------------------------------------------------------------------
- GetAEDescData
-
- This function retrieves the data from an AEDesc (the dataHandle
- pre-Carbon). The caller must pass in the data buffer and its
- size.
-
- Parameters:
- In: inDesc - an AEDesc
- outData - the data buffer
- inSize - the data size
- Out: (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- GetAEDescData(
- const AEDesc & inDesc,
- void * outData,
- UInt32 inSize)
- {
- if (inDesc.dataHandle == NULL || outData == NULL)
- return paramErr;
-
- #if TARGET_API_MAC_CARBON
- return ::AEGetDescData(&inDesc, outData, UMin32(inSize, ::AEGetDescDataSize(&inDesc)));
- #else
- ::BlockMoveData(*(inDesc.dataHandle), outData, UMin32(inSize, ::GetHandleSize(inDesc.dataHandle)));
- return noErr;
- #endif
- }
-
-
- /*------------------------------------------------------------------
- SetAEDescData
-
- This function replaces the data in an AEDesc (the dataHandle
- pre-Carbon).
-
- Parameters:
- In: descriptor - an AEDesc
- type - the data type
- data - the data buffer
- datasize - the data size
- Out: (return) - non-zero indicates an error
- ------------------------------------------------------------------*/
-
- OSErr
- SetAEDescData(
- AEDesc & ioDesc,
- DescType inType,
- const void * inData,
- UInt32 inSize)
- {
- #if TARGET_API_MAC_CARBON
- return ::AEReplaceDescData(inType, inData, inSize, &ioDesc);
- #else
- ioDesc.descriptorType = inType;
- ::SetHandleSize(ioDesc.dataHandle, inSize);
- ::BlockMoveData(inData, *(ioDesc.dataHandle), inSize);
- return noErr;
- #endif
- }
-
-
- CTX_End_Namespace_MacOS
-
-
- /*==================================================================
- Change History (most recent first):
-
- $Log: MacOS_AppleEventUtils.cpp,v $
- ==================================================================*/
-