ObjFW  Check-in [b597d49f43]

Overview
Comment:Multiple changes, see details.

* OFObject getMem: renamd to getMemWithSize:.
* OFString compare: renamed to compareTo:.
* Exceptions don't throw itself anymore.
* Exceptions include an error string now.
* Exceptions now got raise and string.
* New methods for OFFile:
* changeModeOfFile:toMode:
* changeOwnerOfFile:toOwner:andGroup:
* delete:
* link:to:
* symlink:to:
* OFFile isEndOfFile renamd to atEndOfFile
* OFNotImplementedExeception newWithObject:andMethod renamed to
newWithObject:andSelector:.
* Tests updated accordingly.
* TODO list added.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b597d49f43757f7b3da49044b2f25ca9fa84dd6ae18ff5e44b082bd3e3b66747
User & Date: js on 2008-10-08 23:15:26
Other Links: manifest | tags
Context
2008-10-09
00:25
Multiple changes, see details. check-in: 7a49441656 user: js tags: trunk
2008-10-08
23:15
Multiple changes, see details. check-in: b597d49f43 user: js tags: trunk
2008-10-07
22:04
#import <stdint.h> was missing. check-in: 1c99e71818 user: js tags: trunk
Changes

Added TODO version [3bc4d8c53a].

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OFArray
OFDictionary
OFSortedArray
OFSocket
OFAutoreleasePool

OFStack
OFQueue

OFXMLParser
OFHash [cryptographic]

OFSortedQueue

OFTLSSocket
OFXMPPClient

Modified src/OFCString.h from [b9bde22b67] to [6da69d89f7].

18
19
20
21
22
23
24
25
26
27
{
	char   *string;
}

- initWithCString: (char*)str;
- (char*)cString;
- (OFString*)clone;
- (int)compare: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end







|


18
19
20
21
22
23
24
25
26
27
{
	char   *string;
}

- initWithCString: (char*)str;
- (char*)cString;
- (OFString*)clone;
- (int)compareTo: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end

Modified src/OFCString.m from [b967cecc4b] to [dae2c6c4a3].

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
50
51
{
	if ((self = [super init])) {
		if (str == NULL) {
			length = 0;
			string = NULL;
		} else {
			length = strlen(str);
			string = [self getMem: length + 1];
			memcpy(string, str, length + 1);
		}
	}
	return self;
}

- (char*)cString
{
	return string;
}

- (OFString*)clone
{
	return [OFString newWithCString: string];
}

- (int)compare: (OFString*)str
{
	return strcmp(string, [str cString]);
}

- (OFString*)append: (OFString*)str
{
	char   *newstr;







|
















|







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
50
51
{
	if ((self = [super init])) {
		if (str == NULL) {
			length = 0;
			string = NULL;
		} else {
			length = strlen(str);
			string = [self getMemWithSize: length + 1];
			memcpy(string, str, length + 1);
		}
	}
	return self;
}

- (char*)cString
{
	return string;
}

- (OFString*)clone
{
	return [OFString newWithCString: string];
}

- (int)compareTo: (OFString*)str
{
	return strcmp(string, [str cString]);
}

- (OFString*)append: (OFString*)str
{
	char   *newstr;

Modified src/OFConstCString.h from [d27a028e68] to [275b3732d6].

15
16
17
18
19
20
21
22
23
{
	const char *string;
}

- initWithConstCString: (const char*)str;
- (const char*)cString;
- (OFString*)clone;
- (int)compare: (OFString*)str;
@end







|

15
16
17
18
19
20
21
22
23
{
	const char *string;
}

- initWithConstCString: (const char*)str;
- (const char*)cString;
- (OFString*)clone;
- (int)compareTo: (OFString*)str;
@end

Modified src/OFConstCString.m from [d6fb406d96] to [8e3e77d979].

33
34
35
36
37
38
39
40
41
42
43
44
}

- (OFString*)clone
{
	return [OFString newWithConstCString: string];
}

- (int)compare: (OFString*)str
{
	return strcmp(string, [str cString]);
}
@end







|




33
34
35
36
37
38
39
40
41
42
43
44
}

- (OFString*)clone
{
	return [OFString newWithConstCString: string];
}

- (int)compareTo: (OFString*)str
{
	return strcmp(string, [str cString]);
}
@end

Modified src/OFConstWideCString.h from [357f188ce4] to [47a8761c52].

17
18
19
20
21
22
23
24
25
{
	const wchar_t *string;
}

