1/* 2 EOAdaptorChannel.m 3 4 Copyright (C) 1996 Free Software Foundation, Inc. 5 6 Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro> 7 Date: October 1996 8 9 This file is part of the GNUstep Database Library. 10 11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Library General Public 13 License as published by the Free Software Foundation; either 14 version 2 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Library General Public License for more details. 20 21 You should have received a copy of the GNU Library General Public 22 License along with this library; see the file COPYING.LIB. 23 If not, write to the Free Software Foundation, 24 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25*/ 26// $Id: EOFaultHandler.m 1 2004-08-20 10:38:46Z znek $ 27 28#include "EOFaultHandler.h" 29#include "EOFault.h" 30#include "common.h" 31 32#if (defined(__GNU_LIBOBJC__) && (__GNU_LIBOBJC__ >= 20100911)) || defined(APPLE_RUNTIME) || defined(__GNUSTEP_RUNTIME__) 33# define METHOD_NULL NULL 34# define class_get_super_class class_getSuperclass 35# define object_is_instance(object) (object!=nil?YES:NO) 36# define class_get_instance_method class_getInstanceMethod 37typedef struct objc_method *Method_t; 38#endif 39 40#if NeXT_RUNTIME 41# if !defined(METHOD_NULL) 42# define METHOD_NULL NULL 43# endif 44#endif 45 46#if defined (__GNUSTEP_RUNTIME__) 47# define class_get_instance_method class_getInstanceMethod 48#endif 49 50#if !(__GNU_LIBOBJC__ >= 20100911) 51# define sel_getTypeEncoding(selector) ((selector)->sel_types) 52#endif 53 54@implementation EOFaultHandler 55 56- (void)setTargetClass:(Class)_class extraData:(void *)_extraData { 57 self->targetClass = _class; 58 self->extraData = _extraData; 59} 60 61- (Class)targetClass; { 62 return self->targetClass; 63} 64- (void *)extraData { 65 return self->extraData; 66} 67 68/* firing */ 69 70- (BOOL)shouldPerformInvocation:(NSInvocation *)_invocation { 71 return YES; 72} 73 74- (void)faultWillFire:(EOFault *)_fault { 75} 76 77- (void)completeInitializationOfObject:(id)_object { 78 [self doesNotRecognizeSelector:_cmd]; 79} 80 81/* fault reflection */ 82 83- (Class)classForFault:(EOFault *)_fault { 84 85#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) 86 87 return (object_is_instance(_fault)) 88 ? [self targetClass] 89 : (*(Class *)_fault); 90#else 91# warning TODO: add complete implementation for Apple/NeXT runtime! 92 return [self targetClass]; 93#endif 94} 95 96- (BOOL)respondsToSelector:(SEL)_selector forFault:(EOFault *)_fault { 97 Class class; 98 99 /* first check whether fault itself responds to selector */ 100#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) 101 if (class_get_instance_method(*(Class *)_fault, _selector) != METHOD_NULL) 102 return YES; 103#else 104# warning TODO: add implementation for NeXT/Apple runtime! 105#endif 106 107 /* then check whether the target class does */ 108 class = [self targetClass]; 109#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) 110 return (class_get_instance_method(class, _selector) != NULL) ? YES : NO; 111#else 112# warning TODO: use NeXT/Apple runtime function 113 return [(NSObject *)class methodForSelector:_selector] ? YES : NO; 114#endif 115} 116 117- (BOOL)conformsToProtocol:(Protocol *)_protocol forFault:(EOFault *)_fault { 118 Class class, sClass; 119 120#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) && !(__GNU_LIBOBJC__ >= 20100911) 121 struct objc_protocol_list* protos; 122 int i; 123 124 class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; 125 for (protos = class->protocols; protos; protos = protos->next) { 126 for (i = 0; i < protos->count; i++) { 127 if ([protos->list[i] conformsToProtocol:_protocol]) 128 return YES; 129 } 130 } 131#else 132# warning TODO: implement on NeXT/Apple runtime! 133 class = [self targetClass]; 134#endif 135 136 return ((sClass = [class superclass])) 137 ? [sClass conformsToProtocol:_protocol] 138 : NO; 139} 140 141- (BOOL)isKindOfClass:(Class)_class forFault:(EOFault *)_fault { 142 Class class; 143 144#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) 145 class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; 146 for (; class != Nil; class = class_get_super_class(class)) { 147 if (class == _class) 148 return YES; 149 } 150#else 151# warning TODO: add implementation for NeXT/Apple runtime! 152 class = [self targetClass]; 153#endif 154 return NO; 155} 156 157- (BOOL)isMemberOfClass:(Class)_class forFault:(EOFault *)_fault { 158 Class class; 159#if GNU_RUNTIME && !defined(__GNUSTEP_RUNTIME__) 160 class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; 161#else 162# warning TODO: add implementation for NeXT/Apple runtime! 163 class = [self targetClass]; 164#endif 165 return class == _class ? YES : NO; 166} 167 168- (NSMethodSignature *)methodSignatureForSelector:(SEL)_selector 169 forFault:(EOFault *)_fault 170{ 171#if NeXT_Foundation_LIBRARY || defined(__GNUSTEP_RUNTIME__) 172 // probably incorrect 173 return [_fault methodSignatureForSelector:_selector]; 174#else 175 register const char *types = NULL; 176 177 if (_selector == NULL) // invalid selector 178 return nil; 179 180#if GNU_RUNTIME && 0 181 // GNU runtime selectors may be typed, a lookup may not be necessary 182 types = aSelector->sel_types; 183#endif 184 185 /* first check for EOFault's own methods */ 186 187#if !(__GNU_LIBOBJC__ >= 20100911) 188 if (types == NULL) { 189 // lookup method for selector 190 struct objc_method *mth; 191 mth = class_get_instance_method(*(Class *)_fault, _selector); 192 if (mth) types = mth->method_types; 193 } 194 195 /* then check in target class methods */ 196 197 if (types == NULL) { 198 // lookup method for selector 199 struct objc_method *mth; 200 mth = class_get_instance_method([self targetClass], _selector); 201 if (mth) types = mth->method_types; 202 } 203#endif 204 205#if GNU_RUNTIME 206 // GNU runtime selectors may be typed, a lookup may not be necessary 207 if (types == NULL) 208 types = sel_getTypeEncoding(_selector); 209#endif 210 if (types == NULL) 211 return nil; 212 213 return [NSMethodSignature signatureWithObjCTypes:types]; 214#endif 215} 216 217/* description */ 218 219- (NSString *)descriptionForObject:(id)_fault { 220 return [NSString stringWithFormat:@"<%@[0x%p]: on=%@>", 221 NSStringFromClass(*(Class *)_fault), 222 _fault, 223 NSStringFromClass([self targetClass])]; 224} 225 226@end /* EOFaultHandler */ 227