Sources/MSAEUtils.c

// MSAEUtils.c
//
// Original version by Jon Lansdell and Nigel Humphreys.
// 4.0 and 3.1 updates by Greg Sutton.
// ©Apple Computer Inc 1996, all rights reserved.
 
#pragma segment Main
 
#include "MSAEUtils.h"
 
#include "MSUtils.h"
#include "MSWindow.h"
 
#include "MSAERecording.h"
 
#include <AERegistry.h>
#include <AEObjects.h>
 
 
// -----------------------------------------------------------------------
//  Utility Routines for getting data from AEDesc's
// -----------------------------------------------------------------------
    
void    GetRawDataFromDescriptor(const AEDesc *theDesc, Ptr destPtr,
                                        Size destMaxSize, Size *actSize)
{
    Size copySize;
    
    if (theDesc->dataHandle) 
    {
        HLock((Handle)theDesc->dataHandle);
        *actSize = GetHandleSize((Handle)theDesc->dataHandle);
        
        copySize = LesserOf(*actSize, destMaxSize);
        
        BlockMove(*theDesc->dataHandle, destPtr, copySize);
        
        HUnlock((Handle)theDesc->dataHandle);
    }
    else
        *actSize = 0;
} // GetRawDataFromDescriptor
 
 
OSErr   GetPStringFromDescriptor(const AEDesc *aDesc, StringPtr resultStr)
{
    Size         stringSize;
    AEDesc       resultDesc = {typeNull, NULL};
    OSErr        err;
    
    err = AECoerceDesc(aDesc, typeChar, &resultDesc);
    if (noErr != err) goto done;
    
    resultStr[0] = 0;
    
    GetRawDataFromDescriptor(&resultDesc, (Ptr)&resultStr[1], 255, &stringSize);
    if (stringSize <= 255) 
        resultStr[0] = stringSize;
    else
        err = errAECoercionFail;
 
done:       
    (void)AEDisposeDesc(&resultDesc);
        
    return(err);
}
    
 
OSErr   PutPStringToDescriptor(AEDesc* aDesc, StringPtr pStr)
{
    OSErr        err;
    
    if (! aDesc || ! pStr)
        return(errAETypeError);
 
    err = AECreateDesc(typeChar, (Ptr)&pStr[1], pStr[0], aDesc);
        
    return(err);
}
 
 
OSErr   GetIntegerFromDescriptor(const AEDesc *sourceDesc, short *result)
{
    OSErr   myErr;
    OSErr   ignoreErr;
    Size    intSize;
    AEDesc  resultDesc;
    
    *result = 0;
    myErr = AECoerceDesc( sourceDesc, typeShortInteger, &resultDesc );
    
    if ( myErr == noErr ) 
    {
        GetRawDataFromDescriptor(&resultDesc, (Ptr)result, 2, &intSize);
        if ( intSize > 2 ) 
            myErr = errAECoercionFail;
    }
    
    if (resultDesc.dataHandle) 
        ignoreErr = AEDisposeDesc(&resultDesc);
        
    return(myErr);
}
    
OSErr   GetBooleanFromDescriptor(const AEDesc *sourceDesc, Boolean *result)
{
    OSErr  myErr;
    OSErr  ignoreErr;
    Size   boolSize;
    AEDesc resultDesc;
    
    *result = false;
    myErr = AECoerceDesc(sourceDesc,typeBoolean,&resultDesc);
    
    if (myErr==noErr) 
        {
            GetRawDataFromDescriptor(&resultDesc,
                                                             (Ptr)result,
                                                             sizeof(Boolean),
                                                             &boolSize);
            if (boolSize>sizeof(Boolean)) 
                myErr = errAECoercionFail;
        }
    
    if (resultDesc.dataHandle) 
        ignoreErr = AEDisposeDesc(&resultDesc);
        
    return(myErr);
}
 
OSErr   GetLongIntFromDescriptor(const AEDesc *sourceDesc, long *result)
{
    OSErr   myErr;
    Size    intSize;
    AEDesc  resultDesc = { typeNull, NULL };
    
    *result = 0;
    myErr = AECoerceDesc(sourceDesc,typeLongInteger,&resultDesc);
    
    if (myErr==noErr) 
    {
        GetRawDataFromDescriptor(&resultDesc, (Ptr)result, 4, &intSize);
        if (intSize>4) 
            myErr = errAECoercionFail;
    }
    
    (void)AEDisposeDesc(&resultDesc);
    
    return(myErr);
} // GetLongIntFromDescriptor
 
