/* Pipestream: A simple C++ interface to UNIX pipes
  Version 0.05
  Copyright (C) 2005-2014 John C. Bowman,
  with contributions from Mojca Miklavec

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.

  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 Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

#ifndef PIPESTREAM_H
#define PIPESTREAM_H
#if defined(_WIN32)

#include "win32pipestream.h"
typedef w32::Win32IoPipeStream iopipestream;

#else

#include <sys/wait.h>
#include <unistd.h>
#include "common.h"

// bidirectional stream for reading and writing to pipes
class iopipestream {
protected:
 int in[2];
 int out[2];
 static const int BUFSIZE=SHRT_MAX;
 char buffer[BUFSIZE];
 string sbuffer;
 int pid;
 bool Running;
 bool pipeopen;
 bool pipein;
public:

 void open(const mem::vector<string> &command, const char *hint=NULL,
           const char *application="", int out_fileno=STDOUT_FILENO);

 bool isopen() {return pipeopen;}

 iopipestream(): pid(0), pipeopen(false) {}

 iopipestream(const mem::vector<string> &command, const char *hint=NULL,
              const char *application="", int out_fileno=STDOUT_FILENO) :
   pid(0), pipeopen(false) {
   open(command,hint,application,out_fileno);
 }

 void eof();
 virtual void pipeclose();

 virtual ~iopipestream() {
   pipeclose();
 }

 void block(bool write=false, bool read=true);

 ssize_t readbuffer();
 string readline();

 bool running() {return Running;}

 typedef iopipestream& (*imanip)(iopipestream&);

 iopipestream& operator << (imanip func) {
   return (*func)(*this);
 }

 iopipestream& operator >> (string& s) {
   readbuffer();
   s=buffer;
   return *this;
 }

 bool tailequals(const char *buf, size_t len, const char *prompt,
                 size_t plen);

 string getbuffer() {return sbuffer;}

 void wait(const char *prompt);
 int wait();
 void Write(const string &s);

 iopipestream& operator << (const string& s) {
   Write(s);
   return *this;
 }

 template<class T>
 iopipestream& operator << (T x) {
   ostringstream os;
   os << x;
   Write(os.str());
   return *this;
 }
};

#endif
#endif