mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Key value coding and class description support added.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8219 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
47d960b33b
commit
fe09500665
8 changed files with 650 additions and 0 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2000-11-27 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSClassDescription.m: New MacOS-X class added.
|
||||||
|
* Headers/Foundation/NSClassDescription.m: New MacOS-X class added.
|
||||||
|
* Headers/Foundation/NSKeyvalueCoding.m: New MacOS-X protocol added.
|
||||||
|
* Source/NSObject.m: New MacOS-X key value coding methods added.
|
||||||
|
Only objects currently supported - needs work to support scalar
|
||||||
|
types too!
|
||||||
|
|
||||||
2000-11-23 Mirko Viviani <mirko.viviani@rccr.cremona.it>
|
2000-11-23 Mirko Viviani <mirko.viviani@rccr.cremona.it>
|
||||||
|
|
||||||
* Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): fixed an
|
* Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): fixed an
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <Foundation/NSBundle.h>
|
#include <Foundation/NSBundle.h>
|
||||||
#include <Foundation/NSByteOrder.h>
|
#include <Foundation/NSByteOrder.h>
|
||||||
#include <Foundation/NSCharacterSet.h>
|
#include <Foundation/NSCharacterSet.h>
|
||||||
|
#include <Foundation/NSClassDescription.h>
|
||||||
#include <Foundation/NSCoder.h>
|
#include <Foundation/NSCoder.h>
|
||||||
#include <Foundation/NSConnection.h>
|
#include <Foundation/NSConnection.h>
|
||||||
#include <Foundation/NSDate.h>
|
#include <Foundation/NSDate.h>
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
#include <Foundation/NSGeometry.h>
|
#include <Foundation/NSGeometry.h>
|
||||||
#include <Foundation/NSHost.h>
|
#include <Foundation/NSHost.h>
|
||||||
#include <Foundation/NSInvocation.h>
|
#include <Foundation/NSInvocation.h>
|
||||||
|
#include <Foundation/NSKeyValueCoding.h>
|
||||||
#include <Foundation/NSLock.h>
|
#include <Foundation/NSLock.h>
|
||||||
#include <Foundation/NSMapTable.h>
|
#include <Foundation/NSMapTable.h>
|
||||||
#include <Foundation/NSMethodSignature.h>
|
#include <Foundation/NSMethodSignature.h>
|
||||||
|
|
61
Headers/gnustep/base/NSClassDescription.h
Normal file
61
Headers/gnustep/base/NSClassDescription.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* Interface for NSClassDescription for GNUStep
|
||||||
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
Date: 2000
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NSClassDescription_h_GNUSTEP_BASE_INCLUDE
|
||||||
|
#define __NSClassDescription_h_GNUSTEP_BASE_INCLUDE
|
||||||
|
|
||||||
|
#include <Foundation/NSObject.h>
|
||||||
|
#include <Foundation/NSException.h>
|
||||||
|
|
||||||
|
@class NSArray;
|
||||||
|
@class NSDictionary;
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
|
GS_EXPORT NSString* const NSClassDescriptionNeededForClassNotification;
|
||||||
|
|
||||||
|
@interface NSClassDescription : NSObject
|
||||||
|
|
||||||
|
+ (NSClassDescription*) classDescriptionForClass: (Class)aClass;
|
||||||
|
+ (void) invalidateClassDescriptionCache;
|
||||||
|
+ (void) registerClassDescription: (NSClassDescription*)aDescription
|
||||||
|
forClass: (Class)aClass;
|
||||||
|
|
||||||
|
- (NSArray*) attributeKeys;
|
||||||
|
- (NSString*) inverseForRelationshipKey: (NSString*)aKey;
|
||||||
|
- (NSArray*) toManyRelationshipKeys;
|
||||||
|
- (NSArray*) toOneRelationshipKeys;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface NSObject (NSClassDescriptionPrimitives)
|
||||||
|
|
||||||
|
- (NSArray*) attributeKeys;
|
||||||
|
- (NSClassDescription*) classDescription;
|
||||||
|
- (NSString*) inverseForRelationshipKey: (NSString*)aKey;
|
||||||
|
- (NSArray*) toManyRelationshipKeys;
|
||||||
|
- (NSArray*) toOneRelationshipKeys;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
55
Headers/gnustep/base/NSKeyValueCoding.h
Normal file
55
Headers/gnustep/base/NSKeyValueCoding.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
/* Interface for NSKeyvalueCoding for GNUStep
|
||||||
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
Date: 2000
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NSKeyValueCoding_h_GNUSTEP_BASE_INCLUDE
|
||||||
|
#define __NSKeyValueCoding_h_GNUSTEP_BASE_INCLUDE
|
||||||
|
|
||||||
|
#include <Foundation/NSObject.h>
|
||||||
|
|
||||||
|
@class NSArray;
|
||||||
|
@class NSDictionary;
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSObject (NSKeyValueCoding)
|
||||||
|
|
||||||
|
+ (BOOL) accessInstanceVariablesDirectly;
|
||||||
|
+ (BOOL) useStoredAccessor;
|
||||||
|
|
||||||
|
- (id) handleQueryWithUnboundKey: (NSString*)aKey;
|
||||||
|
- (void) handleTakeValue: (id)anObject forUnboundKey: (NSString*)aKey;
|
||||||
|
- (id) storedValueForKey: (NSString*)aKey;
|
||||||
|
- (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey;
|
||||||
|
- (void) takeValue: (id)anObject forKey: (NSString*)aKey;
|
||||||
|
- (void) takeValue: (id)anObject forKeyPath: (NSString*)aKey;
|
||||||
|
- (void) takeValuesFromDictionary: (NSDictionary*)aDictionary;
|
||||||
|
- (void) unableToSetNilForKey: (NSString*)aKey;
|
||||||
|
- (id) valueForKey: (NSString*)aKey;
|
||||||
|
- (id) valueForKeyPath: (NSString*)aKey;
|
||||||
|
- (NSDictionary*) valuesForKeys: (NSArray*)keys;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -157,6 +157,7 @@ NSBundle.m \
|
||||||
NSCalendarDate.m \
|
NSCalendarDate.m \
|
||||||
NSCallBacks.m \
|
NSCallBacks.m \
|
||||||
NSCharacterSet.m \
|
NSCharacterSet.m \
|
||||||
|
NSClassDescription.m \
|
||||||
NSCoder.m \
|
NSCoder.m \
|
||||||
NSCopyObject.m \
|
NSCopyObject.m \
|
||||||
NSConcreteValue.m \
|
NSConcreteValue.m \
|
||||||
|
@ -265,6 +266,7 @@ NSBitmapCharSet.h \
|
||||||
NSBundle.h \
|
NSBundle.h \
|
||||||
NSByteOrder.h \
|
NSByteOrder.h \
|
||||||
NSCharacterSet.h \
|
NSCharacterSet.h \
|
||||||
|
NSClassDescription.h \
|
||||||
NSCoder.h \
|
NSCoder.h \
|
||||||
NSConcreteNumber.h \
|
NSConcreteNumber.h \
|
||||||
NSConcreteValue.h \
|
NSConcreteValue.h \
|
||||||
|
@ -291,6 +293,7 @@ NSGSet.h \
|
||||||
NSHashTable.h \
|
NSHashTable.h \
|
||||||
NSHost.h \
|
NSHost.h \
|
||||||
NSInvocation.h \
|
NSInvocation.h \
|
||||||
|
NSKeyValueEncoding.h \
|
||||||
NSLock.h \
|
NSLock.h \
|
||||||
NSMapTable.h \
|
NSMapTable.h \
|
||||||
NSMethodSignature.h \
|
NSMethodSignature.h \
|
||||||
|
|
143
Source/NSClassDescription.m
Normal file
143
Source/NSClassDescription.m
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
|
||||||
|
/* NSClassDescription
|
||||||
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
Date: 2000
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Foundation/NSClassDescription.h>
|
||||||
|
#include <Foundation/NSLock.h>
|
||||||
|
#include <Foundation/NSMapTable.h>
|
||||||
|
#include <Foundation/NSNotification.h>
|
||||||
|
|
||||||
|
|
||||||
|
@implementation NSClassDescription
|
||||||
|
|
||||||
|
static NSRecursiveLock *mapLock = nil;
|
||||||
|
static NSMapTable *classMap;
|
||||||
|
|
||||||
|
+ (NSClassDescription*) classDescriptionForClass: (Class)aClass
|
||||||
|
{
|
||||||
|
NSClassDescription *description;
|
||||||
|
|
||||||
|
[mapLock lock];
|
||||||
|
description = NSMapGet(classMap, aClass);
|
||||||
|
if (description == nil)
|
||||||
|
{
|
||||||
|
NSNotificationCenter *nc;
|
||||||
|
|
||||||
|
nc = [NSNotificationCenter defaultCenter];
|
||||||
|
[nc postNotificationName: NSClassDescriptionNeededForClassNotification
|
||||||
|
object: aClass];
|
||||||
|
description = NSMapGet(classMap, aClass);
|
||||||
|
}
|
||||||
|
RETAIN(description);
|
||||||
|
[mapLock unlock];
|
||||||
|
|
||||||
|
return AUTORELEASE(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
|
{
|
||||||
|
if (self == [NSClassDescription class])
|
||||||
|
{
|
||||||
|
classMap = NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||||
|
NSObjectMapValueCallBacks, 100);
|
||||||
|
mapLock = [NSRecursiveLock new];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) invalidateClassDescriptionCache
|
||||||
|
{
|
||||||
|
[mapLock lock];
|
||||||
|
NSResetMapTable(classMap);
|
||||||
|
[mapLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) registerClassDescription: (NSClassDescription*)aDescription
|
||||||
|
forClass: (Class)aClass
|
||||||
|
{
|
||||||
|
if (aDescription != nil && aClass != 0)
|
||||||
|
{
|
||||||
|
[mapLock lock];
|
||||||
|
NSMapInsert(classMap, aClass, aDescription);
|
||||||
|
[mapLock unlock];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) attributeKeys
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) inverseForRelationshipKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) toManyRelationshipKeys
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) toOneRelationshipKeys
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@implementation NSObject(ClassDescriptionForwards)
|
||||||
|
|
||||||
|
static Class NSClassDescriptionClass = 0;
|
||||||
|
|
||||||
|
- (NSArray*) attributeKeys
|
||||||
|
{
|
||||||
|
return [[self classDescription] attributeKeys];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSClassDescription*) classDescription
|
||||||
|
{
|
||||||
|
if (NSClassDescriptionClass == 0)
|
||||||
|
{
|
||||||
|
NSClassDescriptionClass = [NSClassDescription class];
|
||||||
|
}
|
||||||
|
return [NSClassDescriptionClass classDescriptionForClass: [self class]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) inverseForRelationshipKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
return [[self classDescription] inverseForRelationshipKey: aKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) toManyRelationshipKeys
|
||||||
|
{
|
||||||
|
return [[self classDescription] toManyRelationshipKeys];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) toOneRelationshipKeys
|
||||||
|
{
|
||||||
|
return [[self classDescription] toOneRelationshipKeys];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -1276,6 +1276,376 @@ static BOOL deallocNotifications = NO;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <Foundation/NSKeyValueCoding.h>
|
||||||
|
#include <Foundation/NSNull.h>
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
GSGetValue(id obj, NSString *iVarName, id *data)
|
||||||
|
{
|
||||||
|
const char *name = [iVarName cString];
|
||||||
|
Class class;
|
||||||
|
struct objc_ivar_list *ivars;
|
||||||
|
struct objc_ivar *ivar = 0;
|
||||||
|
int offset;
|
||||||
|
const char *type;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
class = [obj class];
|
||||||
|
while (class != nil && ivar == 0)
|
||||||
|
{
|
||||||
|
ivars = class->ivars;
|
||||||
|
class = class->super_class;
|
||||||
|
if (ivars != 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ivars->ivar_count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0)
|
||||||
|
{
|
||||||
|
ivar = &ivars->ivar_list[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ivar == 0)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = ivar->ivar_offset;
|
||||||
|
type = ivar->ivar_type;
|
||||||
|
size = objc_sizeof_type(type);
|
||||||
|
memcpy(data, ((void*)obj) + offset, size);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
GSSetValue(id obj, NSString *iVarName, id *data)
|
||||||
|
{
|
||||||
|
const char *name = [iVarName cString];
|
||||||
|
Class class;
|
||||||
|
struct objc_ivar_list *ivars;
|
||||||
|
struct objc_ivar *ivar = 0;
|
||||||
|
int offset;
|
||||||
|
const char *type;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
class = [obj class];
|
||||||
|
while (class != nil && ivar == 0)
|
||||||
|
{
|
||||||
|
ivars = class->ivars;
|
||||||
|
class = class->super_class;
|
||||||
|
if (ivars != 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ivars->ivar_count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0)
|
||||||
|
{
|
||||||
|
ivar = &ivars->ivar_list[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ivar == 0)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = ivar->ivar_offset;
|
||||||
|
type = ivar->ivar_type;
|
||||||
|
size = objc_sizeof_type(type);
|
||||||
|
memcpy(((void*)obj) + offset, data, size);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation NSObject (KeyValueCoding)
|
||||||
|
|
||||||
|
+ (BOOL) accessInstanceVariablesDirectly
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL) useStoredAccessor
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) handleQueryWithUnboundKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) handleTakeValue: (id)anObject forUnboundKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"Unable to find %@ in %@", aKey, anObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) storedValueForKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
SEL sel;
|
||||||
|
|
||||||
|
if ([[self class] useStoredAccessor] == NO)
|
||||||
|
{
|
||||||
|
return [self valueForKey: aKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_get%@",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_%@", aKey]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
||||||
|
{
|
||||||
|
id v;
|
||||||
|
|
||||||
|
if (GSGetValue(self, [NSString stringWithFormat: @"_%@", aKey],
|
||||||
|
(void*)&v) == YES)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (GSGetValue(self, aKey, (void*)&v) == YES)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"get%@",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
sel = NSSelectorFromString(aKey);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self handleTakeValue: nil forUnboundKey: aKey];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
SEL sel;
|
||||||
|
|
||||||
|
if ([[self class] useStoredAccessor] == NO)
|
||||||
|
{
|
||||||
|
[self takeValue: anObject forKey: aKey];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_set%@:",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
[self performSelector: sel withObject: anObject];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
||||||
|
{
|
||||||
|
if (GSSetValue(self, [NSString stringWithFormat: @"_%@", aKey],
|
||||||
|
(void*)&anObject) == YES)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GSSetValue(self, aKey, (void*)&anObject) == YES)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"set%@:",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
[self performSelector: sel withObject: anObject];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self handleTakeValue: anObject forUnboundKey: aKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeValue: (id)anObject forKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
SEL sel;
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"set%@:",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
[self performSelector: sel withObject: anObject];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_set%@:",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
[self performSelector: sel withObject: anObject];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
||||||
|
{
|
||||||
|
if (GSSetValue(self, [NSString stringWithFormat: @"_%@", aKey],
|
||||||
|
(void*)&anObject) == YES)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GSSetValue(self, aKey, (void*)&anObject) == YES)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self handleTakeValue: anObject forUnboundKey: aKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeValue: (id)anObject forKeyPath: (NSString*)aKey
|
||||||
|
{
|
||||||
|
NSArray *keys = [aKey componentsSeparatedByString: @"."];
|
||||||
|
id obj = self;
|
||||||
|
unsigned count = [keys count];
|
||||||
|
unsigned pos;
|
||||||
|
|
||||||
|
for (pos = 0; pos + 1 < count; pos++)
|
||||||
|
{
|
||||||
|
obj = [obj valueForKey: [keys objectAtIndex: pos]];
|
||||||
|
}
|
||||||
|
if (pos < count)
|
||||||
|
{
|
||||||
|
[obj takeValue: anObject forKey: [keys objectAtIndex: pos]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeValuesFromDictionary: (NSDictionary*)aDictionary
|
||||||
|
{
|
||||||
|
NSEnumerator *enumerator = [aDictionary keyEnumerator];
|
||||||
|
NSNull *null = [NSNull null];
|
||||||
|
NSString *key;
|
||||||
|
|
||||||
|
while ((key = [enumerator nextObject]) != nil)
|
||||||
|
{
|
||||||
|
id obj = [aDictionary objectForKey: key];
|
||||||
|
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
obj = nil;
|
||||||
|
}
|
||||||
|
[self takeValue: obj forKey: key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) unableToSetNilForKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"Given nil value to set for key"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) valueForKey: (NSString*)aKey
|
||||||
|
{
|
||||||
|
SEL sel;
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"get%@",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
sel = NSSelectorFromString(aKey);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_get%@",
|
||||||
|
[aKey capitalizedString]]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
sel = NSSelectorFromString([NSString stringWithFormat: @"_%@", aKey]);
|
||||||
|
if ([self respondsToSelector: sel] == YES)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
||||||
|
{
|
||||||
|
id v;
|
||||||
|
|
||||||
|
if (GSGetValue(self, [NSString stringWithFormat: @"_%@", aKey],
|
||||||
|
(void*)&v) == YES)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
if (GSGetValue(self, aKey, (void*)&v) == YES)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self handleTakeValue: nil forUnboundKey: aKey];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) valueForKeyPath: (NSString*)aKey
|
||||||
|
{
|
||||||
|
NSArray *keys = [aKey componentsSeparatedByString: @"."];
|
||||||
|
id obj = self;
|
||||||
|
unsigned count = [keys count];
|
||||||
|
unsigned pos;
|
||||||
|
|
||||||
|
for (pos = 0; pos < count; pos++)
|
||||||
|
{
|
||||||
|
obj = [obj valueForKey: [keys objectAtIndex: pos]];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*) valuesForKeys: (NSArray*)keys
|
||||||
|
{
|
||||||
|
NSMutableDictionary *dict;
|
||||||
|
NSNull *null = [NSNull null];
|
||||||
|
unsigned count = [keys count];
|
||||||
|
unsigned pos;
|
||||||
|
|
||||||
|
dict = [NSMutableDictionary dictionaryWithCapacity: count];
|
||||||
|
for (pos = 0; pos < count; pos++)
|
||||||
|
{
|
||||||
|
NSString *key = [keys objectAtIndex: pos];
|
||||||
|
id val = [self valueForKey: key];
|
||||||
|
|
||||||
|
if (val == nil)
|
||||||
|
{
|
||||||
|
val = null;
|
||||||
|
}
|
||||||
|
[dict setObject: val forKey: key];
|
||||||
|
}
|
||||||
|
return AUTORELEASE([dict copy]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSObject (GNUstep)
|
@implementation NSObject (GNUstep)
|
||||||
|
|
||||||
/* GNU Object class compatibility */
|
/* GNU Object class compatibility */
|
||||||
|
|
|
@ -290,6 +290,9 @@ NSString *GSHTTPPropertyProxyHostKey;
|
||||||
NSString *GSHTTPPropertyProxyPortKey;
|
NSString *GSHTTPPropertyProxyPortKey;
|
||||||
|
|
||||||
|
|
||||||
|
/* Class description notification */
|
||||||
|
NSString *NSClassDescriptionNeededForClassNotification;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup function called when NSString is initialised.
|
* Setup function called when NSString is initialised.
|
||||||
|
@ -514,6 +517,10 @@ GSBuildStrings()
|
||||||
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyHostKey"];
|
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyHostKey"];
|
||||||
GSHTTPPropertyProxyPortKey
|
GSHTTPPropertyProxyPortKey
|
||||||
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyPortKey"];
|
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyPortKey"];
|
||||||
|
|
||||||
|
NSClassDescriptionNeededForClassNotification
|
||||||
|
= [[SClass alloc] initWithCString:
|
||||||
|
"NSClassDescriptionNeededForClassNotification"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue