ObjFW  Check-in [6fc7fddef1]

Overview
Comment:Key Value Coding: Handle classes like objects
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6fc7fddef1a0b1e66c562cf0d997302fb8588b58b066eccc11fad9320dd306ac
User & Date: js on 2016-06-05 14:07:56
Other Links: manifest | tags
Context
2016-06-05
14:32
Implement Key Value Coding for OFDictionary check-in: cbacea7ca3 user: js tags: trunk
14:07
Key Value Coding: Handle classes like objects check-in: 6fc7fddef1 user: js tags: trunk
13:56
Add tests for Key Value Coding check-in: eb42896514 user: js tags: trunk
Changes

Modified src/OFObject+KeyValueCoding.m from [b460000a1a] to [a1b8c4dfd4].

48
49
50
51
52
53
54

55
56
57
58
59
60
61
	id ret;

	if (typeEncoding == NULL)
		return [self valueForUndefinedKey: key];

	switch (nextType(&typeEncoding)) {
	case '@':

		ret = [self performSelector: selector];
		break;
#define CASE(encoding, type, method)					  \
	case encoding:							  \
		{							  \
			type (*getter)(id, SEL) = (type(*)(id, SEL))	  \
			    [self methodForSelector: selector];		  \







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	id ret;

	if (typeEncoding == NULL)
		return [self valueForUndefinedKey: key];

	switch (nextType(&typeEncoding)) {
	case '@':
	case '#':
		ret = [self performSelector: selector];
		break;
#define CASE(encoding, type, method)					  \
	case encoding:							  \
		{							  \
			type (*getter)(id, SEL) = (type(*)(id, SEL))	  \
			    [self methodForSelector: selector];		  \
137
138
139
140
141
142
143

144
145
146
147
148
149
150
		[self    setValue: value
		  forUndefinedKey: key];
		return;
	}

	switch (valueType) {
	case '@':

		{
			void (*setter)(id, SEL, id) = (void(*)(id, SEL, id))
			    [self methodForSelector: selector];
			setter(self, selector, value);
		}
		break;
#define CASE(encoding, type, method) \







>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
		[self    setValue: value
		  forUndefinedKey: key];
		return;
	}

	switch (valueType) {
	case '@':
	case '#':
		{
			void (*setter)(id, SEL, id) = (void(*)(id, SEL, id))
			    [self methodForSelector: selector];
			setter(self, selector, value);
		}
		break;
#define CASE(encoding, type, method) \

Modified tests/OFObjectTests.m from [e3b3ae9aa1] to [e7dc8eb450].

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
90
91
# define TOO_BIG (SIZE_MAX - 128)
#endif

static OFString *module = @"OFObject";

@interface MyObj: OFObject
{
	id _object;

	bool _boolValue;
	char _charValue;
	short _shortValue;
	int _intValue;
	long _longValue;
	long long _longLongValue;
	unsigned char _unsignedCharValue;
	unsigned short _unsignedShortValue;
	unsigned int _unsignedIntValue;
	unsigned long _unsignedLongValue;
	unsigned long long _unsignedLongLongValue;
	float _floatValue;
	double _doubleValue;
}

@property (retain) id object;

@property bool boolValue;
@property char charValue;
@property short shortValue;
@property int intValue;
@property long longValue;
@property long long longLongValue;
@property unsigned char unsignedCharValue;
@property unsigned short unsignedShortValue;
@property unsigned int unsignedIntValue;
@property unsigned long unsignedLongValue;
@property unsigned long long unsignedLongLongValue;
@property float floatValue;
@property double doubleValue;
@end

@implementation MyObj

@synthesize object = _object, boolValue = _boolValue, charValue = _charValue;
@synthesize shortValue = _shortValue, intValue = _intValue;
@synthesize longValue = _longValue, longLongValue = _longLongValue;
@synthesize unsignedCharValue = _unsignedCharValue;
@synthesize unsignedShortValue = _unsignedShortValue;
@synthesize unsignedIntValue = _unsignedIntValue;
@synthesize unsignedLongValue = _unsignedLongValue;
@synthesize unsignedLongLongValue = _unsignedLongLongValue;
@synthesize floatValue = _floatValue, doubleValue = _doubleValue;

- (void)dealloc
{
	[_object release];

	[super dealloc];
}
@end

@implementation TestsAppDelegate (OFObjectTests)
- (void)objectTests







|
>















|
>
















>
|











|







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
90
91
92
93
94
# define TOO_BIG (SIZE_MAX - 128)
#endif

static OFString *module = @"OFObject";

@interface MyObj: OFObject
{
	id _objectValue;
	Class _classValue;
	bool _boolValue;
	char _charValue;
	short _shortValue;
	int _intValue;
	long _longValue;
	long long _longLongValue;
	unsigned char _unsignedCharValue;
	unsigned short _unsignedShortValue;
	unsigned int _unsignedIntValue;
	unsigned long _unsignedLongValue;
	unsigned long long _unsignedLongLongValue;
	float _floatValue;
	double _doubleValue;
}

@property (retain) id objectValue;
@property Class classValue;
@property bool boolValue;
@property char charValue;
@property short shortValue;
@property int intValue;
@property long longValue;
@property long long longLongValue;
@property unsigned char unsignedCharValue;
@property unsigned short unsignedShortValue;
@property unsigned int unsignedIntValue;
@property unsigned long unsignedLongValue;
@property unsigned long long unsignedLongLongValue;
@property float floatValue;
@property double doubleValue;
@end

@implementation MyObj
@synthesize objectValue = _objectValue, classValue = _classValue;
@synthesize boolValue = _boolValue, charValue = _charValue;
@synthesize shortValue = _shortValue, intValue = _intValue;
@synthesize longValue = _longValue, longLongValue = _longLongValue;
@synthesize unsignedCharValue = _unsignedCharValue;
@synthesize unsignedShortValue = _unsignedShortValue;
@synthesize unsignedIntValue = _unsignedIntValue;
@synthesize unsignedLongValue = _unsignedLongValue;
@synthesize unsignedLongLongValue = _unsignedLongLongValue;
@synthesize floatValue = _floatValue, doubleValue = _doubleValue;

- (void)dealloc
{
	[_objectValue release];

	[super dealloc];
}
@end

@implementation TestsAppDelegate (OFObjectTests)
- (void)objectTests
144
145
146
147
148
149
150
151

152
153


154
155
156
157
158
159
160




161
162
163
164
165
166
167

	TEST(@"-[description]",
	    [[o description] isEqual:
	    [OFString stringWithFormat: @"<OFObject: %p>", o]] &&
	    [[m description] isEqual:
	    [OFString stringWithFormat: @"<MyObj: %p>", m]])

	[m setObject: @"Hello"];

	TEST(@"-[valueForKey:]",
	    [[m valueForKey: @"object"] isEqual: @"Hello"])



	EXPECT_EXCEPTION(@"-[valueForKey:] with undefined key",
	    OFUndefinedKeyException, [m valueForKey: @"undefined"])

	TEST(@"-[setValue:forKey:]",
	    R([m setValue: @"World"
		   forKey: @"object"]) && [[m object] isEqual: @"World"])





	EXPECT_EXCEPTION(@"-[setValue:forKey:] with undefined key",
	    OFUndefinedKeyException, [m setValue: @"x"
					  forKey: @"undefined"])

	[m setBoolValue: 1];
	[m setCharValue: 2];







|
>

|
>
>






|
>
>
>
>







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

	TEST(@"-[description]",
	    [[o description] isEqual:
	    [OFString stringWithFormat: @"<OFObject: %p>", o]] &&
	    [[m description] isEqual:
	    [OFString stringWithFormat: @"<MyObj: %p>", m]])

	[m setObjectValue: @"Hello"];
	[m setClassValue: [m class]];
	TEST(@"-[valueForKey:]",
	    [[m valueForKey: @"objectValue"] isEqual: @"Hello"] &&
	    [[m valueForKey: @"classValue"] isEqual: [m class]] &&
	    [[m valueForKey: @"class"] isEqual: [m class]])

	EXPECT_EXCEPTION(@"-[valueForKey:] with undefined key",
	    OFUndefinedKeyException, [m valueForKey: @"undefined"])

	TEST(@"-[setValue:forKey:]",
	    R([m setValue: @"World"
		   forKey: @"objectValue"]) &&
	    R([m setValue: [OFObject class]
		   forKey: @"classValue"]) &&
	    [[m objectValue] isEqual: @"World"] &&
	    [[m classValue] isEqual: [OFObject class]])

	EXPECT_EXCEPTION(@"-[setValue:forKey:] with undefined key",
	    OFUndefinedKeyException, [m setValue: @"x"
					  forKey: @"undefined"])

	[m setBoolValue: 1];
	[m setCharValue: 2];