4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/A//
4632N/A// Most of this is adapted from Ken Ferry's KFAppleScript Additions, contributed with permission
4632N/A// http://homepage.mac.com/kenferry/software.html
4632N/A//
4632N/A
4632N/A#import "AS_NS_ConversionUtils.h"
4632N/A
4632N/A#import <Cocoa/Cocoa.h>
4632N/A#import <Carbon/Carbon.h>
4632N/A
4632N/A
4632N/A@interface NSAppleEventDescriptor (JavaAppleScriptEngineAdditionsPrivate)
4632N/A
4632N/A// just returns self. This means that you can pass custom descriptors
4632N/A// to -[NSAppleScript executeHandler:error:withParameters:].
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A
4632N/A// working with primitive descriptor types
4632N/A+ (id)descriptorWithInt16:(SInt16)val;
4632N/A- (SInt16)int16Value;
4632N/A+ (id)descriptorWithUnsignedInt32:(UInt32)val;
4632N/A- (UInt32)unsignedInt32Value;
4632N/A+ (id)descriptorWithFloat32:(Float32)val;
4632N/A- (Float32)float32Value;
4632N/A+ (id)descriptorWithFloat64:(Float64)val;
4632N/A- (Float64)float64Value;
4632N/A+ (id)descriptorWithLongDateTime:(LongDateTime)val;
4632N/A- (LongDateTime)longDateTimeValue;
4632N/A
4632N/A
4632N/A// These are the methods for converting AS objects to objective-C objects.
4632N/A// -[NSAppleEventDescriptor objCObjectValue] is the general method for converting
4632N/A// AS objects to ObjC objects, and is called by -[NSAppleScript executeHandler:error:withParameters:].
4632N/A// It does no work itself. It finds a handler based on the type of the descriptor and lets that
4632N/A// handler object do the work. If there is no handler type registered for a the type of a descriptor,
4632N/A// the raw descriptor is returned.
4632N/A//
4632N/A// You can designate a handlers for descriptor types with
4632N/A// +[NSAppleEventDescriptor registerConversionHandler:selector:forDescriptorTypes:]. Please note
4632N/A// that this method does _not_ retain the handler object (for now anyway). The selector should
4632N/A// take a single argument, a descriptor to translate, and should return an object. An example such
4632N/A// selector is @selector(dictionaryWithAEDesc:), for which the handler object would be [NSDictionary class].
4632N/A//
4632N/A// A number of handlers are designated by default. The methods and objects can be easily inferred (or check
4632N/A// the implementation), but the automatically handled types are
4632N/A// typeUnicodeText,
4632N/A// typeText,
4632N/A// typeUTF8Text,
4632N/A// typeCString,
4632N/A// typeChar,
4632N/A// typeBoolean,
4632N/A// typeTrue,
4632N/A// typeFalse,
4632N/A// typeSInt16,
4632N/A// typeSInt32,
4632N/A// typeUInt32,
4632N/A// typeSInt64,
4632N/A// typeIEEE32BitFloatingPoint,
4632N/A// typeIEEE64BitFloatingPoint,
4632N/A// type128BitFloatingPoint,
4632N/A// typeAEList,
4632N/A// typeAERecord,
4632N/A// typeLongDateTime,
4632N/A// typeNull.
4632N/A+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ...;
4632N/A+ (void) jaseSetUpHandlerDict;
4632N/A@end
4632N/A
4632N/A// wrap the NSAppleEventDescriptor string methods
4632N/A@interface NSString (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A// wrap the NSAppleEventDescriptor longDateTime methods
4632N/A@interface NSDate (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A// these are fairly complicated methods, due to having to try to match up the various
4632N/A// AS number types (see NSAppleEventDescriptor for the primitive number methods)
4632N/A// with NSNumber variants. For complete behavior it's best to look at the implementation.
4632N/A// Some notes:
4632N/A// NSNumbers created with numberWithBool should be correctly translated to AS booleans and vice versa.
4632N/A// NSNumbers created with large integer types may have to be translated to AS doubles,
4632N/A// so be careful if checking equality (you may have to check equality within epsilon).
4632N/A// Since NSNumbers can't remember if they were created with an unsigned value,
4632N/A// [[NSNumber numberWithUnsignedChar:255] aeDescriptorValue] is going to get you an AS integer
4632N/A// with value -1. If you really need a descriptor with an unsigned value, you'll need to do it
4632N/A// manually using the primitive methods on NSAppleEventDescriptor. The resulting descriptor
4632N/A// can still be passed to AS with -[NSAppleScript executeHandler:error:withParameters:].
4632N/A@interface NSNumber (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A// Here we're following the behavior described in the CocoaScripting release note.
4632N/A//
4632N/A// NSPoint -> list of two numbers: {x, y}
4632N/A// NSRange -> list of two numbers: {begin offset, end offset}
4632N/A// NSRect -> list of four numbers: {left, bottom, right, top}
4632N/A// NSSize -> list of two numbers: {width, height}
4632N/A@interface NSValue (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A@end
4632N/A
4632N/A// No need for ObjC -> AS conversion here, we fall through to NSObject as a collection.
4632N/A// For AS -> ObjC conversion, we build an array using the primitive list methods on
4632N/A// NSAppleEventDescriptor.
4632N/A@interface NSArray (JavaAppleScriptEngineAdditions)
4632N/A+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A
4632N/A// Please see the CocoaScripting release note for behavior. It's kind of complicated.
4632N/A//
4632N/A// methods wrap the primitive record methods on NSAppleEventDescriptor.
4632N/A@interface NSDictionary (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A// be aware that a null descriptor does not correspond to the 'null' keyword in
4632N/A// AppleScript - it's more like nothing at all. For example, the return
4632N/A// from an empty handler.
4632N/A@interface NSNull (JavaAppleScriptEngineAdditions)
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue;
4632N/A+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc;
4632N/A@end
4632N/A
4632N/A
4632N/A@interface NSNumber (JavaAppleScriptEngineAdditionsPrivate)
4632N/A+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes;
4632N/A+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes;
4632N/A+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes;
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSObject (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A // collections go to lists
4632N/A if (![self respondsToSelector:@selector(objectEnumerator)]) {
4632N/A // encode the description as a fallback - this is pretty useless, only helpful for debugging
4632N/A return [[self description] aeDescriptorValue];
4632N/A }
4632N/A
4632N/A NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor listDescriptor];
4632N/A NSEnumerator *objectEnumerator = [(id)self objectEnumerator];
4632N/A
4632N/A unsigned int i = 1; // apple event descriptors are 1-indexed
4632N/A id currentObject;
4632N/A while((currentObject = [objectEnumerator nextObject]) != nil) {
4632N/A [resultDesc insertDescriptor:[currentObject aeDescriptorValue] atIndex:i++];
4632N/A }
4632N/A
4632N/A return resultDesc;
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSArray (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A// don't need to override aeDescriptorValue, the NSObject will treat the array as a collection
4632N/A+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A NSAppleEventDescriptor *listDesc = [desc coerceToDescriptorType:typeAEList];
4632N/A NSMutableArray *resultArray = [NSMutableArray array];
4632N/A
4632N/A // apple event descriptors are 1-indexed
4632N/A unsigned int listCount = [listDesc numberOfItems];
4632N/A unsigned int i;
4632N/A for (i = 1; i <= listCount; i++) {
4632N/A [resultArray addObject:[[listDesc descriptorAtIndex:i] objCObjectValue]];
4632N/A }
4632N/A
4632N/A return resultArray;
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSDictionary (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor recordDescriptor];
4632N/A NSMutableArray *userFields = [NSMutableArray array];
4632N/A NSArray *keys = [self allKeys];
4632N/A
4632N/A unsigned int keyCount = [keys count];
4632N/A unsigned int i;
4632N/A for (i = 0; i < keyCount; i++) {
4632N/A id key = [keys objectAtIndex:i];
4632N/A
4632N/A if ([key isKindOfClass:[NSNumber class]]) {
4632N/A [resultDesc setDescriptor:[[self objectForKey:key] aeDescriptorValue] forKeyword:[(NSNumber *)key intValue]];
4632N/A } else if ([key isKindOfClass:[NSString class]]) {
4632N/A [userFields addObject:key];
4632N/A [userFields addObject:[self objectForKey:key]];
4632N/A }
4632N/A }
4632N/A
4632N/A if ([userFields count] > 0) {
4632N/A [resultDesc setDescriptor:[userFields aeDescriptorValue] forKeyword:keyASUserRecordFields];
4632N/A }
4632N/A
4632N/A return resultDesc;
4632N/A}
4632N/A
4632N/A+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A NSAppleEventDescriptor *recDescriptor = [desc coerceToDescriptorType:typeAERecord];
4632N/A NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
4632N/A
4632N/A // NSAppleEventDescriptor uses 1 indexing
4632N/A unsigned int recordCount = [recDescriptor numberOfItems];
4632N/A unsigned int recordIndex;
4632N/A for (recordIndex = 1; recordIndex <= recordCount; recordIndex++) {
4632N/A AEKeyword keyword = [recDescriptor keywordForDescriptorAtIndex:recordIndex];
4632N/A
4632N/A if(keyword == keyASUserRecordFields) {
4632N/A NSAppleEventDescriptor *listDescriptor = [recDescriptor descriptorAtIndex:recordIndex];
4632N/A
4632N/A // NSAppleEventDescriptor uses 1 indexing
4632N/A unsigned int listCount = [listDescriptor numberOfItems];
4632N/A unsigned int listIndex;
4632N/A for (listIndex = 1; listIndex <= listCount; listIndex += 2) {
4632N/A id keyObj = [[listDescriptor descriptorAtIndex:listIndex] objCObjectValue];
4632N/A id valObj = [[listDescriptor descriptorAtIndex:listIndex+1] objCObjectValue];
4632N/A
4632N/A [resultDict setObject:valObj forKey:keyObj];
4632N/A }
4632N/A } else {
4632N/A id keyObj = [NSNumber numberWithInt:keyword];
4632N/A id valObj = [[recDescriptor descriptorAtIndex:recordIndex] objCObjectValue];
4632N/A
4632N/A [resultDict setObject:valObj forKey:keyObj];
4632N/A }
4632N/A }
4632N/A
4632N/A return resultDict;
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSString (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A return [NSAppleEventDescriptor descriptorWithString:self];
4632N/A}
4632N/A
4632N/A+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A return [desc stringValue];
4632N/A}
4632N/A
4632N/A+ (NSString *)versionWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A const AEDesc *aeDesc = [desc aeDesc];
4632N/A VersRec v;
4632N/A AEGetDescData(aeDesc, &v, sizeof(v));
4632N/A return [[[NSString alloc] initWithBytes:&v.shortVersion[1] length:StrLength(v.shortVersion) encoding:NSUTF8StringEncoding] autorelease];
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSNull (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A return [NSAppleEventDescriptor nullDescriptor];
4632N/A}
4632N/A
4632N/A+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A return [NSNull null];
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSDate (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A LongDateTime ldt;
4632N/A UCConvertCFAbsoluteTimeToLongDateTime(CFDateGetAbsoluteTime((CFDateRef)self), &ldt);
4632N/A return [NSAppleEventDescriptor descriptorWithLongDateTime:ldt];
4632N/A}
4632N/A
4632N/A+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A CFAbsoluteTime absTime;
4632N/A UCConvertLongDateTimeToCFAbsoluteTime([desc longDateTimeValue], &absTime);
4632N/A NSDate *resultDate = (NSDate *)CFDateCreate(NULL, absTime);
4632N/A return [resultDate autorelease];
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A
4632N/Astatic inline int areEqualEncodings(const char *enc1, const char *enc2) {
4632N/A return (strcmp(enc1, enc2) == 0);
4632N/A}
4632N/A
4632N/A@implementation NSNumber (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A-(id)jaseDescriptorValueWithFloatP:(void *)float_p byteCount:(int)bytes {
4632N/A float floatVal;
4632N/A if (bytes < sizeof(Float32)) {
4632N/A floatVal = [self floatValue];
4632N/A float_p = &floatVal;
4632N/A bytes = sizeof(floatVal);
4632N/A }
4632N/A
4632N/A double doubleVal;
4632N/A if (bytes > sizeof(Float64)) {
4632N/A doubleVal = [self doubleValue];
4632N/A float_p = &doubleVal;
4632N/A bytes = sizeof(doubleVal);
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(Float32)) {
4632N/A return [NSAppleEventDescriptor descriptorWithFloat32:*(Float32 *)float_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(Float64)) {
4632N/A return [NSAppleEventDescriptor descriptorWithFloat64:*(Float64 *)float_p];
4632N/A }
4632N/A
4632N/A [NSException raise:NSInvalidArgumentException
4632N/A format:@"Cannot create an NSAppleEventDescriptor for float with %d bytes of data.", bytes];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A-(id)jaseDescriptorValueWithSignedIntP:(void *)int_p byteCount:(int)bytes {
4632N/A int intVal;
4632N/A
4632N/A if (bytes < sizeof(SInt16)) {
4632N/A intVal = [self intValue];
4632N/A int_p = &intVal;
4632N/A bytes = sizeof(intVal);
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(SInt16)) {
4632N/A return [NSAppleEventDescriptor descriptorWithInt16:*(SInt16 *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(SInt32)) {
4632N/A return [NSAppleEventDescriptor descriptorWithInt32:*(SInt32 *)int_p];
4632N/A }
4632N/A
4632N/A double val = [self doubleValue];
4632N/A return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
4632N/A}
4632N/A
4632N/A-(id)jaseDescriptorValueWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
4632N/A unsigned int uIntVal;
4632N/A
4632N/A if (bytes < sizeof(UInt32)) {
4632N/A uIntVal = [self unsignedIntValue];
4632N/A int_p = &uIntVal;
4632N/A bytes = sizeof(uIntVal);
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(UInt32)) {
4632N/A return [NSAppleEventDescriptor descriptorWithUnsignedInt32:*(UInt32 *)int_p];
4632N/A }
4632N/A
4632N/A double val = (double)[self unsignedLongLongValue];
4632N/A return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A // NSNumber is unfortunately complicated, because the applescript
4632N/A // type we should use depends on the c type that our NSNumber corresponds to
4632N/A
4632N/A const char *type = [self objCType];
4632N/A
4632N/A // convert
4632N/A if (areEqualEncodings(type, @encode(BOOL))) {
4632N/A return [NSAppleEventDescriptor descriptorWithBoolean:[self boolValue]];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(char))) {
4632N/A char val = [self charValue];
4632N/A return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(short))) {
4632N/A short val = [self shortValue];
4632N/A return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(int))) {
4632N/A int val = [self intValue];
4632N/A return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(long))) {
4632N/A long val = [self longValue];
4632N/A return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(long long))) {
4632N/A long long val = [self longLongValue];
4632N/A return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(unsigned char))) {
4632N/A unsigned char val = [self unsignedCharValue];
4632N/A return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(unsigned short))) {
4632N/A unsigned short val = [self unsignedShortValue];
4632N/A return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(unsigned int))) {
4632N/A unsigned int val = [self unsignedIntValue];
4632N/A return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(unsigned long))) {
4632N/A unsigned long val = [self unsignedLongValue];
4632N/A return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(unsigned long long))) {
4632N/A unsigned long long val = [self unsignedLongLongValue];
4632N/A return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(float))) {
4632N/A float val = [self floatValue];
4632N/A return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(double))) {
4632N/A double val = [self doubleValue];
4632N/A return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
4632N/A format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A DescType type = [desc descriptorType];
4632N/A
4632N/A if ((type == typeTrue) || (type == typeFalse) || (type == typeBoolean)) {
4632N/A return [NSNumber numberWithBool:[desc booleanValue]];
4632N/A }
4632N/A
4632N/A if (type == typeSInt16) {
4632N/A SInt16 val = [desc int16Value];
4632N/A return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (type == typeSInt32) {
4632N/A SInt32 val = [desc int32Value];
4632N/A return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (type == typeUInt32) {
4632N/A UInt32 val = [desc unsignedInt32Value];
4632N/A return [NSNumber jaseNumberWithUnsignedIntP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (type == typeIEEE32BitFloatingPoint) {
4632N/A Float32 val = [desc float32Value];
4632N/A return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A if (type == typeIEEE64BitFloatingPoint) {
4632N/A Float64 val = [desc float64Value];
4632N/A return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A // try to coerce to 64bit floating point
4632N/A desc = [desc coerceToDescriptorType:typeIEEE64BitFloatingPoint];
4632N/A if (desc != nil) {
4632N/A Float64 val = [desc float64Value];
4632N/A return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
4632N/A }
4632N/A
4632N/A [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
4632N/A format:@"JavaAppleScriptEngineAdditions: conversion of an NSAppleEventDescriptor with objCType '%s' to an aeDescriptor is not supported.", type];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes {
4632N/A if (bytes == sizeof(char)) {
4632N/A return [NSNumber numberWithChar:*(char *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(short)) {
4632N/A return [NSNumber numberWithShort:*(short *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(int)) {
4632N/A return [NSNumber numberWithInt:*(int *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(long)) {
4632N/A return [NSNumber numberWithLong:*(long *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(long long)) {
4632N/A return [NSNumber numberWithLongLong:*(long long *)int_p];
4632N/A }
4632N/A
4632N/A [NSException raise:NSInvalidArgumentException
4632N/A format:@"NSNumber jaseNumberWithSignedIntP:byteCount: number with %i bytes not supported.", bytes];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
4632N/A if (bytes == sizeof(unsigned char)) {
4632N/A return [NSNumber numberWithUnsignedChar:*(unsigned char *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(unsigned short)) {
4632N/A return [NSNumber numberWithUnsignedShort:*(unsigned short *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(unsigned int)) {
4632N/A return [NSNumber numberWithUnsignedInt:*(unsigned int *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(unsigned long)) {
4632N/A return [NSNumber numberWithUnsignedLong:*(unsigned long *)int_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(unsigned long long)) {
4632N/A return [NSNumber numberWithUnsignedLongLong:*(unsigned long long *)int_p];
4632N/A }
4632N/A
4632N/A [NSException raise:NSInvalidArgumentException
4632N/A format:@"NSNumber numberWithUnsignedInt:byteCount: number with %i bytes not supported.", bytes];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes {
4632N/A if (bytes == sizeof(float)) {
4632N/A return [NSNumber numberWithFloat:*(float *)float_p];
4632N/A }
4632N/A
4632N/A if (bytes == sizeof(double)) {
4632N/A return [NSNumber numberWithFloat:*(double *)float_p];
4632N/A }
4632N/A
4632N/A [NSException raise:NSInvalidArgumentException
4632N/A format:@"NSNumber numberWithFloat:byteCount: floating point number with %i bytes not supported.", bytes];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A@implementation NSValue (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A const char *type = [self objCType];
4632N/A
4632N/A if (areEqualEncodings(type, @encode(NSSize))) {
4632N/A NSSize size = [self sizeValue];
4632N/A return [[NSArray arrayWithObjects:
4632N/A [NSNumber numberWithFloat:size.width],
4632N/A [NSNumber numberWithFloat:size.height], nil] aeDescriptorValue];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(NSPoint))) {
4632N/A NSPoint point = [self pointValue];
4632N/A return [[NSArray arrayWithObjects:
4632N/A [NSNumber numberWithFloat:point.x],
4632N/A [NSNumber numberWithFloat:point.y], nil] aeDescriptorValue];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(NSRange))) {
4632N/A NSRange range = [self rangeValue];
4632N/A return [[NSArray arrayWithObjects:
4632N/A [NSNumber numberWithUnsignedInt:range.location],
4632N/A [NSNumber numberWithUnsignedInt:range.location + range.length], nil] aeDescriptorValue];
4632N/A }
4632N/A
4632N/A if (areEqualEncodings(type, @encode(NSRect))) {
4632N/A NSRect rect = [self rectValue];
4632N/A return [[NSArray arrayWithObjects:
4632N/A [NSNumber numberWithFloat:rect.origin.x],
4632N/A [NSNumber numberWithFloat:rect.origin.y],
4632N/A [NSNumber numberWithFloat:rect.origin.x + rect.size.width],
4632N/A [NSNumber numberWithFloat:rect.origin.y + rect.size.height], nil] aeDescriptorValue];
4632N/A }
4632N/A
4632N/A [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
4632N/A format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
4632N/A
4632N/A return nil;
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A@implementation NSImage (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A NSData *data = [self TIFFRepresentation];
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeTIFF data:data];
4632N/A}
4632N/A
4632N/A+ (NSImage *)imageWithAEDesc:(NSAppleEventDescriptor *)desc {
4632N/A const AEDesc *d = [desc aeDesc];
4632N/A NSMutableData *data = [NSMutableData dataWithLength:AEGetDescDataSize(d)];
4632N/A AEGetDescData(d, [data mutableBytes], [data length]);
4632N/A return [[[NSImage alloc] initWithData:data] autorelease];
4632N/A}
4632N/A
4632N/A@end
4632N/A
4632N/A
4632N/A
4632N/A@implementation NSAppleEventDescriptor (JavaAppleScriptEngineAdditions)
4632N/A
4632N/A// we're going to leak this. It doesn't matter much for running apps, but
4632N/A// for developers it might be nice to try to dispose of it (so it would not clutter the
4632N/A// output when testing for leaks)
4632N/Astatic NSMutableDictionary *handlerDict = nil;
4632N/A
4632N/A- (id)objCObjectValue {
4632N/A if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
4632N/A
4632N/A id returnObj;
4632N/A DescType type = [self descriptorType];
4632N/A NSInvocation *handlerInvocation = [handlerDict objectForKey:[NSValue valueWithBytes:&type objCType:@encode(DescType)]];
4632N/A if (handlerInvocation == nil) {
4632N/A if (type == typeType) {
4632N/A DescType subType;
4632N/A AEGetDescData([self aeDesc], &subType, sizeof(subType));
4632N/A if (subType == typeNull) return [NSNull null];
4632N/A }
4632N/A // return raw apple event descriptor if no handler is registered
4632N/A returnObj = self;
4632N/A } else {
4632N/A [handlerInvocation setArgument:&self atIndex:2];
4632N/A [handlerInvocation invoke];
4632N/A [handlerInvocation getReturnValue:&returnObj];
4632N/A }
4632N/A
4632N/A return returnObj;
4632N/A}
4632N/A
4632N/A// FIXME - error checking, non nil handler
4632N/A+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ... {
4632N/A if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
4632N/A
4632N/A NSInvocation *handlerInvocation = [NSInvocation invocationWithMethodSignature:[anObject methodSignatureForSelector:aSelector]];
4632N/A [handlerInvocation setTarget:anObject];
4632N/A [handlerInvocation setSelector:aSelector];
4632N/A
4632N/A DescType aType = firstType;
4632N/A va_list typesList;
4632N/A va_start(typesList, firstType);
4632N/A do {
4632N/A NSValue *type = [NSValue valueWithBytes:&aType objCType:@encode(DescType)];
4632N/A [handlerDict setObject:handlerInvocation forKey:type];
4632N/A } while((aType = va_arg(typesList, DescType)) != 0);
4632N/A va_end(typesList);
4632N/A}
4632N/A
4632N/A
4632N/A- (NSAppleEventDescriptor *)aeDescriptorValue {
4632N/A return self;
4632N/A}
4632N/A
4632N/A+ (id)descriptorWithInt16:(SInt16)val {
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt16 bytes:&val length:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (SInt16)int16Value {
4632N/A SInt16 retValue;
4632N/A [[[self coerceToDescriptorType:typeSInt16] data] getBytes:&retValue];
4632N/A return retValue;
4632N/A}
4632N/A
4632N/A+ (id)descriptorWithUnsignedInt32:(UInt32)val {
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeUInt32 bytes:&val length:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (UInt32)unsignedInt32Value {
4632N/A UInt32 retValue;
4632N/A [[[self coerceToDescriptorType:typeUInt32] data] getBytes:&retValue];
4632N/A return retValue;
4632N/A}
4632N/A
4632N/A
4632N/A+ (id)descriptorWithFloat32:(Float32)val {
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE32BitFloatingPoint bytes:&val length:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (Float32)float32Value {
4632N/A Float32 retValue;
4632N/A [[[self coerceToDescriptorType:typeIEEE32BitFloatingPoint] data] getBytes:&retValue];
4632N/A return retValue;
4632N/A}
4632N/A
4632N/A
4632N/A+ (id)descriptorWithFloat64:(Float64)val {
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&val length:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (Float64)float64Value {
4632N/A Float64 retValue;
4632N/A [[[self coerceToDescriptorType:typeIEEE64BitFloatingPoint] data] getBytes:&retValue];
4632N/A return retValue;
4632N/A}
4632N/A
4632N/A+ (id)descriptorWithLongDateTime:(LongDateTime)val {
4632N/A return [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&val length:sizeof(val)];
4632N/A}
4632N/A
4632N/A- (LongDateTime)longDateTimeValue {
4632N/A LongDateTime retValue;
4632N/A [[[self coerceToDescriptorType:typeLongDateTime] data] getBytes:&retValue];
4632N/A return retValue;
4632N/A}
4632N/A
4632N/A+ (void)jaseSetUpHandlerDict {
4632N/A handlerDict = [[NSMutableDictionary alloc] init];
4632N/A
4632N/A // register default handlers
4632N/A // types are culled from AEDataModel.h and AERegistry.h
4632N/A
4632N/A // string -> NSStrings
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(stringWithAEDesc:) forDescriptorTypes:
4632N/A typeUnicodeText, typeText, typeUTF8Text, typeCString, typeChar, nil];
4632N/A
4632N/A // number/bool -> NSNumber
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSNumber class] selector:@selector(numberWithAEDesc:) forDescriptorTypes:
4632N/A typeBoolean, typeTrue, typeFalse,
4632N/A typeSInt16, typeSInt32, typeUInt32, typeSInt64,
4632N/A typeIEEE32BitFloatingPoint, typeIEEE64BitFloatingPoint, type128BitFloatingPoint, nil];
4632N/A
4632N/A // list -> NSArray
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSArray class] selector:@selector(arrayWithAEDesc:) forDescriptorTypes:typeAEList, nil];
4632N/A
4632N/A // record -> NSDictionary
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSDictionary class] selector:@selector(dictionaryWithAEDesc:) forDescriptorTypes:typeAERecord, nil];
4632N/A
4632N/A // date -> NSDate
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSDate class] selector:@selector(dateWithAEDesc:) forDescriptorTypes:typeLongDateTime, nil];
4632N/A
4632N/A // images -> NSImage
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSImage class] selector:@selector(imageWithAEDesc:) forDescriptorTypes:
4632N/A typeTIFF, typeJPEG, typeGIF, typePict, typeIconFamily, typeIconAndMask, nil];
4632N/A
4632N/A // vers -> NSString
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(versionWithAEDesc:) forDescriptorTypes:typeVersion, nil];
4632N/A
4632N/A // null -> NSNull
4632N/A [NSAppleEventDescriptor registerConversionHandler:[NSNull class] selector:@selector(nullWithAEDesc:) forDescriptorTypes:typeNull, nil];
4632N/A}
4632N/A
4632N/A@end