ObjFW  Check-in [033054ad75]

Overview
Comment:A few renames.

OFExceptions:
* OFNoMemException to OFOutOfMemoryException.
* OFMemNotPartOfObjException to OFMemoryNotPartOfObjectException.

OFObject:
* -[addItemToMemoryPool:] to -[addMemoryToPool:].
* -[allocWithSize:] to -[allocMemoryWithSize:].
* -[allocNItems:withSize] to -[allocMemoryForNItems:withSize:].
* -[resizeMem:toSize] to -[resizeMemory:toSize:].
* -[resizeMem:toNItems:withSize:] to
-[resizeMemoryToNItems:withSize:].
* -[freeMem] to -[freeMemory:].

OFString:
* -[urlencode] to -[urlEncodedString].
* -[urldecode] to -[urlDecodedString].

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 033054ad75344811c179100e257e87c232435ca9aa0a36c9b6141b037f9d0727
User & Date: js on 2009-05-29 19:21:57
Other Links: manifest | tags
Context
2009-06-01
01:15
Add --all to objfw-config.in. check-in: c63017b1f3 user: js tags: trunk
2009-05-29
19:21
A few renames. check-in: 033054ad75 user: js tags: trunk
09:28
Always use [self alloc]. check-in: 282aadb9df user: js tags: trunk
Changes

Modified src/OFDataArray.m from [6943671a33] to [118e82fbe1].

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
}

- addItem: (void*)item
{
	if (SIZE_MAX - count < 1)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMem: data
		      toNItems: count + 1
		      withSize: itemsize];

	memcpy(data + count++ * itemsize, item, itemsize);

	return self;
}

- addNItems: (size_t)nitems
 fromCArray: (void*)carray
{
	if (nitems > SIZE_MAX - count)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMem: data
		      toNItems: count + nitems
		      withSize: itemsize];

	memcpy(data + count * itemsize, carray, nitems * itemsize);
	count += nitems;

	return self;
}

- removeNItems: (size_t)nitems
{
	if (nitems > count)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMem: data
		      toNItems: count - nitems
		      withSize: itemsize];

	count -= nitems;

	return self;
}

- (id)copy







|
|
|












|
|
|












|
|
|







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
}

- addItem: (void*)item
{
	if (SIZE_MAX - count < 1)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMemory: data
			 toNItems: count + 1
			 withSize: itemsize];

	memcpy(data + count++ * itemsize, item, itemsize);

	return self;
}

- addNItems: (size_t)nitems
 fromCArray: (void*)carray
{
	if (nitems > SIZE_MAX - count)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMemory: data
			 toNItems: count + nitems
			 withSize: itemsize];

	memcpy(data + count * itemsize, carray, nitems * itemsize);
	count += nitems;

	return self;
}

- removeNItems: (size_t)nitems
{
	if (nitems > count)
		@throw [OFOutOfRangeException newWithClass: isa];

	data = [self resizeMemory: data
			 toNItems: count - nitems
			 withSize: itemsize];

	count -= nitems;

	return self;
}

- (id)copy
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

	if (SIZE_MAX - count < 1 || count + 1 > SIZE_MAX / itemsize)
		@throw [OFOutOfRangeException newWithClass: isa];

	nsize = ((count + 1) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMem: data
				toSize: nsize];

	memcpy(data + count++ * itemsize, item, itemsize);
	size = nsize;

	return self;
}

-  addNItems: (size_t)nitems
  fromCArray: (void*)carray
{
	size_t nsize;

	if (nitems > SIZE_MAX - count || count + nitems > SIZE_MAX / itemsize)
		@throw [OFOutOfRangeException newWithClass: isa];

	nsize = ((count + nitems) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMem: data
				toSize: nsize];

	memcpy(data + count * itemsize, carray, nitems * itemsize);
	count += nitems;
	size = nsize;

	return self;
}

- removeNItems: (size_t)nitems
{
	size_t nsize;

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

	nsize = ((count - nitems) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMem: data
				toSize: nsize];

	count -= nitems;
	size = nsize;

	return self;
}








|
|


















|
|


















|
|







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

	if (SIZE_MAX - count < 1 || count + 1 > SIZE_MAX / itemsize)
		@throw [OFOutOfRangeException newWithClass: isa];

	nsize = ((count + 1) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMemory: data
				   toSize: nsize];

	memcpy(data + count++ * itemsize, item, itemsize);
	size = nsize;

	return self;
}

-  addNItems: (size_t)nitems
  fromCArray: (void*)carray
{
	size_t nsize;

	if (nitems > SIZE_MAX - count || count + nitems > SIZE_MAX / itemsize)
		@throw [OFOutOfRangeException newWithClass: isa];

	nsize = ((count + nitems) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMemory: data
				   toSize: nsize];

	memcpy(data + count * itemsize, carray, nitems * itemsize);
	count += nitems;
	size = nsize;

	return self;
}

- removeNItems: (size_t)nitems
{
	size_t nsize;

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

	nsize = ((count - nitems) * itemsize + lastpagebyte) & ~lastpagebyte;

	if (size != nsize)
		data = [self resizeMemory: data
				   toSize: nsize];

	count -= nitems;
	size = nsize;

	return self;
}

Modified src/OFDictionary.m from [84358f6373] to [2b0ed74966].

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
- init
{
	self = [super init];

	size = 4096;

	@try {
		data = [self allocNItems: size
				withSize: sizeof(OFList*)];
	} @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];







|
|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
- init
{
	self = [super init];

	size = 4096;

	@try {
		data = [self allocMemoryForNItems: size
					 withSize: sizeof(OFList*)];
	} @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];
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
		@throw [OFInvalidArgumentException newWithClass: c
						    andSelector: _cmd];
	}

	size = (size_t)1 << hashsize;

	@try {
		data = [self allocNItems: size
				withSize: sizeof(OFList*)];
	} @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];







|
|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
		@throw [OFInvalidArgumentException newWithClass: c
						    andSelector: _cmd];
	}

	size = (size_t)1 << hashsize;

	@try {
		data = [self allocMemoryForNItems: size
					 withSize: sizeof(OFList*)];
	} @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];

Modified src/OFExceptions.h from [97d15662b8] to [cd34df0695].

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
 */
- (OFString*)string;
@end

/**
 * An OFException indicating there is not enough memory available.
 */
@interface OFNoMemException: OFException
{
	size_t req_size;
}

/**
 * \param class The class of the object which caused the exception
 * \param size The size of the memory that couldn't be allocated







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
 */
- (OFString*)string;
@end

/**
 * An OFException indicating there is not enough memory available.
 */
@interface OFOutOfMemoryException: OFException
{
	size_t req_size;
}

/**
 * \param class The class of the object which caused the exception
 * \param size The size of the memory that couldn't be allocated
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 */
- (size_t)requestedSize;
@end

/**
 * An OFException indicating the given memory is not part of the object.
 */
@interface OFMemNotPartOfObjException: OFException
{
	void *pointer;
}

/**
 * \param class The class of the object which caused the exception
 * \param ptr A pointer to the memory that is not part of the object







|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 */
- (size_t)requestedSize;
@end

/**
 * An OFException indicating the given memory is not part of the object.
 */
@interface OFMemoryNotPartOfObjectException: OFException
{
	void *pointer;
}

