ObjFW  Check-in [ef8d57bd4e]

Overview
Comment:Implement Key Value Coding for OFSet

If the key starts with an @, the @ is stripped and the super method is
called. Otherwise, this returns the value for all objects / sets the
value for all objects.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ef8d57bd4e4d4030fa948c52227cc2ca9148118730be228122959bb0e91189ae
User & Date: js on 2016-06-05 20:37:10
Other Links: manifest | tags
Context
2016-06-05
21:17
Always cast to unsigned char for to{upper,lower}() check-in: 09a0d12bae user: js tags: trunk
20:37
Implement Key Value Coding for OFSet check-in: ef8d57bd4e user: js tags: trunk
20:27
Add +[OFMutableSet setWithCapacity:] check-in: f50d7da785 user: js tags: trunk
Changes

Modified src/OFSet.h from [58c61ab64e] to [be2d24001b].

217
218
219
220
221
222
223































224
225
226
227
228
229
230
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *	  object.
 *
 * @param object The object which is checked for being in the set
 * @return A boolean whether the set contains the specified object
 */
- (bool)containsObject: (nullable ObjectType)object;

/*!
 * @brief Returns the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super valueForKey:]` is called.
 * If the key does not start with an `@`, a new set with the value for the
 * specified key for each object is returned.
 *
 * @note Unlike with @ref OFArray, any nil values are removed!
 *
 * @param key The key of the value to return
 * @return The value for the specified key
 */
- (nullable id)valueForKey: (OFString*)key;

/*!
 * @brief Set the value for the specified key
 *
 * If the key starts with an `@`, the `@` is stripped and
 * `[super setValue:forKey:]` is called.
 * If the key does not start with an `@`, @ref setValue:forKey: is called for
 * each object.
 *
 * @note A @ref OFNull value is translated to nil!
 *
 * @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 Returns an OFEnumerator to enumerate through all objects of the set.
 *
 * @returns An OFEnumerator to enumerate through all objects of the set
 */
- (OFEnumerator OF_GENERIC(ObjectType)*)objectEnumerator;

Modified src/OFSet.m from [704c371206] to [44df76d02e].

19
20
21
22
23
24
25

26
27
28
29
30
31
32
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







+







#include <stdlib.h>

#import "OFSet.h"
#import "OFSet_hashtable.h"
#import "OFString.h"
#import "OFArray.h"
#import "OFXMLElement.h"
#import "OFNull.h"

static struct {
	Class isa;
} placeholder;

@interface OFSet_placeholder: OFSet
@end
208
209
210
211
212
213
214




















































215
216
217
218
219
220
221
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	OF_INVALID_INIT_METHOD
}

- (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (id)valueForKey: (OFString*)key
{
	OFMutableSet *ret;

	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];
	}

	ret = [OFMutableSet setWithCapacity: [self count]];

	for (id object in self) {
		id value = [object valueForKey: key];

		if (value != nil)
			[ret addObject: value];
	}

	[ret makeImmutable];

	return ret;
}

- (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;
	}

	if (value == [OFNull null])
		value = nil;

	for (id object in self)
		[object setValue: value
			  forKey: key];
}

- (bool)containsObject: (id)object
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFEnumerator*)objectEnumerator

Modified tests/OFSetTests.m from [62dfb8dace] to [a90285c3e6].

14
15
16
17
18
19
20

21
22
23
24
25
26
27
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28







+







 * file.
 */

#include "config.h"

#import "OFSet.h"
#import "OFArray.h"
#import "OFNumber.h"
#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFSet";
126
127
128
129
130
131
132








133
134
135
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







+
+
+
+
+
+
+
+



			[mutableSet removeObject: s];
	} @catch (OFEnumerationMutationException *e) {
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok);

	TEST(@"-[valueForKey:]",
	    [(set1 = [[OFSet setWithObjects: @"a", @"ab", @"abc", @"b", nil]
	    valueForKey: @"length"]) isEqual: [OFSet setWithObjects:
	    [OFNumber numberWithSize: 1], [OFNumber numberWithSize: 2],
	    [OFNumber numberWithSize: 3], nil]] &&
	    [[set1 valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 3]])

	[pool drain];
}
@end