ObjFW  Check-in [eddc0ba58c]

Overview
Comment:Implement OFCopying and OFMutableCopying in OFDictionary.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: eddc0ba58c079540e32df2f680ecb4d0692d9e27172eff9c760c475953ba0adb
User & Date: js on 2009-06-30 13:38:36
Other Links: manifest | tags
Context
2009-06-30
14:15
Add +[instancesRespondToSelector:] to OFObject. check-in: 5f47e81a9e user: js tags: trunk
13:38
Implement OFCopying and OFMutableCopying in OFDictionary. check-in: eddc0ba58c user: js tags: trunk
12:55
Add some missing documentation. check-in: 973e19f23c user: js tags: trunk
Changes

Modified src/OFDictionary.h from [8038342f92] to [60d39a625e].

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
	id				   key;
	uint32_t			   hash;
} of_dictionary_list_object_t;

/**
 * The OFDictionary class provides a class for using hash tables.
 */
@interface OFDictionary: OFObject
{
	OFList **data;
	size_t size;
}

/**
 * Creates a new OFDictionary, defaulting to a 12 bit hash.
 *
 * \return A new autoreleased OFDictionary
 */
+ dictionary;









/**
 * Creates a new OFDictionary with a hash of N bits.
 *
 * \param bits The size of the hash to use
 * \return A new autoreleased OFDictionary
 */
+ dictionaryWithHashSize: (int)hashsize;







|












>
>
>
>
>
>
>
>







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
	id				   key;
	uint32_t			   hash;
} of_dictionary_list_object_t;

/**
 * The OFDictionary class provides a class for using hash tables.
 */
@interface OFDictionary: OFObject <OFCopying, OFMutableCopying>
{
	OFList **data;
	size_t size;
}

/**
 * Creates a new OFDictionary, defaulting to a 12 bit hash.
 *
 * \return A new autoreleased OFDictionary
 */
+ dictionary;

/**
 * Creates a new OFDictionary with the specified dictionary.
 *
 * \param dict An OFDictionary
 * \return A new autoreleased OFDictionary
 */
+ dictionaryWithDictionary: (OFDictionary*)dict;

/**
 * Creates a new OFDictionary with a hash of N bits.
 *
 * \param bits The size of the hash to use
 * \return A new autoreleased OFDictionary
 */
+ dictionaryWithHashSize: (int)hashsize;
81
82
83
84
85
86
87









88
89
90
91
92
93
94
/**
 * Initializes an already allocated OFDictionary, defaulting to a 12 bit hash.
 *
 * \return An initialized OFDictionary
 */
- init;










/**
 * Initializes an already allocated OFDictionary with a hash of N bits.
 *
 * \param bits The size of the hash to use
 * \return An initialized OFDictionary
 */
- initWithHashSize: (int)hashsize;







>
>
>
>
>
>
>
>
>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
 * Initializes an already allocated OFDictionary, defaulting to a 12 bit hash.
 *
 * \return An initialized OFDictionary
 */
- init;

/**
 * Initializes an already allocated OFDictionary with the specified
 * OFDictionary.
 *
 * \param dict An OFDictionary
 * \return An initialized OFDictionary
 */
- initWithDictionary: (OFDictionary*)dict;

/**
 * Initializes an already allocated OFDictionary with a hash of N bits.
 *
 * \param bits The size of the hash to use
 * \return An initialized OFDictionary
 */
- initWithHashSize: (int)hashsize;

Modified src/OFDictionary.m from [9fa2393e86] to [59d8f02b6d].

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

#include "config.h"

#include <string.h>

#import "OFDictionary.h"
#import "OFIterator.h"

#import "OFExceptions.h"

/* References for static linking */
void _references_to_categories_of_OFDictionary()
{
	_OFIterator_reference = 1;
}

@implementation OFDictionary
+ dictionary;
{
	return [[[self alloc] init] autorelease];
}






+ dictionaryWithHashSize: (int)hashsize
{
	return [[[self alloc] initWithHashSize: hashsize] autorelease];
}