- initWithConstWideCString: (const wchar_t*)wstr;
- (const wchar_t*)wcString;
- (OFString*)clone;
- (int)compare: (OFString*)str;
@end







|

17
18
19
20
21
22
23
24
25
{
	const wchar_t *string;
}

- initWithConstWideCString: (const wchar_t*)wstr;
- (const wchar_t*)wcString;
- (OFString*)clone;
- (int)compareTo: (OFString*)str;
@end

Modified src/OFConstWideCString.m from [1c21e29078] to [700b4e543c].

33
34
35
36
37
38
39
40
41
42
43
44
}

- (OFString*)clone
{
	return [OFString newWithConstWideCString: string];
}

- (int)compare: (OFString*)str
{
	return wcscmp(string, [str wcString]);
}
@end







|




33
34
35
36
37
38
39
40
41
42
43
44
}

- (OFString*)clone
{
	return [OFString newWithConstWideCString: string];
}

- (int)compareTo: (OFString*)str
{
	return wcscmp(string, [str wcString]);
}
@end

Modified src/OFExceptions.h from [8109e7dcaa] to [03939ec239].

8
9
10
11
12
13
14


15




16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stddef.h>
#import "OFObject.h"



@interface OFException: OFObject




+ newWithObject: (id)obj;
- initWithObject: (id)obj;



@end

@interface OFNoMemException: OFException
+ newWithObject: (id)obj
	andSize: (size_t)size;
- initWithObject: (id)obj
	 andSize: (size_t)size;
@end

@interface OFNotImplementedException: OFException
+ newWithObject: (id)obj
      andMethod: (const char*)method;
- initWithObject: (id)obj
       andMethod: (const char*)method;
@end

@interface OFMemNotPartOfObjException: OFException
+ newWithObject: (id)obj
     andPointer: (void*)ptr;
- initWithObject: (id)obj
      andPointer: (void*)ptr;







>
>

>
>
>
>


>
>
>











|

|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stddef.h>
#import "OFObject.h"

// FIXME: Exceptions should include which type of error occoured (fopen etc.)

@interface OFException: OFObject
{
	char *errstr;
}

+ newWithObject: (id)obj;
- initWithObject: (id)obj;
- free;
- (void)raise;
- (char*)string;
@end

@interface OFNoMemException: OFException
+ newWithObject: (id)obj
	andSize: (size_t)size;
- initWithObject: (id)obj
	 andSize: (size_t)size;
@end

@interface OFNotImplementedException: OFException
+ newWithObject: (id)obj
    andSelector: (SEL)sel;
- initWithObject: (id)obj
     andSelector: (SEL)sel;
@end

@interface OFMemNotPartOfObjException: OFException
+ newWithObject: (id)obj
     andPointer: (void*)ptr;
- initWithObject: (id)obj
      andPointer: (void*)ptr;

Modified src/OFExceptions.m from [37b58b7cb0] to [6d13800ff5].

1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23















24




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

