ObjFW  Check-in [d1a5065e69]

Overview
Comment:OFSocket -> OFTCPSocket.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d1a5065e69fc688293a47769be002e33dddde4c068f2af4be5ba53e8d7320bbb
User & Date: js on 2008-12-07 10:24:23
Other Links: manifest | tags
Context
2008-12-07
10:35
Add - close to OFStream. check-in: 657fae20a4 user: js tags: trunk
10:24
OFSocket -> OFTCPSocket. check-in: d1a5065e69 user: js tags: trunk
03:06
Remove writeWideCString as that's a bad idea. check-in: 70874cf3c5 user: js tags: trunk
Changes

Modified TODO from [e468325e51] to [f827867bc5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Tests for OFFile.

OFBase64

OFDirectory
OFDictionary
OFSortedArray
OFSocket
OFThread
OFAutoreleasePool

OFStack
OFQueue

OFPlugin
OFXMLParser

OFSortedQueue

OFTLSSocket
OFXMPPClient







<













1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
Tests for OFFile.

OFBase64

OFDirectory
OFDictionary
OFSortedArray

OFThread
OFAutoreleasePool

OFStack
OFQueue

OFPlugin
OFXMLParser

OFSortedQueue

OFTLSSocket
OFXMPPClient

Modified src/Makefile from [0178ae76d8] to [152581fb22].

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
LIB = ${LIB_PREFIX}objfw${LIB_SUFFIX}
LIB_MAJOR = 1
LIB_MINOR = 0

SRCS = OFArray.m		\
       OFExceptions.m		\
       OFHashes.m		\
       OFFile.m			\
       OFList.m			\
       OFListObject.m		\
       OFObject.m		\
       OFSocket.m		\
       OFString.m		\

       OFXMLFactory.m

INCLUDES = ${SRCS:.m=.h}	\
	   OFMacros.h		\
	   OFStream.h

include ../buildsys.mk

CPPFLAGS += -I..
OBJCFLAGS += ${LIB_CFLAGS}
LD = ${OBJC}
LDFLAGS += ${LIB_LDFLAGS}
LIBS += -lobjc











<

>













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
LIB = ${LIB_PREFIX}objfw${LIB_SUFFIX}
LIB_MAJOR = 1
LIB_MINOR = 0

SRCS = OFArray.m		\
       OFExceptions.m		\
       OFHashes.m		\
       OFFile.m			\
       OFList.m			\
       OFListObject.m		\
       OFObject.m		\

       OFString.m		\
       OFTCPSocket.m		\
       OFXMLFactory.m

INCLUDES = ${SRCS:.m=.h}	\
	   OFMacros.h		\
	   OFStream.h

include ../buildsys.mk

CPPFLAGS += -I..
OBJCFLAGS += ${LIB_CFLAGS}
LD = ${OBJC}
LDFLAGS += ${LIB_LDFLAGS}
LIBS += -lobjc

Deleted src/OFSocket.h version [e31807ae92].

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
/*
 * 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 <sys/types.h>
#import <sys/socket.h>
#import <netdb.h>

#import "OFObject.h"
#import "OFStream.h"

/**
 * The OFSocketAddress class is a class to build socket addresses.
 */
@interface OFSocketAddress: OFObject
{
	char *hoststr, portstr[6];
	struct addrinfo hints, *res;
}

/**
 * \param host The host of the address
 * \param port The port of the address
 * \param family The protocol family to use
 * \param type The socket type to use
 * \param protocol The specific protocol to use
 * \return A new OFSocketAddress
 */
+ newWithHost: (const char*)host
      andPort: (uint16_t)port
    andFamily: (int)family
      andType: (int)type
  andProtocol: (int)protocol;

/**
 * Initializes an already allocated OFSocketAddress.
 *
 * \param host The host of the address
 * \param port The port of the address
 * \param family The protocol family to use
 * \param type The socket type to use
 * \param protocol The specific protocol to use
 * \return An initialized OFSocketAddress
 */
- initWithHost: (const char*)host
       andPort: (uint16_t)port
     andFamily: (int)family
       andType: (int)type
   andProtocol: (int)protocol;

/*
 * \return The addrinfo struct for the OFSocketAddress
 */
- (struct addrinfo*)getAddressInfo;

- free;
@end

/**
 * The OFSocket class provides functions to create and use sockets.
 */
@interface OFSocket: OFObject <OFStream>
{
	int sock;
}

- free;

/**
 * Connect the OFSocket to a destination specified in an OFSocketAddress.
 *
 * \param addr A OFSocketAddress to connect to.
 */
- connect: (OFSocketAddress*)addr;

/**
 * Receive data from the socket into a buffer.
 *
 * \param buf The buffer into which the data is read
 * \param size The size of the data that should be read.
 *	  The buffer MUST be at least size big!
 * \return The number of bytes read
 */
- (size_t)readNBytes: (size_t)size
	  intoBuffer: (uint8_t*)buf;

/**
 * Receive data from the socket into a new buffer.
 *
 * \param size The size of the data that should be read
 * \return A new buffer with the data read.
 *	   It is part of the memory pool of the OFFile.
 */
- (uint8_t*)readNBytes: (size_t)size;

/**
 * Sends data from a buffer.
 *
 * \param buf The buffer from which the data is written to the file
 * \param size The size of the data that should be written
 * \return The number of bytes written
 */
- (size_t)writeNBytes: (size_t)size
	   fromBuffer: (const uint8_t*)buf;

/**
 * Sends a C string, without the trailing zero.
 *
 * \param str The C string from which the data is sent
 * \return The number of bytes written
 */
- (size_t)writeCString: (const char*)str;
@end
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































Deleted src/OFSocket.m version [9c27c4838b].

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
/*
 * 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 "config.h"

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

#import "OFSocket.h"
#import "OFExceptions.h"

@implementation OFSocketAddress
+ newWithHost: (const char*)host
      andPort: (uint16_t)port
    andFamily: (int)family
      andType: (int)type
  andProtocol: (int)protocol
{
	return [[OFSocketAddress alloc] initWithHost: host
					     andPort: port
					   andFamily: family
					     andType: type
					 andProtocol: protocol];
}

- initWithHost: (const char*)host
       andPort: (uint16_t)port
     andFamily: (int)family
       andType: (int)type
   andProtocol: (int)protocol
{
	if ((self = [super init])) {
		if (port == 0) {
			/* FIXME: Throw exception */
			[self free];
			return nil;
		}

		memset(&hints, 0, sizeof(struct addrinfo));
		hints.ai_family = family;
		hints.ai_socktype = type;
		hints.ai_protocol = protocol;

		hoststr = strdup(host);
		snprintf(portstr, 6, "%d", port);

		res = NULL;
	}

	return self;
}

