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