|
|
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:
1.1.1.2 ! root 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:
1.1 root 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: {
1.1.1.2 ! root 270: return objc_msg_sendv(self, aSel, argFrame);
1.1 root 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:
1.1.1.2 ! root 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:
1.1 root 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: - error:(const char *)aString, ...
315: {
316: #define FMT "error: %s (%s)\n%s\n"
317: char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
318: +((aString!=NULL)?strlen((char*)aString):0)+8)];
319: va_list ap;
320:
321: sprintf(fmt, FMT, object_get_class_name(self),
322: object_is_instance(self)?"instance":"class",
323: (aString!=NULL)?aString:"");
324: va_start(ap, aString);
325: (*_objc_error)(self, fmt, ap);
326: va_end(ap);
327: return nil;
328: #undef FMT
329: }
330:
331: + (int)version
332: {
333: return class_get_version(self);
334: }
335:
336: + setVersion:(int)aVersion
337: {
338: class_set_version(self, aVersion);
339: return self;
340: }
341:
342: + (int)streamVersion: (TypedStream*)aStream
343: {
344: #ifndef __alpha__
345: if (aStream->mode == OBJC_READONLY)
346: return objc_get_stream_class_version (aStream, self);
347: else
348: #endif
349: return class_get_version (self);
350: }
351:
352: // These are used to write or read the instance variables
353: // declared in this particular part of the object. Subclasses
354: // should extend these, by calling [super read/write: aStream]
355: // before doing their own archiving. These methods are private, in
356: // the sense that they should only be called from subclasses.
357:
358: - read: (TypedStream*)aStream
359: {
360: // [super read: aStream];
361: return self;
362: }
363:
364: - write: (TypedStream*)aStream
365: {
366: // [super write: aStream];
367: return self;
368: }
369:
370: - awake
371: {
372: // [super awake];
373: return self;
374: }
375:
376: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.