Commit | Line | Data |
c124bb9b |
1 | // |
134d8dfc |
2 | // $Id: fcgio.cpp,v 1.13 2002/02/24 20:12:22 robs Exp $ |
c124bb9b |
3 | // |
f684a497 |
4 | // Allows you communicate with FastCGI streams using C++ iostreams |
c124bb9b |
5 | // |
98e2ddaa |
6 | // ORIGINAL AUTHOR: George Feinberg |
7 | // REWRITTEN BY: Michael Richards 06/20/1999 |
8 | // REWRITTEN AGAIN BY: Michael Shell 02/23/2000 |
f684a497 |
9 | // REWRITTEN AGAIN BY: Rob Saccoccio 11 Nov 2001 |
98e2ddaa |
10 | // |
11 | // Copyright (c) 2000 Tux the Linux Penguin |
c124bb9b |
12 | // |
13 | // You are free to use this software without charge or royalty |
14 | // as long as this notice is not removed or altered, and recognition |
98e2ddaa |
15 | // is given to the author(s) |
16 | // |
17 | // This code is offered as-is without any warranty either expressed or |
18 | // implied; without even the implied warranty of MERCHANTABILITY or |
19 | // FITNESS FOR A PARTICULAR PURPOSE. |
20 | |
af4a4f30 |
21 | #ifdef _WIN32 |
22 | #define DLLAPI __declspec(dllexport) |
23 | #endif |
24 | |
134d8dfc |
25 | #include <limits.h> |
e52a7487 |
26 | #include "fcgio.h" |
98e2ddaa |
27 | |
134d8dfc |
28 | using std::streambuf; |
29 | using std::istream; |
30 | using std::ostream; |
31 | using std::streamsize; |
32 | |
25413d1c |
33 | fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs, char * b, int bs) |
0cf44b19 |
34 | { |
25413d1c |
35 | init(fs, b, bs); |
0cf44b19 |
36 | } |
37 | |
134d8dfc |
38 | fcgi_streambuf::fcgi_streambuf(char_type * b, streamsize bs) |
0cf44b19 |
39 | { |
25413d1c |
40 | init(0, b, bs); |
0cf44b19 |
41 | } |
42 | |
25413d1c |
43 | fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs) |
f684a497 |
44 | { |
25413d1c |
45 | init(fs, 0, 0); |
f684a497 |
46 | } |
98e2ddaa |
47 | |
f684a497 |
48 | fcgi_streambuf::~fcgi_streambuf(void) |
49 | { |
50 | overflow(EOF); |
51 | // FCGX_Finish()/FCGX_Accept() will flush and close |
0cf44b19 |
52 | } |
53 | |
134d8dfc |
54 | void fcgi_streambuf::init(FCGX_Stream * fs, char_type * b, streamsize bs) |
0cf44b19 |
55 | { |
25413d1c |
56 | this->fcgx = fs; |
57 | this->buf = 0; |
0cf44b19 |
58 | this->bufsize = 0; |
25413d1c |
59 | setbuf(b, bs); |
282622d5 |
60 | } |
98e2ddaa |
61 | |
98e2ddaa |
62 | int fcgi_streambuf::overflow(int c) |
f684a497 |
63 | { |
64 | if (this->bufsize) |
65 | { |
66 | int plen = pptr() - pbase(); |
67 | |
68 | if (plen) |
69 | { |
70 | if (FCGX_PutStr(pbase(), plen, this->fcgx) != plen) return EOF; |
71 | pbump(-plen); |
72 | } |
73 | } |
74 | |
75 | if (c != EOF) |
76 | { |
77 | if (FCGX_PutChar(c, this->fcgx) != c) return EOF; |
78 | } |
79 | |
80 | return 0; |
81 | } |
82 | |
0cf44b19 |
83 | // default base class behaviour seems to be inconsistent |
98e2ddaa |
84 | int fcgi_streambuf::sync() |
f684a497 |
85 | { |
0cf44b19 |
86 | if (overflow(EOF)) return EOF; |
f684a497 |
87 | if (FCGX_FFlush(this->fcgx)) return EOF; |
88 | return 0; |
89 | } |
c124bb9b |
90 | |
4c4f72f0 |
91 | // uflow() removes the char, underflow() doesn't |
92 | int fcgi_streambuf::uflow() |
93 | { |
94 | int rv = underflow(); |
95 | if (this->bufsize) gbump(1); |
96 | return rv; |
97 | } |
98 | |
99 | // Note that the expected behaviour when there is no buffer varies |
98e2ddaa |
100 | int fcgi_streambuf::underflow() |
f684a497 |
101 | { |
102 | if (this->bufsize) |
103 | { |
104 | if (in_avail() == 0) |
105 | { |
106 | int glen = FCGX_GetStr(eback(), this->bufsize, this->fcgx); |
107 | if (glen <= 0) return EOF; |
108 | |
109 | setg(eback(), eback(), eback() + glen); |
110 | } |
111 | |
112 | return (unsigned char) *gptr(); |
113 | } |
114 | else |
115 | { |
116 | return FCGX_GetChar(this->fcgx); |
117 | } |
118 | } |
119 | |
0cf44b19 |
120 | void fcgi_streambuf::reset(void) |
121 | { |
122 | // it should be ok to set up both the get and put areas |
123 | setg(this->buf, this->buf, this->buf); |
124 | setp(this->buf, this->buf + this->bufsize); |
125 | } |
126 | |
134d8dfc |
127 | std::streambuf * fcgi_streambuf::setbuf(char_type * b, streamsize bs) |
f684a497 |
128 | { |
0cf44b19 |
129 | // XXX support moving data from an old buffer |
25413d1c |
130 | if (this->bufsize) return 0; |
0cf44b19 |
131 | |
25413d1c |
132 | this->buf = b; |
133 | this->bufsize = bs; |
0cf44b19 |
134 | |
135 | // the base setbuf() *has* to be called |
25413d1c |
136 | streambuf::setbuf(b, bs); |
f684a497 |
137 | |
0cf44b19 |
138 | reset(); |
f684a497 |
139 | |
140 | return this; |
0cf44b19 |
141 | } |
142 | |
25413d1c |
143 | int fcgi_streambuf::attach(FCGX_Stream * fs) |
0cf44b19 |
144 | { |
25413d1c |
145 | this->fcgx = fs; |
0cf44b19 |
146 | |
147 | if (this->bufsize) |
148 | { |
149 | reset(); |
150 | } |
151 | |
152 | return 0; |
f684a497 |
153 | } |
154 | |
134d8dfc |
155 | streamsize fcgi_streambuf::xsgetn(char_type * s, streamsize n) |
0cf44b19 |
156 | { |
134d8dfc |
157 | if (n > INT_MAX) return 0; |
0cf44b19 |
158 | return (this->bufsize) |
159 | ? streambuf::xsgetn(s, n) |
134d8dfc |
160 | : (streamsize) FCGX_GetStr((char *) s, (int) n, this->fcgx); |
0cf44b19 |
161 | } |
162 | |
134d8dfc |
163 | streamsize fcgi_streambuf::xsputn(const char_type * s, streamsize n) |
0cf44b19 |
164 | { |
134d8dfc |
165 | if (n > INT_MAX) return 0; |
0cf44b19 |
166 | return (this->bufsize) |
167 | ? streambuf::xsputn(s, n) |
134d8dfc |
168 | : (streamsize) FCGX_PutStr((char *) s, (int) n, this->fcgx); |
0cf44b19 |
169 | } |
170 | |
171 | // deprecated |
25413d1c |
172 | fcgi_istream::fcgi_istream(FCGX_Stream * fs) : |
f684a497 |
173 | istream(&fcgi_strmbuf) |
174 | { |
25413d1c |
175 | fcgi_strmbuf.attach(fs); |
f684a497 |
176 | } |
177 | |
0cf44b19 |
178 | // deprecated |
25413d1c |
179 | void fcgi_istream::attach(FCGX_Stream * fs) |
f684a497 |
180 | { |
25413d1c |
181 | fcgi_strmbuf.attach(fs); |
f684a497 |
182 | } |
183 | |
0cf44b19 |
184 | // deprecated |
25413d1c |
185 | fcgi_ostream::fcgi_ostream(FCGX_Stream * fs) : |
0cf44b19 |
186 | ostream(&fcgi_strmbuf) |
f684a497 |
187 | { |
25413d1c |
188 | fcgi_strmbuf.attach(fs); |
f684a497 |
189 | } |
190 | |
0cf44b19 |
191 | // deprecated |
25413d1c |
192 | void fcgi_ostream::attach(FCGX_Stream * fs) |
f684a497 |
193 | { |
25413d1c |
194 | fcgi_strmbuf.attach(fs); |
f684a497 |
195 | } |