40
41
42
43
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
/*
 * Copyright (c) 2008
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stdio.h>


#import "OFExceptions.h"

@implementation OFException
+ newWithObject: (id)obj
{
	return [[OFException alloc] initWithObject: obj];
}

- initWithObject: (id)obj
{
	self = [super init];















	@throw self;




	return self;
}
@end

@implementation OFNoMemException
+ newWithObject: (id)obj
	andSize: (size_t)size
{
	return [[OFNoMemException alloc] initWithObject: obj
						andSize: size];
}

- initWithObject: (id)obj
	 andSize: (size_t)size
{

	fprintf(stderr, "ERROR: Could not allocate %zu bytes for object %s!\n",
	    size, [obj name]);

	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFNotImplementedException
+ newWithObject: (id)obj
      andMethod: (const char*)method
{
	return [[OFNotImplementedException alloc] initWithObject: obj
						       andMethod: method];
}

- initWithObject: (id)obj
       andMethod: (const char*)method
{


	fprintf(stderr, "ERROR: Requested method %s not implemented in %s!\n",
	    method, [obj name]);

	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFMemNotPartOfObjException
+ newWithObject: (id)obj
     andPointer: (void*)ptr
{
	return [[OFMemNotPartOfObjException alloc] initWithObject: obj
						       andPointer: ptr];
}

- initWithObject: (id)obj
      andPointer: (void*)ptr
{

	fprintf(stderr, "ERROR: Memory at %p was not allocated as part of "

	    "object %s!\n"
	    "ERROR: -> Not changing memory allocation!\n"
	    "ERROR: (Hint: It is possible that you tried to free the same "
	    "memory twice!)\n", ptr, [obj name]);

	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFOverflowException
+ newWithObject: (id)obj
{
	return [[OFOverflowException alloc] initWithObject: obj];
}

- initWithObject: (id)obj
{

	fprintf(stderr, "ERROR: Overflow in object %s!\n", [obj name]);


	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFOpenFileFailedException
+ newWithObject: (id)obj
	andPath: (const char*)path
	andMode: (const char*)mode
{
	return [[OFOpenFileFailedException alloc] initWithObject: obj
							 andPath: path
							 andMode: mode];
}

- initWithObject: (id)obj
	 andPath: (const char*)path
	 andMode: (const char*)mode
{

	fprintf(stderr, "ERROR: Failed to open file %s with mode %s in "
	    "object %s!\n", path, mode, [self name]);

	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFReadOrWriteFailedException
+ newWithObject: (id)obj
	andSize: (size_t)size
      andNItems: (size_t)nitems
{
	return [[OFReadOrWriteFailedException alloc] initWithObject: obj
							    andSize: size
							  andNItems: nitems];
}
@end

@implementation OFReadFailedException
- initWithObject: (id)obj
	 andSize: (size_t)size
       andNItems: (size_t)nitems
{

	fprintf(stderr, "ERROR: Failed to read %zu items of size %zu in "
	    "object %s!\n", nitems, size, [obj name]);

	self = [super init];
	@throw self;
	return self;
}
@end

@implementation OFWriteFailedException
- initWithObject: (id)obj
	 andSize: (size_t)size
       andNItems: (size_t)nitems
{

	fprintf(stderr, "ERROR: Failed to write %zu items of size %zu in "
	    "object %s!\n", nitems, size, [obj name]);

	self = [super init];
	@throw self;
	return self;
}
@end












>
>










|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
|














>
|
|

<
<






|


|



|

>
>
|
|

<
<















>
|
>
|
|
|
|

<
<












>
|
>

<
<


















>
|
|

<
<




















>
|
|

<
<









>
|
|

<
<



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
/*
 * Copyright (c) 2008
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stdio.h>
#import <stdlib.h>

#import "OFExceptions.h"

@implementation OFException
+ newWithObject: (id)obj
{
	return [[OFException alloc] initWithObject: obj];
}

- initWithObject: (id)obj
{
	if ((self = [super init]))
		errstr = NULL;

	return self;
}

- free
{
	if (errstr != NULL)
		free(errstr);

	return [super free];
}

- (void)raise
{
	@throw self;
}

- (char*)string
{
	return errstr;
}
@end

@implementation OFNoMemException
+ newWithObject: (id)obj
	andSize: (size_t)size
{
	return [[OFNoMemException alloc] initWithObject: obj
						andSize: size];
}

- initWithObject: (id)obj
	 andSize: (size_t)size
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Could not allocate %zu bytes for "
		    "object of class %s!\n", size, [obj name]);



	return self;
}
@end

@implementation OFNotImplementedException
+ newWithObject: (id)obj
    andSelector: (SEL)sel
{
	return [[OFNotImplementedException alloc] initWithObject: obj
						     andSelector: sel];
}

- initWithObject: (id)obj
     andSelector: (SEL)sel
{
	if ((self = [super init]))
		/* FIXME: Is casting SEL to char* portable? */
		asprintf(&errstr, "ERROR: Requested selector %s not "
		    "implemented in %s!\n", (char*)sel, [obj name]);



	return self;
}
@end

@implementation OFMemNotPartOfObjException
+ newWithObject: (id)obj
     andPointer: (void*)ptr
{
	return [[OFMemNotPartOfObjException alloc] initWithObject: obj
						       andPointer: ptr];
}

- initWithObject: (id)obj
      andPointer: (void*)ptr
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Memory at %p was not allocated as "
		    "part of object of class\n"
		    "ERROR: %s!\n"
		    "ERROR: -> Not changing memory allocation!\n"
		    "ERROR: (Hint: It is possible that you tried to free the "
		    "same memory twice!)\n", ptr, [obj name]);



	return self;
}
@end

@implementation OFOverflowException
+ newWithObject: (id)obj
{
	return [[OFOverflowException alloc] initWithObject: obj];
}

- initWithObject: (id)obj
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Overflow in object of class %s!\n",
		    [obj name]);



	return self;
}
@end

