ObjFW  Diff

Differences From Artifact [2b1836dbc4]:

To Artifact [c675091634]:


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

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

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
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
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
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
314






315
316
317
318
319
320

321
322
323
324
325




326
327
328


329
330





331
332
333
334
335
336
337
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
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



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



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
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





275
276
277
278



279
280
281

282
283
284
285
286
287
288
289
290
291
292
293







-
-


-
-
-
-
-
-
-
+
+
+
+


-






-
+

+
-
+

-
+
-
-
-
-
-
-
+
+
+
-
-





-
-
-
-
-
-
-
-
-
+
-
-
-
+
+

-
-
-
+
+
+

-
-
+
+

-


-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+








+
+
+
-
-
+
+

-
-
-






-
-
-
-
-
-
-
-
-
+
-
-
+
-
-


-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+







-
-
-



+
+









-
+

-
+


-
+


-
+

-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
+
+

-
-
+
+

-
-
-
+
+
+
+

-
-
-
+
+
+

-
-
-
-
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+

-
+

-
-
+
+

-
-
-
+
+
+

-
-
+
+
+

-
+
-
-
-
-
+
+
+
-
-


-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+
+
-

-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
+
+
+
+
+







	return ret;
}

- init
{
	self = [super init];

	size = 1;

	@try {
		data = [self allocMemoryWithSize: sizeof(BUCKET*)];
	} @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];
		size = 1;
		data[0] = NULL;
	} @catch (id e) {
		[self release];
		@throw e;
	}
	data[0] = NULL;

	return self;
}

