2005-07-01 21:00:04 +00:00
|
|
|
/* Test/example program for the base library
|
|
|
|
|
|
|
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
|
|
|
|
2005-07-15 22:51:23 +00:00
|
|
|
Copying and distribution of this file, with or without modification,
|
|
|
|
are permitted in any medium without royalty provided the copyright
|
|
|
|
notice and this notice are preserved.
|
|
|
|
|
2005-07-01 21:00:04 +00:00
|
|
|
This file is part of the GNUstep Base Library.
|
|
|
|
*/
|
1998-08-07 11:55:32 +00:00
|
|
|
#include <Foundation/NSMethodSignature.h>
|
|
|
|
#include <Foundation/NSInvocation.h>
|
|
|
|
#include <Foundation/NSString.h>
|
1998-10-28 15:18:38 +00:00
|
|
|
#include <Foundation/NSAutoreleasePool.h>
|
|
|
|
#include <Foundation/NSArchiver.h>
|
1998-08-07 11:55:32 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char c;
|
|
|
|
int i;
|
|
|
|
} small;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int i;
|
|
|
|
char *s;
|
|
|
|
float f;
|
|
|
|
} large;
|
|
|
|
|
|
|
|
@interface Target: NSObject
|
|
|
|
- (char) loopChar: (char)v;
|
|
|
|
- (double) loopDouble: (double)v;
|
|
|
|
- (float) loopFloat: (float)v;
|
|
|
|
- (int) loopInt: (int)v;
|
|
|
|
- (large) loopLarge: (large)v;
|
|
|
|
- (long) loopLong: (long)v;
|
|
|
|
- (large) loopLargePtr: (large*)v;
|
|
|
|
- (id) loopObject: (id)v;
|
|
|
|
- (short) loopShort: (short)v;
|
|
|
|
- (small) loopSmall: (small)v;
|
|
|
|
- (small) loopSmallPtr: (small*)v;
|
|
|
|
- (char*) loopString: (char*)v;
|
|
|
|
|
2002-04-24 03:12:55 +00:00
|
|
|
- (double) loopMulti: (float)f int: (float)v ch: (char)c;
|
|
|
|
|
1998-08-07 11:55:32 +00:00
|
|
|
- (char) retChar;
|
|
|
|
- (double) retDouble;
|
|
|
|
- (float) retFloat;
|
|
|
|
- (int) retInt;
|
|
|
|
- (large) retLarge;
|
|
|
|
- (long) retLong;
|
|
|
|
- (id) retObject;
|
|
|
|
- (short) retShort;
|
|
|
|
- (small) retSmall;
|
|
|
|
- (char*) retString;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation Target
|
|
|
|
- (char) loopChar: (char)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (double) loopDouble: (double)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1.0;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (float) loopFloat: (float)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1.0;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (int) loopInt: (int)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (large) loopLarge: (large)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (long) loopLong: (long)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (large) loopLargePtr: (large*)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return *v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (id) loopObject: (id)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (short) loopShort: (short)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v+1;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (small) loopSmall: (small)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (small) loopSmallPtr: (small*)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return *v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (char*) loopString: (char*)v
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return v;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
|
2002-04-24 03:12:55 +00:00
|
|
|
- (double) loopMulti: (float)f int: (float)v ch: (char)c
|
|
|
|
{
|
|
|
|
return v+1.0;
|
|
|
|
}
|
|
|
|
|
1998-08-07 11:55:32 +00:00
|
|
|
- (char) retChar
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return (char)99;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (double) retDouble
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return 123.456;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (float) retFloat
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return 123.456;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (int) retInt
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return 123456;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (large) retLarge
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
static large l = {
|
|
|
|
99, "large", 99.99
|
|
|
|
};
|
|
|
|
return l;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (long) retLong
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return 123456;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (id) retObject
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return self;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (short) retShort
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return 12345;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (small) retSmall
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
static small s = {
|
|
|
|
11, 22
|
|
|
|
};
|
|
|
|
return s;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (char*) retString
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
return "string";
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface MyProxy : NSObject
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
id obj;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)inv;
|
|
|
|
- (id) initWithTarget: (id)target;
|
2003-07-27 08:59:08 +00:00
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector;
|
1998-08-07 11:55:32 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation MyProxy
|
|
|
|
- (id) initWithTarget: (id)target
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
obj = target;
|
|
|
|
return self;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)inv
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
NSData *d = [NSArchiver archivedDataWithRootObject: inv];
|
|
|
|
NSInvocation *i = [NSUnarchiver unarchiveObjectWithData: d];
|
|
|
|
unsigned l;
|
|
|
|
void *b;
|
|
|
|
|
|
|
|
[i invokeWithTarget: obj];
|
|
|
|
d = [NSArchiver archivedDataWithRootObject: i];
|
|
|
|
i = [NSUnarchiver unarchiveObjectWithData: d];
|
|
|
|
l = [[i methodSignature] methodReturnLength];
|
2002-04-18 16:02:12 +00:00
|
|
|
if (l < sizeof(void *))
|
|
|
|
l = sizeof(void *);
|
1998-10-28 15:18:38 +00:00
|
|
|
b = (void *)objc_malloc(l);
|
|
|
|
[i getReturnValue: b];
|
|
|
|
[inv setReturnValue: b];
|
|
|
|
objc_free(b);
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
2003-07-27 08:59:08 +00:00
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
|
|
|
|
{
|
|
|
|
return [obj methodSignatureForSelector: aSelector];
|
|
|
|
}
|
1998-08-07 11:55:32 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
int
|
|
|
|
main ()
|
|
|
|
{
|
1998-10-28 15:18:38 +00:00
|
|
|
large la;
|
|
|
|
small sm;
|
|
|
|
large tmpla;
|
|
|
|
large *laptr = &tmpla;
|
|
|
|
small tmpsm;
|
|
|
|
small *smptr = &tmpsm;
|
|
|
|
int i;
|
|
|
|
char c;
|
|
|
|
short s;
|
|
|
|
long l;
|
|
|
|
float f;
|
|
|
|
double d;
|
|
|
|
id o;
|
2003-04-04 10:03:08 +00:00
|
|
|
char *str;
|
1998-10-28 15:18:38 +00:00
|
|
|
NSInvocation *inv;
|
|
|
|
NSMethodSignature *sig;
|
|
|
|
Target *t;
|
|
|
|
id p;
|
|
|
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
|
|
|
2002-04-18 16:02:12 +00:00
|
|
|
printf("Starting\n");
|
1998-10-28 15:18:38 +00:00
|
|
|
t = [Target new];
|
|
|
|
p = [[MyProxy alloc] initWithTarget: t];
|
2002-04-18 16:02:12 +00:00
|
|
|
printf("Calling proxy\n");
|
2002-03-19 07:39:05 +00:00
|
|
|
[p loopInt: 1];
|
1998-08-07 11:55:32 +00:00
|
|
|
|
2003-04-04 10:03:08 +00:00
|
|
|
printf("Testing NS_MESSAGE ... ");
|
|
|
|
inv = NS_MESSAGE(t, loopInt: 5);
|
|
|
|
[inv invoke];
|
|
|
|
[inv getReturnValue: &i];
|
|
|
|
if (i == 6)
|
|
|
|
printf("OK\n");
|
|
|
|
else
|
|
|
|
printf("ERROR ... expecting 6 and got %d\n", i);
|
2005-02-22 11:22:44 +00:00
|
|
|
|
2003-04-04 10:03:08 +00:00
|
|
|
printf("Testing NS_INVOCATION ... ");
|
2003-07-28 10:53:18 +00:00
|
|
|
inv = NS_INVOCATION([Target class], loopInt: 7);
|
2003-04-04 10:03:08 +00:00
|
|
|
[inv setTarget: t];
|
|
|
|
[inv invoke];
|
|
|
|
[inv getReturnValue: &i];
|
|
|
|
if (i == 8)
|
|
|
|
printf("OK\n");
|
|
|
|
else
|
|
|
|
printf("ERROR ... expecting 8 and got %d\n", i);
|
2005-02-22 11:22:44 +00:00
|
|
|
|
1998-08-07 11:55:32 +00:00
|
|
|
#define SETUP(X) \
|
1998-10-28 15:18:38 +00:00
|
|
|
sig = [t methodSignatureForSelector: @selector(X)]; \
|
|
|
|
inv = [NSInvocation invocationWithMethodSignature: sig]; \
|
|
|
|
[inv setSelector: @selector(X)];
|
|
|
|
|
|
|
|
tmpsm.c = 8;
|
|
|
|
tmpsm.i = 9;
|
|
|
|
|
|
|
|
tmpla.i = 1;
|
|
|
|
tmpla.s = "hello";
|
|
|
|
tmpla.f = 1.23;
|
|
|
|
|
|
|
|
SETUP(retChar);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 99, ");
|
|
|
|
[inv getReturnValue: &c];
|
|
|
|
printf("invoke: %d ", c);
|
|
|
|
c = [p retChar];
|
|
|
|
printf("forward: %d\n", c);
|
|
|
|
|
|
|
|
SETUP(retShort);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 12345, ");
|
|
|
|
[inv getReturnValue: &s];
|
|
|
|
printf("invoke: %d ", s);
|
|
|
|
s = [p retShort];
|
|
|
|
printf("forward: %d\n", s);
|
|
|
|
|
|
|
|
SETUP(retInt);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 123456, ");
|
|
|
|
[inv getReturnValue: &i];
|
|
|
|
printf("invoke: %d ", i);
|
|
|
|
i = [p retInt];
|
|
|
|
printf("forward: %d\n", i);
|
|
|
|
|
|
|
|
SETUP(retLong);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 123456, ");
|
|
|
|
[inv getReturnValue: &l];
|
|
|
|
printf("invoke: %ld ", l);
|
|
|
|
l = [p retLong];
|
|
|
|
printf("forward: %ld\n", l);
|
|
|
|
|
|
|
|
SETUP(retFloat);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 123.456, ");
|
|
|
|
[inv getReturnValue: &f];
|
|
|
|
printf("invoke: %.3f ", f);
|
|
|
|
f = [p retFloat];
|
|
|
|
printf("forward: %.3f\n", f);
|
|
|
|
|
|
|
|
SETUP(retDouble);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 123.456, ");
|
|
|
|
[inv getReturnValue: &d];
|
|
|
|
printf("invoke: %.3f ", d);
|
|
|
|
d = [p retDouble];
|
|
|
|
printf("forward: %.3f\n", d);
|
|
|
|
|
|
|
|
SETUP(retObject);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: %x, ", t);
|
|
|
|
[inv getReturnValue: &o];
|
|
|
|
printf("invoke: %x ", o);
|
|
|
|
o = [p retObject];
|
|
|
|
printf("forward: %x\n", o);
|
|
|
|
|
|
|
|
SETUP(retString);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 'string', ");
|
|
|
|
[inv getReturnValue: &str];
|
|
|
|
printf("invoke: '%s' ", str);
|
|
|
|
str = [p retString];
|
|
|
|
printf("forward: '%s'\n", str);
|
|
|
|
|
|
|
|
SETUP(retSmall);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: {11,22}, ");
|
|
|
|
[inv getReturnValue: &sm];
|
|
|
|
printf("invoke: {%d,%d} ", sm.c, sm.i);
|
|
|
|
sm = [p retSmall];
|
|
|
|
printf("forward: {%d,%d}\n", sm.c, sm.i);
|
|
|
|
|
|
|
|
SETUP(retLarge);
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: {99,large,99.99}, ");
|
|
|
|
[inv getReturnValue: &la];
|
|
|
|
printf("invoke: {%d,%s,%.2f} ", la.i, la.s, la.f);
|
|
|
|
la = [p retLarge];
|
|
|
|
printf("forward: {%d,%s,%.2f}\n", la.i, la.s, la.f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SETUP(loopChar:);
|
|
|
|
c = 0;
|
|
|
|
[inv setArgument: &c atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 1, ");
|
|
|
|
[inv getReturnValue: &c];
|
|
|
|
printf("invoke: %d ", c);
|
|
|
|
c = [p loopChar: 0];
|
|
|
|
printf("forward: %d\n", c);
|
|
|
|
|
|
|
|
SETUP(loopShort:);
|
|
|
|
s = 1;
|
|
|
|
[inv setArgument: &s atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 2, ");
|
|
|
|
[inv getReturnValue: &s];
|
|
|
|
printf("invoke: %d ", s);
|
|
|
|
s = [p loopShort: 1];
|
|
|
|
printf("forward: %d\n", s);
|
|
|
|
|
|
|
|
SETUP(loopInt:);
|
|
|
|
i = 2;
|
|
|
|
[inv setArgument: &i atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 3, ");
|
|
|
|
[inv getReturnValue: &i];
|
|
|
|
printf("invoke: %d ", i);
|
|
|
|
i = [p loopInt: 2];
|
|
|
|
printf("forward: %d\n", i);
|
|
|
|
|
|
|
|
SETUP(loopLong:);
|
|
|
|
l = 3;
|
|
|
|
[inv setArgument: &l atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 4, ");
|
|
|
|
[inv getReturnValue: &l];
|
|
|
|
printf("invoke: %d ", l);
|
|
|
|
l = [p loopLong: 3];
|
|
|
|
printf("forward: %d\n", l);
|
|
|
|
|
|
|
|
SETUP(loopFloat:);
|
|
|
|
f = 4.0;
|
|
|
|
[inv setArgument: &f atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 5.0, ");
|
|
|
|
[inv getReturnValue: &f];
|
|
|
|
printf("invoke: %.1f ", f);
|
|
|
|
f = [p loopFloat: 4.0];
|
|
|
|
printf("forward: %.1f\n", f);
|
|
|
|
|
|
|
|
SETUP(loopDouble:);
|
|
|
|
d = 5.0;
|
|
|
|
[inv setArgument: &d atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 6.0, ");
|
|
|
|
[inv getReturnValue: &d];
|
|
|
|
printf("invoke: %.1f ", d);
|
|
|
|
d = [p loopDouble: 5.0];
|
|
|
|
printf("forward: %.1f\n", d);
|
|
|
|
|
2002-04-24 03:12:55 +00:00
|
|
|
SETUP(loopMulti:int:ch:);
|
|
|
|
printf("Expect: 6.0, ");
|
|
|
|
f = [p loopMulti: 3.0 int: 5.0 ch: 'a'];
|
|
|
|
printf("forward: %.1f\n", f);
|
|
|
|
|
1998-10-28 15:18:38 +00:00
|
|
|
SETUP(loopObject:);
|
|
|
|
[inv setArgument: &p atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: %x, ", p);
|
|
|
|
[inv getReturnValue: &o];
|
|
|
|
printf("invoke: %x ", o);
|
|
|
|
o = [p loopObject: p];
|
|
|
|
printf("forward: %x\n", o);
|
|
|
|
|
|
|
|
SETUP(loopString:);
|
|
|
|
str = "Hello";
|
|
|
|
[inv setArgument: &str atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
printf("Expect: 'Hello', ");
|
|
|
|
[inv getReturnValue: &str];
|
|
|
|
printf("invoke: '%s' ", str);
|
|
|
|
str = [p loopString: str];
|
|
|
|
printf("forward: '%s'\n", str);
|
|
|
|
|
|
|
|
SETUP(loopSmall:);
|
|
|
|
printf("Expect: {8,9}, ");
|
|
|
|
[inv setArgument: &tmpsm atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
[inv getReturnValue: &sm];
|
|
|
|
printf("invoke: {%d,%d} ", sm.c, sm.i);
|
|
|
|
sm = [p loopSmall: tmpsm];
|
|
|
|
printf("forward: {%d,%d}\n", sm.c, sm.i);
|
|
|
|
|
|
|
|
SETUP(loopLarge:);
|
|
|
|
printf("Expect: {1,hello,1.23}, ");
|
|
|
|
[inv setArgument: &tmpla atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
[inv getReturnValue: &la];
|
|
|
|
printf("invoke: {%d,%s,%.2f} ", la.i, la.s, la.f);
|
|
|
|
la = [p loopLarge: tmpla];
|
|
|
|
printf("forward: {%d,%s,%.2f}\n", la.i, la.s, la.f);
|
|
|
|
|
|
|
|
SETUP(loopSmallPtr:);
|
|
|
|
printf("Expect: {8,9}, ");
|
|
|
|
[inv setArgument: &smptr atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
[inv getReturnValue: &sm];
|
|
|
|
printf("invoke: {%d,%d} ", sm.c, sm.i);
|
|
|
|
sm = [p loopSmallPtr: smptr];
|
|
|
|
printf("forward: {%d,%d}\n", sm.c, sm.i);
|
|
|
|
|
|
|
|
SETUP(loopLargePtr:);
|
|
|
|
printf("Expect: {1,hello,1.23}, ");
|
|
|
|
[inv setArgument: &laptr atIndex: 2];
|
|
|
|
[inv invokeWithTarget: t];
|
|
|
|
[inv getReturnValue: &la];
|
|
|
|
printf("invoke: {%d,%s,%.2f} ", la.i, la.s, la.f);
|
|
|
|
la = [p loopLargePtr: laptr];
|
|
|
|
printf("forward: {%d,%s,%.2f}\n", la.i, la.s, la.f);
|
|
|
|
|
|
|
|
[arp release];
|
|
|
|
return 0;
|
1998-08-07 11:55:32 +00:00
|
|
|
}
|
|
|
|
|