libi2ncommon: (gerd) initial submission, not in use yet
[libi2ncommon] / src / pipestream.hxx
1 /***************************************************************************
2               inpipestream.hxx  -  C++ streambuffer wrapper 
3                              -------------------
4     begin                : Thu Dec 27 2001
5     copyright            : (C) 2001 by Intra2net AG
6     email                : intranator@intra2net.com
7  ***************************************************************************/
8
9 #ifndef _PIPESTREAM
10 #define _PIPESTREAM
11
12 #include <string>
13 #include <streambuf>
14 #include <cstdio>
15
16 #include "exception.hxx"
17
18 // ATTENTION: A lot of mysterious STL bugs occured
19 //            with a "real" buffer (buffer larger than 1 byte and up to 100 bytes)
20 //            -> Keep it slow and working!
21
22 class inpipebuf : public std::streambuf
23 {
24    protected:
25    char buffer;
26    FILE *pipe;
27
28    public:
29    inpipebuf(const std::string& command)
30    {
31       pipe = popen (command.c_str(), "r");
32       if (pipe == NULL)
33          throw EXCEPTION (pipestream_error, "can't open program or permission denied");
34
35       // force underflow
36       setg (&buffer, &buffer, &buffer);
37    }
38
39    ~inpipebuf()
40    {
41       if (pipe != NULL)
42          pclose (pipe);
43
44       pipe = NULL;
45    }
46
47    protected:
48    virtual int_type underflow()
49    {
50       if (gptr() < egptr())
51          return traits_type::to_int_type(*gptr());
52
53       buffer = fgetc (pipe);
54       if (feof (pipe))
55       {
56          // ERROR or EOF
57          return EOF;
58       }
59
60       setg (&buffer, &buffer, &buffer+sizeof(char));
61
62       return traits_type::to_int_type(*gptr());
63    }
64 }; 
65
66 class inpipestream : public std::istream
67 {
68    protected:
69       inpipebuf buf;
70    public:
71       inpipestream(const std::string& command)
72          : buf(command), std::istream(&buf)
73          {}
74 };
75
76 class outpipebuf : public std::streambuf
77 {
78    protected:
79    FILE *pipe;
80
81    public:
82    outpipebuf(const std::string& command)
83    {
84       pipe = popen (command.c_str(), "w");
85       if (pipe == NULL)
86          throw EXCEPTION (pipestream_error, "can't open program or permission denied");
87    }
88
89    ~outpipebuf()
90    {
91       if (pipe != NULL)
92          pclose (pipe);
93
94       pipe = NULL;
95    }
96
97    protected:
98    virtual int_type overflow(int_type c)
99    {
100       if (c != EOF)
101       {
102          if (fputc(c,pipe)==EOF)
103             return EOF;
104       }
105       return c;
106    }
107
108    virtual std::streamsize xsputn(const char* s, std::streamsize num)
109    {
110       return fwrite(s,num,1,pipe);
111    }
112 };
113
114 class outpipestream : public std::ostream
115 {
116    protected:
117       outpipebuf buf;
118    public:
119       outpipestream(const std::string& command)
120          : buf(command), std::ostream(&buf)
121          {}
122 };
123
124 #endif