/**
 * \param class The class of the object which caused the exception
 * \param ptr A pointer to the memory that is not part of the object

Modified src/OFExceptions.m from [64dbc40d09] to [78e6bb7996].

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

- (OFString*)string
{
	return string;
}
@end

@implementation OFNoMemException
+ newWithClass: (Class)class_
       andSize: (size_t)size
{
	return [[self alloc] initWithClass: class_
				   andSize: size];
}








|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

- (OFString*)string
{
	return string;
}
@end

@implementation OFOutOfMemoryException
+ newWithClass: (Class)class_
       andSize: (size_t)size
{
	return [[self alloc] initWithClass: class_
				   andSize: size];
}

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

- (size_t)requestedSize
{
	return req_size;
}
@end

@implementation OFMemNotPartOfObjException
+ newWithClass: (Class)class_
    andPointer: (void*)ptr
{
	return [[self alloc] initWithClass: class_
				andPointer: ptr];
}








|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

- (size_t)requestedSize
{
	return req_size;
}
@end

@implementation OFMemoryNotPartOfObjectException
+ newWithClass: (Class)class_
    andPointer: (void*)ptr
{
	return [[self alloc] initWithClass: class_
				andPointer: ptr];
}

Modified src/OFList.m from [b49c70c5e4] to [6a33891d13].

59
60
61
62
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
- (of_list_object_t*)last
{
	return last;
}

- (of_list_object_t*)append: (id)obj
{
	of_list_object_t *o = [self allocWithSize: sizeof(of_list_object_t)];


	o->object = obj;
	o->next = NULL;
	o->prev = last;

	if (last != NULL)
		last->next = o;

	last = o;
	if (first == NULL)
		first = o;

	if (retain_and_release)
		[obj retain];

	return o;
}

- (of_list_object_t*)prepend: (id)obj
{
	of_list_object_t *o = [self allocWithSize: sizeof(of_list_object_t)];


	o->object = obj;
	o->next = first;
	o->prev = NULL;

	if (first != NULL)
		first->prev = o;

	first = o;
	if (last == NULL)
		last = o;

	if (retain_and_release)
		[obj retain];

	return o;
}

- (of_list_object_t*)insert: (id)obj
		     before: (of_list_object_t*)listobj
{
	of_list_object_t *o = [self allocWithSize: sizeof(of_list_object_t)];


	o->object = obj;
	o->next = listobj;
	o->prev = listobj->prev;

	if (listobj->prev != NULL)
		listobj->prev->next = o;








|

>



















|

>




















|

>







59
60
61
62
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
- (of_list_object_t*)last
{
	return last;
}

- (of_list_object_t*)append: (id)obj
{
	of_list_object_t *o;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = obj;
	o->next = NULL;
	o->prev = last;

	if (last != NULL)
		last->next = o;

	last = o;
	if (first == NULL)
		first = o;

	if (retain_and_release)
		[obj retain];

	return o;
}

- (of_list_object_t*)prepend: (id)obj
{
	of_list_object_t *o;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = obj;
	o->next = first;
	o->prev = NULL;

	if (first != NULL)
		first->prev = o;

	first = o;
	if (last == NULL)
		last = o;

	if (retain_and_release)
		[obj retain];

	return o;
}

- (of_list_object_t*)insert: (id)obj
		     before: (of_list_object_t*)listobj
{
	of_list_object_t *o;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = obj;
	o->next = listobj;
	o->prev = listobj->prev;

	if (listobj->prev != NULL)
		listobj->prev->next = o;

125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140

	return o;
}

- (of_list_object_t*)insert: (id)obj
		      after: (of_list_object_t*)listobj
{
	of_list_object_t *o = [self allocWithSize: sizeof(of_list_object_t)];


	o->object = obj;
	o->next = listobj->next;
	o->prev = listobj;

	if (listobj->next != NULL)
		listobj->next->prev = o;








|

>







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

	return o;
}

- (of_list_object_t*)insert: (id)obj
		      after: (of_list_object_t*)listobj
{
	of_list_object_t *o;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = obj;
	o->next = listobj->next;
	o->prev = listobj;

	if (listobj->next != NULL)
		listobj->next->prev = o;

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
		first = listobj->next;
	if (last == listobj)
		last = listobj->prev;

	if (retain_and_release)
		[listobj->object release];

	[self freeMem: listobj];

	return self;
}

- (size_t)count
{
	size_t i;







|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
		first = listobj->next;
	if (last == listobj)
		last = listobj->prev;

	if (retain_and_release)
		[listobj->object release];

	[self freeMemory: listobj];

	return self;
}

- (size_t)count
{
	size_t i;
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
		new = [[OFList alloc] initWithoutRetainAndRelease];

	o = NULL;
	prev = NULL;

	@try {
		for (iter = first; iter != NULL; iter = iter->next) {
			o = [new allocWithSize: sizeof(of_list_object_t)];
			o->object = iter->object;
			o->next = NULL;
			o->prev = prev;

			if (new->first == NULL)
				new->first = o;
			if (prev != NULL)







|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
		new = [[OFList alloc] initWithoutRetainAndRelease];

	o = NULL;
	prev = NULL;

	@try {
		for (iter = first; iter != NULL; iter = iter->next) {
			o = [new allocMemoryWithSize: sizeof(of_list_object_t)];
			o->object = iter->object;
			o->next = NULL;
			o->prev = prev;

			if (new->first == NULL)
				new->first = o;
			if (prev != NULL)

Modified src/OFMutableDictionary.m from [b1c46110e9] to [bd2647bb71].

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
	of_list_object_t *iter;

	if (hashsize < 8 || hashsize >= 28)
		@throw [OFInvalidArgumentException newWithClass: isa
						    andSelector: _cmd];

	newsize = (size_t)1 << hashsize;
	newdata = [self allocNItems: newsize
			   withSize: sizeof(OFList*)];
	memset(newdata, 0, newsize * sizeof(OFList*));

	for (i = 0; i < size; i++) {
		if (OF_LIKELY(data[i] == nil))
			continue;

		for (iter = [data[i] first]; iter != NULL;
		    iter = iter->next->next) {
			uint32_t hash = [iter->object hash] & (newsize - 1);

			if (newdata[hash] == nil)
				newdata[hash] = [[OFList alloc] init];

			[newdata[hash] append: iter->object];
			[newdata[hash] append: iter->next->object];
		}

		[data[i] release];
	}

	[self freeMem: data];
	data = newdata;
	size = newsize;

	return self;
}

/* FIXME: Implement this! */







|
|




















|







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
	of_list_object_t *iter;

	if (hashsize < 8 || hashsize >= 28)
		@throw [OFInvalidArgumentException newWithClass: isa
						    andSelector: _cmd];

	newsize = (size_t)1 << hashsize;
	newdata = [self allocMemoryForNItems: newsize
				    withSize: sizeof(OFList*)];
	memset(newdata, 0, newsize * sizeof(OFList*));

	for (i = 0; i < size; i++) {
		if (OF_LIKELY(data[i] == nil))
			continue;

		for (iter = [data[i] first]; iter != NULL;
		    iter = iter->next->next) {
			uint32_t hash = [iter->object hash] & (newsize - 1);

			if (newdata[hash] == nil)
				newdata[hash] = [[OFList alloc] init];

			[newdata[hash] append: iter->object];
			[newdata[hash] append: iter->next->object];
		}

		[data[i] release];
	}

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

	return self;
}

/* FIXME: Implement this! */

Modified src/OFMutableString.m from [7aa9b82d5b] to [fb06bc791e].

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
}

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

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

	len = strlen(str);

	switch (of_string_check_utf8(str, len)) {
	case 1:
		is_utf8 = YES;
		break;
	case -1:
		string = NULL;
		length = 0;
		is_utf8 = NO;

		@throw [OFInvalidEncodingException newWithClass: isa];
	}

	length = len;
	string = [self allocWithSize: length + 1];
	memcpy(string, str, length + 1);

	return self;
}

- append: (OFString*)str
{







|
















|







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
}

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

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

	len = strlen(str);

	switch (of_string_check_utf8(str, len)) {
	case 1:
		is_utf8 = YES;
		break;
	case -1:
		string = NULL;
		length = 0;
		is_utf8 = NO;

		@throw [OFInvalidEncodingException newWithClass: isa];
	}

	length = len;
	string = [self allocMemoryWithSize: length + 1];
	memcpy(string, str, length + 1);

	return self;
}