- initWithDictionary: (OFDictionary*)dict
{
	uint32_t i;
	self = [super init];

	@try {
	self = [super init];
		uint32_t i;

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


	@try {
		data = [self allocMemoryForNItems: dict->size
					 withSize: sizeof(BUCKET*)];

		for (i = 0; i < dict->size; i++)
			data[i] = NULL;
	} @catch (OFException *e) {
		/*
		 * We can't use [super dealloc] on OS X here. Compiler bug?
		 * Anyway, we didn't do anything yet anyway, so [self dealloc]
		 * works.
		 */
		[self dealloc];
		@throw e;
	}


	size = dict->size;
	count = dict->count;
		size = dict->size;
		count = dict->count;

	for (i = 0; i < size; i++) {
		id <OFCopying> key;
		BUCKET *b;
		for (i = 0; i < size; i++) {
			id <OFCopying> key;
			BUCKET *b;

		if (dict->data[i] == NULL || dict->data[i] == DELETED)
			continue;
			if (dict->data[i] == NULL || dict->data[i] == DELETED)
				continue;

		@try {
			b = [self allocMemoryWithSize: sizeof(BUCKET)];
			key = [dict->data[i]->key copy];
		} @catch (OFException *e) {
			[self dealloc];
			@throw e;
		}


		@try {
			[dict->data[i]->object retain];
		} @catch (OFException *e) {
			[(id)key release];
			@try {
				[dict->data[i]->object retain];
			} @catch (id e) {
				[(id)key release];
			[self dealloc];
			@throw e;
		}
				@throw e;
			}

		b->key = key;
		b->object = dict->data[i]->object;
		b->hash = dict->data[i]->hash;
		data[i] = b;
			b->key = key;
			b->object = dict->data[i]->object;
			b->hash = dict->data[i]->hash;

			data[i] = b;
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObject: (id)obj
	  forKey: (id <OFCopying>)key
{
	self = [super init];

	@try {
	uint32_t i;
	BUCKET *b;
		uint32_t i;
		BUCKET *b;

	self = [self init];

	@try {
		data = [self allocMemoryForNItems: 2
					 withSize: sizeof(BUCKET*)];

		size = 2;
		for (i = 0; i < size; i++)
			data[i] = NULL;
	} @catch (OFException *e) {
		/*
		 * We can't use [super dealloc] on OS X here. Compiler bug?
		 * Anyway, we didn't do anything yet anyway, so [self dealloc]
		 * works.
		 */
		[self dealloc];
		@throw e;
	}


	i = [(id)key hash] & 1;
		i = [(id)key hash] & 1;

	@try {
		b = [self allocMemoryWithSize: sizeof(BUCKET)];
		key = [key copy];
	} @catch (OFException *e) {
		[self dealloc];
		@throw e;
	}


	@try {
		[obj retain];
	} @catch (OFException *e) {
		[(id)key release];
		@try {
			[obj retain];
		} @catch (id e) {
			[(id)key release];
		[self dealloc];
		@throw e;
	}
			@throw e;
		}

	b->key = key;
	b->object = obj;
	b->hash = [(id)key hash];
	data[i] = b;
	count = 1;
		b->key = key;
		b->object = obj;
		b->hash = [(id)key hash];

		data[i] = b;
		count = 1;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithObjects: (OFArray*)objs
	  forKeys: (OFArray*)keys
{
	id *objs_carray, *keys_carray;
	size_t i;

	self = [super init];

	@try {
		id *objs_carray, *keys_carray;
		size_t i, nsize;
		uint32_t j;

		keys_carray = [keys cArray];
		objs_carray = [objs cArray];
		count = [keys count];

		if (count > UINT32_MAX)
			@throw [OFOutOfRangeException newWithClass: isa];

		for (size = 1; size < count; size <<= 1);
		for (nsize = 1; nsize < count; nsize <<= 1);

		if (size == 0)
		if (nsize == 0)
			@throw [OFOutOfRangeException newWithClass: isa];

		data = [self allocMemoryForNItems: size
		data = [self allocMemoryForNItems: nsize
					 withSize: sizeof(BUCKET*)];

		for (j = 0; j < size; j++)
		for (j = 0; j < nsize; j++)
			data[j] = NULL;
	} @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;
		size = nsize;
		[self dealloc];
		@throw e;
	}


	for (i = 0; i < count; i++) {
		uint32_t j, hash, last;
		for (i = 0; i < count; i++) {
			uint32_t hash, last;

		hash = [keys_carray[i] hash];
		last = size;
			hash = [keys_carray[i] hash];
			last = size;

		for (j = hash & (size - 1); j < last && data[j] != NULL; j++)
			if ([(id)data[j]->key isEqual: keys_carray[i]])
				break;
			for (j = hash & (size - 1); j < last && data[j] != NULL;
			    j++)
				if ([(id)data[j]->key isEqual: keys_carray[i]])
					break;

		/* In case the last bucket is already used */
		if (j >= last) {
			last = hash & (size - 1);
			/* In case the last bucket is already used */
			if (j >= last) {
				last = hash & (size - 1);

			for (j = 0; j < last && data[j] != NULL; j++)
				if ([(id)data[j]->key isEqual: keys_carray[i]])
					break;
		}
				for (j = 0; j < last && data[j] != NULL; j++)
					if ([(id)data[j]->key
					    isEqual: keys_carray[i]])
						break;
			}

		/* Key not in dictionary */
		if (j >= last || data[j] == NULL ||
		    ![(id)data[j]->key isEqual: keys_carray[i]]) {
			BUCKET *b;
			id <OFCopying> key;
			/* Key not in dictionary */
			if (j >= last || data[j] == NULL ||
			    ![(id)data[j]->key isEqual: keys_carray[i]]) {
				BUCKET *b;
				id <OFCopying> key;

			last = size;
				last = size;

			j = hash & (size - 1);
			for (; j < last && data[j] != NULL; j++);
				j = hash & (size - 1);
				for (; j < last && data[j] != NULL; j++);

			/* In case the last bucket is already used */
			if (j >= last) {
				last = hash & (size - 1);
				/* In case the last bucket is already used */
				if (j >= last) {
					last = hash & (size - 1);

				for (j = 0; j < last && data[j] != NULL; j++);
			}
					for (j = 0; j < last && data[j] != NULL;
					    j++);
				}

			if (j >= last) {
				if (j >= last)
				Class c = isa;
				[self dealloc];
				@throw [OFOutOfRangeException newWithClass: c];
			}
					@throw [OFOutOfRangeException
					    newWithClass: isa];


			@try {
				b = [self allocMemoryWithSize: sizeof(BUCKET)];
				key = [keys_carray[i] copy];
			} @catch (OFException *e) {
				[self dealloc];
				@throw e;
			}


			@try {
				[objs_carray[i] retain];
			} @catch (OFException *e) {
				[(id)key release];
				@try {
					[objs_carray[i] retain];
				} @catch (id e) {
					[(id)key release];
				[self dealloc];
				@throw e;
			}
					@throw e;
				}

			b->key = key;
			b->object = objs_carray[i];
			b->hash = hash;
			data[j] = b;
				b->key = key;
				b->object = objs_carray[i];
				b->hash = hash;

				data[j] = b;

			continue;
		}
				continue;
			}

		/*
		 * They key is already in the dictionary. However, we just
		 * replace it so that the programmer gets the same behavior
		 * as if he'd call setObject:forKey: for each key/object pair.
		 */
			/*
			 * The key is already in the dictionary. However, we
			 * just replace it so that the programmer gets the same
			 * behavior as if he'd call setObject:forKey: for each
			 * key/object pair.
			 */
		@try {
			[objs_carray[i] retain];
		} @catch (OFException *e) {
			[self dealloc];
			@throw e;
		}


		@try {
			[data[j]->object release];
		} @catch (OFException *e) {
			[objs_carray[i] release];
			@try {
				[data[j]->object release];
			} @catch (id e) {
				[objs_carray[i] release];
			[self dealloc];
			@throw e;
		}
				@throw e;
			}

		data[j]->object = objs_carray[i];
			data[j]->object = objs_carray[i];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithKeysAndObjects: (id <OFCopying>)first, ...
{
345
346
347
348
349
350
351

352
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
378
379

380
381
382

383
384
385
386
387
388
389
390
391
392

393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411



412
413
414
415
416
417
418
419

420
421
422
423
424




425
426
427


428
429
430
431
432





433
434
435


436
437
438


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
465
466




467
468
469


470
471
472
473



474
475
476



477
478

479
480
481
482



483
484
485
486
487
488
489
490

491
492
493
494
495




496
497
498


499
500
501
502
503





504
505
506


507
508
509
510
511
512






513
514
515
516
517
518

519
520
521
522
523




524
525
526


527
528





529
530
531
532
533
534
535
301
302
303
304
305
306
307
308





309
310
311
312
313
314
315
316
317

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











346



347
348
349
350

351
352




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



378
379
380



381
382
383
384
385



386
387
388
389




390
391
392
393
394




395
396
397
398
399


400
401
402



403
404
405
406


407
408
409
410

411




412
413
414


415
416




417





418
419
420
421



422
423
424




425
426
427
428
429
430


431
432
433





434
435
436
437
438
439

440




441





442
443
444
445



446
447
448

449
450
451
452
453
454
455
456
457
458
459
460







+
-
-
-
-
-
+
+
+
+
+
+
+

+
-
+
+
+
+

+
+
+
+
-
-
-
+
+
+

-
+
-
-
-
-
-
+
+
+
-

-
+
-
-
-
-
+
+
-
-
-
+


-
+

-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-

-
-
-
+
+
+

-


-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
+
+

-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
+
+
+
+

-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+

-
-
+
+

-
-
-
+
+
+

-
-
+
+
+

-
+
-
-
-
-
+
+
+
-
-


-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+
+
-

-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+

-
+
+
+
+
+








	return ret;
}

- initWithKey: (id <OFCopying>)key
      argList: (va_list)args
{
	self = [super init];
	BUCKET *b;
	id obj;
	size_t i;
	uint32_t j, hash;
	va_list args2;

	@try {
		id obj;
		size_t i, nsize;
		uint32_t j, hash;
		va_list args2;
		BUCKET *b;

		va_copy(args2, args);
	self = [super init];

		if (key == nil)
			@throw [OFInvalidArgumentException newWithClass: isa
							       selector: _cmd];

		if ((obj = va_arg(args, id)) == nil)
			@throw [OFInvalidArgumentException newWithClass: isa
							       selector: _cmd];

	count = 1;
	for (va_copy(args2, args); va_arg(args2, id) != nil; count++);
	count >>= 1;
		count = 1;
		for (; va_arg(args2, id) != nil; count++);
		count >>= 1;

	if (count > UINT32_MAX) {
		if (count > UINT32_MAX)
		Class c = isa;
		[self dealloc];
		@throw [OFOutOfRangeException newWithClass: c];
	}

			@throw [OFOutOfRangeException newWithClass: isa];

		for (nsize = 1; nsize < count; nsize <<= 1);
	for (size = 1; size < count; size <<= 1);

	if (size == 0) {
		if (nsize == 0)
		Class c = isa;
		[self dealloc];
		@throw [OFOutOfRangeException newWithClass: c];
	}
			@throw [OFOutOfRangeException newWithClass: isa];


	@try {
		data = [self allocMemoryForNItems: size
		data = [self allocMemoryForNItems: nsize
					 withSize: sizeof(BUCKET*)];

		for (j = 0; j < size; j++)
		for (j = 0; j < nsize; j++)
			data[j] = NULL;
	} @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;
	}


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

	if ((obj = va_arg(args, id)) == nil) {
		Class c = isa;
		[self dealloc];
		@throw [OFInvalidArgumentException newWithClass: c
						       selector: _cmd];
	}

	/* Add first key / object pair */
	hash = [(id)key hash];
	j = hash & (size - 1);
		/* Add first key / object pair */
		hash = [(id)key hash];
		j = hash & (size - 1);

	@try {
		b = [self allocMemoryWithSize: sizeof(BUCKET)];
		key = [key copy];
	} @catch (OFException *e) {
		[self dealloc];
		@throw e;
	}


	@try {
		[obj retain];
	} @catch (OFException *e) {
		[(id)key release];
		@try {
			[obj retain];
		} @catch (id e) {
			[(id)key release];
		[self dealloc];
		@throw e;
	}
			@throw e;
		}

	b->key = key;
	b->object = obj;
	b->hash = hash;
	data[j] = b;
		b->key = key;
		b->object = obj;
		b->hash = hash;

		data[j] = b;

	for (i = 1; i < count; i++) {
		uint32_t last;
		for (i = 1; i < count; i++) {
			uint32_t last;

		key = va_arg(args, id <OFCopying>);
		obj = va_arg(args, id);
			key = va_arg(args, id <OFCopying>);
			obj = va_arg(args, id);

		if (key == nil || obj == nil) {
			if (key == nil || obj == nil)
			Class c = isa;
			[self dealloc];
			@throw [OFInvalidArgumentException newWithClass: c
							       selector: _cmd];
		}
				@throw [OFInvalidArgumentException
				    newWithClass: isa
					selector: _cmd];


		hash = [(id)key hash];
		last = size;
			hash = [(id)key hash];
			last = size;

		for (j = hash & (size - 1); j < last && data[j] != NULL; j++)
			if ([(id)data[j]->key isEqual: key])
				break;
			for (j = hash & (size - 1); j < last && data[j] != NULL;
			    j++)
				if ([(id)data[j]->key isEqual: key])
					break;

		/* In case the last bucket is already used */
		if (j >= last) {
			last = hash & (size - 1);
			/* In case the last bucket is already used */
			if (j >= last) {
				last = hash & (size - 1);

			for (j = 0; j < last && data[j] != NULL; j++)
				if ([(id)data[j]->key isEqual: key])
					break;
		}
				for (j = 0; j < last && data[j] != NULL; j++)
					if ([(id)data[j]->key isEqual: key])
						break;
			}

		/* Key not in dictionary */
		if (j >= last || data[j] == NULL ||
		    ![(id)data[j]->key isEqual: key]) {
			last = size;
			/* Key not in dictionary */
			if (j >= last || data[j] == NULL ||
			    ![(id)data[j]->key isEqual: key]) {
				last = size;

			j = hash & (size - 1);
			for (; j < last && data[j] != NULL; j++);
				j = hash & (size - 1);
				for (; j < last && data[j] != NULL; j++);

			/* In case the last bucket is already used */
			if (j >= last) {
				last = hash & (size - 1);
				/* In case the last bucket is already used */
				if (j >= last) {
					last = hash & (size - 1);

				for (j = 0; j < last && data[j] != NULL; j++);
			}
					for (j = 0; j < last && data[j] != NULL;
					    j++);
				}

			if (j >= last) {
				if (j >= last)
				Class c = isa;
				[self dealloc];
				@throw [OFOutOfRangeException newWithClass: c];
			}
					@throw [OFOutOfRangeException
					    newWithClass: isa];


			@try {
				b = [self allocMemoryWithSize: sizeof(BUCKET)];
				key = [key copy];
			} @catch (OFException *e) {
				[self dealloc];
				@throw e;
			}


			@try {
				[obj retain];
			} @catch (OFException *e) {
				[(id)key release];
				@try {
					[obj retain];
				} @catch (id e) {
					[(id)key release];
				[self dealloc];
				@throw e;
			}
					@throw e;
				}

			b->key = key;
			b->object = obj;
			b->hash = hash;
			data[j] = b;
				b->key = key;
				b->object = obj;
				b->hash = hash;

				data[j] = b;

			continue;
		}
				continue;
			}

		/*
		 * They key is already in the dictionary. However, we just
		 * replace it so that the programmer gets the same behavior
		 * as if he'd call setObject:forKey: for each key/object pair.
		 */
			/*
			 * The key is already in the dictionary. However, we
			 * just replace it so that the programmer gets the same
			 * behavior as if he'd call setObject:forKey: for each
			 * key/object pair.
			 */
		@try {
			[obj retain];
		} @catch (OFException *e) {
			[self dealloc];
			@throw e;
		}


		@try {
			[data[j]->object release];
		} @catch (OFException *e) {
			[obj release];
			@try {
				[data[j]->object release];
			} @catch (id e) {
				[obj release];
			[self dealloc];
			@throw e;
		}
				@throw e;
			}

		data[j]->object = obj;
			data[j]->object = obj;
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (id)objectForKey: (id)key
{