ObjFW  Check-in [e76a7f52c1]

Overview
Comment:More style improvements.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e76a7f52c11edf01ae14a77a2fd49db44a1be4b5af2f4e3c7ea6e83367f38012
User & Date: js on 2011-04-22 20:19:54
Other Links: manifest | tags
Context
2011-04-22
20:43
OFStreamObserver: Don't ignore the timeout when using select(). check-in: 4b08544ddd user: js tags: trunk
20:19
More style improvements. check-in: e76a7f52c1 user: js tags: trunk
18:22
Fix double-retain in OFList. check-in: 58d10be52f user: js tags: trunk
Changes

Modified src/OFCollection.h from [10d2a861f6] to [68e0dd67a3].

31
32
33
34
35
36
37

38

39
40

41
42

43
44
45
46

47
31
32
33
34
35
36
37
38

39
40

41
42
43
44
45
46
47

48
49







+
-
+

-
+


+



-
+


/**
 * \returns An OFEnumerator to enumerate through all objects of the collection
 */
- (OFEnumerator*)objectEnumerator;

/**
 * \param The object which is checked for being in the collection
 * \return A boolean whether the collection contains the specified object.
 * \return A boolean whether the collection contains the specified object
 */
- (BOOL)containsObject: (id)obj;
- (BOOL)containsObject: (id)object;

/**
 * \param The object which is checked for being in the collection
 * \return A boolean whether the collection contains an object with the
 *	   specified address.
 */
- (BOOL)containsObjectIdenticalTo: (id)obj;
- (BOOL)containsObjectIdenticalTo: (id)object;
@end

Modified src/OFDataArray+Hashing.m from [c3dc8494cf] to [ec54ab978c].

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

62
63
64
65

66
67
68
69
70
71
72
73
74
75


76
77
78
79
80

81
82
83
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
60

61
62
63
64

65
66
67
68
69
70
71
72
73


74
75
76
77
78
79

80
81
82
83







-
+



-
+








-
-
+
+




-
+








-
+



-
+








-
-
+
+




-
+




@implementation OFDataArray (Hashing)
- (OFString*)MD5Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFMD5Hash MD5Hash];
	uint8_t *digest;
	char retCString[OF_MD5_DIGEST_SIZE * 2];
	char cString[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: data
			ofSize: count * itemSize];
			length: count * itemSize];
	digest = [hash digest];

	for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		retCString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		retCString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];

	return [OFString stringWithCString: retCString
	return [OFString stringWithCString: cString
				    length: 32];
}

- (OFString*)SHA1Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFSHA1Hash SHA1Hash];
	uint8_t *digest;
	char retCString[OF_SHA1_DIGEST_SIZE * 2];
	char cString[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: data
			ofSize: count * itemSize];
			length: count * itemSize];
	digest = [hash digest];

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		retCString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		retCString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];

	return [OFString stringWithCString: retCString
	return [OFString stringWithCString: cString
				    length: 40];
}
@end

Modified src/OFFile.m from [437b42878c] to [521d39c7c0].

601
602
603
604
605
606
607
608

609
610
611
612
613
614

615
616
617

618
619
620
621
622
623

624
625
626

627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647

648
649
650
651
652
653

654
655
656
657
658

659
660

661
662
663
664
665
666

667
668
669
670
671
672
673
601
602
603
604
605
606
607

608
609
610
611
612
613

614
615
616

617
618
619
620
621
622

623
624
625

626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646

647
648
649
650
651
652

653
654
655
656
657

658
659

660
661
662
663
664
665

666
667
668
669
670
671
672
673







-
+





-
+


-
+





-
+


-
+




-
+













-
+

-
+





-
+




-
+

-
+





-
+








	return isAtEndOfStream;
}

- (size_t)_readNBytes: (size_t)length
	   intoBuffer: (char*)buffer
{
	size_t retLength;
	size_t ret;

	if (fileDescriptor == -1 || isAtEndOfStream)
		@throw [OFReadFailedException newWithClass: isa
						    stream: self
					   requestedLength: length];
	if ((retLength = read(fileDescriptor, buffer, length)) == 0)
	if ((ret = read(fileDescriptor, buffer, length)) == 0)
		isAtEndOfStream = YES;

	return retLength;
	return ret;
}

- (size_t)_writeNBytes: (size_t)length
	    fromBuffer: (const char*)buffer
{
	size_t retLength;
	size_t ret;

	if (fileDescriptor == -1 || isAtEndOfStream ||
	    (retLength = write(fileDescriptor, buffer, length)) < length)
	    (ret = write(fileDescriptor, buffer, length)) < length)
		@throw [OFWriteFailedException newWithClass: isa
						     stream: self
					    requestedLength: length];

	return retLength;
	return ret;
}

- (void)_seekToOffset: (off_t)offset
{
	if (lseek(fileDescriptor, offset, SEEK_SET) == -1)
		@throw [OFSeekFailedException newWithClass: isa
						    stream: self
						    offset: offset
						    whence: SEEK_SET];
}

- (off_t)_seekForwardWithOffset: (off_t)offset
{
	off_t retOffset;
	off_t ret;

	if ((retOffset = lseek(fileDescriptor, offset, SEEK_CUR)) == -1)
	if ((ret = lseek(fileDescriptor, offset, SEEK_CUR)) == -1)
		@throw [OFSeekFailedException newWithClass: isa
						    stream: self
						    offset: offset
						    whence: SEEK_CUR];

	return retOffset;
	return ret;
}

- (off_t)_seekToOffsetRelativeToEnd: (off_t)offset
{
	off_t retOffset;
	off_t ret;

	if ((retOffset = lseek(fileDescriptor, offset, SEEK_END)) == -1)
	if ((ret = lseek(fileDescriptor, offset, SEEK_END)) == -1)
		@throw [OFSeekFailedException newWithClass: isa
						    stream: self
						    offset: offset
						    whence: SEEK_END];

	return retOffset;
	return ret;
}

- (int)fileDescriptor
{
	return fileDescriptor;
}

Modified src/OFHTTPRequest.h from [cb8dc6b01c] to [55acdcf8df].

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







-
+



-
+














-
+



-
+







/**
 * This callback is called when the OFHTTPRequest received data.
 *
 * This is useful for example if you want to update a status display.
 *
 * \param request The OFHTTPRequest which received data
 * \param data The data the OFHTTPRequest received
 * \param len The length of the data received, in bytes
 * \param length The length of the data received, in bytes
 */
-  (void)request: (OFHTTPRequest*)request
  didReceiveData: (const char*)data
      withLength: (size_t)len;
      withLength: (size_t)length;

/**
 * This callback is called when the OFHTTPRequest will follow a redirect.
 *
 * If you want to get the headers and data for each redirect, set the number of
 * redirects to 0 and perform a new OFHTTPRequest for each redirect. However,
 * this callback will not be called then and you have to look at the status code
 * to detect a redirect.
 *
 * This callback will only be called if the OFHTTPRequest will follow a
 * redirect. If the maximum number of redirects has been reached already, this
 * callback will not be called.
 *
 * \param request The OFHTTPRequest which will follow a redirect
 * \param url The URL to which it will follow a redirect
 * \param URL The URL to which it will follow a redirect
 * \return A boolean whether the OFHTTPRequest should follow the redirect
 */
-	 (BOOL)request: (OFHTTPRequest*)request
  willFollowRedirectTo: (OFURL*)url;
  willFollowRedirectTo: (OFURL*)URL;
@end

/**
 * \brief A class for storing and performing HTTP requests.
 */
