/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ifndef _POLYMAKE_SOCKETSTREAM_H
#define _POLYMAKE_SOCKETSTREAM_H "$Project: polymake $$Id: socketstream.h,v 1.9 2004/06/22 16:22:42 gawrilow Exp $"

#if defined(__GNUC__) && __GNUC_MINOR__<3 && !defined(__APPLE__) && !defined(__COMO__)
#pragma interface
#endif

#include <iostream>
#include <netinet/in.h>

namespace std {

class server_socketbuf;
class socketstream;

class socketbuf : public streambuf {
public:
   socketbuf(int fd) : _fd(fd), _sfd(-1) { init(); }
   socketbuf(in_addr_t addr, int port);
   ~socketbuf();

protected:
   socketbuf() { }
   void init();

   int sync();
   int_type overflow(int_type c=traits_type::eof());
   int_type underflow();
   streamsize showmanyc();
   int_type pbackfail(int_type c=traits_type::eof());

   int _fd, _sfd, bufsize;

   friend class server_socketbuf;
   friend class socketstream;
};

class server_socketbuf : public socketbuf {
public:
   server_socketbuf(int port);
   server_socketbuf(const char* fd_arg);

protected:
   int sync();
   int_type overflow(int_type c=traits_type::eof());
   int_type underflow();
   streamsize showmanyc() { return 0; }
   int_type pbackfail(int_type) { return traits_type::eof(); }

private:
   static socketbuf* start(server_socketbuf*);
};

class socketstream : public iostream {
public:
   socketstream(int port=0)
      : iostream(new server_socketbuf(port)) { }

   socketstream(const char* fd_arg)
      : iostream(new server_socketbuf(fd_arg)) { }

   socketstream(in_addr_t addr, int port)
      : iostream(new socketbuf(addr,port)) { }

   ~socketstream() { delete rdbuf(); }

   int port() const;
};

} // end namespace std

#endif // _POLYMAKE_SOCKETSTREAM_H

// Local Variables:
// mode:C++
// End:
