/** Implementation of NSProtocolChecker for GNUStep
Copyright (C) 1995 Free Software Foundation, Inc.
Written by: Mike Kienenberger
Date: Jun 1998
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
NSProtocolChecker class reference
$Date$ $Revision$
*/
#include "config.h"
#include
#include
#include
#include
#include
@implementation NSProtocolChecker
/*
* Allocates and initializes an NSProtocolChecker instance that will
* forward any messages in the aProtocol protocol to anObject, its
* target. Thus, the checker can be vended in lieu of anObject to
* restrict the messages that can be sent to anObject. Returns the
* new instance.
*/
+ (id) protocolCheckerWithTarget: (NSObject*)anObject
protocol: (Protocol*)aProtocol
{
return AUTORELEASE([[NSProtocolChecker alloc] initWithTarget: anObject
protocol: aProtocol]);
}
/*
* Forwards any message to the delegate if the method is declared in
* the checker's protocol; otherwise raises an NSInvalidArgumentException.
*/
- (void) forwardInvocation: (NSInvocation*)anInvocation
{
unsigned int length;
void *buffer;
if ((struct objc_method_description *)NULL
!= [self methodDescriptionForSelector: [anInvocation selector]])
[[NSException exceptionWithName: NSInvalidArgumentException
reason: @"Method not declared in current protocol"
userInfo: nil] raise];
[anInvocation invokeWithTarget: _myTarget];
length = [[anInvocation methodSignature] methodReturnLength];
buffer = (void *)malloc(length);
[anInvocation getReturnValue: buffer];
if (0 == strcmp([[anInvocation methodSignature] methodReturnType],
[[anInvocation methodSignatureForSelector:
@selector(init: )] methodReturnType]) )
{
if (((id)buffer) == _myTarget)
{
((id)buffer) = self;
[anInvocation setReturnValue: buffer];
}
}
return;
}
- (id) init
{
_myProtocol = nil;
_myTarget = nil;
return self;
}
/*
* Initializes a newly allocated NSProtocolChecker instance that will
* forward any messages in the aProtocol protocol to anObject, its
* delegate. Thus, the checker can be vended in lieu of anObject to
* restrict the messages that can be sent to anObject. If anObject is
* allowed to be freed or dereferenced by clients, the free method
* should be included in aProtocol. Returns the new instance.
*/
- (id) initWithTarget: (NSObject*)anObject protocol: (Protocol*)aProtocol
{
[super init];
_myProtocol = aProtocol;
ASSIGN(_myTarget, anObject);
return self;
}
/*
* Returns an Objective C description for a method in the checker's
* protocol, or NULL if aSelector isn't declared as an instance method
* in the protocol.
*/
- (struct objc_method_description*) methodDescriptionForSelector: (SEL)aSelector
{
return [_myProtocol descriptionForInstanceMethod: aSelector];
}
/*
* Returns the protocol object the checker uses to verify whether a
* given message should be forwarded to its delegate, or the protocol
* checker should raise an NSInvalidArgumentException.
*/
- (Protocol*) protocol
{
if (nil == _myProtocol)
[[NSException exceptionWithName: NSInvalidArgumentException
reason: @"No protocol specified"
userInfo: nil] raise];
return _myProtocol;
}
/*
* Returns the target of the NSProtocolChecker.
*/
- (NSObject*) target
{
return _myTarget;
}
@end