- (struct addrinfo*)getAddressInfo
{
	if (res != NULL)
		return res;

	if (getaddrinfo(hoststr, portstr, &hints, &res)) {
		/* FIXME: Throw exception */
		return NULL;
	}

	return res;
}

- free
{
	free(hoststr);

	if (res != NULL)
		freeaddrinfo(res);

	return [super free];
}
@end

@implementation OFSocket
- free
{
	if (sock >= 0)
		close(sock);

	return [super free];
}

- connect: (OFSocketAddress*)addr
{
	struct addrinfo *ai, *iter;

	ai = [addr getAddressInfo];
	for (iter = ai; iter != NULL; iter = iter->ai_next) {
		if ((sock = socket(iter->ai_family, iter->ai_socktype,
		    iter->ai_protocol)) < 0)
			continue;

		if (connect(sock, iter->ai_addr, iter->ai_addrlen) < 0) {
			close(sock);
			sock = -1;
			continue;
		}

		break;
	}

	if (sock < 0) {
		/* FIXME: Throw exception */
		return nil;
	}

	return self;
}

- (size_t)readNBytes: (size_t)size
	  intoBuffer: (uint8_t*)buf
{
	ssize_t ret;

	if ((ret = recv(sock, buf, size, 0)) < 0) {
		/* FIXME: Throw exception */
		return 0;
	}

	/* This is safe, as we already checked < 0 */
	return ret;
}