OSErr   GetRectFromDescriptor(const AEDesc *sourceDesc, Rect *result)
{
    OSErr   myErr;
    Size    rectSize;
    AEDesc  resultDesc = { typeNull, NULL };
        
    SetRect(result,0,0,0,0);
    myErr = AECoerceDesc(sourceDesc,typeQDRectangle,&resultDesc);
    
    if (myErr==noErr) 
    {
        GetRawDataFromDescriptor(&resultDesc, (Ptr)result, sizeof(Rect), &rectSize);
        if ( rectSize < sizeof( Rect ) ) 
            myErr = errAECoercionFail;
    }
    
    (void)AEDisposeDesc(&resultDesc);
        
    return(myErr);
} // GetRectFromDescriptor
 
OSErr   GetPointFromDescriptor(const AEDesc *sourceDesc, Point  *result)
{
    OSErr   myErr;
    Size    ptSize;
    AEDesc  resultDesc = { typeNull, NULL };
    
    SetPt(result,0,0);
    
    myErr = AECoerceDesc(sourceDesc,typeQDPoint,&resultDesc);
    
    if (myErr==noErr) 
    {
        GetRawDataFromDescriptor(&resultDesc, (Ptr)result, sizeof(Point), &ptSize);
                                                         
        if ( ptSize < sizeof( Point ) ) 
            myErr = errAECoercionFail;
    }
    
    (void)AEDisposeDesc(&resultDesc);
        
    return(myErr);
} // GetPointFromDescriptor
 
 
// ----------------------------------------------------------------------
//  Name:       GotRequiredParams
//  Function:   Checks all parameters defined as 'required' have been read
// ----------------------------------------------------------------------
                            
OSErr   GotRequiredParams(const AppleEvent *theAppleEvent)
{
    DescType    returnedType;
    Size        actualSize;
    OSErr       err;
    
        // look for the keyMissedKeywordAttr, just to see if it's there
    
    err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
                                                &returnedType, NULL, 0, &actualSize);
    
    switch (err)
    {
        case errAEDescNotFound:     // attribute not there means we
            err = noErr;            // got all required parameters.
            break;
            
        case noErr:                 // attribute there means missed
            err = errAEParamMissed; // at least one parameter.
            break;
            
        // default:     pass on unexpected error in looking for the attribute
    }
    
    return(err);
} // GotReqiredParams
 
 
// This routine takes a result descriptor, a reply descriptor and an error.
// If there is a result to add to the reply it makes sure the reply isn't
// NULL itself then adds the result to the reply depending on the error
// and the type of result.
 
OSErr   AddResultToReply(AEDesc* result, AEDesc* reply, OSErr error)
{
    OSErr   err;
 
        // Check that the reply is not NULL and there is a result to put in it  
    if (typeNull == reply->descriptorType || typeNull == result->descriptorType)
        return(error);
    
    if (noErr == error)
        err = AEPutParamDesc(reply, keyDirectObject, result);
    else
    {
        switch (result->descriptorType)
        {
            case typeInteger:
                err = AEPutParamDesc(reply, keyErrorNumber, result);
                break;
                
            case typeChar:
                err = AEPutParamDesc(reply, keyErrorString, result);
                break;
                
            default:
                err = errAETypeError;
        }
        
        if (noErr == err)
            err = error;        // Don't loose that error
    }
 
    return(err);
}
 
// -----------------------------------------------------------------------
//      Name:           MakeSelfAddress
//      Purpose:        Builds an AEAddressDesc for the current process
// -----------------------------------------------------------------------
    
OSErr   MakeSelfAddress(AEAddressDesc *selfAddress)
{
    ProcessSerialNumber procSerNum;
    
    procSerNum.highLongOfPSN = 0;
    procSerNum.lowLongOfPSN  = kCurrentProcess;
    
    return(AECreateDesc(typeProcessSerialNumber, (Ptr)&procSerNum, sizeof(procSerNum), selfAddress));
} // MakeSelfAddress
 
 
 
OSErr   GetEnumeratedFromDescriptor(const AEDesc *sourceDesc, DescType  *result)
{
    OSErr   myErr;
    OSErr   ignoreErr;
    Size    enumSize;
    AEDesc  resultDesc;
    
    *result = typeNull;
    
    myErr = AECoerceDesc(sourceDesc,typeEnumerated,&resultDesc);
    
    if (myErr==noErr)
    {
        GetRawDataFromDescriptor(&resultDesc, (Ptr)result, sizeof(DescType), &enumSize);
    
        if (enumSize<sizeof(DescType))
            myErr = errAECoercionFail;
    }
    
    if (resultDesc.dataHandle)
        ignoreErr = AEDisposeDesc(&resultDesc);
    
    return(myErr);
} // GetEnumeratedFromDescriptor