|
|
1.1 ! root 1: /* The implementation of class Object for Objective-C. ! 2: Copyright (C) 1993 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify it ! 7: under the terms of the GNU General Public License as published by the ! 8: Free Software Foundation; either version 2, or (at your option) any ! 9: later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, but WITHOUT ! 12: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ! 13: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ! 14: License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: /* As a special exception, if you link this library with files compiled ! 21: with GCC to produce an executable, this does not cause the resulting ! 22: executable to be covered by the GNU General Public License. This ! 23: exception does not however invalidate any other reasons why the ! 24: executable file might be covered by the GNU General Public License. */ ! 25: ! 26: #include "objc/Object.h" ! 27: #include "objc/Protocol.h" ! 28: #include "objc/objc-api.h" ! 29: ! 30: #include "gstdarg.h" ! 31: extern void (*_objc_error)(id object, const char *format, va_list); ! 32: ! 33: extern int errno; ! 34: ! 35: #define MAX_CLASS_NAME_LEN 256 ! 36: ! 37: @implementation Object ! 38: ! 39: + initialize ! 40: { ! 41: return self; ! 42: } ! 43: ! 44: - init ! 45: { ! 46: return self; ! 47: } ! 48: ! 49: + new ! 50: { ! 51: return [[self alloc] init]; ! 52: } ! 53: ! 54: + alloc ! 55: { ! 56: return class_create_instance(self); ! 57: } ! 58: ! 59: - free ! 60: { ! 61: return object_dispose(self); ! 62: } ! 63: ! 64: - copy ! 65: { ! 66: return [[self shallowCopy] deepen]; ! 67: } ! 68: ! 69: - shallowCopy ! 70: { ! 71: return object_copy(self); ! 72: } ! 73: ! 74: - deepen ! 75: { ! 76: return self; ! 77: } ! 78: ! 79: - deepCopy ! 80: { ! 81: return [self copy]; ! 82: } ! 83: ! 84: - (Class*)class ! 85: { ! 86: return object_get_class(self); ! 87: } ! 88: ! 89: - (Class*)superClass ! 90: { ! 91: return object_get_super_class(self); ! 92: } ! 93: ! 94: - (MetaClass*)metaClass ! 95: { ! 96: return object_get_meta_class(self); ! 97: } ! 98: ! 99: - (const char *)name ! 100: { ! 101: return object_get_class_name(self); ! 102: } ! 103: ! 104: - self ! 105: { ! 106: return self; ! 107: } ! 108: ! 109: - (unsigned int)hash ! 110: { ! 111: return (size_t)self; ! 112: } ! 113: ! 114: - (BOOL)isEqual:anObject ! 115: { ! 116: return self==anObject; ! 117: } ! 118: ! 119: - (BOOL)isMetaClass ! 120: { ! 121: return NO; ! 122: } ! 123: ! 124: - (BOOL)isClass ! 125: { ! 126: return object_is_class(self); ! 127: } ! 128: ! 129: - (BOOL)isInstance ! 130: { ! 131: return object_is_instance(self); ! 132: } ! 133: ! 134: - (BOOL)isKindOf:(Class*)aClassObject ! 135: { ! 136: Class* class; ! 137: ! 138: for (class = self->isa; class!=Nil; class = class_get_super_class(class)) ! 139: if (class==aClassObject) ! 140: return YES; ! 141: return NO; ! 142: } ! 143: ! 144: - (BOOL)isMemberOf:(Class*)aClassObject ! 145: { ! 146: return self->isa==aClassObject; ! 147: } ! 148: ! 149: - (BOOL)isKindOfClassNamed:(const char *)aClassName ! 150: { ! 151: Class* class; ! 152: ! 153: if (aClassName!=NULL) ! 154: for (class = self->isa; class!=Nil; class = class_get_super_class(class)) ! 155: if (!strcmp(class_get_class_name(class), aClassName)) ! 156: return YES; ! 157: return NO; ! 158: } ! 159: ! 160: - (BOOL)isMemberOfClassNamed:(const char *)aClassName ! 161: { ! 162: return ((aClassName!=NULL) ! 163: &&!strcmp(class_get_class_name(self->isa), aClassName)); ! 164: } ! 165: ! 166: + (BOOL)instancesRespondTo:(SEL)aSel ! 167: { ! 168: return class_get_instance_method(self, aSel)!=METHOD_NULL; ! 169: } ! 170: ! 171: - (BOOL)respondsTo:(SEL)aSel ! 172: { ! 173: return ((object_is_instance(self) ! 174: ?class_get_instance_method(self->isa, aSel) ! 175: :class_get_class_method(self->isa, aSel))!=METHOD_NULL); ! 176: } ! 177: ! 178: + (IMP)instanceMethodFor:(SEL)aSel ! 179: { ! 180: return method_get_imp(class_get_instance_method(self, aSel)); ! 181: } ! 182: ! 183: // Indicates if the receiving class or instance conforms to the given protocol ! 184: // not usually overridden by subclasses ! 185: - (BOOL) conformsTo: (Protocol*)aProtocol ! 186: { ! 187: int i; ! 188: struct objc_protocol_list* proto_list; ! 189: ! 190: for (proto_list = isa->protocols; ! 191: proto_list; proto_list = proto_list->next) ! 192: { ! 193: for (i=0; i < proto_list->count; i++) ! 194: { ! 195: if ([proto_list->list[i] conformsTo: aProtocol]) ! 196: return YES; ! 197: } ! 198: } ! 199: ! 200: if ([self superClass]) ! 201: return [[self superClass] conformsTo: aProtocol]; ! 202: else ! 203: return NO; ! 204: } ! 205: ! 206: - (IMP)methodFor:(SEL)aSel ! 207: { ! 208: return (method_get_imp(object_is_instance(self) ! 209: ?class_get_instance_method(self->isa, aSel) ! 210: :class_get_class_method(self->isa, aSel))); ! 211: } ! 212: ! 213: + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel ! 214: { ! 215: return ((struct objc_method_description *) ! 216: class_get_instance_method(self, aSel)); ! 217: } ! 218: ! 219: - (struct objc_method_description *)descriptionForMethod:(SEL)aSel ! 220: { ! 221: return ((struct objc_method_description *) ! 222: (object_is_instance(self) ! 223: ?class_get_instance_method(self->isa, aSel) ! 224: :class_get_class_method(self->isa, aSel))); ! 225: } ! 226: ! 227: - perform:(SEL)aSel ! 228: { ! 229: IMP msg = objc_msg_lookup(self, aSel); ! 230: if (!msg) ! 231: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 232: return (*msg)(self, aSel); ! 233: } ! 234: ! 235: - perform:(SEL)aSel with:anObject ! 236: { ! 237: IMP msg = objc_msg_lookup(self, aSel); ! 238: if (!msg) ! 239: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 240: return (*msg)(self, aSel, anObject); ! 241: } ! 242: ! 243: - perform:(SEL)aSel with:anObject1 with:anObject2 ! 244: { ! 245: IMP msg = objc_msg_lookup(self, aSel); ! 246: if (!msg) ! 247: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 248: return (*msg)(self, aSel, anObject1, anObject2); ! 249: } ! 250: ! 251: - forward:(SEL)aSel :(arglist_t)argFrame ! 252: { ! 253: return [self doesNotRecognize: aSel]; ! 254: } ! 255: ! 256: - performv:(SEL)aSel :(arglist_t)argFrame ! 257: { ! 258: return objc_msg_sendv(self, aSel, method_get_argsize(0), argFrame); ! 259: } ! 260: ! 261: + poseAs:(Class*)aClassObject ! 262: { ! 263: return class_pose_as(self, aClassObject); ! 264: } ! 265: ! 266: - (Class*)transmuteClassTo:(Class*)aClassObject ! 267: { ! 268: if (object_is_instance(self)) ! 269: if (class_is_class(aClassObject)) ! 270: if (class_get_instance_size(aClassObject)==class_get_instance_size(isa)) ! 271: if ([self isKindOf:aClassObject]) ! 272: { ! 273: Class* old_isa = isa; ! 274: isa = aClassObject; ! 275: return old_isa; ! 276: } ! 277: return nil; ! 278: } ! 279: ! 280: - subclassResponsibility:(SEL)aSel ! 281: { ! 282: return [self error:"subclass should override %s", sel_get_name(aSel)]; ! 283: } ! 284: ! 285: - notImplemented:(SEL)aSel ! 286: { ! 287: return [self error:"method %s not implemented", sel_get_name(aSel)]; ! 288: } ! 289: ! 290: - doesNotRecognize:(SEL)aSel ! 291: { ! 292: return [self error:"%s does not recognize %s", ! 293: object_get_class_name(self), sel_get_name(aSel)]; ! 294: } ! 295: ! 296: - error:(const char *)aString, ... ! 297: { ! 298: #define FMT "error: %s (%s)\n%s\n" ! 299: char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self)) ! 300: +((aString!=NULL)?strlen((char*)aString):0)+8)]; ! 301: va_list ap; ! 302: ! 303: sprintf(fmt, FMT, object_get_class_name(self), ! 304: object_is_instance(self)?"instance":"class", ! 305: (aString!=NULL)?aString:""); ! 306: va_start(ap, aString); ! 307: (*_objc_error)(self, fmt, ap); ! 308: va_end(ap); ! 309: return nil; ! 310: #undef FMT ! 311: } ! 312: ! 313: + (int)version ! 314: { ! 315: return class_get_version(self); ! 316: } ! 317: ! 318: + setVersion:(int)aVersion ! 319: { ! 320: class_set_version(self, aVersion); ! 321: return self; ! 322: } ! 323: ! 324: + (int)streamVersion: (TypedStream*)aStream ! 325: { ! 326: #ifndef __alpha__ ! 327: if (aStream->mode == OBJC_READONLY) ! 328: return objc_get_stream_class_version (aStream, self); ! 329: else ! 330: #endif ! 331: return class_get_version (self); ! 332: } ! 333: ! 334: // These are used to write or read the instance variables ! 335: // declared in this particular part of the object. Subclasses ! 336: // should extend these, by calling [super read/write: aStream] ! 337: // before doing their own archiving. These methods are private, in ! 338: // the sense that they should only be called from subclasses. ! 339: ! 340: - read: (TypedStream*)aStream ! 341: { ! 342: // [super read: aStream]; ! 343: return self; ! 344: } ! 345: ! 346: - write: (TypedStream*)aStream ! 347: { ! 348: // [super write: aStream]; ! 349: return self; ! 350: } ! 351: ! 352: - awake ! 353: { ! 354: // [super awake]; ! 355: return self; ! 356: } ! 357: ! 358: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.