2 // $Id: fcgio.cpp,v 1.14 2003/06/22 00:51:27 robs Exp $
4 // Allows you communicate with FastCGI streams using C++ iostreams
6 // ORIGINAL AUTHOR: George Feinberg
7 // REWRITTEN BY: Michael Richards 06/20/1999
8 // REWRITTEN AGAIN BY: Michael Shell 02/23/2000
9 // REWRITTEN AGAIN BY: Rob Saccoccio 11 Nov 2001
11 // Copyright (c) 2000 Tux the Linux Penguin
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
15 // is given to the author(s)
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.
22 #define DLLAPI __declspec(dllexport)
31 using std::streamsize;
33 fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs, char * b, int bs)
38 fcgi_streambuf::fcgi_streambuf(char_type * b, streamsize bs)
43 fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs)
48 fcgi_streambuf::~fcgi_streambuf(void)
51 // FCGX_Finish()/FCGX_Accept() will flush and close
54 void fcgi_streambuf::init(FCGX_Stream * fs, char_type * b, streamsize bs)
62 int fcgi_streambuf::overflow(int c)
66 int plen = pptr() - pbase();
70 if (FCGX_PutStr(pbase(), plen, this->fcgx) != plen) return EOF;
77 if (FCGX_PutChar(c, this->fcgx) != c) return EOF;
83 // default base class behaviour seems to be inconsistent
84 int fcgi_streambuf::sync()
86 if (overflow(EOF)) return EOF;
87 if (FCGX_FFlush(this->fcgx)) return EOF;
91 // uflow() removes the char, underflow() doesn't
92 int fcgi_streambuf::uflow()
102 return FCGX_GetChar(this->fcgx);
106 int fcgi_streambuf::underflow()
112 int glen = FCGX_GetStr(eback(), this->bufsize, this->fcgx);
113 if (glen <= 0) return EOF;
115 setg(eback(), eback(), eback() + glen);
118 return (unsigned char) *gptr();
122 return FCGX_UnGetChar(FCGX_GetChar(this->fcgx), this->fcgx);
126 void fcgi_streambuf::reset(void)
128 // it should be ok to set up both the get and put areas
129 setg(this->buf, this->buf, this->buf);
130 setp(this->buf, this->buf + this->bufsize);
133 std::streambuf * fcgi_streambuf::setbuf(char_type * b, streamsize bs)
135 // XXX support moving data from an old buffer
136 if (this->bufsize) return 0;
141 // the base setbuf() *has* to be called
142 streambuf::setbuf(b, bs);
149 int fcgi_streambuf::attach(FCGX_Stream * fs)
161 streamsize fcgi_streambuf::xsgetn(char_type * s, streamsize n)
163 if (n > INT_MAX) return 0;
164 return (this->bufsize)
165 ? streambuf::xsgetn(s, n)
166 : (streamsize) FCGX_GetStr((char *) s, (int) n, this->fcgx);
169 streamsize fcgi_streambuf::xsputn(const char_type * s, streamsize n)
171 if (n > INT_MAX) return 0;
172 return (this->bufsize)
173 ? streambuf::xsputn(s, n)
174 : (streamsize) FCGX_PutStr((char *) s, (int) n, this->fcgx);
178 fcgi_istream::fcgi_istream(FCGX_Stream * fs) :
179 istream(&fcgi_strmbuf)
181 fcgi_strmbuf.attach(fs);
185 void fcgi_istream::attach(FCGX_Stream * fs)
187 fcgi_strmbuf.attach(fs);
191 fcgi_ostream::fcgi_ostream(FCGX_Stream * fs) :
192 ostream(&fcgi_strmbuf)
194 fcgi_strmbuf.attach(fs);
198 void fcgi_ostream::attach(FCGX_Stream * fs)
200 fcgi_strmbuf.attach(fs);