- append: (OFString*)str
{
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	case 1:
		is_utf8 = YES;
		break;
	case -1:
		@throw [OFInvalidEncodingException newWithClass: isa];
	}

	string = [self resizeMem: string
			  toSize: length + strlength + 1];
	memcpy(string + length, str, strlength + 1);
	length += strlength;

	return self;
}

- appendWithFormat: (OFString*)fmt, ...







|
|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	case 1:
		is_utf8 = YES;
		break;
	case -1:
		@throw [OFInvalidEncodingException newWithClass: isa];
	}

	string = [self resizeMemory: string
			     toSize: length + strlength + 1];
	memcpy(string + length, str, strlength + 1);
	length += strlength;

	return self;
}

- appendWithFormat: (OFString*)fmt, ...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

	if ((vasprintf(&t, [fmt cString], args)) == -1)
		/*
		 * This is only the most likely error to happen.
		 * Unfortunately, as errno isn't always thread-safe, there's
		 * no good way for us to find out what really happened.
		 */
		@throw [OFNoMemException newWithClass: isa];

	@try {
		[self appendCString: t];
	} @finally {
		free(t);
	}








|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

	if ((vasprintf(&t, [fmt cString], args)) == -1)
		/*
		 * This is only the most likely error to happen.
		 * Unfortunately, as errno isn't always thread-safe, there's
		 * no good way for us to find out what really happened.
		 */
		@throw [OFOutOfMemoryException newWithClass: isa];

	@try {
		[self appendCString: t];
	} @finally {
		free(t);
	}

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
	tmp_len = 0;

	for (i = 0, last = 0; i <= length - str_len; i++) {
		if (memcmp(string + i, str_c, str_len))
			continue;

		@try {
			tmp = [self resizeMem: tmp
				       toSize: tmp_len + i - last +
					       repl_len + 1];
		} @catch (OFException *e) {
			[self freeMem: tmp];
			@throw e;
		}
		memcpy(tmp + tmp_len, string + last, i - last);
		memcpy(tmp + tmp_len + i - last, repl_c, repl_len);
		tmp_len += i - last + repl_len;
		i += str_len - 1;
		last = i + 1;
	}

	@try {
		tmp = [self resizeMem: tmp
			       toSize: tmp_len + length - last + 1];
	} @catch (OFException *e) {
		[self freeMem: tmp];
		@throw e;
	}
	memcpy(tmp + tmp_len, string + last, length - last);
	tmp_len += length - last;
	tmp[tmp_len] = 0;

	[self freeMem: string];
	string = tmp;
	length = tmp_len;

	return self;
}
@end







|
|
|

|










|
|

|






|






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
	tmp_len = 0;

	for (i = 0, last = 0; i <= length - str_len; i++) {
		if (memcmp(string + i, str_c, str_len))
			continue;

		@try {
			tmp = [self resizeMemory: tmp
					  toSize: tmp_len + i - last +
						  repl_len + 1];
		} @catch (OFException *e) {
			[self freeMemory: tmp];
			@throw e;
		}
		memcpy(tmp + tmp_len, string + last, i - last);
		memcpy(tmp + tmp_len + i - last, repl_c, repl_len);
		tmp_len += i - last + repl_len;
		i += str_len - 1;
		last = i + 1;
	}

	@try {
		tmp = [self resizeMemory: tmp
				  toSize: tmp_len + length - last + 1];
	} @catch (OFException *e) {
		[self freeMemory: tmp];
		@throw e;
	}
	memcpy(tmp + tmp_len, string + last, length - last);
	tmp_len += length - last;
	tmp[tmp_len] = 0;

	[self freeMemory: string];
	string = tmp;
	length = tmp_len;

	return self;
}
@end

Modified src/OFObject.h from [7205341d87] to [1ae322315c].

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
 * Adds a pointer to the memory pool.
 *
 * This is useful to add memory allocated by functions such as asprintf to the
 * pool so it gets free'd automatically when the object is deallocated.
 *
 * \param ptr A pointer to add to the memory pool
 */
- addItemToMemoryPool: (void*)ptr;

/**
 * Allocate memory and store it in the objects memory pool so it can be free'd
 * automatically when the object is deallocated.
 *
 * \param size The size of the memory to allocate
 * \return A pointer to the allocated memory
 */
- (void*)allocWithSize: (size_t)size;

/**
 * Allocate memory for a specified number of items and store it in the objects
 * memory pool so it can be free'd automatically when the object is deallocated.
 *
 * \param nitems The number of items to allocate
 * \param size The size of each item to allocate
 * \return A pointer to the allocated memory
 */
- (void*)allocNItems: (size_t)nitems
	    withSize: (size_t)size;

/**
 * Resize memory in the memory pool to a specified size.
 *
 * \param ptr A pointer to the already allocated memory
 * \param size The new size for the memory chunk
 * \return A pointer to the resized memory chunk
 */
- (void*)resizeMem: (void*)ptr
	    toSize: (size_t)size;

/**
 * Resize memory in the memory pool to a specific number of items of a
 * specified size.
 *
 * \param ptr A pointer to the already allocated memory
 * \param nitems The number of items to resize to
 * \param size The size of each item to resize to
 * \return A pointer to the resized memory chunk
 */
- (void*)resizeMem: (void*)ptr
	  toNItems: (size_t)nitems
	  withSize: (size_t)size;

/**
 * Frees allocated memory and removes it from the memory pool.
 *
 * \param ptr A pointer to the allocated memory
 */
- freeMem: (void*)ptr;

/**
 * Increases the retain count.
 */
- retain;

/**







|








|









|
|








|
|










|
|
|






|







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
 * Adds a pointer to the memory pool.
 *
 * This is useful to add memory allocated by functions such as asprintf to the
 * pool so it gets free'd automatically when the object is deallocated.
 *
 * \param ptr A pointer to add to the memory pool
 */
- addMemoryToPool: (void*)ptr;

/**
 * Allocate memory and store it in the objects memory pool so it can be free'd
 * automatically when the object is deallocated.
 *
 * \param size The size of the memory to allocate
 * \return A pointer to the allocated memory
 */
- (void*)allocMemoryWithSize: (size_t)size;

/**
 * Allocate memory for a specified number of items and store it in the objects
 * memory pool so it can be free'd automatically when the object is deallocated.
 *
 * \param nitems The number of items to allocate
 * \param size The size of each item to allocate
 * \return A pointer to the allocated memory
 */
- (void*)allocMemoryForNItems: (size_t)nitems
		     withSize: (size_t)size;

/**
 * Resize memory in the memory pool to a specified size.
 *
 * \param ptr A pointer to the already allocated memory
 * \param size The new size for the memory chunk
 * \return A pointer to the resized memory chunk
 */
- (void*)resizeMemory: (void*)ptr
	       toSize: (size_t)size;

/**
 * Resize memory in the memory pool to a specific number of items of a
 * specified size.
 *
 * \param ptr A pointer to the already allocated memory
 * \param nitems The number of items to resize to
 * \param size The size of each item to resize to
 * \return A pointer to the resized memory chunk
 */
- (void*)resizeMemory: (void*)ptr
	     toNItems: (size_t)nitems
	     withSize: (size_t)size;

/**
 * Frees allocated memory and removes it from the memory pool.
 *
 * \param ptr A pointer to the allocated memory
 */
- freeMemory: (void*)ptr;

/**
 * Increases the retain count.
 */
- retain;

/**

Modified src/OFObject.m from [8515c66c59] to [4147582b99].

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

- (uint32_t)hash
{
	/* Classes containing data should reimplement this! */
	return (uint32_t)(intptr_t)self;
}

- addItemToMemoryPool: (void*)ptr
{
	void **memchunks;
	size_t memchunks_size;

	memchunks_size = PRE_IVAR->memchunks_size + 1;

	if (SIZE_MAX - PRE_IVAR->memchunks_size < 1 ||
	    memchunks_size > SIZE_MAX / sizeof(void*))
		@throw [OFOutOfRangeException newWithClass: isa];

	if ((memchunks = realloc(PRE_IVAR->memchunks,
	    memchunks_size * sizeof(void*))) == NULL)
		@throw [OFNoMemException newWithClass: isa
					      andSize: memchunks_size];

	PRE_IVAR->memchunks = memchunks;
	PRE_IVAR->memchunks[PRE_IVAR->memchunks_size] = ptr;
	PRE_IVAR->memchunks_size = memchunks_size;

	return self;
}

- (void*)allocWithSize: (size_t)size
{
	void *ptr, **memchunks;
	size_t memchunks_size;

	if (size == 0)
		return NULL;

	memchunks_size = PRE_IVAR->memchunks_size + 1;

	if (SIZE_MAX - PRE_IVAR->memchunks_size == 0 ||
	    memchunks_size > SIZE_MAX / sizeof(void*))
		@throw [OFOutOfRangeException newWithClass: isa];

	if ((ptr = malloc(size)) == NULL)
		@throw [OFNoMemException newWithClass: isa
					      andSize: size];

	if ((memchunks = realloc(PRE_IVAR->memchunks,
	    memchunks_size * sizeof(void*))) == NULL) {
		free(ptr);
		@throw [OFNoMemException newWithClass: isa
					      andSize: memchunks_size];
	}

	PRE_IVAR->memchunks = memchunks;
	PRE_IVAR->memchunks[PRE_IVAR->memchunks_size] = ptr;
	PRE_IVAR->memchunks_size = memchunks_size;

	return ptr;
}

- (void*)allocNItems: (size_t)nitems
	    withSize: (size_t)size
{
	if (nitems == 0 || size == 0)
		return NULL;

	if (nitems > SIZE_MAX / size)
		@throw [OFOutOfRangeException newWithClass: isa];

	return [self allocWithSize: nitems * size];
}

- (void*)resizeMem: (void*)ptr
	    toSize: (size_t)size
{
	void **iter;

	if (ptr == NULL)
		return [self allocWithSize: size];

	if (size == 0) {
		[self freeMem: ptr];
		return NULL;
	}

	iter = PRE_IVAR->memchunks + PRE_IVAR->memchunks_size;

	while (iter-- > PRE_IVAR->memchunks) {
		if (OF_UNLIKELY(*iter == ptr)) {
			if (OF_UNLIKELY((ptr = realloc(ptr, size)) == NULL))

				@throw [OFNoMemException newWithClass: isa
							      andSize: size];

			*iter = ptr;
			return ptr;
		}
	}

	@throw [OFMemNotPartOfObjException newWithClass: isa
					     andPointer: ptr];
}

- (void*)resizeMem: (void*)ptr
	  toNItems: (size_t)nitems
	  withSize: (size_t)size
{
	if (ptr == NULL)
		return [self allocNItems: nitems
				withSize: size];

	if (nitems == 0 || size == 0) {
		[self freeMem: ptr];
		return NULL;
	}

	if (nitems > SIZE_MAX / size)
		@throw [OFOutOfRangeException newWithClass: isa];

	return [self resizeMem: ptr
			toSize: nitems * size];
}

- freeMem: (void*)ptr;
{
	void **iter, *last, **memchunks;
	size_t i, memchunks_size;

	iter = PRE_IVAR->memchunks + PRE_IVAR->memchunks_size;
	i = PRE_IVAR->memchunks_size;








|












|
|








|














|
|




|
|









|
|







|


|
|




|


|








>
|
|






|
|


|
|
|


|
|


|






|
|


|







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

- (uint32_t)hash
{
	/* Classes containing data should reimplement this! */
	return (uint32_t)(intptr_t)self;
}

- addMemoryToPool: (void*)ptr
{
	void **memchunks;
	size_t memchunks_size;

	memchunks_size = PRE_IVAR->memchunks_size + 1;

	if (SIZE_MAX - PRE_IVAR->memchunks_size < 1 ||
	    memchunks_size > SIZE_MAX / sizeof(void*))
		@throw [OFOutOfRangeException newWithClass: isa];

	if ((memchunks = realloc(PRE_IVAR->memchunks,
	    memchunks_size * sizeof(void*))) == NULL)
		@throw [OFOutOfMemoryException newWithClass: isa
						    andSize: memchunks_size];

	PRE_IVAR->memchunks = memchunks;
	PRE_IVAR->memchunks[PRE_IVAR->memchunks_size] = ptr;
	PRE_IVAR->memchunks_size = memchunks_size;

	return self;
}

- (void*)allocMemoryWithSize: (size_t)size
{
	void *ptr, **memchunks;
	size_t memchunks_size;

	if (size == 0)
		return NULL;

	memchunks_size = PRE_IVAR->memchunks_size + 1;

	if (SIZE_MAX - PRE_IVAR->memchunks_size == 0 ||
	    memchunks_size > SIZE_MAX / sizeof(void*))
		@throw [OFOutOfRangeException newWithClass: isa];

	if ((ptr = malloc(size)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: isa
						    andSize: size];

	if ((memchunks = realloc(PRE_IVAR->memchunks,
	    memchunks_size * sizeof(void*))) == NULL) {
		free(ptr);
		@throw [OFOutOfMemoryException newWithClass: isa
						    andSize: memchunks_size];
	}

	PRE_IVAR->memchunks = memchunks;
	PRE_IVAR->memchunks[PRE_IVAR->memchunks_size] = ptr;
	PRE_IVAR->memchunks_size = memchunks_size;

	return ptr;
}

- (void*)allocMemoryForNItems: (size_t)nitems
		     withSize: (size_t)size
{
	if (nitems == 0 || size == 0)
		return NULL;

	if (nitems > SIZE_MAX / size)
		@throw [OFOutOfRangeException newWithClass: isa];

	return [self allocMemoryWithSize: nitems * size];
}

- (void*)resizeMemory: (void*)ptr
	       toSize: (size_t)size
{
	void **iter;

	if (ptr == NULL)
		return [self allocMemoryWithSize: size];

	if (size == 0) {
		[self freeMemory: ptr];
		return NULL;
	}

	iter = PRE_IVAR->memchunks + PRE_IVAR->memchunks_size;

	while (iter-- > PRE_IVAR->memchunks) {
		if (OF_UNLIKELY(*iter == ptr)) {
			if (OF_UNLIKELY((ptr = realloc(ptr, size)) == NULL))
				@throw [OFOutOfMemoryException
				    newWithClass: isa
					 andSize: size];

			*iter = ptr;
			return ptr;
		}
	}

	@throw [OFMemoryNotPartOfObjectException newWithClass: isa
						   andPointer: ptr];
}

- (void*)resizeMemory: (void*)ptr
	     toNItems: (size_t)nitems
	     withSize: (size_t)size
{
	if (ptr == NULL)
		return [self allocMemoryForNItems: nitems
					 withSize: size];

	if (nitems == 0 || size == 0) {
		[self freeMemory: ptr];
		return NULL;
	}

	if (nitems > SIZE_MAX / size)
		@throw [OFOutOfRangeException newWithClass: isa];

	return [self resizeMemory: ptr
			   toSize: nitems * size];
}

- freeMemory: (void*)ptr;
{
	void **iter, *last, **memchunks;
	size_t i, memchunks_size;

	iter = PRE_IVAR->memchunks + PRE_IVAR->memchunks_size;
	i = PRE_IVAR->memchunks_size;

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
			PRE_IVAR->memchunks[i] = last;
			PRE_IVAR->memchunks_size = memchunks_size;

			return self;
		}
	}

	@throw [OFMemNotPartOfObjException newWithClass: isa
					     andPointer: ptr];
}

- retain
{
	PRE_IVAR->retain_count++;

	return self;







|
|







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
			PRE_IVAR->memchunks[i] = last;
			PRE_IVAR->memchunks_size = memchunks_size;

			return self;
		}
	}

	@throw [OFMemoryNotPartOfObjectException newWithClass: isa
						   andPointer: ptr];
}