- (uint8_t*)readNBytes: (size_t)size
{
	uint8_t *ret;

	ret = [self getMemWithSize: size];

	@try {
		[self readNBytes: size
		      intoBuffer: ret];
	} @catch (id exception) {
		[self freeMem: ret];
		@throw exception;
	}

	return ret;
}

- (size_t)writeNBytes: (size_t)size
	   fromBuffer: (const uint8_t*)buf
{
	ssize_t ret;

	if ((ret = send(sock, buf, size, 0)) < 0) {
		/* FIXME: Throw exception */
		return 0;
	}

	/* This is safe, as we already checked < 0 */
	return ret;
}

- (size_t)writeCString: (const char*)str
{
	return [self writeNBytes: strlen(str)
		      fromBuffer: (const uint8_t*)str];
}
@end
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































Added src/OFTCPSocket.h version [89f3d3aa72].



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 <sys/types.h>
#import <sys/socket.h>
#import <netdb.h>

#import "OFObject.h"
#import "OFStream.h"

/**
 * The OFTCPSocket class provides functions to create and use sockets.
 */
@interface OFTCPSocket: OFObject <OFStream>
{
	int sock;
}

- free;

/**
 * Connect the OFTCPSocket to the specified destination.
 *
 * \param host The host to connect to
 * \param port The port of the host to connect to
 */
- connectTo: (const char*)host
     onPort: (uint16_t)port;

/**
 * Receive data from the socket into a buffer.
 *
 * \param buf The buffer into which the data is read
 * \param size The size of the data that should be read.
 *	  The buffer MUST be at least size big!
 * \return The number of bytes read
 */
- (size_t)readNBytes: (size_t)size
	  intoBuffer: (uint8_t*)buf;

/**
 * Receive data from the socket into a new buffer.
 *
 * \param size The size of the data that should be read
 * \return A new buffer with the data read.
 *	   It is part of the memory pool of the OFFile.
 */
- (uint8_t*)readNBytes: (size_t)size;

/**
 * Sends data from a buffer.
 *
 * \param buf The buffer from which the data is written to the file
 * \param size The size of the data that should be written
 * \return The number of bytes written
 */
- (size_t)writeNBytes: (size_t)size
	   fromBuffer: (const uint8_t*)buf;

/**
 * Sends a C string, without the trailing zero.
 *
 * \param str The C string from which the data is sent
 * \return The number of bytes written
 */
- (size_t)writeCString: (const char*)str;
@end

Added src/OFTCPSocket.m version [1175a4c331].





















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "config.h"

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

#import "OFTCPSocket.h"
#import "OFExceptions.h"

@implementation OFTCPSocket
- free
{
	if (sock >= 0)
		close(sock);

	return [super free];
}

- connectTo: (const char*)host
     onPort: (uint16_t)port
{
	struct addrinfo hints, *res, *res0;
	char portstr[6];

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	snprintf(portstr, 6, "%d", port);

	if (getaddrinfo(host, portstr, &hints, &res0)) {
		/* FIXME: Throw exception */
		return NULL;
	}

	for (res = res0; res != NULL; res = res->ai_next) {
		if ((sock = socket(res->ai_family, res->ai_socktype,
		    res->ai_protocol)) < 0)
			continue;

		if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
			close(sock);
			sock = -1;
			continue;
		}

		break;
	}
	
	freeaddrinfo(res0);

	if (sock < 0) {
		/* FIXME: Throw exception */
		return nil;
	}

	return self;
}

- (size_t)readNBytes: (size_t)size
	  intoBuffer: (uint8_t*)buf
{
	ssize_t ret;

	if ((ret = recv(sock, buf, size, 0)) < 0) {
		/* FIXME: Throw exception */
		return 0;
	}

	/* This is safe, as we already checked < 0 */
	return ret;
}

- (uint8_t*)readNBytes: (size_t)size
{
	uint8_t *ret;

	ret = [self getMemWithSize: size];

	@try {
		[self readNBytes: size
		      intoBuffer: ret];
	} @catch (id exception) {
		[self freeMem: ret];
		@throw exception;
	}

	return ret;
}