@interface OFHTTPRequest: OFObject
{
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
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







-
+


-
+




-
+


-
+






-
+









-
+

-
+









-
+

-
+








/**
 * \return A new, autoreleased OFHTTPRequest
 */
+ request;

/**
 * \param url The URL for the request
 * \param URL The URL for the request
 * \return A new, autoreleased OFHTTPRequest
 */
+ requestWithURL: (OFURL*)url;
+ requestWithURL: (OFURL*)URL;

/**
 * Initializes an already allocated OFHTTPRequest with the specified URL.
 *
 * \param url The URL for the request
 * \param URL The URL for the request
 * \return An initialized OFHTTPRequest
 */
- initWithURL: (OFURL*)url;
- initWithURL: (OFURL*)URL;

/**
 * Sets the URL for the HTTP request.
 *
 * \param URL The URL for the HTTP request
 */
- (void)setURL: (OFURL*)url;
- (void)setURL: (OFURL*)URL;

/**
 * \return The URL for the HTTP request
 */
- (OFURL*)URL;

/**
 * Sets the request type for the HTTP request.
 *
 * \param type The request type for the HTTP request
 * \param requestType The request type for the HTTP request
 */
- (void)setRequestType: (of_http_request_type_t)type;
- (void)setRequestType: (of_http_request_type_t)requestType;

/**
 * \return The request type for the HTTP request
 */
- (of_http_request_type_t)requestType;

/**
 * Sets the query string for the HTTP request.
 *
 * \param qs The query string for the HTTP request
 * \param queryString The query string for the HTTP request
 */
- (void)setQueryString: (OFString*)qs;
- (void)setQueryString: (OFString*)queryString;

/**
 * \return The query string for the HTTP request
 */
- (OFString*)queryString;

/**
201
202
203
204
205
206
207
208

209
210

211
212
213
214
215
216
217
201
202
203
204
205
206
207

208
209

210
211
212
213
214
215
216
217







-
+

-
+








/**
 * Sets whether an OFDataArray with the data is created.
 *
 * Setting this to NO is only useful if you are using the delegate to handle the
 * data.
 *
 * \param enabled Whether to store the data in an OFDataArray
 * \param storesData Whether to store the data in an OFDataArray
 */
- (void)setStoresData: (BOOL)enabled;
- (void)setStoresData: (BOOL)storesData;

/**
 * \return Whether an OFDataArray with the data is created
 */
- (BOOL)storesData;

/**

Modified src/OFHTTPRequest.m from [97fcaf53fd] to [908217ca1f].

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







-
+

-
+
















-
+




-
+


















-
+

-
+







-
+

-
+







-
+

-
+








@implementation OFHTTPRequest
+ request
{
	return [[[self alloc] init] autorelease];
}

+ requestWithURL: (OFURL*)url
+ requestWithURL: (OFURL*)URL
{
	return [[[self alloc] initWithURL: url] autorelease];
	return [[[self alloc] initWithURL: URL] autorelease];
}

- init
{
	self = [super init];

	requestType = OF_HTTP_REQUEST_TYPE_GET;
	headers = [[OFDictionary alloc]
	    initWithObject: @"Something using ObjFW "
			    @"<https://webkeks.org/objfw/>"
		    forKey: @"User-Agent"];
	storesData = YES;

	return self;
}

- initWithURL: (OFURL*)url
- initWithURL: (OFURL*)URL_
{
	self = [self init];

	@try {
		[self setURL: url];
		[self setURL: URL_];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[URL release];
	[queryString release];
	[headers release];
	[(id)delegate release];

	[super dealloc];
}

- (void)setURL: (OFURL*)url
- (void)setURL: (OFURL*)URL_
{
	OF_SETTER(URL, url, YES, YES)
	OF_SETTER(URL, URL_, YES, YES)
}

- (OFURL*)URL
{
	OF_GETTER(URL, YES)
}

- (void)setRequestType: (of_http_request_type_t)type
- (void)setRequestType: (of_http_request_type_t)requestType_
{
	requestType = type;
	requestType = requestType_;
}

- (of_http_request_type_t)requestType
{
	return requestType;
}

- (void)setQueryString: (OFString*)qs
- (void)setQueryString: (OFString*)queryString_
{
	OF_SETTER(queryString, qs, YES, YES)
	OF_SETTER(queryString, queryString_, YES, YES)
}

- (OFString*)queryString
{
	OF_GETTER(queryString, YES)
}

164
165
166
167
168
169
170
171

172
173

174
175
176
177
178
179
180
164
165
166
167
168
169
170

171
172

173
174
175
176
177
178
179
180







-
+

-
+







}

- (id <OFHTTPRequestDelegate>)delegate
{
	OF_GETTER(delegate, YES)
}

- (void)setStoresData: (BOOL)enabled
- (void)setStoresData: (BOOL)storesData_
{
	storesData = enabled;
	storesData = storesData_;
}

- (BOOL)storesData
{
	return storesData;
}

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







-
-
+
+













-
+

-
+

-
+






-
+

-
+







	@try {
		OFString *line, *path;
		OFMutableDictionary *serverHeaders;
		OFDataArray *data;
		OFEnumerator *enumerator;
		OFString *key;
		int status;
		const char *t = NULL;
		char *buf;
		const char *type = NULL;
		char *buffer;
		size_t bytesReceived;
		OFString *contentLengthHeader;

		[sock connectToHost: [URL host]
			     onPort: [URL port]];

		/*
		 * Work around a bug with packet bisection in lighttpd when
		 * using HTTPS.
		 */
		[sock setBuffersWrites: YES];

		if (requestType == OF_HTTP_REQUEST_TYPE_GET)
			t = "GET";
			type = "GET";
		if (requestType == OF_HTTP_REQUEST_TYPE_HEAD)
			t = "HEAD";
			type = "HEAD";
		if (requestType == OF_HTTP_REQUEST_TYPE_POST)
			t = "POST";
			type = "POST";

		if ([(path = [URL path]) isEqual: @""])
			path = @"/";

		if ([URL query] != nil)
			[sock writeFormat: @"%s %@?%@ HTTP/1.0\r\n",
					   t, path, [URL query]];
					   type, path, [URL query]];
		else
			[sock writeFormat: @"%s %@ HTTP/1.0\r\n", t, path];
			[sock writeFormat: @"%s %@ HTTP/1.0\r\n", type, path];

		if ([URL port] == 80)
			[sock writeFormat: @"Host: %@\r\n", [URL host]];
		else
			[sock writeFormat: @"Host: %@:%d\r\n", [URL host],
					   [URL port]];

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







-
+





-
+

-
+




-
+