- retain
{
	PRE_IVAR->retain_count++;

	return self;

Modified src/OFPlugin.m from [78e8296fc9] to [fccb9d70a0].

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
	OFPlugin *(*init_plugin)();
	OFPlugin *plugin;

	pathlen = [path length];
	suffixlen = strlen(PLUGIN_SUFFIX);

	if ((file = malloc(pathlen + suffixlen + 1)) == NULL) {
		@throw [OFNoMemException newWithClass: self
					      andSize: pathlen +
					      suffixlen + 1];
	}
	memcpy(file, [path cString], pathlen);
	memcpy(file + pathlen, PLUGIN_SUFFIX, suffixlen);
	file[pathlen + suffixlen] = 0;

	if ((handle = dlopen(file, RTLD_NOW)) == NULL) {
		free(file);







|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
	OFPlugin *(*init_plugin)();
	OFPlugin *plugin;

	pathlen = [path length];
	suffixlen = strlen(PLUGIN_SUFFIX);

	if ((file = malloc(pathlen + suffixlen + 1)) == NULL) {
		@throw [OFOutOfMemoryException newWithClass: self
						    andSize: pathlen +
							     suffixlen + 1];
	}
	memcpy(file, [path cString], pathlen);
	memcpy(file + pathlen, PLUGIN_SUFFIX, suffixlen);
	file[pathlen + suffixlen] = 0;

	if ((handle = dlopen(file, RTLD_NOW)) == NULL) {
		free(file);

Modified src/OFStream.m from [1ada4c447c] to [3f64dd68d8].

60
61
62
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
	OFString *ret;

	/* Look if there's a line or \0 in our cache */
	if (cache != NULL) {
		for (i = 0; i < cache_len; i++) {
			if (OF_UNLIKELY(cache[i] == '\n' ||
			    cache[i] == '\0')) {
				ret_c = [self allocWithSize: i + 1];
				memcpy(ret_c, cache, i);
				ret_c[i] = '\0';

				@try {
					tmp = [self allocWithSize: cache_len -

								   i - 1];
				} @catch (OFException *e) {
					[self freeMem: ret_c];
					@throw e;
				}
				memcpy(tmp, cache + i + 1, cache_len - i - 1);

				[self freeMem: cache];
				cache = tmp;
				cache_len = cache_len - i - 1;

				@try {
					ret = [OFString
					    stringWithCString: ret_c];
				} @finally {
					[self freeMem: ret_c];
				}
				return ret;
			}
		}
	}

	/* Read until we get a newline or \0 */
	tmp = [self allocWithSize: pagesize];

	for (;;) {
		@try {
			len = [self readNBytes: pagesize - 1
				    intoBuffer: tmp];
		} @catch (OFException *e) {
			[self freeMem: tmp];
			@throw e;
		}

		/* Look if there's a newline or \0 */
		for (i = 0; i < len; i++) {
			if (OF_UNLIKELY(tmp[i] == '\n' || tmp[i] == '\0')) {
				@try {
					ret_c = [self
					    allocWithSize: cache_len + i + 1];

				} @catch (OFException *e) {
					[self freeMem: tmp];
					@throw e;
				}
				if (cache != NULL)
					memcpy(ret_c, cache, cache_len);
				memcpy(ret_c + cache_len, tmp, i);
				ret_c[i] = '\0';

				if (i < len) {
					@try {
						tmp2 = [self
						    allocWithSize: len - i - 1];

					} @catch (OFException *e) {
						[self freeMem: ret_c];
						[self freeMem: tmp];
						@throw e;
					}
					memcpy(tmp2, tmp + i + 1, len - i - 1);

					if (cache != NULL)
						[self freeMem: cache];
					cache = tmp2;
					cache_len = len - i - 1;
				} else {
					if (cache != NULL)
						[self freeMem: cache];
					cache = NULL;
					cache_len = 0;
				}

				[self freeMem: tmp];
				@try {
					ret = [OFString
					    stringWithCString: ret_c];
				} @finally {
					[self freeMem: ret_c];
				}
				return ret;
			}
		}

		/* There was no newline or \0 */
		@try {
			cache = [self resizeMem: cache
					 toSize: cache_len + len];
		} @catch (OFException *e) {
			[self freeMem: tmp];
			@throw e;
		}
		memcpy(cache + cache_len, tmp, len);
		cache_len += len;
	}
}








|




|
>
|

|




|







|







|






|








|
>

|










|
>

|
|





|




|




|




|







|
|

|







60
61
62
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
	OFString *ret;

	/* Look if there's a line or \0 in our cache */
	if (cache != NULL) {
		for (i = 0; i < cache_len; i++) {
			if (OF_UNLIKELY(cache[i] == '\n' ||
			    cache[i] == '\0')) {
				ret_c = [self allocMemoryWithSize: i + 1];
				memcpy(ret_c, cache, i);
				ret_c[i] = '\0';

				@try {
					tmp = [self
					    allocMemoryWithSize: cache_len -
								 i - 1];
				} @catch (OFException *e) {
					[self freeMemory: ret_c];
					@throw e;
				}
				memcpy(tmp, cache + i + 1, cache_len - i - 1);

				[self freeMemory: cache];
				cache = tmp;
				cache_len = cache_len - i - 1;

				@try {
					ret = [OFString
					    stringWithCString: ret_c];
				} @finally {
					[self freeMemory: ret_c];
				}
				return ret;
			}
		}
	}

	/* Read until we get a newline or \0 */
	tmp = [self allocMemoryWithSize: pagesize];

	for (;;) {
		@try {
			len = [self readNBytes: pagesize - 1
				    intoBuffer: tmp];
		} @catch (OFException *e) {
			[self freeMemory: tmp];
			@throw e;
		}

		/* Look if there's a newline or \0 */
		for (i = 0; i < len; i++) {
			if (OF_UNLIKELY(tmp[i] == '\n' || tmp[i] == '\0')) {
				@try {
					ret_c = [self
					    allocMemoryWithSize: cache_len +
								 i + 1];
				} @catch (OFException *e) {
					[self freeMemory: tmp];
					@throw e;
				}
				if (cache != NULL)
					memcpy(ret_c, cache, cache_len);
				memcpy(ret_c + cache_len, tmp, i);
				ret_c[i] = '\0';

				if (i < len) {
					@try {
						tmp2 = [self
						    allocMemoryWithSize: len -
									 i - 1];
					} @catch (OFException *e) {
						[self freeMemory: ret_c];
						[self freeMemory: tmp];
						@throw e;
					}
					memcpy(tmp2, tmp + i + 1, len - i - 1);

					if (cache != NULL)
						[self freeMemory: cache];
					cache = tmp2;
					cache_len = len - i - 1;
				} else {
					if (cache != NULL)
						[self freeMemory: cache];
					cache = NULL;
					cache_len = 0;
				}

				[self freeMemory: tmp];
				@try {
					ret = [OFString
					    stringWithCString: ret_c];
				} @finally {
					[self freeMemory: ret_c];
				}
				return ret;
			}
		}

		/* There was no newline or \0 */
		@try {
			cache = [self resizeMemory: cache
					    toSize: cache_len + len];
		} @catch (OFException *e) {
			[self freeMemory: tmp];
			@throw e;
		}
		memcpy(cache + cache_len, tmp, len);
		cache_len += len;
	}
}

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

	return cache_len;
}

- clearCache
{
	if (cache != NULL)
		[self freeMem: cache];

	cache = NULL;
	cache_len = 0;

	return self;
}

- close
{
	@throw [OFNotImplementedException newWithClass: isa
					   andSelector: _cmd];
}
@end







|













188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

	return cache_len;
}

- clearCache
{
	if (cache != NULL)
		[self freeMemory: cache];

	cache = NULL;
	cache_len = 0;

	return self;
}

