|
|
1.1 ! root 1: /* The implementation of class Object for Objective-C. ! 2: Copyright (C) 1993, 1994 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: - (int)compare:anotherObject; ! 120: { ! 121: if ([self isEqual:anotherObject]) ! 122: return 0; ! 123: // Ordering objects by their address is pretty useless, ! 124: // so subclasses should override this is some useful way. ! 125: else if (self > anotherObject) ! 126: return 1; ! 127: else ! 128: return -1; ! 129: } ! 130: ! 131: - (BOOL)isMetaClass ! 132: { ! 133: return NO; ! 134: } ! 135: ! 136: - (BOOL)isClass ! 137: { ! 138: return object_is_class(self); ! 139: } ! 140: ! 141: - (BOOL)isInstance ! 142: { ! 143: return object_is_instance(self); ! 144: } ! 145: ! 146: - (BOOL)isKindOf:(Class*)aClassObject ! 147: { ! 148: Class* class; ! 149: ! 150: for (class = self->isa; class!=Nil; class = class_get_super_class(class)) ! 151: if (class==aClassObject) ! 152: return YES; ! 153: return NO; ! 154: } ! 155: ! 156: - (BOOL)isMemberOf:(Class*)aClassObject ! 157: { ! 158: return self->isa==aClassObject; ! 159: } ! 160: ! 161: - (BOOL)isKindOfClassNamed:(const char *)aClassName ! 162: { ! 163: Class* class; ! 164: ! 165: if (aClassName!=NULL) ! 166: for (class = self->isa; class!=Nil; class = class_get_super_class(class)) ! 167: if (!strcmp(class_get_class_name(class), aClassName)) ! 168: return YES; ! 169: return NO; ! 170: } ! 171: ! 172: - (BOOL)isMemberOfClassNamed:(const char *)aClassName ! 173: { ! 174: return ((aClassName!=NULL) ! 175: &&!strcmp(class_get_class_name(self->isa), aClassName)); ! 176: } ! 177: ! 178: + (BOOL)instancesRespondTo:(SEL)aSel ! 179: { ! 180: return class_get_instance_method(self, aSel)!=METHOD_NULL; ! 181: } ! 182: ! 183: - (BOOL)respondsTo:(SEL)aSel ! 184: { ! 185: return ((object_is_instance(self) ! 186: ?class_get_instance_method(self->isa, aSel) ! 187: :class_get_class_method(self->isa, aSel))!=METHOD_NULL); ! 188: } ! 189: ! 190: + (IMP)instanceMethodFor:(SEL)aSel ! 191: { ! 192: return method_get_imp(class_get_instance_method(self, aSel)); ! 193: } ! 194: ! 195: // Indicates if the receiving class or instance conforms to the given protocol ! 196: // not usually overridden by subclasses ! 197: - (BOOL) conformsTo: (Protocol*)aProtocol ! 198: { ! 199: int i; ! 200: struct objc_protocol_list* proto_list; ! 201: ! 202: for (proto_list = isa->protocols; ! 203: proto_list; proto_list = proto_list->next) ! 204: { ! 205: for (i=0; i < proto_list->count; i++) ! 206: { ! 207: if ([proto_list->list[i] conformsTo: aProtocol]) ! 208: return YES; ! 209: } ! 210: } ! 211: ! 212: if ([self superClass]) ! 213: return [[self superClass] conformsTo: aProtocol]; ! 214: else ! 215: return NO; ! 216: } ! 217: ! 218: - (IMP)methodFor:(SEL)aSel ! 219: { ! 220: return (method_get_imp(object_is_instance(self) ! 221: ?class_get_instance_method(self->isa, aSel) ! 222: :class_get_class_method(self->isa, aSel))); ! 223: } ! 224: ! 225: + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel ! 226: { ! 227: return ((struct objc_method_description *) ! 228: class_get_instance_method(self, aSel)); ! 229: } ! 230: ! 231: - (struct objc_method_description *)descriptionForMethod:(SEL)aSel ! 232: { ! 233: return ((struct objc_method_description *) ! 234: (object_is_instance(self) ! 235: ?class_get_instance_method(self->isa, aSel) ! 236: :class_get_class_method(self->isa, aSel))); ! 237: } ! 238: ! 239: - perform:(SEL)aSel ! 240: { ! 241: IMP msg = objc_msg_lookup(self, aSel); ! 242: if (!msg) ! 243: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 244: return (*msg)(self, aSel); ! 245: } ! 246: ! 247: - perform:(SEL)aSel with:anObject ! 248: { ! 249: IMP msg = objc_msg_lookup(self, aSel); ! 250: if (!msg) ! 251: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 252: return (*msg)(self, aSel, anObject); ! 253: } ! 254: ! 255: - perform:(SEL)aSel with:anObject1 with:anObject2 ! 256: { ! 257: IMP msg = objc_msg_lookup(self, aSel); ! 258: if (!msg) ! 259: return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; ! 260: return (*msg)(self, aSel, anObject1, anObject2); ! 261: } ! 262: ! 263: - forward:(SEL)aSel :(arglist_t)argFrame ! 264: { ! 265: return [self doesNotRecognize: aSel]; ! 266: } ! 267: ! 268: - performv:(SEL)aSel :(arglist_t)argFrame ! 269: { ! 270: return objc_msg_sendv(self, aSel, argFrame); ! 271: } ! 272: ! 273: + poseAs:(Class*)aClassObject ! 274: { ! 275: return class_pose_as(self, aClassObject); ! 276: } ! 277: ! 278: - (Class*)transmuteClassTo:(Class*)aClassObject ! 279: { ! 280: if (object_is_instance(self)) ! 281: if (class_is_class(aClassObject)) ! 282: if (class_get_instance_size(aClassObject)==class_get_instance_size(isa)) ! 283: if ([self isKindOf:aClassObject]) ! 284: { ! 285: Class* old_isa = isa; ! 286: isa = aClassObject; ! 287: return old_isa; ! 288: } ! 289: return nil; ! 290: } ! 291: ! 292: - subclassResponsibility:(SEL)aSel ! 293: { ! 294: return [self error:"subclass should override %s", sel_get_name(aSel)]; ! 295: } ! 296: ! 297: - notImplemented:(SEL)aSel ! 298: { ! 299: return [self error:"method %s not implemented", sel_get_name(aSel)]; ! 300: } ! 301: ! 302: - shouldNotImplement:(SEL)aSel ! 303: { ! 304: return [self error:"%s should not implement %s", ! 305: object_get_class_name(self), sel_get_name(aSel)]; ! 306: } ! 307: ! 308: - doesNotRecognize:(SEL)aSel ! 309: { ! 310: return [self error:"%s does not recognize %s", ! 311: object_get_class_name(self), sel_get_name(aSel)]; ! 312: } ! 313: ! 314: #ifdef __alpha__ ! 315: extern size_t strlen(const char*); ! 316: #endif ! 317: ! 318: - error:(const char *)aString, ... ! 319: { ! 320: #define FMT "error: %s (%s)\n%s\n" ! 321: char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self)) ! 322: +((aString!=NULL)?strlen((char*)aString):0)+8)]; ! 323: va_list ap; ! 324: ! 325: sprintf(fmt, FMT, object_get_class_name(self), ! 326: object_is_instance(self)?"instance":"class", ! 327: (aString!=NULL)?aString:""); ! 328: va_start(ap, aString); ! 329: (*_objc_error)(self, fmt, ap); ! 330: va_end(ap); ! 331: return nil; ! 332: #undef FMT ! 333: } ! 334: ! 335: + (int)version ! 336: { ! 337: return class_get_version(self); ! 338: } ! 339: ! 340: + setVersion:(int)aVersion ! 341: { ! 342: class_set_version(self, aVersion); ! 343: return self; ! 344: } ! 345: ! 346: + (int)streamVersion: (TypedStream*)aStream ! 347: { ! 348: if (aStream->mode == OBJC_READONLY) ! 349: return objc_get_stream_class_version (aStream, self); ! 350: else ! 351: return class_get_version (self); ! 352: } ! 353: ! 354: // These are used to write or read the instance variables ! 355: // declared in this particular part of the object. Subclasses ! 356: // should extend these, by calling [super read/write: aStream] ! 357: // before doing their own archiving. These methods are private, in ! 358: // the sense that they should only be called from subclasses. ! 359: ! 360: - read: (TypedStream*)aStream ! 361: { ! 362: // [super read: aStream]; ! 363: return self; ! 364: } ! 365: ! 366: - write: (TypedStream*)aStream ! 367: { ! 368: // [super write: aStream]; ! 369: return self; ! 370: } ! 371: ! 372: - awake ! 373: { ! 374: // [super awake]; ! 375: return self; ! 376: } ! 377: ! 378: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.