-
+







		   withStatusCode: status];

		if (storesData)
			data = [OFDataArray dataArrayWithItemSize: 1];
		else
			data = nil;

		buf = [self allocMemoryWithSize: of_pagesize];
		buffer = [self allocMemoryWithSize: of_pagesize];
		bytesReceived = 0;
		@try {
			size_t len;

			while ((len = [sock readNBytes: of_pagesize
					    intoBuffer: buf]) > 0) {
					    intoBuffer: buffer]) > 0) {
				[delegate request: self
				   didReceiveData: buf
				   didReceiveData: buffer
				       withLength: len];

				bytesReceived += len;
				[data addNItems: len
				     fromCArray: buf];
				     fromCArray: buffer];
			}
		} @finally {
			[self freeMemory: buf];
			[self freeMemory: buffer];
		}

		if ((contentLengthHeader =
		    [serverHeaders objectForKey: @"Content-Length"]) != nil) {
			intmax_t cl = [contentLengthHeader decimalValue];

			if (cl > SIZE_MAX)

Modified src/OFHash.h from [537a82b073] to [0b332e5a5e].

38
39
40
41
42
43
44
45

46
47
48

49
50
51
52
53
54
55
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55







-
+


-
+







 */
+ (size_t)blockSize;

/**
 * Adds a buffer to the hash to be calculated.
 *
 * \param buf The buffer which should be included into the calculation.
 * \param size The size of the buffer
 * \param length The length of the buffer
 */
- (void)updateWithBuffer: (const char*)buf
		  ofSize: (size_t)size;
		  length: (size_t)length;

/**
 * \return A buffer containing the hash. The size of the buffer is depending
 *	   on the hash used. The buffer is part of object's memory pool.
 */
- (uint8_t*)digest;

Modified src/OFHash.m from [0f1145ec18] to [528220f4b7].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







+ (size_t)blockSize
{
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
}

- (void)updateWithBuffer: (const char*)buffer
		  ofSize: (size_t)size
		  length: (size_t)length
{
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}

- (uint8_t*)digest
{

Modified src/OFList.h from [3cd365a47f] to [e94ed80ca6].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39







-
+







 * A struct that contains a pointer to the next list object, the previous list
 * object and the object.
 */
struct of_list_object_t {
	/// A pointer to the next list object in the list
	of_list_object_t *next;
	/// A pointer to the previous list object in the list
	of_list_object_t *prev;
	of_list_object_t *previous;
	/// The object for the list object
	id		 object;
};

/**
 * \brief A class which provides easy to use double-linked lists.
 */
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
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







-
+




-
+




-
+




-
+



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





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




-
+

-
+













 * \return The last list object in the list
 */
- (of_list_object_t*)lastListObject;

/**
 * Appends an object to the list.
 *
 * \param obj The object to append
 * \param object The object to append
 * \return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)appendObject: (id)obj;
- (of_list_object_t*)appendObject: (id)object;

/**
 * Prepends an object to the list.
 *
 * \param obj The object to prepend
 * \param object The object to prepend
 * \return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)prependObject: (id)obj;
- (of_list_object_t*)prependObject: (id)object;

/**
 * Inserts an object before another object.
 * \param obj The object to insert
 * \param listobj The of_list_object_t of the object before which it should be
 * \param object The object to insert
 * \param listObject The of_list_object_t of the object before which it should be
 *	  inserted
 * \return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)insertObject: (id)object
		 beforeListObject: (of_list_object_t*)listObject;

/**
 * Inserts an object after another object.
 * \param object The object to insert
 * \param listObject The of_list_object_t of the object after which it should be
 *	  inserted
 * \return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)insertObject: (id)obj
- (of_list_object_t*)insertObject: (id)object
		 beforeListObject: (of_list_object_t*)listobj;

/**
 * Inserts an object after another object.
 * \param obj The object to insert
 * \param listobj The of_list_object_t of the object after which it should be
 *	  inserted
 * \return An of_list_object_t, needed to identify the object inside the list.
 *	   For example, if you want to remove an object from the list, you need
 *	   its of_list_object_t.
 */
- (of_list_object_t*)insertObject: (id)obj
		  afterListObject: (of_list_object_t*)listobj;
		  afterListObject: (of_list_object_t*)listObject;

/**
 * Removes the object with the specified list object from the list.
 *
 * \param listobj The list object returned by append / prepend
 * \param listObject The list object returned by append / prepend
 */
- (void)removeListObject: (of_list_object_t*)listobj;
- (void)removeListObject: (of_list_object_t*)listObject;
@end

@interface OFListEnumerator: OFEnumerator
{
	OFList		 *list;
	of_list_object_t *current;
	unsigned long	 mutations;
	unsigned long	 *mutationsPtr;
}

-     initWithList: (OFList*)list
  mutationsPointer: (unsigned long*)mutationsPtr;
@end

Modified src/OFList.m from [80de30a57f] to [7c3c7d8b0c].

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

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







-
+

-
+

-
-
-
-
+
+
+
+


-
+

-
+

-
+




-
+


-
+

-
+

-
-
-
-
+
+
+
+


-
+

-
+

-
+




-
+


-
-
+
+

-
+

-
-
-
-
+
+
+
+

-
+
-
+

-
+

-
-
+
+




-
+


-
-
+
+

-
+

-
-
-
-
+
+
+
+

-
-
+
+

-
+

-
-
+
+




-
+


-
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+




-
+

-
+







-
+

+


-
+


+
+
-
+


-
+











-
+







-
+





-
+







-
+







-
-
+
+

-
-
+
+



+
-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+

-
+

-
+


-
+



-
+

-
+







}

- (of_list_object_t*)lastListObject;
{
	return lastListObject;
}

- (of_list_object_t*)appendObject: (id)obj
- (of_list_object_t*)appendObject: (id)object
{
	of_list_object_t *o;
	of_list_object_t *listObject;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = [obj retain];
	o->next = NULL;
	o->prev = lastListObject;
	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = NULL;
	listObject->previous = lastListObject;

	if (lastListObject != NULL)
		lastListObject->next = o;
		lastListObject->next = listObject;

	lastListObject = o;
	lastListObject = listObject;
	if (firstListObject == NULL)
		firstListObject = o;
		firstListObject = listObject;

	count++;
	mutations++;

	return o;
	return listObject;
}

- (of_list_object_t*)prependObject: (id)obj
- (of_list_object_t*)prependObject: (id)object
{
	of_list_object_t *o;
	of_list_object_t *listObject;

	o = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	o->object = [obj retain];
	o->next = firstListObject;
	o->prev = NULL;
	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject->object = [object retain];
	listObject->next = firstListObject;
	listObject->previous = NULL;

	if (firstListObject != NULL)
		firstListObject->prev = o;
		firstListObject->previous = listObject;

	firstListObject = o;
	firstListObject = listObject;
	if (lastListObject == NULL)
		lastListObject = o;
		lastListObject = listObject;

	count++;
	mutations++;

	return o;
	return listObject;
}

- (of_list_object_t*)insertObject: (id)obj
		 beforeListObject: (of_list_object_t*)listobj
- (of_list_object_t*)insertObject: (id)object
		 beforeListObject: (of_list_object_t*)listObject
{
	of_list_object_t *o;
	of_list_object_t *newListObject;

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

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

	listobj->prev = o;
	listObject->previous = newListObject;

	if (listobj == firstListObject)
		firstListObject = o;
	if (listObject == firstListObject)
		firstListObject = newListObject;

	count++;
	mutations++;

	return o;
	return newListObject;
}

- (of_list_object_t*)insertObject: (id)obj
		  afterListObject: (of_list_object_t*)listobj
- (of_list_object_t*)insertObject: (id)object
		  afterListObject: (of_list_object_t*)listObject
{
	of_list_object_t *o;
	of_list_object_t *newListObject;

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

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

	listobj->next = o;
	listObject->next = newListObject;

	if (listobj == lastListObject)
		lastListObject = o;
	if (listObject == lastListObject)
		lastListObject = newListObject;

	count++;
	mutations++;

	return o;
	return newListObject;
}

- (void)removeListObject: (of_list_object_t*)listobj
- (void)removeListObject: (of_list_object_t*)listObject
{
	if (listobj->prev != NULL)
		listobj->prev->next = listobj->next;
	if (listobj->next != NULL)
		listobj->next->prev = listobj->prev;
	if (listObject->previous != NULL)
		listObject->previous->next = listObject->next;
	if (listObject->next != NULL)
		listObject->next->previous = listObject->previous;

	if (firstListObject == listobj)
		firstListObject = listobj->next;
	if (lastListObject == listobj)
		lastListObject = listobj->prev;
	if (firstListObject == listObject)
		firstListObject = listObject->next;
	if (lastListObject == listObject)
		lastListObject = listObject->previous;

	count--;
	mutations++;

	[listobj->object release];
	[listObject->object release];

	[self freeMemory: listobj];
	[self freeMemory: listObject];
}

- (size_t)count
{
	return count;
}

- (BOOL)isEqual: (id)obj
- (BOOL)isEqual: (id)object
{
	OFList *otherList;
	of_list_object_t *iter, *iter2;

	if (![obj isKindOfClass: [OFList class]])
	if (![object isKindOfClass: [OFList class]])
		return NO;

	otherList = (OFList*)object;

	if ([(OFList*)obj count] != count)
	if ([otherList count] != count)
		return NO;

	for (iter = firstListObject, iter2 = [(OFList*)obj firstListObject];
	for (iter = firstListObject, iter2 = [otherList firstListObject];
	    iter != NULL && iter2 != NULL;
	    iter = iter->next, iter2 = iter2->next)
		if (![iter->object isEqual: iter2->object])
			return NO;

	/* One is bigger than the other although we checked the count */
	assert(iter == NULL && iter2 == NULL);

	return YES;
}

- (BOOL)containsObject: (id)obj
- (BOOL)containsObject: (id)object
{
	of_list_object_t *iter;

	if (count == 0)
		return NO;

	for (iter = firstListObject; iter != NULL; iter = iter->next)
		if ([iter->object isEqual: obj])
		if ([iter->object isEqual: object])
			return YES;

	return NO;
}

- (BOOL)containsObjectIdenticalTo: (id)obj
- (BOOL)containsObjectIdenticalTo: (id)object
{
	of_list_object_t *iter;

	if (count == 0)
		return NO;

	for (iter = firstListObject; iter != NULL; iter = iter->next)
		if (iter->object == obj)
		if (iter->object == object)
			return YES;

	return NO;
}

- copy
{
	OFList *new = [[OFList alloc] init];
	of_list_object_t *iter, *o, *prev;
	OFList *copy = [[OFList alloc] init];
	of_list_object_t *iter, *listObject, *previous;

	o = NULL;
	prev = NULL;
	listObject = NULL;
	previous = NULL;

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

			if (new->firstListObject == NULL)
				new->firstListObject = o;
			if (prev != NULL)
				prev->next = o;
			if (copy->firstListObject == NULL)
				copy->firstListObject = listObject;
			if (previous != NULL)
				previous->next = listObject;

			new->count++;
			copy->count++;

			prev = o;
			previous = listObject;
		}
	} @catch (id e) {
		[new release];
		[copy release];
		@throw e;
	}

	new->lastListObject = o;
	copy->lastListObject = listObject;

	return new;
	return copy;
}