- close
{
	@throw [OFNotImplementedException newWithClass: isa
					   andSelector: _cmd];
}
@end

Modified src/OFString.m from [27bf821a65] to [aeeb03c826].

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
				c = isa;
				[super dealloc];
				@throw [OFInvalidEncodingException
					newWithClass: c];
		}

		@try {
			string = [self allocWithSize: length + 1];
		} @catch (OFException *e) {
			/*
			 * We can't use [super dealloc] on OS X here.
			 * Compiler bug? Anyway, [self dealloc] will do here as
			 * we don't reimplement dealloc.
			 */
			[self dealloc];







|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
				c = isa;
				[super dealloc];
				@throw [OFInvalidEncodingException
					newWithClass: c];
		}

		@try {
			string = [self allocMemoryWithSize: length + 1];
		} @catch (OFException *e) {
			/*
			 * We can't use [super dealloc] on OS X here.
			 * Compiler bug? Anyway, [self dealloc] will do here as
			 * we don't reimplement dealloc.
			 */
			[self dealloc];
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
			free(string);
			c = isa;
			[super dealloc];
			@throw [OFInvalidEncodingException newWithClass: c];
	}

	@try {
		[self addItemToMemoryPool: string];
	} @catch (OFException *e) {
		free(string);
		@throw e;
	}

	return self;
}

- initWithString: (OFString*)str
{
	self = [super init];

	string = strdup([str cString]);
	length = [str length];

	@try {
		[self addItemToMemoryPool: string];
	} @catch (OFException *e) {
		/*
		 * We can't use [super dealloc] on OS X here.
		 * Compiler bug? Anyway, [self dealloc] will do here as we
		 * don't reimplement dealloc.
		 */
		free(string);







|
















|







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
			free(string);
			c = isa;
			[super dealloc];
			@throw [OFInvalidEncodingException newWithClass: c];
	}

	@try {
		[self addMemoryToPool: string];
	} @catch (OFException *e) {
		free(string);
		@throw e;
	}

	return self;
}

