ObjFW  Check-in [05196e511a]

Overview
Comment:Implement Key Value Coding for OFArray

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: 05196e511aa3b6c1c2ca239a1482f9d6ca56ccd0d2eaab781d2cc32db109d569
User & Date: js on 2016-06-05 15:00:33
Other Links: manifest | tags
Context
2016-06-05
15:11
Move -[setValue:forKey:] to OFDictionary check-in: f816d1ec7c user: js tags: trunk
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
Changes

Modified src/OFArray.h from [a3a32a9cf7] to [66a6bc8b55].

192
193
194
195
196
197
198































199
200
201
202
203
204
205
 *
 * @param index The index of the object to return
 * @return The object at the specified index in the array
 */
- (ObjectType)objectAtIndex: (size_t)index;
- (ObjectType)objectAtIndexedSubscript: (size_t)index;
































/*!
 * @brief Copies the objects at the specified range to the specified buffer.
 *
 * @param buffer The buffer to copy the objects to
 * @param range The range to copy
 */
- (void)getObjects: (ObjectType __unsafe_unretained _Nonnull *_Nonnull)buffer







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







192
193
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
 *
 * @param index The index of the object to return
 * @return The object at the specified index in the array
 */
- (ObjectType)objectAtIndex: (size_t)index;
- (ObjectType)objectAtIndexedSubscript: (size_t)index;

/*!
 * @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 array with the value for the
 * specified key for each object is returned.
 *
 * @note Any nil values are replaced with @ref OFNull!
 *
 * @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 Copies the objects at the specified range to the specified buffer.
 *
 * @param buffer The buffer to copy the objects to
 * @param range The range to copy
 */
- (void)getObjects: (ObjectType __unsafe_unretained _Nonnull *_Nonnull)buffer

Modified src/OFArray.m from [a881a5d8d9] to [2d002f2918].

23
24
25
26
27
28
29

30
31
32
33
34
35
36

#import "OFArray.h"
#import "OFArray_subarray.h"
#import "OFArray_adjacent.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFDataArray.h"


#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

static struct {
	Class isa;







>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

#import "OFArray.h"
#import "OFArray_subarray.h"
#import "OFArray_adjacent.h"
#import "OFString.h"
#import "OFXMLElement.h"
#import "OFDataArray.h"
#import "OFNull.h"

#import "OFEnumerationMutationException.h"
#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

static struct {
	Class isa;
270
271
272
273
274
275
276





























277
278
279
280
281
282
283
	OF_UNRECOGNIZED_SELECTOR
}

- (id)objectAtIndexedSubscript: (size_t)index
{
	return [self objectAtIndex: index];
}






























- (size_t)indexOfObject: (id)object
{
	size_t i = 0;

	if (object == nil)
		return OF_NOT_FOUND;







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







271
272
273
274
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
306
307
308
309
310
311
312
313
	OF_UNRECOGNIZED_SELECTOR
}

- (id)objectAtIndexedSubscript: (size_t)index
{
	return [self objectAtIndex: index];
}

- (id)valueForKey: (OFString*)key
{
	OFMutableArray *ret = [OFMutableArray arrayWithCapacity: [self count]];

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

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

		[ret addObject: value];
	}

	[ret makeImmutable];

	return ret;
}

- (void)setValue: (id)value
	  forKey: (OFString*)key
{
	if (value == [OFNull null])
		value = nil;

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

- (size_t)indexOfObject: (id)object
{
	size_t i = 0;

	if (object == nil)
		return OF_NOT_FOUND;

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

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 * @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;

/*!







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 * @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 Returns 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;

/*!

Modified tests/OFArrayTests.m from [ea65aa5e42] to [75808adfc5].

14
15
16
17
18
19
20


21
22
23
24
25
26
27
 * file.
 */

#include "config.h"

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


#import "OFAutoreleasePool.h"

#import "OFEnumerationMutationException.h"
#import "OFOutOfRangeException.h"

#import "TestsAppDelegate.h"








>
>







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

#include "config.h"

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

#import "OFEnumerationMutationException.h"
#import "OFOutOfRangeException.h"

#import "TestsAppDelegate.h"

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
		case 1:
			return @"bar";
		}

		return nil;
		}]) && [[m[0] description] isEqual: @"(\n\tfoo,\n\tbar\n)"])

	TEST(@"-[mappedArrayUsingBLock]",
	    [[[m[0] mappedArrayUsingBlock: ^ id (id obj, size_t idx) {
		switch (idx) {
		case 0:
			return @"foobar";
		case 1:
			return @"qux";
		}







|







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
		case 1:
			return @"bar";
		}

		return nil;
		}]) && [[m[0] description] isEqual: @"(\n\tfoo,\n\tbar\n)"])

	TEST(@"-[mappedArrayUsingBlock:]",
	    [[[m[0] mappedArrayUsingBlock: ^ id (id obj, size_t idx) {
		switch (idx) {
		case 0:
			return @"foobar";
		case 1:
			return @"qux";
		}
316
317
318
319
320
321
322


















323
324
325
	    [[OFArray arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;
	    }])
#endif



















	[pool drain];
}
@end







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



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
	    [[OFArray arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;
	    }])
#endif

	TEST(@"-[valueForKey:]",
	    [[[OFArray arrayWithObjects: @"foo", @"bar", @"quxqux", nil]
	    valueForKey: @"length"] isEqual:
	    [OFArray arrayWithObjects: [OFNumber numberWithSize: 3],
	    [OFNumber numberWithSize: 3], [OFNumber numberWithSize: 6], nil]])

	m[0] = [OFMutableArray arrayWithObjects:
	    [OFURL URLWithString: @"http://foo.bar/"],
	    [OFURL URLWithString: @"http://bar.qux/"],
	    [OFURL URLWithString: @"http://qux.quxqux/"], nil];
	TEST(@"-[setValue:forKey:]",
	    R([m[0] setValue: [OFNumber numberWithShort: 1234]
		      forKey: @"port"]) &&
	    [m[0] isEqual: [OFArray arrayWithObjects:
	    [OFURL URLWithString: @"http://foo.bar:1234/"],
	    [OFURL URLWithString: @"http://bar.qux:1234/"],
	    [OFURL URLWithString: @"http://qux.quxqux:1234/"], nil]])

	[pool drain];
}
@end