// Copyright (c) 1999-2000 David Muse
// See the COPYING file for more information.

#ifndef GENERICSOCKET_H
#define GENERICSOCKET_H

#include <strstream.h>

#include <sys/types.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>

// The client class allows you to write programs that can talk to other
// programs over TCP connections.
//
// It provides connection management and data transfer methods but
// does not imply any particular client/server protocol.
//
// The class supports TCP connections over Inet and Unix domain sockets.
// Inet sockets allow clients and servers on different machines to talk over a
// network.  Unix sockets allow clients and servers on the same machine to 
// talk.  Inet sockets can be used by clients and servers on the same machine
// but Unix sockets generally perform better.
//
// This class is a base class for the client and server socket classes.  It
// provides methods for reading and writing data across sockets, closing sockets
// and managing errors.  The client and server socket classes provide methods
// for listening on ports and connecting to servers.

class genericsocket {
	public:
			genericsocket();
			genericsocket(int descriptor);
			// creates an instance of genericsocket using the
			// already open socket represented by "descriptor"
		virtual	~genericsocket();


		void	showErrors();
			// errors will be printed to stderr
		void	dontShowErrors();
			// errors will not be printed at all


		void	retryInterruptedReads();
			// causes reads that were interrupted by signals to
			// retry and not return errors
		void	dontRetryInterruptedReads();
			// causes reads that were interrupted by signals to
			// return errors and not retry


		void	retryInterruptedWrites();
			// causes writes that were interrupted by signals to
			// retry and not return errors
		void	dontRetryInterruptedWrites();
			// causes writes that were interrupted by signals to
			// return errors and not retry


		// These methods write data to the socket.  On success, the
		// number of bytes written is returned.  On failure, a -1 is
		// returned.
		int	writeData(unsigned short number);
		int	writeData(unsigned long number);
		int	writeData(float number);
		int	writeData(double number);
		int	writeData(char character);
		int	writeData(char *string);
		int	writeData(char *string, size_t size);
		int	writeData(void *buffer, size_t size);

		// These methods read data from the socket.  If no data is
		// available, they will wait until data is available or
		// the connection is closed.  On success, the number of bytes 
		// read is returned.  On failure, a -1 is returned.
		int	readData(unsigned short *buffer);
		int	readData(unsigned long *buffer);
		int	readData(float *buffer);
		int	readData(double *buffer);
		int	readData(char *buffer, size_t size);
		int	readData(void *buffer, size_t size);
		int	readData(strstream *buffer, char *terminator);


		// These methods allow you to pass file descriptors between
		// processes.  They only work over unix sockets.
		int	passFileDescriptor(int descriptor);
		int	receiveFileDescriptor(int *descriptor);


		int	closeSocket();
			// closes the socket

		int	getDescriptor();
			// returns the internal file descriptor for the socket


		int	isInetSocket();
			// returns 1 if the socket is an inet domain socket
			// and 0 if the socket is a unix domain socket
		int	isUnixSocket();
			// returns 1 if the socket is a unix domain socket
			// and 0 if the socket is an inet domain socket

	protected:
		#include <rudiments/private/genericsocket.h>

};

#endif
