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