+ dictionaryWithKey: (OFObject <OFCopying>*)key







>













>
>
>
>
>







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

#include "config.h"

#include <string.h>

#import "OFDictionary.h"
#import "OFIterator.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"

/* References for static linking */
void _references_to_categories_of_OFDictionary()
{
	_OFIterator_reference = 1;
}

@implementation OFDictionary
+ dictionary;
{
	return [[[self alloc] init] autorelease];
}

+ dictionaryWithDictionary: (OFDictionary*)dict
{
	return [[[self alloc] initWithDictionary: dict] autorelease];
}

+ dictionaryWithHashSize: (int)hashsize
{
	return [[[self alloc] initWithHashSize: hashsize] autorelease];
}

+ dictionaryWithKey: (OFObject <OFCopying>*)key
77
78
79
80
81
82
83
















































































84
85
86
87
88
89
90
		 */
		size = 0;
		[self dealloc];
		@throw e;
	}
	memset(data, 0, size * sizeof(OFList*));

















































































	return self;
}

- initWithHashSize: (int)hashsize
{
	self = [super init];








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







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
165
166
167
168
169
170
171
172
173
174
175
176
		 */
		size = 0;
		[self dealloc];
		@throw e;
	}
	memset(data, 0, size * sizeof(OFList*));

	return self;
}

- initWithDictionary: (OFDictionary*)dict
{
	OFAutoreleasePool *pool;
	OFIterator *iter;
	of_iterator_pair_t pair;
	of_iterator_pair_t (*next)(id, SEL);

	self = [super init];

	if (dict == nil) {
		Class c = isa;
		size = 0;
		[self dealloc];
		@throw [OFInvalidArgumentException newWithClass: c
						    andSelector: _cmd];
	}

	size = dict->size;

	@try {
		data = [self allocMemoryForNItems: size
					 withSize: sizeof(OFList*)];
		memset(data, 0, size * sizeof(OFList*));

		pool = [[OFAutoreleasePool alloc] init];
		iter = [dict iterator];
		next = (of_iterator_pair_t(*)(id, SEL))
		    [iter methodForSelector: @selector(nextKeyObjectPair)];
	} @catch (OFException *e) {
		/*
		 * We can't use [super dealloc] on OS X here. Compiler bug?
		 * Anyway, set size to 0 so that [self dealloc] works.
		 */
		size = 0;
		[self dealloc];
		@throw e;
	}

	for (;;) {
		uint32_t hash;
		OFObject <OFCopying> *key;

		pair = next(iter, @selector(nextKeyObjectPair));

		if (pair.key == nil || pair.object == nil)
			break;

		hash = pair.hash & (size - 1);

		@try {
			key = [pair.key copy];
		} @catch (OFException *e) {
			[self dealloc];
			@throw e;
		}

		@try {
			of_dictionary_list_object_t *o;

			if (data[hash] == nil)
				data[hash] = [[OFList alloc]
				    initWithListObjectSize:
				    sizeof(of_dictionary_list_object_t)];

			o = (of_dictionary_list_object_t*)
			    [data[hash] append: pair.object];
			o->key = key;
			o->hash = pair.hash;
		} @catch (OFException *e) {
			[key release];
			[self dealloc];
			@throw e;
		}
	}

	[pool release];

	return self;
}

- initWithHashSize: (int)hashsize
{
	self = [super init];

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370






371
372
373
374
375
376
377
	    iter != NULL; iter = iter->next)
		if ([iter->key isEqual: key])
			return iter->object;

	return nil;
}

/* FIXME: Implement this! */
/*
- (BOOL)isEqual
{
}

- (id)copy
{

}

- (id)mutableCopy






{
}
*/

- (void)dealloc
{
	size_t i;







<
<
<
<
<
<


>



>
>
>
>
>
>







439
440
441
442
443
444
445






446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	    iter != NULL; iter = iter->next)
		if ([iter->key isEqual: key])
			return iter->object;

	return nil;
}







