/* Copyright (c) 1997-2006
   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_POLYBUF_H
#define _POLYMAKE_POLYBUF_H "$Project: polymake $$Id: Polybuf.h 7315 2006-04-02 21:37:53Z gawrilow $"

#include <socketstream.h>
#include <Poly.h>

namespace pm { namespace client {

class streambuf : public std::socketbuf {
protected:
   std::string name;
   int last_nl, _lines;

public:
   streambuf(int fd) : std::socketbuf(fd), last_nl(0) { }

   typedef std::char_traits<char> ctraits;
   typedef ctraits::int_type int_type;

   void start_input();
   void clear_input();
   void finish_output();
   void check_exception();

   int fd() const { return _fd; }

   int_type underflow();

   void send_cmd(int id, const char *cmd, bool immed=true);
   void send_cmd(int id, const char *cmd, const char *arg, bool immed=true);
   void send_arg(const char *arg);

   friend class Object;
   friend class streambuf_holder;
   friend class Object::istream_germ;

   char* input_limit() const { return socketbuf::input_limit; }
   int lines() { return _lines; }
};

class streambuf_holder {
   friend class Object;

   static streambuf* get() { return inst()->buf; }

   int new_object(const char *object_arg, bool exists, const char *options);
   void delete_object(int id);

   ~streambuf_holder();
   static streambuf_holder* inst();

   bool client_mode() const { return server==0; }
protected:
   streambuf_holder() : buf(0), server(0), object_cnt(-1), server_options(0) { }

   void set_options(const char*);

   streambuf *buf;
   pid_t server;
   int object_cnt;
   const char* server_options;
};

} } // end namespace pm::client

#endif // _POLYMAKE_POLYBUF_H

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