intranator-language, libi2ncommon: (tomj) translation update, indent of pipestream.hxx
[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     // "callback" variables for destructor to store exit status
29     bool *status_set;
30     int *exit_status;
31
32 public:
33     inpipebuf(const std::string& command)
34     {
35         status_set = NULL;
36         exit_status = NULL;
37
38         pipe = popen (command.c_str(), "r");
39         if (pipe == NULL)
40             throw EXCEPTION (pipestream_error, "can't open program or permission denied");
41
42         // force underflow
43         setg (&buffer, &buffer, &buffer);
44     }
45
46     ~inpipebuf()
47     {
48         if (pipe != NULL) {
49             int pclose_exit = pclose (pipe);
50
51             if (exit_status && pclose_exit != -1) {
52                 *status_set = true;
53                 *exit_status = pclose_exit;
54             }
55
56             pipe = NULL;
57         }
58     }
59
60     void store_exit_status(bool *_status_set, int *_exit_status)
61     { status_set = _status_set; exit_status = _exit_status; }
62
63 protected:
64     virtual int_type underflow()
65     {
66         if (gptr() < egptr())
67             return traits_type::to_int_type(*gptr());
68
69         buffer = fgetc (pipe);
70         if (feof (pipe))
71         {
72             // ERROR or EOF
73             return EOF;
74         }
75
76         setg (&buffer, &buffer, &buffer+sizeof(char));
77
78         return traits_type::to_int_type(*gptr());
79     }
80 };
81
82 class inpipestream : public std::istream
83 {
84 protected:
85     inpipebuf buf;
86
87 public:
88     inpipestream(const std::string& command)
89             : buf(command), std::istream(&buf)
90     {}
91
92     void store_exit_status(bool *_status_set, int *_exit_status)
93     { buf.store_exit_status(_status_set, _exit_status); }
94 };
95
96 class outpipebuf : public std::streambuf
97 {
98 protected:
99     FILE *pipe;
100
101     // "callback" variables for destructor to store exit status
102     bool *status_set;
103     int *exit_status;
104
105 public:
106     outpipebuf(const std::string& command)
107     {
108         status_set = NULL;
109         exit_status = NULL;
110
111         pipe = popen (command.c_str(), "w");
112         if (pipe == NULL)
113             throw EXCEPTION (pipestream_error, "can't open program or permission denied");
114     }
115
116     ~outpipebuf()
117     {
118         if (pipe != NULL) {
119             int pclose_exit = pclose (pipe);
120
121             if (exit_status && pclose_exit != -1) {
122                 *status_set = true;
123                 *exit_status = pclose_exit;
124             }
125
126             pipe = NULL;
127         }
128     }
129
130     void store_exit_status(bool *_status_set, int *_exit_status)
131     { status_set = _status_set; exit_status = _exit_status; }
132
133 protected:
134     virtual int_type overflow(int_type c)
135     {
136         if (c != EOF)
137         {
138             if (fputc(c,pipe)==EOF)
139                 return EOF;
140         }
141         return c;
142     }
143
144     virtual std::streamsize xsputn(const char* s, std::streamsize num)
145     {
146         return fwrite(s,num,1,pipe);
147     }
148 };
149
150 class outpipestream : public std::ostream
151 {
152 protected:
153     outpipebuf buf;
154 public:
155     outpipestream(const std::string& command)
156             : buf(command), std::ostream(&buf)
157     {}
158
159     void store_exit_status(bool *_status_set, int *_exit_status)
160     { buf.store_exit_status(_status_set, _exit_status); }
161 };
162
163 #endif