mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +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>
|
||||
|
||||
* Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): fixed an
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSByteOrder.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <Foundation/NSClassDescription.h>
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSConnection.h>
|
||||
#include <Foundation/NSDate.h>
|
||||
|
@ -57,6 +58,7 @@
|
|||
#include <Foundation/NSGeometry.h>
|
||||
#include <Foundation/NSHost.h>
|
||||
#include <Foundation/NSInvocation.h>
|
||||
#include <Foundation/NSKeyValueCoding.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSMapTable.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 \
|
||||
NSCallBacks.m \
|
||||
NSCharacterSet.m \
|
||||
NSClassDescription.m \
|
||||
NSCoder.m \
|
||||
NSCopyObject.m \
|
||||
NSConcreteValue.m \
|
||||
|
@ -265,6 +266,7 @@ NSBitmapCharSet.h \
|
|||
NSBundle.h \
|
||||
NSByteOrder.h \
|
||||
NSCharacterSet.h \
|
||||
NSClassDescription.h \
|
||||
NSCoder.h \
|
||||
NSConcreteNumber.h \
|
||||
NSConcreteValue.h \
|
||||
|
@ -291,6 +293,7 @@ NSGSet.h \
|
|||
NSHashTable.h \
|
||||
NSHost.h \
|
||||
NSInvocation.h \
|
||||
NSKeyValueEncoding.h \
|
||||
NSLock.h \
|
||||
NSMapTable.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
|
||||
|
||||
|
||||
|
||||
#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)
|
||||
|
||||
/* GNU Object class compatibility */
|
||||
|
|
|
@ -290,6 +290,9 @@ NSString *GSHTTPPropertyProxyHostKey;
|
|||
NSString *GSHTTPPropertyProxyPortKey;
|
||||
|
||||
|
||||
/* Class description notification */
|
||||
NSString *NSClassDescriptionNeededForClassNotification;
|
||||
|
||||
|
||||
/*
|
||||
* Setup function called when NSString is initialised.
|
||||
|
@ -514,6 +517,10 @@ GSBuildStrings()
|
|||
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyHostKey"];
|
||||
GSHTTPPropertyProxyPortKey
|
||||
= [[SClass alloc] initWithCString: "GSHTTPPropertyProxyPortKey"];
|
||||
|
||||
NSClassDescriptionNeededForClassNotification
|
||||
= [[SClass alloc] initWithCString:
|
||||
"NSClassDescriptionNeededForClassNotification"];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue