/*  Abstract class to act as a cover for sockets.
 *
 *  Copyright (c) 1996 Aleksey Sudakov <zander@cnext.crec.mipt.ru>.
 *
 *  This software is subject to the terms of the MiscKit license
 *  agreement. Refer to the license document included with the
 *  MiscKit distribution for these terms.
 *
 *  Version 1.0 BETA (16 December 1995)
 */

#import "MiscSocket.h"
//#import <misckit/MiscSocket.h>
#import <Foundation/NSCoder.h>
#import <errno.h>
#ifdef WIN32
#import <winsock.h>
#import <io.h>
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#else
#import <sys/socket.h>
extern int close(int);
extern int dup(int);
#endif WIN32
extern int errno;

@implementation MiscSocket

- init
{
	if (0 <= sock && 0 < initCount) {
		int old_errno = errno;
		close(sock);
		errno = old_errno;
	}
	initCount++;
	sock = domain = type = -1;
	return self;
}

- initWithCoder:(NSCoder *)coder
{
	[coder decodeValuesOfObjCTypes:"iii", &sock, &domain, &type];
	return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
	[coder encodeValuesOfObjCTypes:"iii", &sock, &domain, &type];
}

- initDomain:(int)aDomain type:(int)aType
{
	[self init];
	switch (aType) {
	case MiscSOCK_RAW:
		sock = socket(aDomain, SOCK_RAW, 0);
		break;
	case MiscSOCK_DGRAM:
		sock = socket(aDomain, SOCK_DGRAM, 0);
		break;
	case MiscSOCK_STREAM:
		sock = socket(aDomain, SOCK_STREAM, 0);
		break;
	default :
		sock = -1;
		errno = ESOCKTNOSUPPORT;
	}
	if (sock < 0){
		[self release];
		return nil;
		}
	domain = aDomain;
	type = aType;
	return self;
}

- close
{
	return [self init];
}

- copy
{
	return [self copyWithZone:[self zone]];
}


- copyWithZone:(NSZone *)zone
{
	MiscSocket *copy = [[[self class] allocWithZone:zone] init];
	if (sock != -1) {
		copy->sock = dup(sock);
		if (copy->sock == -1)
			return nil;
	}
	return copy;
}

- (BOOL)isClosed
{
	return (sock == -1 && domain == -1 && type == -1);
}

- (int)domain
{
	return domain;
}

- (int)socket
{
	return sock;
}

- (int)type
{
	return type;
}

@end
