]> git.wincent.com - WOTest.git/blob - NSMethodSignature+WOTest.m
b483115d809199d81dc303f08fc17dd2755f9625
[WOTest.git] / NSMethodSignature+WOTest.m
1 //
2 //  NSMethodSignature+WOTest.m
3 //  WOTest
4 //
5 //  Created by Wincent Colaiuta on 30 January 2006.
6 //
7 //  Copyright 2006-2007 Wincent Colaiuta.
8 //  This program is free software: you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License as published by
10 //  the Free Software Foundation, either version 3 of the License, or
11 //  (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 //
21
22 #import "NSMethodSignature+WOTest.h"
23 #import <objc/objc-class.h>
24
25 /*
26
27  The real 10.4 NSMethodSignature API (obtained using class-dump; TODO: run class-dump to get 10.5 API):
28
29 @interface NSMethodSignature : NSObject
30 {
31     char *_types;
32     int _nargs;
33     unsigned int _sizeofParams;
34     unsigned int _returnValueLength;
35     void *_parmInfoP;
36     int *_fixup;
37     void *_reserved;
38 }
39
40 + (id)signatureWithObjCTypes:(const char *)fp8;
41 - (BOOL)_isReturnStructInRegisters;
42 - (id)retain;
43 - (void)release;
44 - (unsigned int)retainCount;
45 - (const char *)methodReturnType;  // PUBLIC
46 - (unsigned int)methodReturnLength; // PUBLIC
47 - (BOOL)isOneway; // PUBLIC
48 - (const char *)getArgumentTypeAtIndex:(unsigned int)fp8; // PUBLIC
49 - (struct _arginfo)_argumentInfoAtIndex:(unsigned int)fp8;
50 - (unsigned int)frameLength; // PUBLIC
51 - (unsigned int)numberOfArguments; // PUBLIC
52 - (id)description;
53 - (id)debugDescription;
54
55 @end
56
57 The public API:
58
59 @interface NSMethodSignature : NSObject {
60     @private
61     const char  *_types;
62     int         _nargs;
63     unsigned    _sizeofParams;
64     unsigned    _returnValueLength;
65     void        *_parmInfoP;
66     int         *_fixup;
67     void        *_reserved;
68 }
69
70 - (unsigned)numberOfArguments;
71 - (const char *)getArgumentTypeAtIndex:(unsigned)index;
72 - (unsigned)frameLength;
73 - (BOOL)isOneway;
74 - (const char *)methodReturnType;
75 - (unsigned)methodReturnLength;
76
77 @end
78
79 Many public implementations of that use NSProxy subclasses to implement trampolines make use of the signatureWithObjCTypes: private API.
80
81 Examples: OCMock
82 http://www.cocoadev.com/index.pl?LSTrampoline
83 http://www.cocoadev.com/index.pl?BSTrampoline
84
85 See also http://www.stuffonfire.com/2005/12/signaturewithobjctypes_is_stil.html
86
87  */
88
89 @interface NSMethodSignature (WOApplePrivate)
90
91 /*! Private Apple API. */
92 + (id)signatureWithObjCTypes:(const char *)fp8;
93
94 @end
95
96 @interface NSMethodSignature (WOPrivate)
97
98 - (id)initWithObjCTypes:(const char *)types;
99
100 @end
101
102 @implementation NSMethodSignature (WOTest)
103
104 + (id)WOTest_signatureBasedOnObjCTypes:(const char *)types
105 {
106     NSParameterAssert(types != NULL);
107
108 #ifdef WO_USE_OWN_METHOD_SIGNATURE_IMPLEMENTATION
109
110     return [[[self alloc] initWithObjCTypes:types] autorelease];
111
112 #else /* use private Apple API */
113
114     NSAssert([self respondsToSelector:@selector(signatureWithObjCTypes:)],
115              @"signatureWithObjCTypes: selector not recognized");
116     return [self signatureWithObjCTypes:types];
117
118 #endif
119
120 }
121
122 - (id)initWithObjCTypes:(const char *)types
123 {
124     NSParameterAssert(types != NULL);
125     if ((self = [super init]))
126     {
127         // TODO: finish implementation
128         // loop through args
129 /*        unsigned method_getNumberOfArguments(Method);
130         unsigned method_getSizeOfArguments(Method); */
131
132         // I hate using private Apple APIs, even ones that appear stable, but
133         // not sure that meddling with these instance variables is a good idea
134     }
135     return self;
136 }
137
138 @end