ObjFW  Check-in [ba7219b1b6]

Overview
Comment:Add inital OFSocket class.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ba7219b1b6c58507bddb2ae7e382b3098957676f4d033e68376cbad3441f07c5
User & Date: js on 2008-12-07 02:35:59
Other Links: manifest | tags
Context
2008-12-07
02:53
Add writeCString and writeWideCString to OFStream. check-in: 6ed7c33611 user: js tags: trunk
02:35
Add inital OFSocket class. check-in: ba7219b1b6 user: js tags: trunk
2008-12-06
19:50
Update to lastest rev of buildsys. check-in: 7d7c87f110 user: js tags: trunk
Changes

Modified src/Makefile from [b5c2942d72] to [0178ae76d8].

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
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		\
       OFXMLFactory.m

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












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

Modified src/OFFile.m from [af02f63c5b] to [ecb56994e1].

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	ret = [self getMemForNItems: nitems
			     ofSize: size];

	@try {
		[self readNItems: nitems
			  ofSize: size
		      intoBuffer: ret];
	} @catch (OFReadFailedException *e) {
		[self freeMem: ret];
		@throw e;
		return NULL;
	}

	return ret;
}

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







|

|
<







116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
	ret = [self getMemForNItems: nitems
			     ofSize: size];

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

	}

	return ret;
}

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

Added src/OFSocket.h version [4a5db4859f].





































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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: (uint8_t*)buf;
@end

Added src/OFSocket.m version [b2671e0dfd].











































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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 <stdlib.h>
#import <string.h>
#import <unistd.h>

#import "OFSocket.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: (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;
}
@end

Modified tests/Makefile from [06e32c1877] to [48ff136ddb].

1
2
3

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

	  OFString	\
	  OFList	\
	  OFXMLFactory

include ../buildsys.mk



>





1
2
3
4
5
6
7
8
9
SUBDIRS = OFObject	\
	  OFArray	\
	  OFHashes	\
	  OFSocket	\
	  OFString	\
	  OFList	\
	  OFXMLFactory

include ../buildsys.mk

Added 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

Added tests/OFSocket/OFSocket.m version [53eb38c1df].

































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * 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"

const char *sendstr = "GET / HTTP/1.1\r\nHost: webkeks.org\r\n\r\n";

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 writeNBytes: strlen(sendstr)
		       fromBuffer: (uint8_t*)sendstr];

		puts((char*)[sock readNBytes: 1024]);

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

	return 0;
}