- (size_t)writeNBytes: (size_t)size
	   fromBuffer: (const uint8_t*)buf
{
	ssize_t ret;

	if ((ret = send(sock, buf, size, 0)) < 0) {
		/* FIXME: Throw exception */
		return 0;
	}

	/* This is safe, as we already checked < 0 */
	return ret;
}

- (size_t)writeCString: (const char*)str
{
	return [self writeNBytes: strlen(str)
		      fromBuffer: (const uint8_t*)str];
}
@end

Modified tests/Makefile from [48ff136ddb] to [49f488ca75].

1
2
3
4
5

6
7
8
9
SUBDIRS = OFObject	\
	  OFArray	\
	  OFHashes	\
	  OFSocket	\
	  OFString	\

	  OFList	\
	  OFXMLFactory

include ../buildsys.mk



<

>




1
2
3

4
5
6
7
8
9
SUBDIRS = OFObject	\
	  OFArray	\
	  OFHashes	\

	  OFString	\
	  OFTCPSocket	\
	  OFList	\
	  OFXMLFactory

include ../buildsys.mk

Deleted tests/OFSocket/Makefile version [d3ead38df9].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PROG_NOINST = ofsocket
SRCS = OFSocket.m

include ../../buildsys.mk

CPPFLAGS += -I../../src -I../..
LIBS += -lobjc -L../../src -lobjfw

.PHONY: run

all: run
run: ${PROG_NOINST}
	rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dylib
	ln -s ../../src/libobjfw.so libobjfw.so.1
	ln -s ../../src/libobjfw.so libobjfw.so.1.0
	ln -s ../../src/libobjfw.dylib libobjfw.dylib
	LD_LIBRARY_PATH=. \
	DYLD_LIBRARY_PATH=. \
	./${PROG_NOINST}
	rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dylib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted tests/OFSocket/OFSocket.m version [cdce310541].

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
/*
 * 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 "config.h"

#import <string.h>

#import "OFSocket.h"
#import "OFExceptions.h"

int
main()
{
	OFSocketAddress *addr;
	OFSocket *sock;

	@try {
		addr = [OFSocketAddress newWithHost: "webkeks.org"
					    andPort: 80
					  andFamily: AF_UNSPEC
					    andType: SOCK_STREAM
					andProtocol: 0];
		sock = [OFSocket new];
		[sock connect: addr];
		[addr free];

		[sock writeCString: "GET / HTTP/1.1\r\n"
				    "Host: webkeks.org\r\n\r\n"];
		puts((char*)[sock readNBytes: 1024]);

		[sock free];
	} @catch(OFException *e) {
		printf("EXCEPTION: %s\n", [e cString]);
	}

	return 0;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































Added tests/OFTCPSocket/Makefile version [cafac2176f].









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PROG_NOINST = oftcpsocket
SRCS = OFTCPSocket.m

include ../../buildsys.mk

CPPFLAGS += -I../../src -I../..
LIBS += -lobjc -L../../src -lobjfw

.PHONY: run

all: run
run: ${PROG_NOINST}
	rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dylib
	ln -s ../../src/libobjfw.so libobjfw.so.1
	ln -s ../../src/libobjfw.so libobjfw.so.1.0
	ln -s ../../src/libobjfw.dylib libobjfw.dylib
	LD_LIBRARY_PATH=. \
	DYLD_LIBRARY_PATH=. \
	./${PROG_NOINST}
	rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dylib

Added tests/OFTCPSocket/OFTCPSocket.m version [6368be628d].











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 "config.h"

#import <string.h>

#import "OFTCPSocket.h"
#import "OFExceptions.h"

int
main()
{
	OFTCPSocket *sock;

	@try {
		sock = [OFTCPSocket new];
		[sock connectTo: "webkeks.org"
			 onPort: 80];
		[sock writeCString: "GET / HTTP/1.1\r\n"
				    "Host: webkeks.org\r\n\r\n"];
		puts((char*)[sock readNBytes: 1024]);
		[sock free];
	} @catch(OFException *e) {
		printf("EXCEPTION: %s\n", [e cString]);
	}

	return 0;
}