home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / objam01.lha / objam / objc / Object.m < prev    next >
Encoding:
Text File  |  1995-02-14  |  8.3 KB  |  438 lines

  1. /*
  2. ** ObjectiveAmiga: The implementation of class Object for Objective-C
  3. ** See GNU:lib/libobjam/ReadMe for details
  4. */
  5.  
  6.  
  7. #import "Object.h"
  8. #import "Protocol.h"
  9.  
  10. #include "objc-api.h"
  11.  
  12. #include <stdarg.h>
  13. #include <fcntl.h>
  14.  
  15. extern int errno;
  16.  
  17.  
  18. @implementation Object
  19.  
  20. + initialize
  21. {
  22.   return self;
  23. }
  24.  
  25. - init
  26. {
  27.   return self;
  28. }
  29.  
  30. + new
  31. {
  32.   return [[self alloc] init];
  33. }
  34.  
  35. + alloc
  36. {
  37.   return class_create_instance(self);
  38. }
  39.  
  40. + allocFromZone:(NXZone *)zone // NeXT only
  41. {
  42.   return class_create_instance_from_zone(self,zone);
  43. }
  44.  
  45. - free
  46. {
  47.   return object_dispose(self);
  48. }
  49.  
  50. - copy
  51. {
  52.   return [[self shallowCopy] deepen];
  53. }
  54.  
  55. - copyFromZone:(NXZone *)zone
  56. {
  57.   return [object_copy_from_zone(self,zone) deepen];
  58. }
  59.  
  60. - (NXZone *)zone // NeXT only
  61. {
  62.   return NXZoneFromPtr(self);
  63. }
  64.  
  65. - shallowCopy
  66. {
  67.   return object_copy(self);
  68. }
  69.  
  70. - deepen
  71. {
  72.   return self;
  73. }
  74.  
  75. - deepCopy
  76. {
  77.   return [self copy];
  78. }
  79.  
  80. - (OCClass*)class
  81. {
  82.   return object_get_class(self);
  83. }
  84.  
  85. - (OCClass*)superclass
  86. {
  87.   return object_get_super_class(self);
  88. }
  89.  
  90. - (OCClass*)superClass
  91. {
  92.   return object_get_super_class(self);
  93. }
  94.  
  95. - (MetaClass*)metaClass
  96. {
  97.   return object_get_meta_class(self);
  98. }
  99.  
  100. - (const char *)name
  101. {
  102.   return object_get_class_name(self);
  103. }
  104.  
  105. - self
  106. {
  107.   return self;
  108. }
  109.  
  110. - (unsigned int)hash
  111. {
  112.   return (size_t)self;
  113. }
  114.  
  115. - (BOOL)isEqual:anObject
  116. {
  117.   return self==anObject;
  118. }
  119.  
  120. - (void)printForDebugger // [stz] //-- - (void)printForDebugger:(NXStream *)stream;
  121. {
  122.   printf("*** Object dump:\n");
  123.   printf("  Object named.....%s\n",[self name]);
  124.   printf("  Of class.........%s\n",[[self class] name]);
  125.   printf("  At address.......%x\n",(int)self);
  126.   printf("  In zone at.......%x\n",[self zone]);
  127. }
  128.  
  129. - (int)compare:anotherObject;
  130. {
  131.   if ([self isEqual:anotherObject])
  132.     return 0;
  133.   // Ordering objects by their address is pretty useless, 
  134.   // so subclasses should override this is some useful way.
  135.   else if (self > anotherObject)
  136.     return 1;
  137.   else 
  138.     return -1;
  139. }
  140.  
  141. - (BOOL)isMetaClass
  142. {
  143.   return NO;
  144. }
  145.  
  146. - (BOOL)isClass
  147. {
  148.   return object_is_class(self);
  149. }
  150.  
  151. - (BOOL)isInstance
  152. {
  153.   return object_is_instance(self);
  154. }
  155.  
  156. - (BOOL)isKindOf:(OCClass*)aClassObject
  157. {
  158.   OCClass* class;
  159.  
  160.   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
  161.     if (class==aClassObject)
  162.       return YES;
  163.   return NO;
  164. }
  165.  
  166. - (BOOL)isMemberOf:(OCClass*)aClassObject
  167. {
  168.   return self->isa==aClassObject;
  169. }
  170.  
  171. - (BOOL)isKindOfClassNamed:(const char *)aClassName
  172. {
  173.   OCClass* class;
  174.  
  175.   if (aClassName!=NULL)
  176.     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
  177.       if (!strcmp(class_get_class_name(class), aClassName))
  178.         return YES;
  179.   return NO;
  180. }
  181.  
  182. - (BOOL)isMemberOfClassNamed:(const char *)aClassName
  183. {
  184.   return ((aClassName!=NULL)
  185.           &&!strcmp(class_get_class_name(self->isa), aClassName));
  186. }
  187.  
  188. + (BOOL)instancesRespondTo:(SEL)aSel
  189. {
  190.   return class_get_instance_method(self, aSel)!=METHOD_NULL;
  191. }
  192.  
  193. - (BOOL)respondsTo:(SEL)aSel
  194. {
  195.   return ((object_is_instance(self)
  196.            ?class_get_instance_method(self->isa, aSel)
  197.            :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
  198. }
  199.  
  200. + (IMP)instanceMethodFor:(SEL)aSel
  201. {
  202.   return method_get_imp(class_get_instance_method(self, aSel));
  203. }
  204.  
  205. // Indicates if the receiving class or instance conforms to the given protocol
  206. // not usually overridden by subclasses
  207. - (BOOL) conformsTo: (Protocol*)aProtocol
  208. {
  209.   int i;
  210.   struct objc_protocol_list* proto_list;
  211.  
  212.   for (proto_list = isa->protocols;
  213.        proto_list; proto_list = proto_list->next)
  214.     {
  215.       for (i=0; i < proto_list->count; i++)
  216.       {
  217.         if ([proto_list->list[i] conformsTo: aProtocol])
  218.           return YES;
  219.       }
  220.     }
  221.  
  222.   if ([self superClass])
  223.     return [[self superClass] conformsTo: aProtocol];
  224.   else
  225.     return NO;
  226. }
  227.  
  228. - (IMP)methodFor:(SEL)aSel
  229. {
  230.   return (method_get_imp(object_is_instance(self)
  231.                          ?class_get_instance_method(self->isa, aSel)
  232.                          :class_get_class_method(self->isa, aSel)));
  233. }
  234.  
  235. + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
  236. {
  237.   return ((struct objc_method_description *)
  238.            class_get_instance_method(self, aSel));
  239. }
  240.  
  241. - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
  242. {
  243.   return ((struct objc_method_description *)
  244.            (object_is_instance(self)
  245.             ?class_get_instance_method(self->isa, aSel)
  246.             :class_get_class_method(self->isa, aSel)));
  247. }
  248.  
  249. - perform:(SEL)aSel
  250. {
  251.   IMP msg = objc_msg_lookup(self, aSel);
  252.   if (!msg)
  253.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  254.   return (*msg)(self, aSel);
  255. }
  256.  
  257. - perform:(SEL)aSel with:anObject
  258. {
  259.   IMP msg = objc_msg_lookup(self, aSel);
  260.   if (!msg)
  261.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  262.   return (*msg)(self, aSel, anObject);
  263. }
  264.  
  265. - perform:(SEL)aSel with:anObject1 with:anObject2
  266. {
  267.   IMP msg = objc_msg_lookup(self, aSel);
  268.   if (!msg)
  269.     return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
  270.   return (*msg)(self, aSel, anObject1, anObject2);
  271. }
  272.  
  273. - forward:(SEL)aSel :(arglist_t)argFrame
  274. {
  275.   return [self doesNotRecognize: aSel];
  276. }
  277.  
  278. - performv:(SEL)aSel :(arglist_t)argFrame
  279. {
  280.   return objc_msg_sendv(self, aSel, argFrame);
  281. }
  282.  
  283. + poseAs:(OCClass*)aClassObject
  284. {
  285.   return class_pose_as(self, aClassObject);
  286. }
  287.  
  288. - (OCClass*)transmuteClassTo:(OCClass*)aClassObject
  289. {
  290.   if (object_is_instance(self))
  291.     if (class_is_class(aClassObject))
  292.       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
  293.         if ([self isKindOf:aClassObject])
  294.           {
  295.             OCClass* old_isa = isa;
  296.             isa = aClassObject;
  297.             return old_isa;
  298.           }
  299.   return nil;
  300. }
  301.  
  302. - subclassResponsibility:(SEL)aSel
  303. {
  304.   return [self error:"subclass should override %s", sel_get_name(aSel)];
  305. }
  306.  
  307. - notImplemented:(SEL)aSel
  308. {
  309.   return [self error:"method %s not implemented", sel_get_name(aSel)];
  310. }
  311.  
  312. - shouldNotImplement:(SEL)aSel
  313. {
  314.   return [self error:"%s should not implement %s", 
  315.                  object_get_class_name(self), sel_get_name(aSel)];
  316. }
  317.  
  318. - doesNotRecognize:(SEL)aSel
  319. {
  320.   return [self error:"%s does not recognize %s",
  321.                      object_get_class_name(self), sel_get_name(aSel)];
  322. }
  323.  
  324. - error:(const char *)aString, ...
  325. {
  326. #define FMT "error: %s (%s)\n%s\n"
  327.   char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
  328.             +((aString!=NULL)?strlen((char*)aString):0)+8)];
  329.   va_list ap;
  330.  
  331.   sprintf(fmt, FMT, object_get_class_name(self),
  332.                     object_is_instance(self)?"instance":"class",
  333.                     (aString!=NULL)?aString:"");
  334.   va_start(ap, aString);
  335.   /* _objc_error(self, fmt, ap); inlined: */
  336.     vfprintf (stderr, fmt, ap);
  337.     abort();
  338.   va_end(ap);
  339.   return nil;
  340. #undef FMT
  341. }
  342.  
  343. + (int)version
  344. {
  345.   return class_get_version(self);
  346. }
  347.  
  348. + setVersion:(int)aVersion
  349. {
  350.   class_set_version(self, aVersion);
  351.   return self;
  352. }
  353.  
  354. + (int)streamVersion: (TypedStream*)aStream
  355. {
  356.   if (aStream->mode == OBJC_READONLY) return objc_get_stream_class_version (aStream, self);
  357.   else return class_get_version (self);
  358. }
  359.  
  360. // These are used to write or read the instance variables 
  361. // declared in this particular part of the object.  Subclasses
  362. // should extend these, by calling [super read/write: aStream]
  363. // before doing their own archiving.  These methods are private, in
  364. // the sense that they should only be called from subclasses.
  365.  
  366. - read: (TypedStream*)aStream
  367. {
  368.   // [super read: aStream];  
  369.   return self;
  370. }
  371.  
  372. - write: (TypedStream*)aStream
  373. {
  374.   // [super write: aStream];
  375.   return self;
  376. }
  377.  
  378. - awake
  379. {
  380.   // [super awake];
  381.   return self;
  382. }
  383.  
  384. @end
  385.  
  386.  
  387. @implementation Object (StepstoneArchiving)
  388.  
  389. + readFrom:(STR)aFile
  390. {
  391.   TypedStream *stream;
  392.   id newObject=nil;
  393.  
  394.   if(stream=objc_open_typed_stream_for_file(aFile,OBJC_READONLY))
  395.   {
  396.     objc_read_object(stream,&newObject);
  397.     objc_close_typed_stream(stream);
  398.     return newObject;
  399.   }
  400.  
  401.   return nil;
  402. }
  403.  
  404. - (BOOL)storeOn:(STR)aFile
  405. {
  406.   TypedStream *stream;
  407.  
  408.   if(stream=objc_open_typed_stream_for_file(aFile,OBJC_WRITEONLY))
  409.   {
  410.     objc_write_root_object(stream,self);
  411.     objc_close_typed_stream(stream);
  412.     return YES;
  413.   }
  414.  
  415.   return NO;
  416. }
  417.  
  418. @end
  419.  
  420.  
  421. /* Unimplemented (Stepstone):
  422.  
  423. - (BOOL)isCopyOf:anObject;
  424. - (BOOL)isSame:anObject;
  425. - (BOOL)notEqual:anObject;
  426. - (BOOL)notSame:anObject;
  427. - (STR)describe;
  428. - asGraph:(BOOL)unique;
  429. - isOfSTR:(STR)aClassName;
  430. - notImplemented;
  431. - print;
  432. - printOn:(IOD)anIOD;
  433. - shouldNotImplement;
  434. - show;
  435. - subclassResponsibility;
  436.  
  437. */
  438.