- (id)copy
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableDictionary alloc] initWithDictionary: self];
}

/* FIXME: Implement this!
- (BOOL)isEqual
{
}
*/

- (void)dealloc
{
	size_t i;

Modified src/OFIterator.h from [7d79beb13c] to [b88ba4de2f].

10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
 */

#import "OFObject.h"
#import "OFList.h"
#import "OFDictionary.h"

typedef struct __of_iterator_pair {
	id key;
	id object;

} of_iterator_pair_t;

extern int _OFIterator_reference;

/**
 * The OFIterator class provides methods to iterate through objects.
 */







|
|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 */

#import "OFObject.h"
#import "OFList.h"
#import "OFDictionary.h"

typedef struct __of_iterator_pair {
	id	 key;
	id	 object;
	uint32_t hash;
} of_iterator_pair_t;

extern int _OFIterator_reference;

/**
 * The OFIterator class provides methods to iterate through objects.
 */

Modified src/OFIterator.m from [96f23ad28b] to [7c8346b7b5].

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

	for (;;) {
		if (last == NULL) {
			for (; pos < size && data[pos] == nil; pos++);
			if (pos == size) {
				next.key = nil;
				next.object = nil;

				return next;
			}

			last = (of_dictionary_list_object_t*)
			    [data[pos++] first];
			next.key = last->key;
			next.object = last->object;

			return next;
		}

		if ((last = last->next) != NULL) {
			next.key = last->key;
			next.object = last->object;

			return next;
		}
	}
}

- reset
{







>







>






>







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

	for (;;) {
		if (last == NULL) {
			for (; pos < size && data[pos] == nil; pos++);
			if (pos == size) {
				next.key = nil;
				next.object = nil;
				next.hash = 0;
				return next;
			}

			last = (of_dictionary_list_object_t*)
			    [data[pos++] first];
			next.key = last->key;
			next.object = last->object;
			next.hash = last->hash;
			return next;
		}

		if ((last = last->next) != NULL) {
			next.key = last->key;
			next.object = last->object;
			next.hash = last->hash;
			return next;
		}
	}
}

- reset
{

Modified src/OFMutableDictionary.m from [eed907dfa3] to [66ece5ed91].

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
	[self freeMemory: data];
	data = newdata;
	size = newsize;

	return self;
}

/* FIXME: Implement this! */
/*
- (id)copy
{
}

- (id)mutableCopy
{
}
*/
@end







<
<


<
|
<
<

<

134
135
136
137
138
139
140


141
142

143


144

145
	[self freeMemory: data];
	data = newdata;
	size = newsize;

	return self;
}



- (id)copy
{

	return [[OFDictionary alloc] initWithDictionary: self];


}

@end

Modified src/OFMutableString.m from [b1e7f862ab] to [fdbe2b51a4].

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#import "OFMutableString.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#import "asprintf.h"

@implementation OFMutableString
- (id)copy
{
	return [[OFString alloc] initWithString: self];
}

- setToCString: (const char*)str
{
	size_t len;

	if (string != NULL)
		[self freeMemory: string];








<
<
<
<
<







27
28
29
30
31
32
33





34
35
36
37
38
39
40
#import "OFMutableString.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#import "asprintf.h"

@implementation OFMutableString





- setToCString: (const char*)str
{
	size_t len;

	if (string != NULL)
		[self freeMemory: string];

392
393
394
395
396
397
398





399
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
		[e dealloc];
	}

	return self;
}





@end







>
>
>
>
>

387
388
389
390
391
392
393
394
395
396
397
398
399
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
		[e dealloc];
	}

	return self;
}

- (id)copy
{
	return [[OFString alloc] initWithString: self];
}
@end

Modified src/OFString.m from [98df1c138a] to [248b3d5447].

264
265
266
267
268
269
270










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
	return string;
}

- (size_t)length
{
	return length;
}











- (id)copy
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableString alloc] initWithString: self];
}

