ObjFW  Check-in [cbacea7ca3]

Overview
Comment:Implement Key Value Coding for OFDictionary

If the key starts with an @, the @ is stripped and the super method is
called. Otherwise, this is equivalent to -[objectForKey:] /
-[setValue:forKey:].

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: cbacea7ca3c0d6364473be5d4fac545e642b78f5d9b82ccc491be2ad5b2c8b58
User & Date: js on 2016-06-05 14:32:21
Other Links: manifest | tags
Context
2016-06-05
15:00
Implement Key Value Coding for OFArray check-in: 05196e511a user: js tags: trunk
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
Changes

Modified src/OFDictionary.h from [24f80d368e] to [2d197e0288].

194
195
196
197
198
199
200














201
202
203
204
205
206
207
 *
 * @param key The key whose object should be returned
 * @return The object for the given key or `nil` if the key was not found
 */
- (nullable ObjectType)objectForKey: (KeyType)key;
- (nullable ObjectType)objectForKeyedSubscript: (KeyType)key;















/*!
 * @brief Checks whether the dictionary contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains the specified object
 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 *
 * @param key The key whose object should be returned
 * @return The object for the given key or `nil` if the key was not found
 */
- (nullable ObjectType)objectForKey: (KeyType)key;
- (nullable ObjectType)objectForKeyedSubscript: (KeyType)key;

/*!
 * @brief Returns the value for the given key or `nil` if the key was not
 *	  found.
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super valueForKey:]` is called.
 * If the key does not start with an `@`, this is equivalent to
 * @ref objectForKey:.
 *
 * @param key The key whose value should be returned
 * @return The value for the given key or `nil` if the key was not found
 */
- (nullable id)valueForKey: (OFString*)key;

/*!
 * @brief Checks whether the dictionary contains an object equal to the
 *	  specified object.
 *
 * @param object The object which is checked for being in the dictionary
 * @return A boolean whether the dictionary contains the specified object
 */

Modified src/OFDictionary.m from [8f1dc3b962] to [3204259101].

275
276
277
278
279
280
281

















282
283
284
285
286
287
288
- (id)objectForKey: (id)key
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)objectForKeyedSubscript: (id)key
{

















	return [self objectForKey: key];
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
- (id)objectForKey: (id)key
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)objectForKeyedSubscript: (id)key
{
	return [self objectForKey: key];
}

- (id)valueForKey: (OFString*)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();
		id ret;

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		ret = [[super valueForKey: key] retain];

		objc_autoreleasePoolPop(pool);

		return [ret autorelease];
	}

	return [self objectForKey: key];
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

Modified src/OFKeyValueCoding.h from [3dd35e7786] to [141094746d].

10
11
12
13
14
15
16


17


18
19
20
21
22
23
24
25
26
27
28
29
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


 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */



@class OFString;



/*!
 * @protocol OFKeyValueCoding OFKeyValueCoding.h ObjFW/OFKeyValueCoding.h
 *
 * @brief A protocol for Key Value Coding.
 *
 * Key Value Coding makes it possible to access properties dynamically using
 * the interface described by this protocol.
 */
@protocol OFKeyValueCoding
/*!
 * @brief Return the value for the specified key
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (id)valueForKey: (OFString*)key;

/*!
 * @brief This is called by @ref valueForKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param key The undefined key of the value to return
 * @return The value for the specified undefined key
 */
- (id)valueForUndefinedKey: (OFString*)key;

/*!
 * @brief Set the value for the specified key
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (id)value
	  forKey: (OFString*)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param value The value for the specified undefined key
 * @param key The undefined key of the value to set
 */
-  (void)setValue: (id)value
  forUndefinedKey: (OFString*)key;
@end









>
>

>
>
















|










|







|











|


>
>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "macros.h"

@class OFString;

OF_ASSUME_NONNULL_BEGIN

/*!
 * @protocol OFKeyValueCoding OFKeyValueCoding.h ObjFW/OFKeyValueCoding.h
 *
 * @brief A protocol for Key Value Coding.
 *
 * Key Value Coding makes it possible to access properties dynamically using
 * the interface described by this protocol.
 */
@protocol OFKeyValueCoding
/*!
 * @brief Return the value for the specified key
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (nullable id)valueForKey: (OFString*)key;

/*!
 * @brief This is called by @ref valueForKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param key The undefined key of the value to return
 * @return The value for the specified undefined key
 */
- (nullable id)valueForUndefinedKey: (OFString*)key;

/*!
 * @brief Set the value for the specified key
 *
 * @param value The value for the specified key
 * @param key The key of the value to set
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;

/*!
 * @brief This is called by @ref setValue:forKey: if the specified key does not
 *	  exist.
 *
 * By default, this throws an @ref OFUndefinedKeyException.
 *
 * @param value The value for the specified undefined key
 * @param key The undefined key of the value to set
 */