@implementation OFOpenFileFailedException
+ newWithObject: (id)obj
	andPath: (const char*)path
	andMode: (const char*)mode
{
	return [[OFOpenFileFailedException alloc] initWithObject: obj
							 andPath: path
							 andMode: mode];
}

- initWithObject: (id)obj
	 andPath: (const char*)path
	 andMode: (const char*)mode
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Failed to open file %s with mode %s "
		    "in object of class %s!\n", path, mode, [self name]);



	return self;
}
@end

@implementation OFReadOrWriteFailedException
+ newWithObject: (id)obj
	andSize: (size_t)size
      andNItems: (size_t)nitems
{
	return [[OFReadOrWriteFailedException alloc] initWithObject: obj
							    andSize: size
							  andNItems: nitems];
}
@end

@implementation OFReadFailedException
- initWithObject: (id)obj
	 andSize: (size_t)size
       andNItems: (size_t)nitems
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Failed to read %zu items of size "
		    "%zu in object of class %s!\n", nitems, size, [obj name]);



	return self;
}
@end

@implementation OFWriteFailedException
- initWithObject: (id)obj
	 andSize: (size_t)size
       andNItems: (size_t)nitems
{
	if ((self = [super init]))
		asprintf(&errstr, "ERROR: Failed to write %zu items of size "
		    "%zu in object of class %s!\n", nitems, size, [obj name]);



	return self;
}
@end

Modified src/OFFile.h from [f1d0a00de8] to [fb39a1e440].

16
17
18
19
20
21
22











23
24
25
26
27
28
29
30
31
32
33
34
35
@interface OFFile: OFObject
{
	FILE *fp;
}

+ newWithPath: (const char*)path
      andMode: (const char*)mode;











- initWithPath: (const char*)path
       andMode: (const char*)mode;
- free;
- (BOOL)isEndOfFile;
- (size_t)readIntoBuffer: (char*)buf
		withSize: (size_t)size
	       andNItems: (size_t)nItems;
- (char*)readWithSize: (size_t)size
	    andNItems: (size_t)nitems;
- (size_t)writeBuffer: (char*)buf
	     withSize: (size_t)size
	    andNItems: (size_t)nitems;
@end







>
>
>
>
>
>
>
>
>
>
>



|









16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@interface OFFile: OFObject
{
	FILE *fp;
}

+ newWithPath: (const char*)path
      andMode: (const char*)mode;
+ (int)changeModeOfFile: (const char*)path
		 toMode: (mode_t)mode;
+ (int)changeOwnerOfFile: (const char*)path
		 toOwner: (uid_t)owner
		andGroup: (gid_t)group;
+ (int)delete: (const char*)path;
+ (int)link: (const char*)src
	 to: (const char*)dest;
+ (int)symlink: (const char*)src
	    to: (const char*)dest;

- initWithPath: (const char*)path
       andMode: (const char*)mode;
- free;
- (BOOL)atEndOfFile;
- (size_t)readIntoBuffer: (char*)buf
		withSize: (size_t)size
	       andNItems: (size_t)nItems;
- (char*)readWithSize: (size_t)size
	    andNItems: (size_t)nitems;
- (size_t)writeBuffer: (char*)buf
	     withSize: (size_t)size
	    andNItems: (size_t)nitems;
@end

Modified src/OFFile.m from [485706b49a] to [ab4b7dd898].

1
2
3
4
5
6
7
8
9
10
11
12
13



14
15
16
17
18
19
20
21
22
23
24



































