Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -16,10 +16,11 @@ OFList.m \ OFMutableString.m \ OFNumber.m \ OFObject.m \ ${OFPLUGIN_M} \ + OFSocket.m \ OFStream.m \ OFString.m \ OFTCPSocket.m \ OFThread.m \ OFXMLFactory.m \ ADDED src/OFSocket.h Index: src/OFSocket.h ================================================================== --- src/OFSocket.h +++ src/OFSocket.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * 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. + */ + +/* + * Headers for UNIX systems + */ +#ifndef _WIN32 +#include +#include +#include +#endif + +#import "OFStream.h" + +/* + * Headers for Win32 + * + * These must be imported after objc/Object and thus OFObject! + */ +#ifdef _WIN32 +#define _WIN32_WINNT 0x0501 +#include +#include +#endif + +/** + * The OFTCPSocket class provides functions to create and use sockets. + */ +@interface OFSocket: OFStream +{ +#ifndef _WIN32 + int sock; +#else + SOCKET sock; +#endif + struct sockaddr *saddr; + socklen_t saddr_len; +} + +/** + * Enables/disables non-blocking I/O. + */ +- setBlocking: (BOOL)enable; +@end ADDED src/OFSocket.m Index: src/OFSocket.m ================================================================== --- src/OFSocket.m +++ src/OFSocket.m @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * 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" + +#include +#include + +#import "OFSocket.h" +#import "OFExceptions.h" + +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + +@implementation OFSocket +#ifdef _WIN32 ++ initialize +{ + WSADATA wsa; + + if (WSAStartup(MAKEWORD(2, 0), &wsa)) + @throw [OFInitializationFailedException newWithClass: self]; + + return self; +} +#endif + +- init +{ + self = [super init]; + + sock = INVALID_SOCKET; + saddr = NULL; + saddr_len = 0; + + return self; +} + +- (size_t)readNBytes: (size_t)size + intoBuffer: (char*)buf +{ + ssize_t ret; + + if (sock == INVALID_SOCKET) + @throw [OFNotConnectedException newWithClass: isa]; + + switch ((ret = recv(sock, buf, size, 0))) { + case 0: + @throw [OFNotConnectedException newWithClass: isa]; + case -1: + @throw [OFReadFailedException newWithClass: isa + andSize: size]; + } + + /* This is safe, as we already checked < 1 */ + return ret; +} + +- (size_t)writeNBytes: (size_t)size + fromBuffer: (const char*)buf +{ + ssize_t ret; + + if (sock == INVALID_SOCKET) + @throw [OFNotConnectedException newWithClass: isa]; + + if ((ret = send(sock, buf, size, 0)) == -1) + @throw [OFWriteFailedException newWithClass: isa + andSize: size]; + + /* This is safe, as we already checked for -1 */ + return ret; +} + +- (size_t)writeCString: (const char*)str +{ + if (sock == INVALID_SOCKET) + @throw [OFNotConnectedException newWithClass: isa]; + + return [self writeNBytes: strlen(str) + fromBuffer: str]; +} + +- setBlocking: (BOOL)enable +{ +#ifndef _WIN32 + int flags; + + if ((flags = fcntl(sock, F_GETFL)) == -1) + @throw [OFSetOptionFailedException newWithClass: isa]; + + if (enable) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(sock, F_SETFL, flags) == -1) + @throw [OFSetOptionFailedException newWithClass: isa]; +#else + u_long v = enable; + + if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) + @throw [OFSetOptionFailedException newWithClass: isa]; +#endif + + return self; +} +@end Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -144,12 +144,12 @@ andSelector: _cmd]; } - (size_t)writeCString: (const char*)str { - @throw [OFNotImplementedException newWithClass: isa - andSelector: _cmd]; + return [self writeNBytes: strlen(str) + fromBuffer: str]; } - (size_t)getCache: (char**)ptr { if (ptr != NULL) Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -7,48 +7,16 @@ * 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. */ -#include - -/* - * Headers for UNIX systems - */ -#ifndef _WIN32 -#include -#include -#include -#endif - -#import "OFStream.h" - -/* - * Headers for Win32 - * - * These must be imported after objc/Object and thus OFObject! - */ -#ifdef _WIN32 -#define _WIN32_WINNT 0x0501 -#include -#include -#endif +#import "OFSocket.h" /** * The OFTCPSocket class provides functions to create and use sockets. */ -@interface OFTCPSocket: OFStream -{ -#ifndef _WIN32 - int sock; -#else - SOCKET sock; -#endif - struct sockaddr *saddr; - socklen_t saddr_len; -} - +@interface OFTCPSocket: OFSocket {} /** * \return A new autoreleased OFTCPSocket */ + tcpSocket; @@ -95,15 +63,10 @@ * Accept an incoming connection. * \return An autoreleased OFTCPSocket for the accepted connection. */ - (OFTCPSocket*)accept; -/** - * Enables/disables non-blocking I/O. - */ -- setBlocking: (BOOL)enable; - /** * Enable or disable keep alives for the connection. */ - enableKeepAlives: (BOOL)enable; Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -10,14 +10,12 @@ */ #import "config.h" #include -#include #include #include -#include #import "OFTCPSocket.h" #import "OFExceptions.h" #ifndef INVALID_SOCKET @@ -28,22 +26,10 @@ + tcpSocket { return [[[OFTCPSocket alloc] init] autorelease]; } -#ifdef _WIN32 -+ initialize -{ - WSADATA wsa; - - if (WSAStartup(MAKEWORD(2, 0), &wsa)) - @throw [OFInitializationFailedException newWithClass: self]; - - return self; -} -#endif - - init { self = [super init]; sock = INVALID_SOCKET; @@ -204,80 +190,10 @@ newsock->saddr_len = addrlen; return newsock; } -- (size_t)readNBytes: (size_t)size - intoBuffer: (char*)buf -{ - ssize_t ret; - - if (sock == INVALID_SOCKET) - @throw [OFNotConnectedException newWithClass: isa]; - - switch ((ret = recv(sock, buf, size, 0))) { - case 0: - @throw [OFNotConnectedException newWithClass: isa]; - case -1: - @throw [OFReadFailedException newWithClass: isa - andSize: size]; - } - - /* This is safe, as we already checked < 1 */ - return ret; -} - -- (size_t)writeNBytes: (size_t)size - fromBuffer: (const char*)buf -{ - ssize_t ret; - - if (sock == INVALID_SOCKET) - @throw [OFNotConnectedException newWithClass: isa]; - - if ((ret = send(sock, buf, size, 0)) == -1) - @throw [OFWriteFailedException newWithClass: isa - andSize: size]; - - /* This is safe, as we already checked for -1 */ - return ret; -} - -- (size_t)writeCString: (const char*)str -{ - if (sock == INVALID_SOCKET) - @throw [OFNotConnectedException newWithClass: isa]; - - return [self writeNBytes: strlen(str) - fromBuffer: str]; -} - -- setBlocking: (BOOL)enable -{ -#ifndef _WIN32 - int flags; - - if ((flags = fcntl(sock, F_GETFL)) == -1) - @throw [OFSetOptionFailedException newWithClass: isa]; - - if (enable) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - if (fcntl(sock, F_SETFL, flags) == -1) - @throw [OFSetOptionFailedException newWithClass: isa]; -#else - u_long v = enable; - - if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) - @throw [OFSetOptionFailedException newWithClass: isa]; -#endif - - return self; -} - - enableKeepAlives: (BOOL)enable { int v = enable; if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v))) Index: tests/OFTCPSocket/OFTCPSocket.m ================================================================== --- tests/OFTCPSocket/OFTCPSocket.m +++ tests/OFTCPSocket/OFTCPSocket.m @@ -9,10 +9,11 @@ * the packaging of this file. */ #import "config.h" +#include #include #include #include #import "OFTCPSocket.h"