/* 
   invocation.m

   Copyright (C) 1995, 1996, 1997 Ovidiu Predescu and Mircea Oancea.
   All rights reserved.

   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>

   This file is part of libFoundation.

   Permission to use, copy, modify, and distribute this software and its
   documentation for any purpose and without fee is hereby granted, provided
   that the above copyright notice appear in all copies and that both that
   copyright notice and this permission notice appear in supporting
   documentation.

   We disclaim all warranties with regard to this software, including all
   implied warranties of merchantability and fitness, in no event shall
   we be liable for any special, indirect or consequential damages or any
   damages whatsoever resulting from loss of use, data or profits, whether in
   an action of contract, negligence or other tortious action, arising out of
   or in connection with the use or performance of this software.
*/

#include <stdio.h>
#include <Foundation/NSInvocation.h>
#include <extensions/objc-runtime.h>
#include "MyObject.h"

void invocation_setFlag(id object)
{
    BOOL flag = YES;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setFlag:)];
    [invocation setTarget:object];
    [invocation setArgument:&flag atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setShortValue(id object)
{
    short aShort = 21;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setShortValue:)];
    [invocation setTarget:object];
    [invocation setArgument:&aShort atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setIntValue(id object)
{
    int anInt = 21;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setIntValue:)];
    [invocation setTarget:object];
    [invocation setArgument:&anInt atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setString(id object)
{
    char* string = "foo";
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setString:)];
    [invocation setTarget:object];
    [invocation setArgument:&string atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setIntFloatDoubleValues(id object)
{
    BOOL flag = YES;
    int anInt = 1234;
    float aFloat = 12345.0;
    double aDouble = 98765.0;
    id invocation = [NSInvocation new];

    [invocation setSelector:
	    @selector(setFlag:intValue:floatValue:doubleValue:)];
    [invocation setTarget:object];
    [invocation setArgument:&flag atIndex:2];
    [invocation setArgument:&anInt atIndex:3];
    [invocation setArgument:&aFloat atIndex:4];
    [invocation setArgument:&aDouble atIndex:5];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct1(id object)
{
    Struct1 s = { 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct1:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct2(id object)
{
    Struct2 s = { 123 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct2:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct3(id object)
{
    Struct3 s = { 123, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct3:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct4(id object)
{
    Struct4 s = { 1234 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct4:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct5(id object)
{
    Struct5 s = { 1234, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct5:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct6(id object)
{
    Struct6 s = { 9876, 123 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct6:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct7(id object)
{
    Struct7 s = { 9876, 123, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct7:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct8(id object)
{
    Struct8 s = { 9876, 1234 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct8:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct9(id object)
{
    Struct9 s = { 9876, 1234, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct9:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct10(id object)
{
    Struct10 s = { 9876, 5432, 123 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct10:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct11(id object)
{
    Struct11 s = { 9876, 5432, 123, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct11:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct12(id object)
{
    Struct12 s = { 9876543.0, 12345 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct12:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct13(id object)
{
    Struct13 s = { 9876543.0, 12345, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct13:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct14(id object)
{
    Struct14 s = { 9876543.0, 12345, 123 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct14:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct15(id object)
{
    Struct15 s = { 9876543.0, 12345, 123, 12 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct15:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_setStruct16(id object)
{
    Struct16 s = { 1, 123, 2, 98765, 1234567.0 };
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(setStruct16:)];
    [invocation setTarget:object];
    [invocation setArgument:&s atIndex:2];
    [invocation invoke];
    [invocation release];
}

void invocation_flag(id object)
{
    BOOL flag;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(flag)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&flag];
    [invocation release];
    printf("flag: value = %d\n", flag);
}

void invocation_shortValue(id object)
{
    short aShort;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(shortValue)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&aShort];
    [invocation release];
    printf("shortValue: value = %hd\n", aShort);
}

void invocation_intValue(id object)
{
    int anInt;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(intValue)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&anInt];
    [invocation release];
    printf("intValue: value = %d\n", anInt);
}

void invocation_floatValue(id object)
{
    float aFloat;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(floatValue)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&aFloat];
    [invocation release];
    printf("floatValue: value = %f\n", aFloat);
}

void invocation_doubleValue(id object)
{
    double aDouble;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(doubleValue)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&aDouble];
    [invocation release];
    printf("doubleValue: value = %f\n", aDouble);
}

void invocation_string(id object)
{
    char* string;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(string)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&string];
    [invocation release];
    printf("string: value = '%s'\n", string);
}

void invocation_struct1(id object)
{
    Struct1 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct1)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct1:\nc = %d\n", (int)s.c);
}

void invocation_struct2(id object)
{
    Struct2 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct2)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct2:\ns = %hd\n", s.s);
}

void invocation_struct3(id object)
{
    Struct3 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct3)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct3:\ns = %hd\nc = %d\n", s.s, (int)s.c);
}

void invocation_struct4(id object)
{
    Struct4 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct4)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct4:\ni = %d\n", s.i);
}

void invocation_struct5(id object)
{
    Struct5 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct5)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct5:\ni = %d\nc = %d\n", s.i, s.c);
}

void invocation_struct6(id object)
{
    Struct6 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct6)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct6:\ni = %d\ns = %hd\n", s.i, s.s);
}

void invocation_struct7(id object)
{
    Struct7 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct7)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct7:\ni = %d\ns = %hd\nc = %d\n", s.i, s.s, s.c);
}

void invocation_struct8(id object)
{
    Struct8 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct8)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct8:\ni = %d\nj = %d\n", s.i, s.j);
}

void invocation_struct9(id object)
{
    Struct9 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct9)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct9:\ni = %d\nj = %d\nc = %d\n", s.i, s.j, s.c);
}

void invocation_struct10(id object)
{
    Struct10 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct10)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct10:\ni = %d\nj = %d\ns = %hd\n", s.i, s.j, s.s);
}

void invocation_struct11(id object)
{
    Struct11 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct11)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct11:\ni = %d\nj = %d\ns = %hd\nc = %d\n", s.i, s.j, s.s, s.c);
}

void invocation_struct12(id object)
{
    Struct12 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct12)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct12:\nd = %f\ni = %d\n", s.d, s.i);
}

void invocation_struct13(id object)
{
    Struct13 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct13)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct13:\nd = %f\ni = %d\nc = %d\n", s.d, s.i, s.c);
}

void invocation_struct14(id object)
{
    Struct14 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct14)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct14:\nd = %f\ni = %d\ns = %hd\n", s.d, s.i, s.s);
}

void invocation_struct15(id object)
{
    Struct15 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct15)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct15:\nd = %f\ni = %d\ns = %hd\nc = %d\n", s.d, s.i, s.s, s.c);
}

void invocation_struct16(id object)
{
    Struct16 s;
    id invocation = [NSInvocation new];

    [invocation setSelector:@selector(struct16)];
    [invocation invokeWithTarget:object];
    [invocation getReturnValue:&s];
    [invocation release];
    printf("struct16:\nc1 = %d\ns = %hd\nc2 = %d\ni = %d\nd = %f\n",
	    (int)s.c1, s.s, (int)s.c2, s.i, s.d);
}

void forwarder_setFlag(id object)
{
    BOOL flag = 123;
    [object setFlag:flag];
}

void forwarder_setShortValue(id object)
{
    short aShort = 123;
    [object setShortValue:aShort];
}

void forwarder_setIntValue(id object)
{
    int anInt = 9876;
    [(MyObject*)object setIntValue:anInt];
}

void forwarder_setIntFloatDoubleValues(id object)
{
    [object setFlag:YES intValue:1234 floatValue:12345.0 doubleValue:98765.0];
}

void forwarder_setStruct1(id object)
{
    Struct1 s = { 12 };
    [object setStruct1:s];
}

void forwarder_setStruct2(id object)
{
    Struct2 s = { 123 };
    [object setStruct2:s];
}

void forwarder_setStruct3(id object)
{
    Struct3 s = { 123, 12 };
    [object setStruct3:s];
}

void forwarder_setStruct4(id object)
{
    Struct4 s = { 1234 };
    [object setStruct4:s];
}

void forwarder_setStruct5(id object)
{
    Struct5 s = { 1234, 12 };
    [object setStruct5:s];
}

void forwarder_setStruct6(id object)
{
    Struct6 s = { 9876, 123 };
    [object setStruct6:s];
}

void forwarder_setStruct7(id object)
{
    Struct7 s = { 9876, 123, 12 };
    [object setStruct7:s];
}

void forwarder_setStruct8(id object)
{
    Struct8 s = { 9876, 1234 };
    [object setStruct8:s];
}

void forwarder_setStruct9(id object)
{
    Struct9 s = { 9876, 1234, 12 };
    [object setStruct9:s];
}

void forwarder_setStruct10(id object)
{
    Struct10 s = { 9876, 5432, 123 };
    [object setStruct10:s];
}

void forwarder_setStruct11(id object)
{
    Struct11 s = { 9876, 5432, 123, 12 };
    [object setStruct11:s];
}

void forwarder_setStruct12(id object)
{
    Struct12 s = { 9876543.0, 12345 };
    [object setStruct12:s];
}

void forwarder_setStruct13(id object)
{
    Struct13 s = { 9876543.0, 12345, 12 };
    [object setStruct13:s];
}

void forwarder_setStruct14(id object)
{
    Struct14 s = { 9876543.0, 12345, 123 };
    [object setStruct14:s];
}

void forwarder_setStruct15(id object)
{
    Struct15 s = { 9876543.0, 12345, 123, 12 };
    [object setStruct15:s];
}

void forwarder_setStruct16(id object)
{
    Struct16 s = { 1, 123, 2, 98765, 1234567.0 };
    [object setStruct16:s];
}

void forwarder_flag(id object)
{
    BOOL flag = [object flag];
    printf("flag: value = %d\n", flag);
}

void forwarder_shortValue(id object)
{
    short aShort = [object shortValue];
    printf("shortValue: value = %hd\n", aShort);
}

void forwarder_intValue(id object)
{
    int anInt = [object intValue];
    printf("intValue: value = %d\n", anInt);
}

void forwarder_floatValue(id object)
{
    float aFloat = [object floatValue];
    printf("floatValue: value = %f\n", aFloat);
}

void forwarder_doubleValue(id object)
{
    double aDouble = [object doubleValue];
    printf("doubleValue: value = %f\n", aDouble);
}

void forwarder_struct1(id object)
{
    Struct1 s = [object struct1];
    printf("struct1:\nc = %d\n", (int)s.c);
}

void forwarder_struct2(id object)
{
    Struct2 s = [object struct2];
    printf("struct2:\ns = %hd\n", s.s);
}

void forwarder_struct3(id object)
{
    Struct3 s = [object struct3];
    printf("struct3:\ns = %hd\nc = %d\n", s.s, s.c);
}

void forwarder_struct4(id object)
{
    Struct4 s = [object struct4];
    printf("struct4:\ni = %d\n", s.i);
}

void forwarder_struct5(id object)
{
    Struct5 s = [object struct5];
    printf("struct5:\ni = %d\nc = %d\n", s.i, s.c);
}

void forwarder_struct6(id object)
{
    Struct6 s = [object struct6];
    printf("struct6:\ni = %d\ns = %hd\n", s.i, s.s);
}

void forwarder_struct7(id object)
{
    Struct7 s = [object struct7];
    printf("struct7:\ni = %d\ns = %hd\nc = %d\n", s.i, s.s, s.c);
}

void forwarder_struct8(id object)
{
    Struct8 s = [object struct8];
    printf("struct8:\ni = %d\nj = %d\n", s.i, s.j);
}

void forwarder_struct9(id object)
{
    Struct9 s = [object struct9];
    printf("struct9:\ni = %d\nj = %d\nc = %d\n", s.i, s.j, s.c);
}

void forwarder_struct10(id object)
{
    Struct10 s = [object struct10];
    printf("struct10:\ni = %d\nj = %d\ns = %hd\n", s.i, s.j, s.s);
}

void forwarder_struct11(id object)
{
    Struct11 s = [object struct11];
    printf("struct11:\ni = %d\nj = %d\ns = %hd\nc = %d\n", s.i, s.j, s.s, s.c);
}

void forwarder_struct12(id object)
{
    Struct12 s = [object struct12];
    printf("struct12:\nd = %f\ni = %d\n", s.d, s.i);
}

void forwarder_struct13(id object)
{
    Struct13 s = [object struct13];
    printf("struct13:\nd = %f\ni = %d\nc = %d\n", s.d, s.i, s.c);
}

void forwarder_struct14(id object)
{
    Struct14 s = [object struct14];
    printf("struct14:\nd = %f\ni = %d\ns = %hd\n", s.d, s.i, s.s);
}

void forwarder_struct15(id object)
{
    Struct15 s = [object struct15];
    printf("struct15:\nd = %f\ni = %d\ns = %hd\nc = %d\n", s.d, s.i, s.s, s.c);
}

void forwarder_struct16(id object)
{
    Struct16 s = [object struct16];
    printf("struct16:\nc1 = %d\ns = %hd\nc2 = %d\ni = %d\nd = %f\n",
				(int)s.c1, s.s, (int)s.c2, s.i, s.d);
}

void setReturnValue_flag(id invocation)
{
    BOOL flag = 78;
    [invocation setReturnValue:&flag];
}

void setReturnValue_shortValue(id invocation)
{
    short value = 456;
    [invocation setReturnValue:&value];
}

void setReturnValue_intValue(id invocation)
{
    int value = 2345;
    [invocation setReturnValue:&value];
}

void setReturnValue_floatValue(id invocation)
{
    float value = 34567.0;
    [invocation setReturnValue:&value];
}

void setReturnValue_doubleValue(id invocation)
{
    double value = 45678.0;
    [invocation setReturnValue:&value];
}

void setReturnValue_struct1(id invocation)
{
    Struct1 s = { 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct2(id invocation)
{
    Struct2 s = { 234 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct3(id invocation)
{
    Struct3 s = { 234, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct4(id invocation)
{
    Struct4 s = { 2345 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct5(id invocation)
{
    Struct5 s = { 2345, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct6(id invocation)
{
    Struct6 s = { 2345, 234 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct7(id invocation)
{
    Struct7 s = { 2345, 234, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct8(id invocation)
{
    Struct8 s = { 2345, 5678 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct9(id invocation)
{
    Struct9 s = { 2345, 5678, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct10(id invocation)
{
    Struct10 s = { 2345, 5678, 234 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct11(id invocation)
{
    Struct11 s = { 2345, 5678, 234, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct12(id invocation)
{
    Struct12 s = { 3456789.0, 2345 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct13(id invocation)
{
    Struct13 s = { 3456789.0, 2345, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct14(id invocation)
{
    Struct14 s = { 3456789.0, 2345, 234 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct15(id invocation)
{
    Struct15 s = { 3456789.0, 2345, 234, 78 };
    [invocation setReturnValue:&s];
}

void setReturnValue_struct16(id invocation)
{
    Struct16 s = { 78, 234, 89, 2345, 3456789.0 };
    [invocation setReturnValue:&s];
}