- (BOOL)isEqual: (id)obj
{
	if (![obj isKindOfClass: [OFString class]])
		return NO;
	if (strcmp(string, [obj cString]))
		return NO;

	return YES;
}

- (int)compare: (id)obj
{
	if (![obj isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						    andSelector: _cmd];

	return strcmp(string, [obj cString]);







>
>
>
>
>
>
>
>
>
>











<
<
<
<
<
<
<
<
<
<







264
265
266
267
268
269
270
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
	return string;
}

- (size_t)length
{
	return length;
}

- (BOOL)isEqual: (id)obj
{
	if (![obj isKindOfClass: [OFString class]])
		return NO;
	if (strcmp(string, [obj cString]))
		return NO;

	return YES;
}

- (id)copy
{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableString alloc] initWithString: self];
}











- (int)compare: (id)obj
{
	if (![obj isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						    andSelector: _cmd];

	return strcmp(string, [obj cString]);

Modified tests/OFDictionary/OFDictionary.m from [ae3f01c9a0] to [8f8688c53b].

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

30
31
32
33
34
35
36
#include <string.h>

#import "OFAutoreleasePool.h"
#import "OFDictionary.h"
#import "OFString.h"
#import "OFExceptions.h"

#define TESTS 12

int
main()
{
	int i = 0;

	OFDictionary *dict = [OFMutableDictionary dictionaryWithHashSize: 16];

	OFIterator *iter = [dict iterator];
	of_iterator_pair_t pair[2];

	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFString *key1 = [OFString stringWithCString: "key1"];
	OFString *key2 = [OFString stringWithCString: "key2"];
	OFString *value1 = [OFString stringWithCString: "value1"];







|







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string.h>

#import "OFAutoreleasePool.h"
#import "OFDictionary.h"
#import "OFString.h"
#import "OFExceptions.h"

#define TESTS 15

int
main()
{
	int i = 0;

	OFDictionary *dict = [OFMutableDictionary dictionaryWithHashSize: 16];
	OFDictionary *dict2;
	OFIterator *iter = [dict iterator];
	of_iterator_pair_t pair[2];

	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFString *key1 = [OFString stringWithCString: "key1"];
	OFString *key2 = [OFString stringWithCString: "key2"];
	OFString *value1 = [OFString stringWithCString: "value1"];
133
134
135
136
137
138
139




























140
141
142
143
144
	}

	i++;
	if (![[dict objectForKey: @"k2"] isEqual: @"o2"]) {
		printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS);
		return 1;
	}





























	printf("\033[1;32mTests successful: %d/%d\033[0m\n", i, TESTS);

	return 0;
}







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





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
165
166
167
168
169
170
171
172
173
	}

	i++;
	if (![[dict objectForKey: @"k2"] isEqual: @"o2"]) {
		printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS);
		return 1;
	}

	i++;
	dict2 = [dict copy];
	[dict release];
	if (![[dict2 objectForKey: @"k1"] isEqual: @"o1"] ||
	    ![[dict2 objectForKey: @"k2"] isEqual: @"o2"]) {
		printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS);
		return 1;
	}

	i++;
	dict = [dict2 mutableCopy];
	[dict2 release];
	if (![[dict objectForKey: @"k1"] isEqual: @"o1"] ||
	    ![[dict objectForKey: @"k2"] isEqual: @"o2"]) {
		printf("\033[k\033[1;31mtest %d/%d failed!\033[m\n", i, TESTS);
		return 1;
	}

	i++;
	[dict setObject: @"o0" forKey: @"k1"];
	[dict setObject: @"o3" forKey: @"k3"];
	if (![[dict objectForKey: @"k1"] isEqual: @"o0"] ||
	    ![[dict objectForKey: @"k2"] isEqual: @"o2"] ||
	    ![[dict objectForKey: @"k3"] isEqual: @"o3"]) {
		printf("\033[k\033[1;31mtest %d/%d failed!\033[m\n", i, TESTS);
		return 1;
	}

	printf("\033[1;32mTests successful: %d/%d\033[0m\n", i, TESTS);

	return 0;
}