- initWithString: (OFString*)str
{
	self = [super init];

	string = strdup([str cString]);
	length = [str length];

	@try {
		[self addMemoryToPool: string];
	} @catch (OFException *e) {
		/*
		 * We can't use [super dealloc] on OS X here.
		 * Compiler bug? Anyway, [self dealloc] will do here as we
		 * don't reimplement dealloc.
		 */
		free(string);
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
	for (i = 0, last = 0; i <= length - delim_len; i++) {
		char *tmp;

		if (memcmp(string + i, delim, delim_len))
			continue;

		/*
		 * We can't use [self allocWithSize:] here as self might be a
		 * @""-literal.
		 */
		if ((tmp = malloc(i - last + 1)) == NULL)

			@throw [OFNoMemException newWithClass: isa
						      andSize: i - last + 1];
		memcpy(tmp, string + last, i - last);
		tmp[i - last] = '\0';
		@try {
			str = [OFString stringWithCString: tmp];
		} @finally {
			free(tmp);
		}







|
|


>
|
|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
	for (i = 0, last = 0; i <= length - delim_len; i++) {
		char *tmp;

		if (memcmp(string + i, delim, delim_len))
			continue;

		/*
		 * We can't use [self allocMemoryWithSize:] here as self might
		 * be a @""-literal.
		 */
		if ((tmp = malloc(i - last + 1)) == NULL)
			@throw [OFOutOfMemoryException
			    newWithClass: isa
				 andSize: i - last + 1];
		memcpy(tmp, string + last, i - last);
		tmp[i - last] = '\0';
		@try {
			str = [OFString stringWithCString: tmp];
		} @finally {
			free(tmp);
		}

Modified src/OFTCPSocket.m from [9070a0d7b2] to [3f2fb0c9c6].

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
	socklen_t addrlen;
	int s;

	newsock = [OFTCPSocket socket];
	addrlen = sizeof(struct sockaddr);

	@try {
		addr = [newsock allocWithSize: sizeof(struct sockaddr)];
	} @catch (OFException *e) {
		[newsock dealloc];
		@throw e;
	}

	if ((s = accept(sock, addr, &addrlen)) == INVALID_SOCKET) {
		[newsock dealloc];







|







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
	socklen_t addrlen;
	int s;

	newsock = [OFTCPSocket socket];
	addrlen = sizeof(struct sockaddr);

	@try {
		addr = [newsock allocMemoryWithSize: sizeof(struct sockaddr)];
	} @catch (OFException *e) {
		[newsock dealloc];
		@throw e;
	}

	if ((s = accept(sock, addr, &addrlen)) == INVALID_SOCKET) {
		[newsock dealloc];
297
298
299
300
301
302
303
304
305
306
307
308
309
{
	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException newWithClass: isa];

	sock = INVALID_SOCKET;

	if (saddr != NULL)
		[self freeMem: saddr];
	saddr_len = 0;

	return self;
}
@end







|





297
298
299
300
301
302
303
304
305
306
307
308
309
{
	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException newWithClass: isa];

	sock = INVALID_SOCKET;

	if (saddr != NULL)
		[self freeMemory: saddr];
	saddr_len = 0;

	return self;
}
@end

Modified src/OFURLEncoding.h from [413ff97b8f] to [372c3e5fe1].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 */
@interface OFString (OFURLEncoding)
/**
 * Encodes a string for use in a URL.
 *
 * \return A new, autoreleased string
 */
- (OFString*)urlencode;

/**
 * Decodes a string used in a URL.
 *
 * \return A new, autoreleased string
 */
- (OFString*)urldecode;
@end







|






|

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 */
@interface OFString (OFURLEncoding)
/**
 * Encodes a string for use in a URL.
 *
 * \return A new, autoreleased string
 */
- (OFString*)urlEncodedString;

/**
 * Decodes a string used in a URL.
 *
 * \return A new, autoreleased string
 */
- (OFString*)urlDecodedString;
@end

Modified src/OFURLEncoding.m from [6ffc687158] to [573e813f26].

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
#import "OFURLEncoding.h"
#import "OFExceptions.h"

/* Reference for static linking */
int _OFURLEncoding_reference;

@implementation OFString (OFURLEncoding)
- (OFString*)urlencode
{
	const char *s;
	char *ret_c;
	size_t i;
	OFString *ret;

	s = string;

	/*
	 * Worst case: 3 times longer than before.
	 * Oh, and we can't use [self allocWithSize:] here as self might be a
	 * @"" literal.
	 */
	if ((ret_c = malloc((length * 3) + 1)) == NULL)
		@throw [OFNoMemException newWithClass: isa
					      andSize: (length * 3) + 1];

	for (i = 0; *s != '\0'; s++) {
		if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.')
			ret_c[i++] = *s;
		else {
			char buf[3];
			snprintf(buf, 3, "%02X", *s);







|














|
|







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
#import "OFURLEncoding.h"
#import "OFExceptions.h"

/* Reference for static linking */
int _OFURLEncoding_reference;

@implementation OFString (OFURLEncoding)
- (OFString*)urlEncodedString
{
	const char *s;
	char *ret_c;
	size_t i;
	OFString *ret;

	s = string;

	/*
	 * Worst case: 3 times longer than before.
	 * Oh, and we can't use [self allocWithSize:] here as self might be a
	 * @"" literal.
	 */
	if ((ret_c = malloc((length * 3) + 1)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: isa
						    andSize: (length * 3) + 1];

	for (i = 0; *s != '\0'; s++) {
		if (isalnum(*s) || *s == '-' || *s == '_' || *s == '.')
			ret_c[i++] = *s;
		else {
			char buf[3];
			snprintf(buf, 3, "%02X", *s);
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	} @finally {
		free(ret_c);
	}

	return ret;
}

- (OFString*)urldecode
{
	const char *s;
	char *ret_c, c;
	size_t i;
	int st;
	OFString *ret;

	s = string;

	if ((ret_c = malloc(length + 1)) == NULL)
		@throw [OFNoMemException newWithClass: isa
					      andSize: length + 1];

	for (st = 0, i = 0, c = 0; *s; s++) {
		switch (st) {
		case 0:
			if (*s == '%')
				st = 1;
			else







|










|
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	} @finally {
		free(ret_c);
	}

	return ret;
}

- (OFString*)urlDecodedString
{
	const char *s;
	char *ret_c, c;
	size_t i;
	int st;
	OFString *ret;

	s = string;

	if ((ret_c = malloc(length + 1)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: isa
						    andSize: length + 1];

	for (st = 0, i = 0, c = 0; *s; s++) {
		switch (st) {
		case 0:
			if (*s == '%')
				st = 1;
			else

Modified src/OFXMLFactory.m from [17553b85c5] to [2d5c8a5504].

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
		@throw [OFOutOfRangeException newWithClass: class];
	len2 = *len + add;

	if ((str2 = realloc(*str, len2)) == NULL) {
		if (*str)
			free(*str);
		*str = NULL;
		@throw [OFNoMemException newWithClass: class
					      andSize: len2];
	}

	*str = str2;
	*len = len2;
}

static inline void







|
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
		@throw [OFOutOfRangeException newWithClass: class];
	len2 = *len + add;

	if ((str2 = realloc(*str, len2)) == NULL) {
		if (*str)
			free(*str);
		*str = NULL;
		@throw [OFOutOfMemoryException newWithClass: class
						    andSize: len2];
	}

	*str = str2;
	*len = len2;
}

static inline void
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

	len = strlen(s);
	if (SIZE_MAX - len < 1)
		@throw [OFOutOfRangeException newWithClass: self];

	len++;
	if ((ret = malloc(len)) == NULL)
		@throw [OFNoMemException newWithClass: self
					      andSize: len];

	@try {
		for (i = 0; *s; s++) {
			switch (*s) {
				case '<':
					append(&ret, &len, &i, "&lt;", self);
					break;







|
|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

	len = strlen(s);
	if (SIZE_MAX - len < 1)
		@throw [OFOutOfRangeException newWithClass: self];

	len++;
	if ((ret = malloc(len)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: self
						    andSize: len];

	@try {
		for (i = 0; *s; s++) {
			switch (*s) {
				case '<':
					append(&ret, &len, &i, "&lt;", self);
					break;
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
	/* Start of tag */
	len = strlen(name);
	if (SIZE_MAX - len < 3)
		@throw [OFOutOfRangeException newWithClass: self];
	len += 3;

	if ((xml = malloc(len)) == NULL)
		@throw [OFNoMemException newWithClass: self
					      andSize: len];

	i = 0;
	xml[i++] = '<';
	memcpy(xml + i, name, strlen(name));
	i += strlen(name);

	@try {







|
|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
	/* Start of tag */
	len = strlen(name);
	if (SIZE_MAX - len < 3)
		@throw [OFOutOfRangeException newWithClass: self];
	len += 3;

	if ((xml = malloc(len)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: self
						    andSize: len];

	i = 0;
	xml[i++] = '<';
	memcpy(xml + i, name, strlen(name));
	i += strlen(name);

	@try {
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

	len = strlen(*strs);
	if (SIZE_MAX - len < 1)
		@throw [OFOutOfRangeException newWithClass: self];
	len++;

	if ((ret = malloc(len)) == NULL)
		@throw [OFNoMemException newWithClass: self
					      andSize: len];

	memcpy(ret, strs[0], len - 1);
	pos = len - 1;

	@try {
		for (i = 1; strs[i] != NULL; i++)
			append(&ret, &len, &pos, strs[i], self);







|
|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

	len = strlen(*strs);
	if (SIZE_MAX - len < 1)
		@throw [OFOutOfRangeException newWithClass: self];
	len++;

	if ((ret = malloc(len)) == NULL)
		@throw [OFOutOfMemoryException newWithClass: self
						    andSize: len];

	memcpy(ret, strs[0], len - 1);
	pos = len - 1;

	@try {
		for (i = 1; strs[i] != NULL; i++)
			append(&ret, &len, &pos, strs[i], self);

Modified tests/OFDataArray/OFDataArray.m from [1d94987f01] to [92c6e56e71].

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	puts("Trying to add too much to an array...");			\
	a = [[type alloc] initWithItemSize: 4096];			\
	CATCH_EXCEPTION([a addNItems: SIZE_MAX				\
			  fromCArray: NULL],				\
	    OFOutOfRangeException)					\
									\
	puts("Trying to add something after that error...");		\
	p = [a allocWithSize: 4096];					\
	memset(p, 255, 4096);						\
	[a addItem: p];							\
	if (!memcmp([a lastItem], p, 4096))				\
		puts("[a lastItem] matches with p!");			\
	else {								\
		puts("[a lastItem] does not match p!");			\
		abort();						\
	}								\
	[a freeMem: p];							\
									\
	puts("Adding more data...");					\
	q = [a allocWithSize: 4096];					\
	memset(q, 42, 4096);						\
	[a addItem: q];							\
	if (!memcmp([a lastItem], q, 4096))				\
		puts("[a lastItem] matches with q!");			\
	else {								\
		puts("[a lastItem] does not match q!");			\
		abort();						\
	}								\
	[a freeMem: q];							\
									\
	puts("Adding multiple items at once...");			\
	p = [a allocWithSize: 8192];					\
	memset(p, 64, 8192);						\
	[a addNItems: 2							\
	  fromCArray: p];						\
	if (!memcmp([a lastItem], [a itemAtIndex: [a count] - 2], 4096) && \
	    !memcmp([a itemAtIndex: [a count] - 2], p, 4096))		\
		puts("[a lastItem], [a itemAtIndex: [a count] - 2] "	\
		    "and p match!");					\
	else {								\
		puts("[a lastItem], [a itemAtIndex: [a count] - 2] "	\
		    "and p do not match!");				\
		abort();						\
	}								\
	[a freeMem: p];							\
									\
	i = [a count];							\
	puts("Removing 2 items...");					\
	[a removeNItems: 2];						\
	if ([a count] + 2 != i) {					\
		puts("[a count] + 2 != i!");				\
		abort();						\







|








|


|








|


|












|







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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	puts("Trying to add too much to an array...");			\
	a = [[type alloc] initWithItemSize: 4096];			\
	CATCH_EXCEPTION([a addNItems: SIZE_MAX				\
			  fromCArray: NULL],				\
	    OFOutOfRangeException)					\
									\
	puts("Trying to add something after that error...");		\
	p = [a allocMemoryWithSize: 4096];				\
	memset(p, 255, 4096);						\
	[a addItem: p];							\
	if (!memcmp([a lastItem], p, 4096))				\
		puts("[a lastItem] matches with p!");			\
	else {								\
		puts("[a lastItem] does not match p!");			\
		abort();						\
	}								\
	[a freeMemory: p];						\
									\
	puts("Adding more data...");					\
	q = [a allocMemoryWithSize: 4096];				\
	memset(q, 42, 4096);						\
	[a addItem: q];							\
	if (!memcmp([a lastItem], q, 4096))				\
		puts("[a lastItem] matches with q!");			\
	else {								\
		puts("[a lastItem] does not match q!");			\
		abort();						\
	}								\
	[a freeMemory: q];						\
									\
	puts("Adding multiple items at once...");			\
	p = [a allocMemoryWithSize: 8192];				\
	memset(p, 64, 8192);						\
	[a addNItems: 2							\
	  fromCArray: p];						\
	if (!memcmp([a lastItem], [a itemAtIndex: [a count] - 2], 4096) && \
	    !memcmp([a itemAtIndex: [a count] - 2], p, 4096))		\
		puts("[a lastItem], [a itemAtIndex: [a count] - 2] "	\
		    "and p match!");					\
	else {								\
		puts("[a lastItem], [a itemAtIndex: [a count] - 2] "	\
		    "and p do not match!");				\
		abort();						\
	}								\
	[a freeMemory: p];						\
									\
	i = [a count];							\
	puts("Removing 2 items...");					\
	[a removeNItems: 2];						\
	if ([a count] + 2 != i) {					\
		puts("[a count] + 2 != i!");				\
		abort();						\

Modified tests/OFObject/OFObject.m from [68866f4346] to [e3a197e96b].

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
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
{
	OFObject *obj = [[OFObject alloc] init];
	void *p, *q, *r;

	/* Test freeing memory not allocated by obj */
	puts("Freeing memory not allocated by object (should throw an "
	    "exception)...");
	CATCH_EXCEPTION([obj freeMem: NULL], OFMemNotPartOfObjException)


	/* Test allocating memory */
	puts("Allocating memory through object...");
	p = [obj allocWithSize: 4096];
	puts("Allocated 4096 bytes.");

	/* Test freeing the just allocated memory */
	puts("Freeing just allocated memory...");
	[obj freeMem: p];
	puts("Free'd.");

	/* It shouldn't be recognized as part of our obj anymore */
	puts("Trying to free it again (should throw an exception)...");
	CATCH_EXCEPTION([obj freeMem: p], OFMemNotPartOfObjException)

	/* Test multiple memory chunks */
	puts("Allocating 3 chunks of memory...");
	p = [obj allocWithSize: 4096];
	q = [obj allocWithSize: 4096];
	r = [obj allocWithSize: 4096];
	puts("Allocated 3 * 4096 bytes.");

	/* Free them */
	puts("Now freeing them...");
	[obj freeMem: p];
	[obj freeMem: q];
	[obj freeMem: r];
	puts("Freed them all.");

	/* Try to free again */
	puts("Now trying to free them again...");
	CATCH_EXCEPTION([obj freeMem: p], OFMemNotPartOfObjException)
	CATCH_EXCEPTION([obj freeMem: q], OFMemNotPartOfObjException)
	CATCH_EXCEPTION([obj freeMem: r], OFMemNotPartOfObjException)
	puts("Got all 3!");

	puts("Trying to allocate more memory than possible...");
	CATCH_EXCEPTION(p = [obj allocWithSize: SIZE_MAX], OFNoMemException)


	puts("Allocating 1 byte...");
	p = [obj allocWithSize: 1];

	puts("Trying to resize that 1 byte to more than possible...");
	CATCH_EXCEPTION(p = [obj resizeMem: p
				    toSize: SIZE_MAX],
	    OFNoMemException)

	puts("Trying to resize NULL to 1024 bytes...");
	p = [obj resizeMem: NULL
		    toSize: 1024];
	[obj freeMem: p];

	puts("Trying to resize memory that is not part of object...");
	CATCH_EXCEPTION(p = [obj resizeMem: (void*)1
				    toSize: 1024],
	    OFMemNotPartOfObjException)

	/* TODO: Test if freeing object frees all memory */

	return 0;
}







|
>



|




|




|



|
|
|




|
|
|




|
|
|



|
>


|


|
|
|


|
|
|


|
|
|





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
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
{
	OFObject *obj = [[OFObject alloc] init];
	void *p, *q, *r;

	/* Test freeing memory not allocated by obj */
	puts("Freeing memory not allocated by object (should throw an "
	    "exception)...");
	CATCH_EXCEPTION([obj freeMemory: NULL],
	    OFMemoryNotPartOfObjectException)

	/* Test allocating memory */
	puts("Allocating memory through object...");
	p = [obj allocMemoryWithSize: 4096];
	puts("Allocated 4096 bytes.");

	/* Test freeing the just allocated memory */
	puts("Freeing just allocated memory...");
	[obj freeMemory: p];
	puts("Free'd.");

	/* It shouldn't be recognized as part of our obj anymore */
	puts("Trying to free it again (should throw an exception)...");
	CATCH_EXCEPTION([obj freeMemory: p], OFMemoryNotPartOfObjectException)

	/* Test multiple memory chunks */
	puts("Allocating 3 chunks of memory...");
	p = [obj allocMemoryWithSize: 4096];
	q = [obj allocMemoryWithSize: 4096];
	r = [obj allocMemoryWithSize: 4096];
	puts("Allocated 3 * 4096 bytes.");

	/* Free them */
	puts("Now freeing them...");
	[obj freeMemory: p];
	[obj freeMemory: q];
	[obj freeMemory: r];
	puts("Freed them all.");

	/* Try to free again */
	puts("Now trying to free them again...");
	CATCH_EXCEPTION([obj freeMemory: p], OFMemoryNotPartOfObjectException)
	CATCH_EXCEPTION([obj freeMemory: q], OFMemoryNotPartOfObjectException)
	CATCH_EXCEPTION([obj freeMemory: r], OFMemoryNotPartOfObjectException)
	puts("Got all 3!");

	puts("Trying to allocate more memory than possible...");
	CATCH_EXCEPTION(p = [obj allocMemoryWithSize: SIZE_MAX],
	    OFOutOfMemoryException)

	puts("Allocating 1 byte...");
	p = [obj allocMemoryWithSize: 1];

	puts("Trying to resize that 1 byte to more than possible...");
	CATCH_EXCEPTION(p = [obj resizeMemory: p
				       toSize: SIZE_MAX],
	    OFOutOfMemoryException)

	puts("Trying to resize NULL to 1024 bytes...");
	p = [obj resizeMemory: NULL
		       toSize: 1024];
	[obj freeMemory: p];

	puts("Trying to resize memory that is not part of object...");
	CATCH_EXCEPTION(p = [obj resizeMemory: (void*)1
				       toSize: 1024],
	    OFMemoryNotPartOfObjectException)

	/* TODO: Test if freeing object frees all memory */

	return 0;
}

Modified tests/OFString/OFString.m from [3c5eadaa9e] to [894fde2106].

105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
	CHECK([[a objectAtIndex: j++] isEqual: @"foo"])
	CHECK([[a objectAtIndex: j++] isEqual: @"bar"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @"baz"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @""])

	CHECK([[@"foo\"ba'_$" urlencode] isEqual: @"foo%22ba%27_%24"])
	CHECK([[@"foo%20bar%22%24" urldecode] isEqual: @"foo bar\"$"])
	CHECK_EXCEPT([@"foo%bar" urldecode], OFInvalidEncodingException)
	CHECK_EXCEPT([@"foo%FFbar" urldecode], OFInvalidEncodingException)


	s1 = [@"asd fo asd fofo asd" mutableCopy];
	[s1 replaceOccurrencesOfString: @"fo"
			    withString: @"foo"];
	CHECK([s1 isEqual: @"asd foo asd foofoo asd"])
	s1 = [@"XX" mutableCopy];
	[s1 replaceOccurrencesOfString: @"X"







|
|
|
|
>







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	CHECK([[a objectAtIndex: j++] isEqual: @"foo"])
	CHECK([[a objectAtIndex: j++] isEqual: @"bar"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @"baz"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @""])

	CHECK([[@"foo\"ba'_$" urlEncodedString] isEqual: @"foo%22ba%27_%24"])
	CHECK([[@"foo%20bar%22%24" urlDecodedString] isEqual: @"foo bar\"$"])
	CHECK_EXCEPT([@"foo%bar" urlDecodedString], OFInvalidEncodingException)
	CHECK_EXCEPT([@"foo%FFbar" urlDecodedString],
	    OFInvalidEncodingException)

	s1 = [@"asd fo asd fofo asd" mutableCopy];
	[s1 replaceOccurrencesOfString: @"fo"
			    withString: @"foo"];
	CHECK([s1 isEqual: @"asd foo asd foofoo asd"])
	s1 = [@"XX" mutableCopy];
	[s1 replaceOccurrencesOfString: @"X"