25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
/*
 * Copyright (c) 2008
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stdio.h>
#import <stdint.h>




#import "OFFile.h"
#import "OFExceptions.h"

@implementation OFFile
+ newWithPath: (const char*)path
      andMode: (const char*)mode
{
	return [[OFFile alloc] initWithPath: path
				    andMode: mode];
}




































- initWithPath: (const char*)path
       andMode: (const char*)mode
{
	if ((self = [super init])) {
		if ((fp = fopen(path, mode)) == NULL) {
			[self free];
			return nil;
		}
	}
	return self;
}

- free
{
	fclose(fp);
	return [super free];
}

- (BOOL)isEndOfFile
{
	return feof(fp);
}

- (size_t)readIntoBuffer: (char*)buf
		withSize: (size_t)size
	       andNItems: (size_t)nitems
{
	size_t ret;

	if ((ret = fread(buf, size, nitems, fp)) == 0 && ![self isEndOfFile])
		[OFReadFailedException newWithObject: self
					     andSize: size
					   andNItems: nitems];

	return ret;
}

- (char*)readWithSize: (size_t)size
	    andNItems: (size_t)nitems
{
	uint64_t memsize;
	char *ret;
       
	if (size >= 0xFFFFFFFF || nitems >= 0xFFFFFFFF ||
	    (memsize = (uint64_t)nitems * size) > 0xFFFFFFFF) {
		[OFOverflowException newWithObject: self];
		return NULL;
	}
	
	ret = [self getMem: (size_t)memsize];

	@try {
		[self readIntoBuffer: ret
			    withSize: size
			   andNItems: nitems];
	} @catch (OFReadFailedException *e) {
		[self freeMem: ret];













>
>
>











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



















|










|
|
|
|












|



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
/*
 * Copyright (c) 2008
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import <stdio.h>
#import <stdint.h>
#import <unistd.h>
#import <sys/types.h>
#import <sys/stat.h>

#import "OFFile.h"
#import "OFExceptions.h"

@implementation OFFile
+ newWithPath: (const char*)path
      andMode: (const char*)mode
{
	return [[OFFile alloc] initWithPath: path
				    andMode: mode];
}

+ (int)changeModeOfFile: (const char*)path
		 toMode: (mode_t)mode
{
	// FIXME: On error, throw exception
	return chmod(path, mode);
}

+ (int)changeOwnerOfFile: (const char*)path
		 toOwner: (uid_t)owner
		andGroup: (gid_t)group
{
	// FIXME: On error, throw exception
	return chown(path, owner, group);
}

+ (int)delete: (const char*)path
{
	// FIXME: On error, throw exception
	return unlink(path);
}

+ (int)link: (const char*)src
	 to: (const char*)dest
{
	// FIXME: On error, throw exception
	return link(src, dest);
}

+ (int)symlink: (const char*)src
	    to: (const char*)dest
{
	// FIXME: On error, throw exception
	return symlink(src, dest);
}

- initWithPath: (const char*)path
       andMode: (const char*)mode
{
	if ((self = [super init])) {
		if ((fp = fopen(path, mode)) == NULL) {
			[self free];
			return nil;
		}
	}
	return self;
}

- free
{
	fclose(fp);
	return [super free];
}

- (BOOL)atEndOfFile
{
	return feof(fp);
}

- (size_t)readIntoBuffer: (char*)buf
		withSize: (size_t)size
	       andNItems: (size_t)nitems
{
	size_t ret;

	if ((ret = fread(buf, size, nitems, fp)) == 0 && !feof(fp))
		[[OFReadFailedException newWithObject: self
					      andSize: size
					    andNItems: nitems] raise];

	return ret;
}

- (char*)readWithSize: (size_t)size
	    andNItems: (size_t)nitems
{
	uint64_t memsize;
	char *ret;
       
	if (size >= 0xFFFFFFFF || nitems >= 0xFFFFFFFF ||
	    (memsize = (uint64_t)nitems * size) > 0xFFFFFFFF) {
		[[OFOverflowException newWithObject: self] raise];
		return NULL;
	}
	
	ret = [self getMemWithSize: (size_t)memsize];

	@try {
		[self readIntoBuffer: ret
			    withSize: size
			   andNItems: nitems];
	} @catch (OFReadFailedException *e) {
		[self freeMem: ret];
91
92
93
94
95
96
97
98
99
100
101
102
103
104
	     withSize: (size_t)size
	    andNItems: (size_t)nitems
{
	size_t ret;

	if ((ret = fwrite(buf, size, nitems, fp)) == 0 &&
	    size != 0 && nitems != 0)
		[OFWriteFailedException newWithObject: self
					      andSize: size
					    andNItems: nitems];
	
	return ret;
}
@end







|
|
|




129
130
131
132
133
134
135
136
137
138
139
140
141
142
	     withSize: (size_t)size
	    andNItems: (size_t)nitems
{
	size_t ret;

	if ((ret = fwrite(buf, size, nitems, fp)) == 0 &&
	    size != 0 && nitems != 0)
		[[OFWriteFailedException newWithObject: self
					       andSize: size
					     andNItems: nitems] raise];
	
	return ret;
}
@end

Modified src/OFObject.h from [b47bfb1d54] to [20796294ad].

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

@interface OFObject: Object
{
	struct __ofobject_allocated_mem *__mem_pool;
}

- init;
- (void*)getMem: (size_t)size;
- (void*)resizeMem: (void*)ptr
	    toSize: (size_t)size;
- (void)freeMem: (void*)ptr;
- free;
@end







|





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

@interface OFObject: Object
{
	struct __ofobject_allocated_mem *__mem_pool;
}

- init;
- (void*)getMemWithSize: (size_t)size;
- (void*)resizeMem: (void*)ptr
	    toSize: (size_t)size;
- (void)freeMem: (void*)ptr;
- free;
@end

Modified src/OFObject.m from [deca1fe096] to [c1de4ea884].

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

33
34
35
36
37
38
39
40
41
42
43
44
45
46
- init
{
	if ((self = [super init]) != nil)
		__mem_pool  = NULL;
	return self;
}

- (void*)getMem: (size_t)size
{
	struct __ofobject_allocated_mem *iter;

	if ((iter = malloc(sizeof(struct __ofobject_allocated_mem))) == NULL) {
		[OFNoMemException newWithObject: self
					andSize: sizeof(struct
						     __ofobject_allocated_mem)];

		return NULL;
	}

	if ((iter->ptr = malloc(size)) == NULL) {
		free(iter);
		[OFNoMemException newWithObject: self
					andSize: size];
		return NULL;
	}

	iter->next = NULL;
	iter->prev = __mem_pool;

	if (__mem_pool != NULL)







|




|

|
>





|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
- init
{
	if ((self = [super init]) != nil)
		__mem_pool  = NULL;
	return self;
}

- (void*)getMemWithSize: (size_t)size
{
	struct __ofobject_allocated_mem *iter;

	if ((iter = malloc(sizeof(struct __ofobject_allocated_mem))) == NULL) {
		[[OFNoMemException newWithObject: self
					andSize: sizeof(struct
						     __ofobject_allocated_mem)
		    ] raise];
		return NULL;
	}

	if ((iter->ptr = malloc(size)) == NULL) {
		free(iter);
		[[OFNoMemException newWithObject: self
					andSize: size] raise];
		return NULL;
	}

	iter->next = NULL;
	iter->prev = __mem_pool;

	if (__mem_pool != NULL)
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
	    toSize: (size_t)size
{
	struct __ofobject_allocated_mem *iter;

	for (iter = __mem_pool; iter != NULL; iter = iter->prev) {
		if (iter->ptr == ptr) {
			if ((ptr = realloc(iter->ptr, size)) == NULL) {
				[OFNoMemException newWithObject: self
							andSize: size];
				return NULL;
			}
			
			iter->ptr = ptr;
			return ptr;
		}
	}

	[OFMemNotPartOfObjException newWithObject: self
				       andPointer: ptr];
	return NULL;
}

- (void)freeMem: (void*)ptr;
{
	struct __ofobject_allocated_mem *iter;








|
|








|
|







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
	    toSize: (size_t)size
{
	struct __ofobject_allocated_mem *iter;

	for (iter = __mem_pool; iter != NULL; iter = iter->prev) {
		if (iter->ptr == ptr) {
			if ((ptr = realloc(iter->ptr, size)) == NULL) {
				[[OFNoMemException newWithObject: self
							 andSize: size] raise];
				return NULL;
			}
			
			iter->ptr = ptr;
			return ptr;
		}
	}

	[[OFMemNotPartOfObjException newWithObject: self
					andPointer: ptr] raise];
	return NULL;
}

- (void)freeMem: (void*)ptr;
{
	struct __ofobject_allocated_mem *iter;

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
			free(iter);
			free(ptr);

			return;
		}
	}

	[OFMemNotPartOfObjException newWithObject: self
				       andPointer: ptr];
}

- free
{
	struct __ofobject_allocated_mem *iter, *iter2;

	for (iter = __mem_pool; iter != NULL; iter = iter2) {







|
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
			free(iter);
			free(ptr);

			return;
		}
	}

	[[OFMemNotPartOfObjException newWithObject: self
					andPointer: ptr] raise];
}

- free
{
	struct __ofobject_allocated_mem *iter, *iter2;

	for (iter = __mem_pool; iter != NULL; iter = iter2) {

Modified src/OFString.h from [9a4ef12426] to [6806a7a1f1].

18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
	size_t length;
}

+ newWithConstCString: (const char*)str;
+ newWithConstWideCString: (const wchar_t*)str;
+ newWithCString: (char*)str;
+ newWithWideCString: (wchar_t*)str;

- (char*)cString;
- (wchar_t*)wcString;
- (size_t)length;
- (OFString*)setTo: (OFString*)str;
- (OFString*)clone;
- (int)compare: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end







>





|


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
	size_t length;
}

+ newWithConstCString: (const char*)str;
+ newWithConstWideCString: (const wchar_t*)str;
+ newWithCString: (char*)str;
+ newWithWideCString: (wchar_t*)str;

- (char*)cString;
- (wchar_t*)wcString;
- (size_t)length;
- (OFString*)setTo: (OFString*)str;
- (OFString*)clone;
- (int)compareTo: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end

Modified src/OFString.m from [7599c02c21] to [a57e73bfa3].

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
+ newWithWideCString: (wchar_t*)str
{
	return [[OFWideCString alloc] initWithWideCString: str];
}

- (char*)cString
{
	[OFNotImplementedException newWithObject: self
				       andMethod: "cString"];
	return NULL;
}

- (wchar_t*)wcString
{
	[OFNotImplementedException newWithObject: self
				       andMethod: "wcString"];
	return NULL;
}

- (size_t)length
{
	return length;
}

- (OFString*)setTo: (OFString*)str
{
	[self free];
	self = [str clone];
	return self;
}

- (OFString*)clone
{
	[OFNotImplementedException newWithObject: self
				       andMethod: "clone"];
	return nil;
}

- (int)compare: (OFString*)str
{
	[OFNotImplementedException newWithObject: self
				       andMethod: "compare:"];

	return 0;
}

- (OFString*)append: (OFString*)str
{
	[OFNotImplementedException newWithObject: self
				       andMethod: "append:"];
	return nil;
}
@end







|
|





|
|

















|
|



|

|
|
>





|
|



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
+ newWithWideCString: (wchar_t*)str
{
	return [[OFWideCString alloc] initWithWideCString: str];
}

- (char*)cString
{
	[[OFNotImplementedException newWithObject: self
				      andSelector: @selector(cString)] raise];
	return NULL;
}

- (wchar_t*)wcString
{
	[[OFNotImplementedException newWithObject: self
				      andSelector: @selector(wcString)] raise];
	return NULL;
}

- (size_t)length
{
	return length;
}

- (OFString*)setTo: (OFString*)str
{
	[self free];
	self = [str clone];
	return self;
}

- (OFString*)clone
{
	[[OFNotImplementedException newWithObject: self
				      andSelector: @selector(clone)] raise];
	return nil;
}

- (int)compareTo: (OFString*)str
{
	[[OFNotImplementedException newWithObject: self
				      andSelector: @selector(compareTo:)]
	    raise];
	return 0;
}

- (OFString*)append: (OFString*)str
{
	[[OFNotImplementedException newWithObject: self
				      andSelector: @selector(append:)] raise];
	return nil;
}
@end

Modified src/OFWideCString.h from [80e2b819bc] to [3956b2854d].

18
19
20
21
22
23
24
25
26
27
{
	wchar_t	*string;
}

- initWithWideCString: (wchar_t*)str;
- (wchar_t*)wcString;
- (OFString*)clone;
- (int)compare: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end







|


18
19
20
21
22
23
24
25
26
27
{
	wchar_t	*string;
}

- initWithWideCString: (wchar_t*)str;
- (wchar_t*)wcString;
- (OFString*)clone;
- (int)compareTo: (OFString*)str;
- (OFString*)append: (OFString*)str;
@end

Modified src/OFWideCString.m from [87572356ea] to [581afa2b30].

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
50
51
{
	if ((self = [super init])) {
		if (str == NULL) {
			length = 0;
			string = NULL;
		} else {
			length = wcslen(str);

			string = [self getMem: (length + 1) * sizeof(wchar_t)];
			wmemcpy(string, str, length + 1);
		}
	}
	return self;
}

- (wchar_t*)wcString
{
	return string;
}

- (OFString*)clone
{
	return [OFString newWithWideCString: string];
}

- (int)compare: (OFString*)str
{
	return wcscmp(string, [str wcString]);
}

- (OFString*)append: (OFString*)str
{
	wchar_t	*newstr;







>
|
















|







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
50
51
52
{
	if ((self = [super init])) {
		if (str == NULL) {
			length = 0;
			string = NULL;
		} else {
			length = wcslen(str);
			string = [self getMemWithSize: (length + 1) *
							   sizeof(wchar_t)];
			wmemcpy(string, str, length + 1);
		}
	}
	return self;
}

- (wchar_t*)wcString
{
	return string;
}

- (OFString*)clone
{
	return [OFString newWithWideCString: string];
}

- (int)compareTo: (OFString*)str
{
	return wcscmp(string, [str wcString]);
}

- (OFString*)append: (OFString*)str
{
	wchar_t	*newstr;

Modified tests/OFObject/OFObject.m from [436ef088ef] to [15b4656509].

12
13
14
15
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
#import <stdio.h>
#import <stdlib.h>
#import <stdbool.h>

#import "OFObject.h"
#import "OFExceptions.h"

#define CATCH_EXCEPTION(code, exception)	\
	caught = false;				\
	@try {					\
		code;				\
	} @catch (exception *e) {		\
		caught = true;			\


		puts("CAUGHT! Resuming...");	\
	}					\
	if (!caught) {				\
		puts("NOT CAUGHT!");		\
		return 1;			\
	}

int
main()
{
	OFObject *obj = [OFObject new];
	bool caught;
	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 getMem: 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 getMem: 4096];
	q = [obj getMem: 4096];
	r = [obj getMem: 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 getMem: 4294967295U], OFNoMemException)

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

	puts("Trying to resize that 1 byte to more than possible...");
	CATCH_EXCEPTION(p = [obj resizeMem: p toSize: 4294967295U],
	    OFNoMemException)
	
	/* TODO: Test if freeing object frees all memory */

	return 0;
}