- (uint32_t)hash
{
	of_list_object_t *iter;
	uint32_t hash;

Modified src/OFMD5Hash.h from [bbea038319] to [483543b630].

19
20
21
22
23
24
25
26

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

26
27
28
29
30
31
32
33







-
+







#define OF_MD5_DIGEST_SIZE  16

/**
 * \brief A class which provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFHash
{
	uint32_t buf[4];
	uint32_t buffer[4];
	uint32_t bits[2];
	union {
		uint8_t	u8[64];
		uint32_t u32[16];
	} in;
}

Modified src/OFMD5Hash.m from [8c8aeaf4bf] to [bbf6824f58].

31
32
33
34
35
36
37
38

39
40
41
42
43
44
45




46
47
48
49
50
51
52
31
32
33
34
35
36
37

38
39
40
41




42
43
44
45
46
47
48
49
50
51
52







-
+



-
-
-
-
+
+
+
+







#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
	(w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)

static void
md5_transform(uint32_t buf[4], const uint32_t in[16])
md5_transform(uint32_t buffer[4], const uint32_t in[16])
{
	register uint32_t a, b, c, d;

	a = buf[0];
	b = buf[1];
	c = buf[2];
	d = buf[3];
	a = buffer[0];
	b = buffer[1];
	c = buffer[2];
	d = buffer[3];

	MD5STEP(F1, a, b, c, d, in[0]  + 0xD76AA478, 7);
	MD5STEP(F1, d, a, b, c, in[1]  + 0xE8C7B756, 12);
	MD5STEP(F1, c, d, a, b, in[2]  + 0x242070DB, 17);
	MD5STEP(F1, b, c, d, a, in[3]  + 0xC1BDCEEE, 22);
	MD5STEP(F1, a, b, c, d, in[4]  + 0xF57C0FAF, 7);
	MD5STEP(F1, d, a, b, c, in[5]  + 0x4787C62A, 12);
108
109
110
111
112
113
114
115
116
117
118




119
120
121
122
123
124
125
108
109
110
111
112
113
114




115
116
117
118
119
120
121
122
123
124
125







-
-
-
-
+
+
+
+







	MD5STEP(F4, c, d, a, b, in[6]  + 0xA3014314, 15);
	MD5STEP(F4, b, c, d, a, in[13] + 0x4E0811A1, 21);
	MD5STEP(F4, a, b, c, d, in[4]  + 0xF7537E82, 6);
	MD5STEP(F4, d, a, b, c, in[11] + 0xBD3AF235, 10);
	MD5STEP(F4, c, d, a, b, in[2]  + 0x2AD7D2BB, 15);
	MD5STEP(F4, b, c, d, a, in[9]  + 0xEB86D391, 21);

	buf[0] += a;
	buf[1] += b;
	buf[2] += c;
	buf[3] += d;
	buffer[0] += a;
	buffer[1] += b;
	buffer[2] += c;
	buffer[3] += d;
}

@implementation OFMD5Hash
+ MD5Hash
{
	return [[[self alloc] init] autorelease];
}
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
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







-
-
-
-
+
+
+
+




-
-
+
+



-
+








-
+


-
+










-
-
+
+



-
+

-
+

-
-
+
+



-
-
+
+

-
+

-
-
+
+



-
+








-
+



















-
+













-
+




-
+


	return 64;
}

- init
{
	self = [super init];

	buf[0] = 0x67452301;
	buf[1] = 0xEFCDAB89;
	buf[2] = 0x98BADCFE;
	buf[3] = 0x10325476;
	buffer[0] = 0x67452301;
	buffer[1] = 0xEFCDAB89;
	buffer[2] = 0x98BADCFE;
	buffer[3] = 0x10325476;

	return self;
}

- (void)updateWithBuffer: (const char*)buffer
		  ofSize: (size_t)size
- (void)updateWithBuffer: (const char*)buffer_
		  length: (size_t)length
{
	uint32_t t;

	if (size == 0)
	if (length == 0)
		return;

	if (isCalculated)
		@throw [OFHashAlreadyCalculatedException newWithClass: isa
								 hash: self];

	/* Update bitcount */
	t = bits[0];
	if ((bits[0] = t + ((uint32_t)size << 3)) < t)
	if ((bits[0] = t + ((uint32_t)length << 3)) < t)
		/* Carry from low to high */
		bits[1]++;
	bits[1] += (uint32_t)size >> 29;
	bits[1] += (uint32_t)length >> 29;

	/* Bytes already in shsInfo->data */
	t = (t >> 3) & 0x3F;

	/* Handle any leading odd-sized chunks */
	if (t) {
		uint8_t *p = in.u8 + t;

		t = 64 - t;

		if (size < t) {
			memcpy(p, buffer, size);
		if (length < t) {
			memcpy(p, buffer_, length);
			return;
		}

		memcpy(p, buffer, t);
		memcpy(p, buffer_, t);
		of_bswap32_vec_if_be(in.u32, 16);
		md5_transform(buf, in.u32);
		md5_transform(buffer, in.u32);

		buffer += t;
		size -= t;
		buffer_ += t;
		length -= t;
	}

	/* Process data in 64-byte chunks */
	while (size >= 64) {
		memcpy(in.u8, buffer, 64);
	while (length >= 64) {
		memcpy(in.u8, buffer_, 64);
		of_bswap32_vec_if_be(in.u32, 16);
		md5_transform(buf, in.u32);
		md5_transform(buffer, in.u32);

		buffer += 64;
		size -= 64;
		buffer_ += 64;
		length -= 64;
	}

	/* Handle any remaining bytes of data. */
	memcpy(in.u8, buffer, size);
	memcpy(in.u8, buffer_, length);
}

- (uint8_t*)digest
{
	uint8_t	*p;
	size_t	count;

	if (isCalculated)
		return (uint8_t*)buf;
		return (uint8_t*)buffer;

	/* Compute number of bytes mod 64 */
	count = (bits[0] >> 3) & 0x3F;

	/*
	 * Set the first char of padding to 0x80. This is safe since there is
	 * always at least one byte free
	 */
	p = in.u8 + count;
	*p++ = 0x80;

	/* Bytes of padding needed to make 64 bytes */
	count = 64 - 1 - count;

	/* Pad out to 56 mod 64 */
	if (count < 8) {
		/* Two lots of padding: Pad the first block to 64 bytes */
		memset(p, 0, count);
		of_bswap32_vec_if_be(in.u32, 16);
		md5_transform(buf, in.u32);
		md5_transform(buffer, in.u32);

		/* Now fill the next block with 56 bytes */
		memset(in.u8, 0, 56);
	} else {
		/* Pad block to 56 bytes */
		memset(p, 0, count - 8);
	}
	of_bswap32_vec_if_be(in.u32, 14);

	/* Append length in bits and transform */
	in.u32[14] = bits[0];
	in.u32[15] = bits[1];

	md5_transform(buf, in.u32);
	md5_transform(buffer, in.u32);
	of_bswap32_vec_if_be(buf, 4);

	isCalculated = YES;

	return (uint8_t*)buf;
	return (uint8_t*)buffer;
}
@end

Modified src/OFMutableArray.h from [8c6d38e392] to [1c792f75c6].

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







-
+

-
+




-
+


-
+






-
-
+
+

-
-
+
+





-
+


-
+





-
-
+
+

-
-
+
+




-
+

-
+




-
+

-
+











-
+

-
+







-
+







{
	unsigned long mutations;
}

/**
 * Adds an object to the OFArray.
 *
 * \param obj An object to add
 * \param object An object to add
 */
- (void)addObject: (id)obj;
- (void)addObject: (id)object;

/**
 * Adds an object to the OFArray at the specified index.
 *
 * \param obj An object to add
 * \param object An object to add
 * \param index The index where the object should be added
 */
- (void)addObject: (id)obj
- (void)addObject: (id)object
	  atIndex: (size_t)index;

/**
 * Replaces the first object equivalent to the first specified object with the
 * second specified object.
 *
 * \param old The object to replace
 * \param new_ The replacement object
 * \param oldObject The object to replace
 * \param newObject The replacement object
 */
- (void)replaceObject: (id)old
	   withObject: (id)new_;
- (void)replaceObject: (id)oldObject
	   withObject: (id)newObject;

/**
 * Replaces the object at the specified index with the specified object.
 *
 * \param index The index of the object to replace
 * \param obj The replacement object
 * \param object The replacement object
 */
- (void)replaceObjectAtIndex: (size_t)index
		  withObject: (id)obj;
		  withObject: (id)object;

/**
 * Replaces the first object that has the same address as the first specified
 * object with the second specified object.
 *
 * \param old The object to replace
 * \param new_ The replacement object
 * \param oldObject The object to replace
 * \param newObject The replacement object
 */
- (void)replaceObjectIdenticalTo: (id)old
		      withObject: (id)new_;
- (void)replaceObjectIdenticalTo: (id)oldObject
		      withObject: (id)newObject;

/**
 * Removes the first object equivalent to the specified object.
 *
 * \param obj The object to remove
 * \param object The object to remove
 */
- (void)removeObject: (id)obj;
- (void)removeObject: (id)object;

/**
 * Removes the first object that has the same address as the specified object.
 *
 * \param obj The object to remove
 * \param object The object to remove
 */
- (void)removeObjectIdenticalTo: (id)obj;
- (void)removeObjectIdenticalTo: (id)object;

/**
 * Removes the object at the specified index.
 *
 * \param index The index of the object to remove
 */
- (void)removeObjectAtIndex: (size_t)index;

/**
 * Removes the specified amount of objects from the end of the OFArray.
 *
 * \param nobjects The number of objects to remove
 * \param nObjects The number of objects to remove
 */
- (void)removeNObjects: (size_t)nobjects;
- (void)removeNObjects: (size_t)nObjects;

/**
 * Removes the specified amount of objects at the specified index.
 *
 * \param nobjects The number of objects to remove
 * \param index The index at which the objects are removed
 */
- (void)removeNObjects: (size_t)nobjects
- (void)removeNObjects: (size_t)nObjects
	       atIndex: (size_t)index;

#ifdef OF_HAVE_BLOCKS
/**
 * Replaces each object with the object returned by the block.
 *
 * \param block The block which returns a new object for each object

Modified src/OFMutableArray.m from [d3e5b8eedf] to [26e57101fb].

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

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







-
+
-
-
-
-
-
+
+

-
-
+
+


-
+

-
+


-
+

-
-
+
+


+
-
+
-
-
+


-
+

-
+




-
-
+
+

-
+



-
-
-
-
+
+
+
+







-
+

-
-
+
+




-
-
-
+
+
+


-
-
+
+

-
+



-
-
-
-
+
+
+
+






-
+

-
+



-
-
+
+




-
+






-
+

-
+



-
+



-
+








-
+

-
+




-
+

-
+


-
+


-
+

-
+


-
+


-
+






-
+


-
+


-
+


-
+

-
+


-
+



-
+







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

@implementation OFMutableArray
- copy
{
	OFArray *new = [[OFArray alloc] init];
	OFArray *copy = [[OFArray alloc] init];
	id *objs;
	size_t count, i;

	objs = [array cArray];
	count = [array count];
	id *cArray = [array cArray];
	size_t i, count = [array count];

	[new->array addNItems: count
		   fromCArray: objs];
	[copy->array addNItems: count
		    fromCArray: cArray];

	for (i = 0; i < count; i++)
		[objs[i] retain];
		[cArray[i] retain];

	return new;
	return copy;
}

- (void)addObject: (id)obj
- (void)addObject: (id)object
{
	[array addItem: &obj];
	[obj retain];
	[array addItem: &object];
	[object retain];

	mutations++;
}
}


- (void)addObject: (id)obj
- (void)addObject: (id)object
	  atIndex: (size_t)index
{
	[array addItem: &obj
	[array addItem: &object
	       atIndex: index];
	[obj retain];
	[object retain];

	mutations++;
}

- (void)replaceObject: (id)old
	   withObject: (id)new
- (void)replaceObject: (id)oldObject
	   withObject: (id)newObject
{
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++) {
		if ([objs[i] isEqual: old]) {
			[new retain];
			[objs[i] release];
			objs[i] = new;
		if ([cArray[i] isEqual: oldObject]) {
			[newObject retain];
			[cArray[i] release];
			cArray[i] = newObject;

			return;
		}
	}
}

- (void)replaceObjectAtIndex: (size_t)index
		  withObject: (id)obj
		  withObject: (id)object
{
	id *objs = [array cArray];
	id old;
	id *cArray = [array cArray];
	id oldObject;

	if (index >= [array count])
		@throw [OFOutOfRangeException newWithClass: isa];

	old = objs[index];
	objs[index] = [obj retain];
	[old release];
	oldObject = cArray[index];
	cArray[index] = [object retain];
	[oldObject release];
}

- (void)replaceObjectIdenticalTo: (id)old
		      withObject: (id)new
- (void)replaceObjectIdenticalTo: (id)oldObject
		      withObject: (id)newObject
{
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++) {
		if (objs[i] == old) {
			[new retain];
			[objs[i] release];
			objs[i] = new;
		if (cArray[i] == oldObject) {
			[newObject retain];
			[cArray[i] release];
			cArray[i] = newObject;

			return;
		}
	}
}

- (void)removeObject: (id)obj
- (void)removeObject: (id)object
{
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++) {
		if ([objs[i] isEqual: obj]) {
			id obj = objs[i];
		if ([cArray[i] isEqual: object]) {
			object = cArray[i];

			[array removeItemAtIndex: i];
			mutations++;

			[obj release];
			[object release];

			return;
		}
	}
}

- (void)removeObjectIdenticalTo: (id)obj
- (void)removeObjectIdenticalTo: (id)object
{
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++) {
		if (objs[i] == obj) {
		if (cArray[i] == object) {
			[array removeItemAtIndex: i];
			mutations++;

			[obj release];
			[object release];

			return;
		}
	}
}

- (void)removeObjectAtIndex: (size_t)index
{
	id old = [self objectAtIndex: index];
	id object = [self objectAtIndex: index];
	[array removeItemAtIndex: index];
	[old release];
	[object release];

	mutations++;
}

- (void)removeNObjects: (size_t)nobjects
- (void)removeNObjects: (size_t)nObjects
{
	id *objs = [array cArray], *copy;
	id *cArray = [array cArray], *copy;
	size_t i, count = [array count];

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

	copy = [self allocMemoryForNItems: nobjects
	copy = [self allocMemoryForNItems: nObjects
				 withSize: sizeof(id)];
	memcpy(copy, objs + (count - nobjects), nobjects * sizeof(id));
	memcpy(copy, cArray + (count - nObjects), nObjects * sizeof(id));

	@try {
		[array removeNItems: nobjects];
		[array removeNItems: nObjects];
		mutations++;

		for (i = 0; i < nobjects; i++)
		for (i = 0; i < nObjects; i++)
			[copy[i] release];
	} @finally {
		[self freeMemory: copy];
	}
}

- (void)removeNObjects: (size_t)nobjects
- (void)removeNObjects: (size_t)nObjects
	       atIndex: (size_t)index
{
	id *objs = [array cArray], *copy;
	id *cArray = [array cArray], *copy;
	size_t i, count = [array count];

	if (nobjects > count - index)
	if (nObjects > count - index)
		@throw [OFOutOfRangeException newWithClass: isa];

	copy = [self allocMemoryForNItems: nobjects
	copy = [self allocMemoryForNItems: nObjects
				 withSize: sizeof(id)];
	memcpy(copy, objs + index, nobjects * sizeof(id));
	memcpy(copy, cArray + index, nObjects * sizeof(id));

	@try {
		[array removeNItems: nobjects
		[array removeNItems: nObjects
			    atIndex: index];
		mutations++;

		for (i = 0; i < nobjects; i++)
		for (i = 0; i < nObjects; i++)
			[copy[i] release];
	} @finally {
		[self freeMemory: copy];
	}
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
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
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







-
+










-
+









-
+





+
+





-
+

-
+



-
-
-
+
+
+








	    mutationsPointer: &mutations] autorelease];
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];
	BOOL stop = NO;
	unsigned long mutations2 = mutations;

	for (i = 0; i < count && !stop; i++) {
		if (mutations != mutations2)
			@throw [OFEnumerationMutationException
			    newWithClass: isa
				  object: self];

		block(objs[i], i, &stop);
		block(cArray[i], i, &stop);
		[pool releaseObjects];
	}

	[pool release];
}

- (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	id *objs = [array cArray];
	id *cArray = [array cArray];
	size_t i, count = [array count];
	BOOL stop = NO;
	unsigned long mutations2 = mutations;

	for (i = 0; i < count && !stop; i++) {
		id newObject;

		if (mutations != mutations2)
			@throw [OFEnumerationMutationException
			    newWithClass: isa
				  object: self];

		id new = block(objs[i], i, &stop);
		newObject = block(cArray[i], i, &stop);

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

		[new retain];
		[objs[i] release];
		objs[i] = new;
		[newObject retain];
		[cArray[i] release];
		cArray[i] = newObject;

		[pool releaseObjects];
	}

	[pool release];
}
#endif
@end

Modified src/OFObject.h from [9dc78efdb2] to [71473f3fce].

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







-
+



-
+















-
+



-
+







 * This is mostly for debugging purposes.
 */
+ (OFString*)description;

/**
 * Replaces a class method implementation with another implementation.
 *
 * \param newimp The new implementation for the class method
 * \param newImp The new implementation for the class method
 * \param selector The selector of the class method to replace
 * \return The old implementation
 */
+ (IMP)setImplementation: (IMP)newimp
+ (IMP)setImplementation: (IMP)newImp
	  forClassMethod: (SEL)selector;

/**
 * Replaces a class method with a class method from another class.
 *
 * \param selector The selector of the class method to replace
 * \param class_ The class from which the new class method should be taken
 * \return The old implementation
 */
+ (IMP)replaceClassMethod: (SEL)selector
      withMethodFromClass: (Class)class_;

/**
 * Replaces an instance method implementation with another implementation.
 *
 * \param newimp The new implementation for the instance method
 * \param newImp The new implementation for the instance method
 * \param selector The selector of the instance method to replace
 * \return The old implementation
 */
+ (IMP)setImplementation: (IMP)newimp
+ (IMP)setImplementation: (IMP)newImp
       forInstanceMethod: (SEL)selector;

/**
 * Replaces an instance method with an instance method from another class.
 *
 * \param selector The selector of the instance method to replace
 * \param class_ The class from which the new instance method should be taken
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
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







-
+



-
+

















-
+




-
+







- (void*)allocMemoryWithSize: (size_t)size;

/**
 * Allocates memory for the specified number of items and stores it in the
 * object's memory pool so it can be free'd automatically when the object is
 * deallocated.
 *
 * \param nitems The number of items to allocate
 * \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
- (void*)allocMemoryForNItems: (size_t)nItems
		     withSize: (size_t)size;

/**
 * Resizes memory in the object's memory pool to the 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;

/**
 * Resizes memory in the object's memory pool to the specific number of items of
 * the specified size.
 *
 * \param ptr A pointer to the already allocated memory
 * \param nitems The number of items to resize to
 * \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
	     toNItems: (size_t)nItems
	     withSize: (size_t)size;

/**
 * Frees allocated memory and removes it from the object's memory pool.
 * Does nothing if ptr is NULL.
 *
 * \param ptr A pointer to the allocated memory

Modified src/OFObject.m from [b8a2ef4dd8] to [f33de6810c].

62
63
64
65
66
67
68
69
70
71



72
73

74
75
76
77
78
79
80
62
63
64
65
66
67
68



69
70
71
72

73
74
75
76
77
78
79
80







-
-
-
+
+
+

-
+







# define class_getInstanceSize class_get_instance_size
# define class_getName class_get_class_name
# define class_getSuperclass class_get_super_class
# define sel_registerName sel_get_uid
#endif

struct pre_ivar {
	void	      **memchunks;
	size_t	      memchunks_size;
	int32_t	      retain_count;
	void	      **memoryChunks;
	size_t	      memoryChunksSize;
	int32_t	      retainCount;
#if !defined(OF_ATOMIC_OPS)
	of_spinlock_t retain_spinlock;
	of_spinlock_t retainCountSpinlock;
#endif
};

/* Hopefully no arch needs more than 16 bytes padding */
#ifndef __BIGGEST_ALIGNMENT__
# define __BIGGEST_ALIGNMENT__ 16
#endif
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
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







-
+

-
-
+
+




-
+

-
+







#endif

#ifdef NEED_OBJC_PROPERTIES_INIT
extern BOOL objc_properties_init();
#endif

static void
enumeration_mutation_handler(id obj)
enumeration_mutation_handler(id object)
{
	@throw [OFEnumerationMutationException newWithClass: [obj class]
						     object: obj];
	@throw [OFEnumerationMutationException newWithClass: [object class]
						     object: object];
}

#ifndef HAVE_OBJC_ENUMERATIONMUTATION
void
objc_enumerationMutation(id obj)
objc_enumerationMutation(id object)
{
	enumeration_mutation_handler(obj);
	enumeration_mutation_handler(object);
}
#endif

@implementation OFObject
+ (void)load
{
#ifdef NEED_OBJC_SYNC_INIT
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
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







-
+



-
+




-
-
-
+
+
+


-
+
+






-
+







+ (void)initialize
{
}

+ alloc
{
	OFObject *instance;
	size_t isize = class_getInstanceSize(self);
	size_t instanceSize = class_getInstanceSize(self);
	Class class;
	void (*last)(id, SEL) = NULL;

	if ((instance = malloc(isize + PRE_IVAR_ALIGN)) == NULL) {
	if ((instance = malloc(instanceSize + PRE_IVAR_ALIGN)) == NULL) {
		alloc_failed_exception.isa = [OFAllocFailedException class];
		@throw (OFAllocFailedException*)&alloc_failed_exception;
	}

	((struct pre_ivar*)instance)->memchunks = NULL;
	((struct pre_ivar*)instance)->memchunks_size = 0;
	((struct pre_ivar*)instance)->retain_count = 1;
	((struct pre_ivar*)instance)->memoryChunks = NULL;
	((struct pre_ivar*)instance)->memoryChunksSize = 0;
	((struct pre_ivar*)instance)->retainCount = 1;

#if !defined(OF_ATOMIC_OPS)
	if (!of_spinlock_new(&((struct pre_ivar*)instance)->retain_spinlock)) {
	if (!of_spinlock_new(
	    &((struct pre_ivar*)instance)->retainCountSpinlock)) {
		free(instance);
		@throw [OFInitializationFailedException newWithClass: self];
	}
#endif

	instance = (OFObject*)((char*)instance + PRE_IVAR_ALIGN);
	memset(instance, 0, isize);
	memset(instance, 0, instanceSize);
	instance->isa = self;

	for (class = self; class != Nil; class = class_getSuperclass(class)) {
		void (*construct)(id, SEL);

		if ([class instancesRespondToSelector: cxx_construct]) {
			if ((construct = (void(*)(id, SEL))[class
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
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







-
+



-
+



-
+


-
+







-
+



-
+







-
+



-
+








-
+







-
+





-
+

-
+



-
+



-
+



-
+


-
+





-
+



-
+







-
+



-
+




-
+







-
+





-
+

-
+







}

+ (OFString*)description
{
	return [self className];
}

+ (IMP)setImplementation: (IMP)newimp
+ (IMP)setImplementation: (IMP)newImp
	  forClassMethod: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	if (newimp == (IMP)0 || !class_respondsToSelector(self->isa, selector))
	if (newImp == (IMP)0 || !class_respondsToSelector(self->isa, selector))
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	return objc_replace_class_method(self, selector, newimp);
	return objc_replace_class_method(self, selector, newImp);
#elif defined(OF_OLD_GNU_RUNTIME)
	Method_t method;
	IMP oldimp;
	IMP oldImp;

	/* The class method is the instance method of the meta class */
	if ((method = class_get_instance_method(self->class_pointer,
	    selector)) == NULL)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	if ((oldimp = method_get_imp(method)) == (IMP)0 || newimp == (IMP)0)
	if ((oldImp = method_get_imp(method)) == (IMP)0 || newImp == (IMP)0)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	method->method_imp = newimp;
	method->method_imp = newImp;

	/* Update the dtable if necessary */
	if (sarray_get_safe(((Class)self->class_pointer)->dtable,
	    (sidx)method->method_name->sel_id))
		sarray_at_put_safe(((Class)self->class_pointer)->dtable,
		    (sidx)method->method_name->sel_id, method->method_imp);

	return oldimp;
	return oldImp;
#else
	Method method;

	if (newimp == (IMP)0 ||
	if (newImp == (IMP)0 ||
	    (method = class_getClassMethod(self, selector)) == NULL)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	/*
	 * Cast needed because it's isa in the Apple runtime, but class_pointer
	 * in the GNU runtime.
	 */
	return class_replaceMethod(((OFObject*)self)->isa, selector, newimp,
	return class_replaceMethod(((OFObject*)self)->isa, selector, newImp,
	    method_getTypeEncoding(method));
#endif
}

+ (IMP)replaceClassMethod: (SEL)selector
      withMethodFromClass: (Class)class;
{
	IMP newimp;
	IMP newImp;

	if (![class isSubclassOfClass: self])
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	newimp = [class methodForSelector: selector];
	newImp = [class methodForSelector: selector];

	return [self setImplementation: newimp
	return [self setImplementation: newImp
			forClassMethod: selector];
}

+ (IMP)setImplementation: (IMP)newimp
+ (IMP)setImplementation: (IMP)newImp
       forInstanceMethod: (SEL)selector
{
#if defined(OF_OBJFW_RUNTIME)
	if (newimp == (IMP)0 || !class_respondsToSelector(self, selector))
	if (newImp == (IMP)0 || !class_respondsToSelector(self, selector))
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	return objc_replace_instance_method(self, selector, newimp);
	return objc_replace_instance_method(self, selector, newImp);
#elif defined(OF_OLD_GNU_RUNTIME)
	Method_t method = class_get_instance_method(self, selector);
	IMP oldimp;
	IMP oldImp;

	if (method == NULL)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	if ((oldimp = method_get_imp(method)) == (IMP)0 || newimp == (IMP)0)
	if ((oldImp = method_get_imp(method)) == (IMP)0 || newImp == (IMP)0)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	method->method_imp = newimp;
	method->method_imp = newImp;

	/* Update the dtable if necessary */
	if (sarray_get_safe(((Class)self)->dtable,
	    (sidx)method->method_name->sel_id))
		sarray_at_put_safe(((Class)self)->dtable,
		    (sidx)method->method_name->sel_id, method->method_imp);

	return oldimp;
	return oldImp;
#else
	Method method;

	if (newimp == (IMP)0 ||
	if (newImp == (IMP)0 ||
	    (method = class_getInstanceMethod(self, selector)) == NULL)
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	return class_replaceMethod(self, selector, newimp,
	return class_replaceMethod(self, selector, newImp,
	    method_getTypeEncoding(method));
#endif
}

+ (IMP)replaceInstanceMethod: (SEL)selector
	 withMethodFromClass: (Class)class;
{
	IMP newimp;
	IMP newImp;

	if (![class isSubclassOfClass: self])
		@throw [OFInvalidArgumentException newWithClass: self
						       selector: _cmd];

	newimp = [class instanceMethodForSelector: selector];
	newImp = [class instanceMethodForSelector: selector];

	return [self setImplementation: newimp
	return [self setImplementation: newImp
		     forInstanceMethod: selector];
}

- init
{
	return self;
}
562
563
564
565
566
567
568
569
570


571
572

573
574
575


576
577
578
579


580
581

582
583
584
585



586
587
588
589
590
591


592
593
594
595
596

597
598
599


600
601
602
603
604
605
606
607


608
609
610

611
612
613
614
615



616
617
618
619
620

621
622
623

624
625
626

627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668

669
670
671

672
673
674
675
676

677
678
679
680

681
682
683
684
685
686


687
688
689
690
691
692


693
694

695
696
697
698
699


700
701
702


703
704

705
706

707
708
709


710
711
712
713
714
715
716


717
718
719


720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736

737
738
739
740



741
742
743
744
745
746
747
748
749


750
751
752
753
754
755

756
757
758
759
760
761
762



763
764
765
766
767
768
769
563
564
565
566
567
568
569


570
571
572

573
574


575
576
577
578


579
580
581

582
583



584
585
586
587
588
589
590


591
592
593
594
595
596

597
598


599
600
601
602
603
604
605
606


607
608
609
610

611
612
613



614
615
616
617
618
619
620

621
622
623

624
625
626

627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668

669
670
671

672
673
674
675
676

677
678
679
680

681
682
683
684
685


686
687
688
689
690
691


692
693
694

695
696
697
698


699
700
701


702
703
704

705
706

707
708


709
710
711
712
713
714
715


716
717
718


719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736

737
738



739
740
741
742
743
744
745
746
747
748


749
750
751
752
753
754
755

756
757
758
759
760



761
762
763
764
765
766
767
768
769
770







-
-
+
+

-
+

-
-
+
+


-
-
+
+

-
+

-
-
-
+
+
+




-
-
+
+




-
+

-
-
+
+






-
-
+
+


-
+


-
-
-
+
+
+




-
+


-
+


-
+


-
+















-
+

-
+
















-
+



-
+


-
+




-
+



-
+




-
-
+
+




-
-
+
+

-
+



-
-
+
+

-
-
+
+

-
+

-
+

-
-
+
+





-
-
+
+

-
-
+
+



-
+












-
+

-
-
-
+
+
+







-
-
+
+





-
+




-
-
-
+
+
+







{
	/* Classes containing data should reimplement this! */
	return [OFString stringWithFormat: @"<%@: %p>", [self className], self];
}

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

	memchunks_size = PRE_IVAR->memchunks_size + 1;
	memoryChunksSize = PRE_IVAR->memoryChunksSize + 1;

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

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

	PRE_IVAR->memchunks = memchunks;
	PRE_IVAR->memchunks[PRE_IVAR->memchunks_size] = ptr;
	PRE_IVAR->memchunks_size = memchunks_size;
	PRE_IVAR->memoryChunks = memoryChunks;
	PRE_IVAR->memoryChunks[PRE_IVAR->memoryChunksSize] = ptr;
	PRE_IVAR->memoryChunksSize = memoryChunksSize;
}

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

	if (size == 0)
		return NULL;

	memchunks_size = PRE_IVAR->memchunks_size + 1;
	memoryChunksSize = PRE_IVAR->memoryChunksSize + 1;

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

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

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

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

	return ptr;
}

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

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

	return [self allocMemoryWithSize: nitems * size];
	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;
	iter = PRE_IVAR->memoryChunks + PRE_IVAR->memoryChunksSize;

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

			*iter = ptr;
			return ptr;
		}
	}

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

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

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

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

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

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

	if (ptr == NULL)
		return;

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

	while (iter-- > PRE_IVAR->memchunks) {
	while (iter-- > PRE_IVAR->memoryChunks) {
		i--;

		if (OF_UNLIKELY(*iter == ptr)) {
			memchunks_size = PRE_IVAR->memchunks_size - 1;
			last = PRE_IVAR->memchunks[memchunks_size];
			memoryChunksSize = PRE_IVAR->memoryChunksSize - 1;
			last = PRE_IVAR->memoryChunks[memoryChunksSize];

			assert(PRE_IVAR->memchunks_size != 0 &&
			    memchunks_size <= SIZE_MAX / sizeof(void*));
			assert(PRE_IVAR->memoryChunksSize != 0 &&
			    memoryChunksSize <= SIZE_MAX / sizeof(void*));

			if (OF_UNLIKELY(memchunks_size == 0)) {
			if (OF_UNLIKELY(memoryChunksSize == 0)) {
				free(ptr);
				free(PRE_IVAR->memchunks);
				free(PRE_IVAR->memoryChunks);

				PRE_IVAR->memchunks = NULL;
				PRE_IVAR->memchunks_size = 0;
				PRE_IVAR->memoryChunks = NULL;
				PRE_IVAR->memoryChunksSize = 0;

				return;
			}

			free(ptr);
			PRE_IVAR->memchunks[i] = last;
			PRE_IVAR->memchunks_size = memchunks_size;
			PRE_IVAR->memoryChunks[i] = last;
			PRE_IVAR->memoryChunksSize = memoryChunksSize;

			if (OF_UNLIKELY((memchunks = realloc(
			    PRE_IVAR->memchunks, memchunks_size *
			if (OF_UNLIKELY((memoryChunks = realloc(
			    PRE_IVAR->memoryChunks, memoryChunksSize *
			    sizeof(void*))) == NULL))
				return;

			PRE_IVAR->memchunks = memchunks;
			PRE_IVAR->memoryChunks = memoryChunks;

			return;
		}
	}

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

- retain
{
#if defined(OF_ATOMIC_OPS)
	of_atomic_inc_32(&PRE_IVAR->retain_count);
	of_atomic_inc_32(&PRE_IVAR->retainCount);
#else
	assert(of_spinlock_lock(&PRE_IVAR->retain_spinlock));
	PRE_IVAR->retain_count++;
	assert(of_spinlock_unlock(&PRE_IVAR->retain_spinlock));
	assert(of_spinlock_lock(&PRE_IVAR->retainCountSpinlock));
	PRE_IVAR->retainCount++;
	assert(of_spinlock_unlock(&PRE_IVAR->retainCountSspinlock));
#endif

	return self;
}

- (unsigned int)retainCount
{
	assert(PRE_IVAR->retain_count >= 0);
	return PRE_IVAR->retain_count;
	assert(PRE_IVAR->retainCount >= 0);
	return PRE_IVAR->retainCount;
}

- (void)release
{
#if defined(OF_ATOMIC_OPS)
	if (of_atomic_dec_32(&PRE_IVAR->retain_count) <= 0)
	if (of_atomic_dec_32(&PRE_IVAR->retainCount) <= 0)
		[self dealloc];
#else
	size_t c;

	assert(of_spinlock_lock(&PRE_IVAR->retain_spinlock));
	c = --PRE_IVAR->retain_count;
	assert(of_spinlock_unlock(&PRE_IVAR->retain_spinlock));
	assert(of_spinlock_lock(&PRE_IVAR->retainCountSpinlock));
	c = --PRE_IVAR->retainCount;
	assert(of_spinlock_unlock(&PRE_IVAR->retainCountSpinlock));

	if (!c)
		[self dealloc];
#endif
}

- autorelease
795
796
797
798
799
800
801
802
803


804
805
806
807


808
809
810
811
812
813
814
796
797
798
799
800
801
802


803
804
805
806


807
808
809
810
811
812
813
814
815







-
-
+
+


-
-
+
+







				destruct(self, cxx_destruct);

			last = destruct;
		} else
			break;
	}

	iter = PRE_IVAR->memchunks + PRE_IVAR->memchunks_size;
	while (iter-- > PRE_IVAR->memchunks)
	iter = PRE_IVAR->memoryChunks + PRE_IVAR->memoryChunksSize;
	while (iter-- > PRE_IVAR->memoryChunks)
		free(*iter);

	if (PRE_IVAR->memchunks != NULL)
		free(PRE_IVAR->memchunks);
	if (PRE_IVAR->memoryChunks != NULL)
		free(PRE_IVAR->memoryChunks);

	free((char*)self - PRE_IVAR_ALIGN);
}

/* Required to use properties with the Apple runtime */
- copyWithZone: (void*)zone
{
840
841
842
843
844
845
846
847

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862

863
864
865
866
867
868
869
841
842
843
844
845
846
847

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862

863
864
865
866
867
868
869
870







-
+














-
+








+ (void*)allocMemoryWithSize: (size_t)size
{
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
}

+ (void*)allocMemoryForNItems: (size_t)nitems
+ (void*)allocMemoryForNItems: (size_t)nItems
                     withSize: (size_t)size
{
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
}

+ (void*)resizeMemory: (void*)ptr
	       toSize: (size_t)size
{
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
}

+ (void*)resizeMemory: (void*)ptr
	     toNItems: (size_t)nitems
	     toNItems: (size_t)nItems
	     withSize: (size_t)size
{
	@throw [OFNotImplementedException newWithClass: self
					      selector: _cmd];
}

+ (void)freeMemory: (void*)ptr

Modified src/OFSHA1Hash.m from [c68eae11dd] to [595fab433e].

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







-
+




-
+

-
+




-
+






-
+







	state[2] += c;
	state[3] += d;
	state[4] += e;
}

static inline void
sha1_update(uint32_t *state, uint64_t *count, char *buffer,
    const char *buf, size_t size)
    const char *buf, size_t length)
{
	size_t i, j;

	j = (size_t)((*count >> 3) & 63);
	*count += (size << 3);
	*count += (length << 3);

	if ((j + size) > 63) {
	if ((j + length) > 63) {
		memcpy(&buffer[j], buf, (i = 64 - j));

		sha1_transform(state, buffer);

		for (; i + 63 < size; i += 64)
		for (; i + 63 < length; i += 64)
			sha1_transform(state, &buf[i]);

		j = 0;
	} else
		i = 0;

	memcpy(&buffer[j], &buf[i], size - i);
	memcpy(&buffer[j], &buf[i], length - i);
}

@implementation OFSHA1Hash
+ SHA1Hash
{
	return [[[self alloc] init] autorelease];
}
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
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







-
-
+
+

-
+






-
+







	state[2] = 0x98BADCFE;
	state[3] = 0x10325476;
	state[4] = 0xC3D2E1F0;

	return self;
}

- (void)updateWithBuffer: (const char*)buf
		  ofSize: (size_t)size
- (void)updateWithBuffer: (const char*)buffer_
		  length: (size_t)length
{
	if (size == 0)
	if (length == 0)
		return;

	if (isCalculated)
		@throw [OFHashAlreadyCalculatedException newWithClass: isa
								 hash: self];

	sha1_update(state, &count, buffer, buf, size);
	sha1_update(state, &count, buffer, buffer_, length);
}

- (uint8_t*)digest
{
	size_t i;
	char   finalcount[8];

Modified src/OFSeekableStream.m from [693313aa14] to [cbcf953b58].

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







-
+

-
+





-
+




-
+

-
+





-
+


	[self freeMemory: cache];
	cache = NULL;
	cacheLength = 0;
}

- (off_t)seekForwardWithOffset: (off_t)offset
{
	off_t retOffset;
	off_t ret;

	retOffset = [self _seekForwardWithOffset: offset - cacheLength];
	ret = [self _seekForwardWithOffset: offset - cacheLength];

	[self freeMemory: cache];
	cache = NULL;
	cacheLength = 0;

	return retOffset;
	return ret;
}

- (off_t)seekToOffsetRelativeToEnd: (off_t)offset
{
	off_t retOffset;
	off_t ret;

	retOffset = [self _seekToOffsetRelativeToEnd: offset];
	ret = [self _seekToOffsetRelativeToEnd: offset];

	[self freeMemory: cache];
	cache = NULL;
	cacheLength = 0;

	return retOffset;
	return ret;
}
@end

Modified src/OFStreamSocket.m from [7c915a3b62] to [773bb7067f].

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







-
+




















-
+




-
+


-
+





-
+




















-
+




-
+







{
	return isAtEndOfStream;
}

- (size_t)_readNBytes: (size_t)length
	   intoBuffer: (char*)buffer
{
	ssize_t retLength;
	ssize_t ret;

	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException newWithClass: isa
						      socket: self];

	if (isAtEndOfStream) {
		OFReadFailedException *e;

		e = [OFReadFailedException newWithClass: isa
						 stream: self
					requestedLength: length];
#ifndef _WIN32
		e->errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if ((retLength = recv(sock, buffer, length, 0)) < 0)
	if ((ret = recv(sock, buffer, length, 0)) < 0)
		@throw [OFReadFailedException newWithClass: isa
						    stream: self
					   requestedLength: length];

	if (retLength == 0)
	if (ret == 0)
		isAtEndOfStream = YES;

	return retLength;
	return ret;
}

- (size_t)_writeNBytes: (size_t)length
	    fromBuffer: (const char*)buffer
{
	ssize_t retLength;
	ssize_t ret;

	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException newWithClass: isa
						      socket: self];

	if (isAtEndOfStream) {
		OFWriteFailedException *e;

		e = [OFWriteFailedException newWithClass: isa
						  stream: self
					 requestedLength: length];
#ifndef _WIN32
		e->errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if ((retLength = send(sock, buffer, length, 0)) == -1)
	if ((ret = send(sock, buffer, length, 0)) == -1)
		@throw [OFWriteFailedException newWithClass: isa
						     stream: self
					    requestedLength: length];

	return retLength;
	return ret;
}

#ifdef _WIN32
- (void)setBlocking: (BOOL)enable
{
	u_long v = enable;
	isBlocking = enable;

Modified src/OFString+Hashing.m from [856205c228] to [4e1492dfab].

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
60

61
62
63
64

65
66
67
68
69
70
71
72
73
74


75
76
77
78
79

80
81
82
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

60
61
62
63

64
65
66
67
68
69
70
71
72


73
74
75
76
77
78

79
80
81
82







-
+



-
+








-
-
+
+




-
+








-
+



-
+








-
-
+
+




-
+




@implementation OFString (Hashing)
- (OFString*)MD5Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFMD5Hash MD5Hash];
	uint8_t *digest;
	char ret_c[OF_MD5_DIGEST_SIZE * 2];
	char cString[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: string
			ofSize: length];
			length: length];
	digest = [hash digest];

	for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		ret_c[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret_c[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];

	return [OFString stringWithCString: ret_c
	return [OFString stringWithCString: cString
				    length: 32];
}

- (OFString*)SHA1Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFSHA1Hash SHA1Hash];
	uint8_t *digest;
	char ret_c[OF_SHA1_DIGEST_SIZE * 2];
	char cString[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: string
			ofSize: length];
			length: length];
	digest = [hash digest];

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		ret_c[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret_c[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	[pool release];

	return [OFString stringWithCString: ret_c
	return [OFString stringWithCString: cString
				    length: 40];
}
@end

Modified tests/OFListTests.m from [2488afe1b6] to [0db3614a7f].

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







-
-
+
+











-
+








	TEST(@"-[firstListObject]->next",
	    [[list firstListObject]->next->object isEqual: strings[1]])

	TEST(@"-[lastListObject]",
	    [[list lastListObject]->object isEqual: strings[2]])

	TEST(@"-[lastListObject]->prev",
	    [[list lastListObject]->prev->object isEqual: strings[1]])
	TEST(@"-[lastListObject]->previous",
	    [[list lastListObject]->previous->object isEqual: strings[1]])

	TEST(@"-[removeListObject:]",
	    R([list removeListObject: [list lastListObject]]) &&
	    [[list lastListObject]->object isEqual: strings[1]] &&
	    R([list removeListObject: [list firstListObject]]) &&
	    [[list firstListObject]->object isEqual:
	    [list lastListObject]->object])

	TEST(@"-[insertObject:beforeListObject:]",
	    [list insertObject: strings[0]
	      beforeListObject: [list lastListObject]] &&
	    [[list lastListObject]->prev->object isEqual: strings[0]])
	    [[list lastListObject]->previous->object isEqual: strings[0]])

	TEST(@"-[insertObject:afterListObject:]",
	    [list insertObject: strings[2]
	       afterListObject: [list firstListObject]->next] &&
	    [[list lastListObject]->object isEqual: strings[2]])

	TEST(@"-[count]", [list count] == 3)

Modified tests/OFMD5HashTests.m from [e94d6df1df] to [e80a1f9b87].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59




60
61
62
63
43
44
45
46
47
48
49

50
51
52
53
54
55
56



57
58
59
60
61
62
63
64







-
+






-
-
-
+
+
+
+




	TEST(@"+[md5Hash]", (md5 = [OFMD5Hash MD5Hash]))

	while (![f isAtEndOfStream]) {
		char buf[64];
		size_t len = [f readNBytes: 64
				intoBuffer: buf];
		[md5 updateWithBuffer: buf
			       ofSize: len];
			       length: len];
	}
	[f close];

	TEST(@"-[digest]",
	    !memcmp([md5 digest], testfile_md5, OF_MD5_DIGEST_SIZE))

	EXPECT_EXCEPTION(@"Detect invalid call of -[updateWithBuffer]",
	    OFHashAlreadyCalculatedException, [md5 updateWithBuffer: ""
							     ofSize: 1])
	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException,
	    [md5 updateWithBuffer: ""
			   length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA1HashTests.m from [af8da2df4c] to [18f5bdbcf3].

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60




61
62
63
64
44
45
46
47
48
49
50

51
52
53
54
55
56
57



58
59
60
61
62
63
64
65







-
+






-
-
-
+
+
+
+




	TEST(@"+[sha1Hash]", (sha1 = [OFSHA1Hash SHA1Hash]))

	while (![f isAtEndOfStream]) {
		char buf[64];
		size_t len = [f readNBytes: 64
				intoBuffer: buf];
		[sha1 updateWithBuffer: buf
				ofSize: len];
				length: len];
	}
	[f close];

	TEST(@"-[digest]",
	    !memcmp([sha1 digest], testfile_sha1, OF_SHA1_DIGEST_SIZE))

	EXPECT_EXCEPTION(@"Detect invalid call of -[updateWithBuffer]",
	    OFHashAlreadyCalculatedException, [sha1 updateWithBuffer: ""
							      ofSize: 1])
	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha1 updateWithBuffer: ""
			    length: 1])

	[pool drain];
}
@end