|
|
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.