libi2ncommon: (gerd) initial submission, not in use yet
[libi2ncommon] / src / pipestream.hxx
CommitLineData
e93545dd
GE
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
22class 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
66class 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
76class 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
114class 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