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