-  (void)setValue: (nullable id)value
  forUndefinedKey: (OFString*)key;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMutableDictionary.h from [d87ccc345a] to [549070ec8e].

73
74
75
76
77
78
79














80
81
82
83
84
85
86
 * @param object The object to set the key to
 */
- (void)setObject: (ObjectType)object
	   forKey: (KeyType)key;
-   (void)setObject: (ObjectType)object
  forKeyedSubscript: (KeyType)key;















/*!
 * @brief Removes the object for the specified key from the dictionary.
 *
 * @param key The key whose object should be removed
 */
- (void)removeObjectForKey: (KeyType)key;








>
>
>
>
>
>
>
>
>
>
>
>
>
>







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 * @param object The object to set the key to
 */
- (void)setObject: (ObjectType)object
	   forKey: (KeyType)key;
-   (void)setObject: (ObjectType)object
  forKeyedSubscript: (KeyType)key;

/*!
 * @brief Sets a value for a key.
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super setValue:forKey:]` is called.
 * If the key does not start with an `@`, this is equivalent to
 * @ref setObject:forKey:.
 *
 * @param key The key to set
 * @param value The value to set the key to
 */
- (void)setValue: (nullable id)value
	  forKey: (OFString*)key;

/*!
 * @brief Removes the object for the specified key from the dictionary.
 *
 * @param key The key whose object should be removed
 */
- (void)removeObjectForKey: (KeyType)key;

Modified src/OFMutableDictionary.m from [6b8bc772b6] to [87db87aaf2].

16
17
18
19
20
21
22

23
24
25
26
27
28
29

#include "config.h"

#include <stdlib.h>

#import "OFMutableDictionary_hashtable.h"
#import "OFArray.h"


static struct {
	Class isa;
} placeholder;

@interface OFMutableDictionary_placeholder: OFDictionary
@end







>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#include "config.h"

#include <stdlib.h>

#import "OFMutableDictionary_hashtable.h"
#import "OFArray.h"
#import "OFString.h"

static struct {
	Class isa;
} placeholder;

@interface OFMutableDictionary_placeholder: OFDictionary
@end
171
172
173
174
175
176
177


















178
179
180
181
182
183
184

-   (void)setObject: (id)object
  forKeyedSubscript: (id)key
{
	[self setObject: object
		 forKey: key];
}



















- (void)removeObjectForKey: (id)key
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)removeAllObjects







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

-   (void)setObject: (id)object
  forKeyedSubscript: (id)key
{
	[self setObject: object
		 forKey: key];
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
{
	if ([key hasPrefix: @"@"]) {
		void *pool = objc_autoreleasePoolPush();

		key = [key substringWithRange: of_range(1, [key length] - 1)];
		[super setValue: value
			 forKey: key];

		objc_autoreleasePoolPop(pool);
		return;
	}

	[self setObject: value
		 forKey: key];
}

- (void)removeObjectForKey: (id)key
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)removeAllObjects

Modified tests/OFDictionaryTests.m from [6682fa3a80] to [b3dcaccc4e].

15
16
17
18
19
20
21

22
23
24
25
26
27
28
 */

#include "config.h"

#import "OFDictionary.h"
#import "OFString.h"
#import "OFArray.h"

#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFDictionary";







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 */

#include "config.h"

#import "OFDictionary.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFNumber.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFDictionary";
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56





57
58
59
60
61
62
63
	OFMutableDictionary *dict = [OFMutableDictionary dictionary];
	OFDictionary *idict;
	OFEnumerator *key_enum, *obj_enum;
	OFArray *akeys, *avalues;

	[dict setObject: values[0]
		 forKey: keys[0]];
	[dict setObject: values[1]
		 forKey: keys[1]];

	TEST(@"-[objectForKey:]",
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]] &&
	    [dict objectForKey: @"key3"] == nil)






	TEST(@"-[containsObject:]",
	    [dict containsObject: values[0]] &&
	    ![dict containsObject: @"nonexistant"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [dict containsObjectIdenticalTo: values[0]] &&
	    ![dict containsObjectIdenticalTo:







|
|






>
>
>
>
>







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
	OFMutableDictionary *dict = [OFMutableDictionary dictionary];
	OFDictionary *idict;
	OFEnumerator *key_enum, *obj_enum;
	OFArray *akeys, *avalues;

	[dict setObject: values[0]
		 forKey: keys[0]];
	[dict setValue: values[1]
		forKey: keys[1]];

	TEST(@"-[objectForKey:]",
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]] &&
	    [dict objectForKey: @"key3"] == nil)

	TEST(@"-[valueForKey:]",
	    [[dict valueForKey: keys[0]] isEqual: values[0]] &&
	    [[dict valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 2]])

	TEST(@"-[containsObject:]",
	    [dict containsObject: values[0]] &&
	    ![dict containsObject: @"nonexistant"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [dict containsObjectIdenticalTo: values[0]] &&
	    ![dict containsObjectIdenticalTo: