Annotation of objc/Test/forward-simple.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.0 (the 'License').  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License."
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: #import <objc/Object.h>
        !            26: #import <objc/HashTable.h>
        !            27: #import <float.h>
        !            28: #import <stdarg.h>
        !            29: 
        !            30: struct foo 
        !            31: {
        !            32:        int i;
        !            33:        char c;
        !            34:        float f;
        !            35:        char *s;
        !            36: };
        !            37: 
        !            38: static void foo_display(struct foo *s, int i)
        !            39: {
        !            40:     printf("arg[%d]->i = %d\n", i, s->i);
        !            41:     printf("arg[%d]->c = '%c'\n", i, s->c);
        !            42:     printf("arg[%d]->f = %f\n", i, s->f);
        !            43:     printf("arg[%d]->s = %s\n", i, s->s);
        !            44: };
        !            45: 
        !            46: struct large
        !            47: {
        !            48:        int a[50];
        !            49: };
        !            50: 
        !            51: @implementation Tool : Object
        !            52: 
        !            53: - large:(struct large)l small:(int)i
        !            54: {
        !            55:        return self;
        !            56: }
        !            57: 
        !            58: - varargs:(int)n, ... 
        !            59: {
        !            60:        va_list ap;
        !            61:        int i;
        !            62: 
        !            63:        va_start(ap, n); 
        !            64:        for (i = 0; i < n; i++)
        !            65:                printf("va_arg[%d] = %d ", i, va_arg(ap,int));
        !            66:        va_end(ap);
        !            67:        printf("\n");
        !            68: }
        !            69: 
        !            70: - double:(double)d char:(char)c float:(float)f double:(double)dd
        !            71: {
        !            72:        return self;
        !            73: }
        !            74: - incrementMe:(int)i
        !            75: {
        !            76:        printf("i = %d\n",i);
        !            77:        return self;
        !            78: }
        !            79: 
        !            80: - pointerToStructFoo:(struct foo *)s
        !            81: {
        !            82:        printf("i = %d c = '%c' f = %f s = %s\n",s->i,s->c,s->f,s->s);
        !            83: }
        !            84: 
        !            85: - structFoo:(struct foo)s
        !            86: {
        !            87:        printf("i = %d c = '%c' f = %f s = %s\n",s.i,s.c,s.f,s.s);
        !            88: }
        !            89: 
        !            90: - long:(long)l short:(short)a char:(char)c
        !            91: {
        !            92:        return self;
        !            93: }
        !            94: 
        !            95: - array:(int [7])ary 
        !            96: {
        !            97:        return self;
        !            98: }
        !            99: 
        !           100: @end
        !           101: 
        !           102: @implementation Forward : Object
        !           103: {
        !           104:        id destination;
        !           105: }
        !           106: 
        !           107: - setDestination:dest
        !           108: {
        !           109:        destination = dest;
        !           110: }
        !           111: 
        !           112: static int getTagLen(char *tag)
        !           113: {
        !           114:        int len = 0;
        !           115: 
        !           116:        while (*tag++ != _C_STRUCT_E) len++;
        !           117: 
        !           118:        return len;
        !           119: }
        !           120: 
        !           121: /*
        !           122:    Purpose:    Provide support required when forwarding messages 
        !           123:                to remote objects. -performv::, -methodArgSize:,
        !           124:                method_getNumberOfArguments(), method_getSizeOfArguments(),
        !           125:                and method_getArgumentInfo() provide additional support
        !           126:                for understanding the format of the stack. This level of
        !           127:                support is currently used exclusively by Workspace and
        !           128:                is part of the Unpublished API for Remote Objects.
        !           129: 
        !           130:    Semantics:  This function is responsible for two things:
        !           131:                (1) obtaining the object that does respond to the selector.
        !           132:                (2) sending the object the message via "performv::"     
        !           133:    Features:   (1) chance to analyze/transform arguments on the stack 
        !           134:                    before sending the message.
        !           135:                (2) chance to perform a post operation after sending 
        !           136:                    the message.
        !           137:    Limitations:        (1) cannot forward methods that take a variable number 
        !           138:                    of arguments.
        !           139:                (2) forwarding methods that return values greater than
        !           140:                    `sizeof(id)' are unreliable.
        !           141: */
        !           142: 
        !           143: - forward:(SEL)asel :(marg_list)args
        !           144: {
        !           145:        void *retval;
        !           146:        Method method;
        !           147:        int i, nargs;
        !           148: 
        !           149:        // analyze argument types of an anonymous (un-known) selector...
        !           150:        // ...necessary for doing remote objects.
        !           151: 
        !           152:        method = class_getInstanceMethod([destination class], asel);
        !           153:        nargs = method_getNumberOfArguments(method);
        !           154: 
        !           155:        for (i = 0; i < nargs; i++) {
        !           156:                char *type;
        !           157:                int offset;
        !           158: 
        !           159:                method_getArgumentInfo(method, i, &type, &offset);
        !           160: 
        !           161:                printf ("arg[%d] (offset = %d, type = '%c')",
        !           162:                        i, offset, type[0]);
        !           163: 
        !           164:                switch (type[0]) {
        !           165:                   case _C_ID:
        !           166:                        {
        !           167:                        id obj = marg_getValue(args, offset, id);
        !           168:                        printf(" = %s\n", [obj name]);
        !           169:                        break;
        !           170:                        }
        !           171:                   case _C_SEL:
        !           172:                        {
        !           173:                        SEL sel = marg_getValue(args, offset, SEL);
        !           174:                        printf(" = %s\n", sel_getName(sel));
        !           175:                        break;
        !           176:                        }
        !           177:                   case _C_CHARPTR:
        !           178:                        {
        !           179:                        char *str = marg_getValue(args, offset, char *);
        !           180:                        printf(" = %s\n", str);
        !           181:                        break;
        !           182:                        }
        !           183:                   case _C_LNG: case _C_INT:
        !           184:                        {
        !           185:                        long longVal = marg_getValue(args, offset, long);
        !           186:                        printf(" = %d\n", longVal);
        !           187: 
        !           188:                        if (asel == @selector(incrementMe:))
        !           189:                                marg_setValue(args, offset, long, ++longVal);
        !           190:                        break;
        !           191:                        }
        !           192:                   case _C_SHT:
        !           193:                        {
        !           194:                        short shortVal = marg_getValue(args, offset, short);
        !           195:                        printf(" = %d\n", shortVal); 
        !           196:                        break;
        !           197:                        }
        !           198:                   case _C_CHR:
        !           199:                        {
        !           200:                        char charVal = marg_getValue(args, offset, char);
        !           201:                        printf(" = '%c'\n", charVal);
        !           202:                        break;
        !           203:                        }
        !           204:                   case _C_FLT:
        !           205:                        {
        !           206:                        float floatVal = marg_getValue(args, offset, float);
        !           207:                        printf(" = %f\n", floatVal);
        !           208:                        break;
        !           209:                        }
        !           210:                   case _C_DBL:
        !           211:                        {
        !           212:                        double doubleVal = marg_getValue(args, offset, double);
        !           213:                        printf(" = %f\n", doubleVal);
        !           214:                        break;
        !           215:                        }
        !           216:                   case _C_PTR:
        !           217:                        {
        !           218:                        if (type[1] == _C_STRUCT_B) 
        !           219:                          {
        !           220:                          if (strncmp(&type[2], "foo", getTagLen(&type[2])) == 0) 
        !           221:                            {
        !           222:                            struct foo *s = marg_getValue(args, offset, struct foo *);
        !           223:                            foo_display(s, i);
        !           224:                            }
        !           225:                          }
        !           226:                        break;
        !           227:                        }
        !           228:                   case _C_STRUCT_B:
        !           229:                        {
        !           230:                        if (strncmp(&type[1], "foo", getTagLen(&type[1])) == 0) 
        !           231:                          {
        !           232:                          struct foo s = marg_getValue(args, offset, struct foo);
        !           233:                          foo_display(marg_getRef(args, offset, struct foo), i);
        !           234: 
        !           235:                          s.i++, s.c++, s.f++, s.s = "transformed string";
        !           236:                          marg_setValue(args, offset, struct foo, s);
        !           237:                          }
        !           238:                        break;
        !           239:                        }
        !           240:                   case _C_ARY_B:
        !           241:                        {
        !           242:                        printf("array type not recognized ('%s')\n", type);
        !           243:                        }
        !           244:                   default:
        !           245:                        printf("type not recognized ('%c')\n", type[0]);
        !           246:                        break;
        !           247:                }
        !           248:        }
        !           249:        retval = [destination performv:asel :args];
        !           250: 
        !           251:        return retval;
        !           252: }
        !           253: 
        !           254: @end
        !           255: 
        !           256: 
        !           257: main()
        !           258: {
        !           259:        id forward = [Forward new];
        !           260:        id tool = [Tool new];
        !           261: 
        !           262:        struct foo afoo = {33, 'y', 9.9, "great"};
        !           263:        struct large alarge;
        !           264:        int ary[7];
        !           265: 
        !           266:        [tool varargs:3, 1,2,3];
        !           267:        [tool long:77 short:7 char:'z'];
        !           268:        [tool incrementMe:100];
        !           269:        [tool pointerToStructFoo:&afoo];
        !           270:        [tool structFoo:afoo];
        !           271:        [tool double:4.4 char:'5' float:3.4 double:8.8];
        !           272:        [tool large:alarge small:7007];
        !           273:        [tool array:ary];
        !           274: 
        !           275:        [forward setDestination:tool];
        !           276: 
        !           277:        [forward varargs:3, 1,2,3];
        !           278:        [forward long:77 short:7 char:'z'];
        !           279:        [forward incrementMe:100];
        !           280:        [forward pointerToStructFoo:&afoo];
        !           281:        [forward structFoo:afoo];
        !           282:        [forward double:4.4 char:'5' float:3.4 double:8.8];
        !           283:        [forward large:alarge small:7007];
        !           284:        [forward array:ary];
        !           285:        printf("\n");
        !           286: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.