mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
Make keypath evaluation recursive.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@26296 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
4c45514e71
commit
3c81286dfd
2 changed files with 55 additions and 145 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2008-03-13 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSKeyValueCoding.m:
|
||||||
|
Make all keypath methods perform recursive evaluation of the path
|
||||||
|
for compatibility with MacOS-X and to permit classes to effectively
|
||||||
|
override the keypath methods.
|
||||||
|
|
||||||
2008-03-12 Richard Frith-Macdonald <rfm@gnu.org>
|
2008-03-12 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/Additions/GSInsensitiveDictionary.m:
|
* Source/Additions/GSInsensitiveDictionary.m:
|
||||||
|
|
|
@ -269,34 +269,19 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
|
|
||||||
- (NSMutableSet*) mutableSetValueForKeyPath: (NSString*)aKey
|
- (NSMutableSet*) mutableSetValueForKeyPath: (NSString*)aKey
|
||||||
{
|
{
|
||||||
unsigned size = [aKey length] * 8;
|
NSRange r = [aKey rangeOfString: @"."];
|
||||||
char buf[size+1];
|
|
||||||
unsigned start = 0;
|
|
||||||
unsigned end = 0;
|
|
||||||
id o = self;
|
|
||||||
|
|
||||||
[aKey getCString: buf
|
if (r.length == 0)
|
||||||
maxLength: size+1
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
size = strlen(buf);
|
|
||||||
while (start < size && o != nil)
|
|
||||||
{
|
{
|
||||||
end = start;
|
return [self mutableSetValueForKey: aKey];
|
||||||
while (end < size && buf[end] != '.')
|
}
|
||||||
{
|
else
|
||||||
end++;
|
{
|
||||||
}
|
NSString *key = [aKey substringToIndex: r.location];
|
||||||
aKey = [[NSString alloc] initWithBytes: buf + start
|
NSString *path = [aKey substringFromIndex: NSMaxRange(r)];
|
||||||
length: end - start
|
|
||||||
encoding: NSUTF8StringEncoding];
|
return [[self valueForKey: key] mutableSetValueForKeyPath: path];
|
||||||
AUTORELEASE(aKey);
|
|
||||||
if (end == size)
|
|
||||||
o = [o mutableSetValueForKey: aKey];
|
|
||||||
else
|
|
||||||
o = [o valueForKey: aKey];
|
|
||||||
start = ++end;
|
|
||||||
}
|
}
|
||||||
return o;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableArray*) mutableArrayValueForKey: (NSString*)aKey
|
- (NSMutableArray*) mutableArrayValueForKey: (NSString*)aKey
|
||||||
|
@ -306,34 +291,19 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
|
|
||||||
- (NSMutableArray*) mutableArrayValueForKeyPath: (NSString*)aKey
|
- (NSMutableArray*) mutableArrayValueForKeyPath: (NSString*)aKey
|
||||||
{
|
{
|
||||||
unsigned size = [aKey length] * 8;
|
NSRange r = [aKey rangeOfString: @"."];
|
||||||
char buf[size+1];
|
|
||||||
unsigned start = 0;
|
|
||||||
unsigned end = 0;
|
|
||||||
id o = self;
|
|
||||||
|
|
||||||
[aKey getCString: buf
|
if (r.length == 0)
|
||||||
maxLength: size+1
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
size = strlen(buf);
|
|
||||||
while (start < size && o != nil)
|
|
||||||
{
|
{
|
||||||
end = start;
|
return [self mutableArrayValueForKey: aKey];
|
||||||
while (end < size && buf[end] != '.')
|
}
|
||||||
{
|
else
|
||||||
end++;
|
{
|
||||||
}
|
NSString *key = [aKey substringToIndex: r.location];
|
||||||
aKey = [[NSString alloc] initWithBytes: buf + start
|
NSString *path = [aKey substringFromIndex: NSMaxRange(r)];
|
||||||
length: end - start
|
|
||||||
encoding: NSUTF8StringEncoding];
|
return [[self valueForKey: key] mutableArrayValueForKeyPath: path];
|
||||||
AUTORELEASE(aKey);
|
|
||||||
if (end == size)
|
|
||||||
o = [o mutableArrayValueForKey: aKey];
|
|
||||||
else
|
|
||||||
o = [o valueForKey: aKey];
|
|
||||||
start = ++end;
|
|
||||||
}
|
}
|
||||||
return o;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setNilValueForKey: (NSString*)aKey
|
- (void) setNilValueForKey: (NSString*)aKey
|
||||||
|
@ -385,11 +355,7 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
|
|
||||||
- (void) setValue: (id)anObject forKeyPath: (NSString*)aKey
|
- (void) setValue: (id)anObject forKeyPath: (NSString*)aKey
|
||||||
{
|
{
|
||||||
unsigned size = [aKey length] * 8;
|
NSRange r = [aKey rangeOfString: @"."];
|
||||||
char buf[size+1];
|
|
||||||
unsigned start = 0;
|
|
||||||
unsigned end = 0;
|
|
||||||
id obj = self;
|
|
||||||
#ifdef WANT_DEPRECATED_KVC_COMPAT
|
#ifdef WANT_DEPRECATED_KVC_COMPAT
|
||||||
IMP o = [self methodForSelector: @selector(takeValue:forKeyPath:)];
|
IMP o = [self methodForSelector: @selector(takeValue:forKeyPath:)];
|
||||||
|
|
||||||
|
@ -401,28 +367,16 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[aKey getCString: buf
|
if (r.length == 0)
|
||||||
maxLength: size+1
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
size = strlen(buf);
|
|
||||||
while (obj != nil)
|
|
||||||
{
|
{
|
||||||
end = start;
|
[self setValue: anObject forKey: aKey];
|
||||||
while (end < size && buf[end] != '.')
|
}
|
||||||
{
|
else
|
||||||
end++;
|
{
|
||||||
}
|
NSString *key = [aKey substringToIndex: r.location];
|
||||||
aKey = [[NSString alloc] initWithBytes: buf + start
|
NSString *path = [aKey substringFromIndex: NSMaxRange(r)];
|
||||||
length: end - start
|
|
||||||
encoding: NSUTF8StringEncoding];
|
[[self valueForKey: key] setValue: anObject forKeyPath: path];
|
||||||
AUTORELEASE(aKey);
|
|
||||||
if (end >= size)
|
|
||||||
{
|
|
||||||
[obj setValue: anObject forKey: aKey];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
obj = [obj valueForKey: aKey];
|
|
||||||
start = ++end;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,59 +480,20 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
forKeyPath: (NSString*)aKey
|
forKeyPath: (NSString*)aKey
|
||||||
error: (NSError**)anError
|
error: (NSError**)anError
|
||||||
{
|
{
|
||||||
unsigned size = [aKey length] * 8;
|
NSRange r = [aKey rangeOfString: @"."];
|
||||||
char buf[size+1];
|
|
||||||
unsigned start = 0;
|
|
||||||
unsigned end = 0;
|
|
||||||
id o = self;
|
|
||||||
|
|
||||||
[aKey getCString: buf
|
if (r.length == 0)
|
||||||
maxLength: size+1
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
size = strlen(buf);
|
|
||||||
while (o != nil)
|
|
||||||
{
|
{
|
||||||
end = start;
|
return [self validateValue: aValue forKey: aKey error: anError];
|
||||||
while (end < size && buf[end] != '.')
|
|
||||||
{
|
|
||||||
end++;
|
|
||||||
}
|
|
||||||
if (end >= size)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
aKey = [[NSString alloc] initWithBytes: buf + start
|
|
||||||
length: end - start
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
AUTORELEASE(aKey);
|
|
||||||
o = [o valueForKey: aKey];
|
|
||||||
start = ++end;
|
|
||||||
}
|
|
||||||
if (o == nil)
|
|
||||||
{
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char name[end-start+16];
|
NSString *key = [aKey substringToIndex: r.location];
|
||||||
SEL sel;
|
NSString *path = [aKey substringFromIndex: NSMaxRange(r)];
|
||||||
BOOL (*imp)(id,SEL,id*,id*);
|
|
||||||
|
|
||||||
size = end - start;
|
return [[self valueForKey: key] validateValue: aValue
|
||||||
strcpy(name, "validate");
|
forKeyPath: path
|
||||||
strcpy(&name[8], buf+start);
|
error: anError];
|
||||||
strcpy(&name[size+8], ":error:");
|
|
||||||
if (islower(name[8]))
|
|
||||||
{
|
|
||||||
name[8] = toupper(name[8]);
|
|
||||||
}
|
|
||||||
sel = GSSelectorFromName(name);
|
|
||||||
if (sel != 0
|
|
||||||
&& (imp = (BOOL (*)(id,SEL,id*,id*))[self methodForSelector: sel]) != 0)
|
|
||||||
{
|
|
||||||
return (*imp)(self, sel, aValue, anError);
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,31 +513,19 @@ static id ValueForKey(NSObject *self, const char *key, unsigned size)
|
||||||
|
|
||||||
- (id) valueForKeyPath: (NSString*)aKey
|
- (id) valueForKeyPath: (NSString*)aKey
|
||||||
{
|
{
|
||||||
unsigned size = [aKey length] * 8;
|
NSRange r = [aKey rangeOfString: @"."];
|
||||||
char buf[size+1];
|
|
||||||
unsigned start = 0;
|
|
||||||
unsigned end = 0;
|
|
||||||
id o = self;
|
|
||||||
|
|
||||||
[aKey getCString: buf
|
if (r.length == 0)
|
||||||
maxLength: size+1
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
size = strlen(buf);
|
|
||||||
while (start < size && o != nil)
|
|
||||||
{
|
{
|
||||||
end = start;
|
return [self valueForKey: aKey];
|
||||||
while (end < size && buf[end] != '.')
|
}
|
||||||
{
|
else
|
||||||
end++;
|
{
|
||||||
}
|
NSString *key = [aKey substringToIndex: r.location];
|
||||||
aKey = [[NSString alloc] initWithBytes: buf + start
|
NSString *path = [aKey substringFromIndex: NSMaxRange(r)];
|
||||||
length: end - start
|
|
||||||
encoding: NSUTF8StringEncoding];
|
return [[self valueForKey: key] valueForKeyPath: path];
|
||||||
AUTORELEASE(aKey);
|
|
||||||
o = [o valueForKey: aKey];
|
|
||||||
start = ++end;
|
|
||||||
}
|
}
|
||||||
return o;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue