|
|
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: Protocol.h
26: Copyright 1991 NeXT, Inc.
27: */
28:
29: #ifdef SHLIB
30: #import "shlib.h"
31: #endif SHLIB
32:
33: #include "objc-private.h"
34: #import "Protocol.h"
35: #import "maptable.h"
36: #include <mach-o/ldsyms.h>
37: #include "objc-runtime.h"
38: #include <stdlib.h>
39: #ifndef KERNEL
40: #include <mach-o/dyld.h>
41: #endif /* KERNEL */
42:
43: /* some forward declarations */
44:
45: static struct objc_method_description *
46: lookup_method(struct objc_method_description_list *mlist, SEL aSel);
47:
48: static struct objc_method_description *
49: lookup_class_method(struct objc_protocol_list *plist, SEL aSel);
50:
51: static struct objc_method_description *
52: lookup_instance_method(struct objc_protocol_list *plist, SEL aSel);
53:
54: @implementation Protocol
55:
56: + _fixup: (Protocol *)protos numElements: (int) nentries
57: {
58: int i;
59:
60: for (i = 0; i < nentries; i++)
61: {
62: /* isa has been overloaded by the compiler to indicate version info */
63:
64: /* Versions 0 and 1 will never ship; for internal compatibility only.
65: Compensate for new "next" field in struct objc_protocol_list. */
66: if ((int) protos[i].isa <= 1 && protos[i].protocol_list)
67: (char *) protos[i].protocol_list -= 4;
68:
69: /* In version 0 protocols were referenced by name. */
70: if ((int) protos[i].isa == 0 && protos[i].protocol_list)
71: {
72: _objc_inform ("Unable to install protocols by name...\n");
73: _objc_inform ("Protocol %s must be recompiled.\n",
74: protos[i].protocol_name);
75: }
76:
77: protos[i].isa = self; // install the class descriptor.
78: }
79:
80: return self;
81: }
82:
83:
84: - (BOOL) conformsTo: (Protocol *)aProtocolObj
85: {
86: if (!aProtocolObj)
87: return NO;
88:
89: if (strcmp(aProtocolObj->protocol_name, protocol_name) == 0)
90: return YES;
91: else if (protocol_list)
92: {
93: int i;
94:
95: for (i = 0; i < protocol_list->count; i++)
96: {
97: Protocol *p = protocol_list->list[i];
98:
99: if (strcmp(aProtocolObj->protocol_name, p->protocol_name) == 0)
100: return YES;
101:
102: if ([p conformsTo:aProtocolObj])
103: return YES;
104: }
105: return NO;
106: }
107: else
108: return NO;
109: }
110:
111: - (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel
112: {
113: struct objc_method_description *m = lookup_method(instance_methods, aSel);
114:
115: if (!m && protocol_list)
116: m = lookup_instance_method(protocol_list, aSel);
117:
118: return m;
119: }
120:
121: - (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel
122: {
123: struct objc_method_description *m = lookup_method(class_methods, aSel);
124:
125: if (!m && protocol_list)
126: m = lookup_class_method(protocol_list, aSel);
127:
128: return m;
129: }
130:
131: - (const char *)name
132: {
133: return protocol_name;
134: }
135:
136: static
137: struct objc_method_description *
138: lookup_method(struct objc_method_description_list *mlist, SEL aSel)
139: {
140: if (mlist)
141: {
142: int i;
143: for (i = 0; i < mlist->count; i++)
144: if (mlist->list[i].name == aSel)
145: return mlist->list+i;
146: }
147: return 0;
148: }
149:
150: static
151: struct objc_method_description *
152: lookup_instance_method(struct objc_protocol_list *plist, SEL aSel)
153: {
154: int i;
155: struct objc_method_description *m = 0;
156:
157: for (i = 0; i < plist->count; i++)
158: {
159: if (plist->list[i]->instance_methods)
160: m = lookup_method(plist->list[i]->instance_methods, aSel);
161:
162: /* depth first search */
163: if (!m && plist->list[i]->protocol_list)
164: m = lookup_instance_method(plist->list[i]->protocol_list, aSel);
165:
166: if (m)
167: return m;
168: }
169: return 0;
170: }
171:
172: static
173: struct objc_method_description *
174: lookup_class_method(struct objc_protocol_list *plist, SEL aSel)
175: {
176: int i;
177: struct objc_method_description *m = 0;
178:
179: for (i = 0; i < plist->count; i++)
180: {
181: if (plist->list[i]->class_methods)
182: m = lookup_method(plist->list[i]->class_methods, aSel);
183:
184: /* depth first search */
185: if (!m && plist->list[i]->protocol_list)
186: m = lookup_class_method(plist->list[i]->protocol_list, aSel);
187:
188: if (m)
189: return m;
190: }
191: return 0;
192: }
193:
194: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.