/* $Id: Socket.h,v 1.7 1999/10/19 15:59:21 v2kea318 Exp $

$Log: Socket.h,v $
 * Revision 1.7  1999/10/19  15:59:21  v2kea318
 * Move the implementation of the non-template read_force function to
 * the .cc file.
 *
 * Revision 1.6  1999/07/30  20:44:12  v2kea318
 * Converted the code to G++ compliance.
 *
 * Revision 1.5  1999/07/07  18:53:20  v2kea318
 * Added two read_force functions which will read data from a socket a single
 * byte at a time and loop until all the desired bytes are read.  This
 * guarantees that the required number of bytes will be returned.  When reading
 * multibyte objects across the network, all the data may not have been
 * transferred when we started reading, which would trigger an exception if
 * the normal read functions are used.  These new routines will fix this
 * problem.
 *
 * Revision 1.4  1999/05/04  20:40:17  v2kea318
 * Made the read and write methods const.
 *
 * Revision 1.3  1999/04/27  15:31:29  v2kea318
 * *** empty log message ***
 *
 * Revision 1.2  1999/04/27  15:30:29  v2kea318
 * Added more read and write methods to handle data types other than strings.
 * These should work for all types, with the caveat that the socket reads
 * and writes byte copies of the object, rather than a string representation
 * of the object (like Java).  Templated methods are defined, but not used
 * unless the compiler can handle template methods.  Wrapper functions are
 * also provided, primarily to cover the lack of the template methods.
 *
 * Revision 1.1  1999/04/23  19:52:26  v2kea318
 * Initial revision
 *
***************************************************************************

Define a client socket.

***************************************************************************/

#ifndef SOCKET_MYLIBS_H
#define SOCKET_MYLIBS_H

#include "SocketBase.h"

class Socket : public SocketBase {
  friend class ServerSocket;
protected:
  Socket() : SocketBase() {}
public:
  // constructor.
  Socket(const string& host, int port);

public:
  // write to the socket.
  void write(const void* data, size_t nbytes) const; // writes nbytes of data
  void write(const string& text) const;
  template <class T> void write(const T& data) const
    {
      write(&data, sizeof(T));
    }

  // read from the socket.
  void read(void* data, size_t nbytes) const; // reads nbytes of data.
  void read(string& text) const;
  template <class T> void read(T& data) const
    {
      read(&data, sizeof(T));
    }
};

/***************************************************************************

Template I/O functions.  These are just wrappers to the template methods,
if they exist.

***************************************************************************/
template <class T>
inline void write(const Socket& s, const T& data)
{
  s.write(data);
}

template <class T>
inline void read(const Socket& s, T& data)
{
  s.read(data);
}

/* Provide template functions that will force the correct number of bytes to
   be read. */
void read_force(const Socket& s, void* ptr, size_t nbytes);

template <class T>
inline void read_force(const Socket& s, T& data)
{
  read_force(s, &data, sizeof(T));
}

#endif
