/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	Socket.h
 *
 *****************************************************************************/

// SOL++2000
// 1999.06.12  Added sendAll method. 
// 1999.07.03  Added readLine method.
// 1999.08.10  Added new bind method.
// 1999.08.16  Added a timeout argument to sendAll method.
// 1999.08.22  Added a printf method and a buffer variable to use printf method.
#ifndef _SOL_OBJECT
#include <sol\Object.h>
#endif
#include <winsock.h>

#ifndef _SOL_INETADDRESS
#include <sol\InetAddress.h>
#endif

#ifndef _SOL_STRINGBUFFER
#include <sol\StringBuffer.h>
#endif

#ifndef _SOL_SOCKET
#define _SOL_SOCKET

class Socket :public Object {
    int     domain;
    int     type;
    int     protocol;
    SOCKET  fd;
	char*	buffer;
 public:
    Socket();
    Socket(int domain, int type, int protocol);
    ~Socket();

	SOCKET	accept(sockaddr* addr, int* addrlen);
	
	int		bind(InetAddress& addr);

    int		bind(int port, unsigned long address);
	int		bind(sockaddr* inet, int size); 
    BOOL	close();

    SOCKET	create(int domain, int type, int protocol);
    int		getDomain() { return domain; }
    SOCKET	getFD() { return fd; }

    int		getName(InetAddress& addr);

    int		getName(sockaddr_in* addr);
    int		getOption(int optname, char* optval, int* optlen);
    int		getPeerName(sockaddr_in* addr);

	int		getPeerName(InetAddress& addr);
	
	int		isConnected() { 
		InetAddress addr; 
		return getPeerName(addr);
	}

    int		getType() { return type; }

    int		isFDSet(fd_set* fdset);

    int     ioctl(long cmd, u_long* argp) {
            return ioctlsocket(fd, cmd, argp);
    }

    int     nonBlocking() {
            u_long block = 1;
            return ioctlsocket(fd, FIONBIO, &block);                
    }

    int		listen(int backlog);
	// 1999.08.22
	int		printf(const char*,...);

    int		recv(char* buff, int len, int flag);

	int		readLine(StringBuffer& buffer);

    int		send(const char* buff, int len, int flag);
	
    int		sendAll(const char* buff, int len, int flag, long timeout=30);

    int     sendAll(const char* string);
    int		sendAll(String& string);
    int     sendAll(StringBuffer& buffer);

    void	setFD(SOCKET fd) { this -> fd = fd; }

    void	setFDSet(fd_set* fdset);

    int		setOption(int optname, char* optval, int optlen);

    int		shutdown(int how);

	int		select(HWND hwnd, unsigned int msg, long event);
};

#endif