|
|
|
|
|
|
>
>
|
|
|
|
|
















|













|
|
|

















|


|









12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
#import <stdio.h>
#import <stdlib.h>
#import <stdbool.h>

#import "OFObject.h"
#import "OFExceptions.h"

#define CATCH_EXCEPTION(code, exception)		\
	caught = false;					\
	@try {						\
		code;					\
	} @catch (exception *e) {			\
		caught = true;				\
		puts("CAUGHT! Error string was:");	\
		fputs([e string], stdout);		\
		puts("Resuming...");			\
	}						\
	if (!caught) {					\
		puts("NOT CAUGHT!");			\
		return 1;				\
	}

int
main()
{
	OFObject *obj = [OFObject new];
	bool caught;
	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 getMemWithSize: 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 getMemWithSize: 4096];
	q = [obj getMemWithSize: 4096];
	r = [obj getMemWithSize: 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 getMemWithSize: 4294967295U], OFNoMemException)

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

	puts("Trying to resize that 1 byte to more than possible...");
	CATCH_EXCEPTION(p = [obj resizeMem: p toSize: 4294967295U],
	    OFNoMemException)
	
	/* TODO: Test if freeing object frees all memory */

	return 0;
}

Modified tests/OFString/OFString.m from [453b60b8cb] to [c0f30552d4].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	OFString *s4 = [OFString newWithConstCString: NULL];

	[s2 append: [OFString newWithConstCString: "123"]];
	s3 = [s1 clone];

	[s4 setTo: s2];

	if (![s1 compare: s3])
		puts("s1 and s3 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (![s2 compare: s4])
		puts("s2 and s4 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (!strcmp([[s1 append: s2] cString], "test123"))







|






|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	OFString *s4 = [OFString newWithConstCString: NULL];

	[s2 append: [OFString newWithConstCString: "123"]];
	s3 = [s1 clone];

	[s4 setTo: s2];

	if (![s1 compareTo: s3])
		puts("s1 and s3 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (![s2 compareTo: s4])
		puts("s2 and s4 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (!strcmp([[s1 append: s2] cString], "test123"))

Modified tests/OFWideString/OFWideString.m from [181ff63706] to [1a00935b6a].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
	OFString *s4 = [OFString newWithConstWideCString: NULL];

	[s2 append: [OFString newWithConstWideCString: L"123"]];
	s3 = [s1 clone];

	[s4 setTo: s2];

	if (![s1 compare: s3])
		puts("s1 and s3 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (![s2 compare: s4])
		puts("s2 and s4 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (!wcscmp([[s1 append: s2] wcString], L"test123"))







|






|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
	OFString *s4 = [OFString newWithConstWideCString: NULL];

	[s2 append: [OFString newWithConstWideCString: L"123"]];
	s3 = [s1 clone];

	[s4 setTo: s2];

	if (![s1 compareTo: s3])
		puts("s1 and s3 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (![s2 compareTo: s4])
		puts("s2 and s4 match! GOOD!");
	else {
		puts("s1 and s3 don't match!");
		return 1;
	}

	if (!wcscmp([[s1 append: s2] wcString], L"test123"))