30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
-
+
-
+
-
+
-
+
-
+
-
+
|
#import "OFUndefinedKeyException.h"
int _OFObject_KeyValueCoding_reference;
@implementation OFObject (KeyValueCoding)
- (id)valueForKey: (OFString *)key
{
SEL selector = sel_registerName([key UTF8String]);
SEL selector = sel_registerName(key.UTF8String);
OFMethodSignature *methodSignature =
[self methodSignatureForSelector: selector];
id ret;
if (methodSignature == nil) {
size_t keyLength;
char *name;
if ((keyLength = [key UTF8StringLength]) < 1)
if ((keyLength = key.UTF8StringLength) < 1)
return [self valueForUndefinedKey: key];
if ((name = malloc(keyLength + 3)) == NULL)
@throw [OFOutOfMemoryException
exceptionWithRequestedSize: keyLength + 3];
@try {
memcpy(name, "is", 2);
memcpy(name + 2, [key UTF8String], keyLength);
memcpy(name + 2, key.UTF8String, keyLength);
name[keyLength + 2] = '\0';
name[2] = of_ascii_toupper(name[2]);
selector = sel_registerName(name);
} @finally {
free(name);
}
methodSignature = [self methodSignatureForSelector: selector];
if (methodSignature == NULL)
return [self valueForUndefinedKey: key];
switch (*[methodSignature methodReturnType]) {
switch (*methodSignature.methodReturnType) {
case '@':
case '#':
return [self valueForUndefinedKey: key];
}
}
if ([methodSignature numberOfArguments] != 2 ||
if (methodSignature.numberOfArguments != 2 ||
*[methodSignature argumentTypeAtIndex: 0] != '@' ||
*[methodSignature argumentTypeAtIndex: 1] != ':')
return [self valueForUndefinedKey: key];
switch (*[methodSignature methodReturnType]) {
switch (*methodSignature.methodReturnType) {
case '@':
case '#':
ret = [self performSelector: selector];
break;
#define CASE(encoding, type, method) \
case encoding: \
{ \
|
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
-
+
-
+
-
-
+
+
|
{
size_t keyLength;
char *name;
SEL selector;
OFMethodSignature *methodSignature;
const char *valueType;
if ((keyLength = [key UTF8StringLength]) < 1) {
if ((keyLength = key.UTF8StringLength) < 1) {
[self setValue: value
forUndefinedKey: key];
return;
}
if ((name = malloc(keyLength + 5)) == NULL)
@throw [OFOutOfMemoryException
exceptionWithRequestedSize: keyLength + 5];
@try {
memcpy(name, "set", 3);
memcpy(name + 3, [key UTF8String], keyLength);
memcpy(name + 3, key.UTF8String, keyLength);
memcpy(name + keyLength + 3, ":", 2);
name[3] = of_ascii_toupper(name[3]);
selector = sel_registerName(name);
} @finally {
free(name);
}
methodSignature = [self methodSignatureForSelector: selector];
if (methodSignature == nil ||
[methodSignature numberOfArguments] != 3 ||
*[methodSignature methodReturnType] != 'v' ||
methodSignature.numberOfArguments != 3 ||
*methodSignature.methodReturnType != 'v' ||
*[methodSignature argumentTypeAtIndex: 0] != '@' ||
*[methodSignature argumentTypeAtIndex: 1] != ':') {
[self setValue: value
forUndefinedKey: key];
return;
}
|