Added a LIMITATIONS section to POD
[catagits/fcgi2.git] / libfcgi / fcgio.cpp
CommitLineData
c124bb9b 1//
ac8d264a 2// $Id: fcgio.cpp,v 1.14 2003/06/22 00:51:27 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 28using std::streambuf;
29using std::istream;
30using std::ostream;
31using std::streamsize;
32
25413d1c 33fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs, char * b, int bs)
0cf44b19 34{
25413d1c 35 init(fs, b, bs);
0cf44b19 36}
37
134d8dfc 38fcgi_streambuf::fcgi_streambuf(char_type * b, streamsize bs)
0cf44b19 39{
25413d1c 40 init(0, b, bs);
0cf44b19 41}
42
25413d1c 43fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs)
f684a497 44{
25413d1c 45 init(fs, 0, 0);
f684a497 46}
98e2ddaa 47
f684a497 48fcgi_streambuf::~fcgi_streambuf(void)
49{
50 overflow(EOF);
51 // FCGX_Finish()/FCGX_Accept() will flush and close
0cf44b19 52}
53
134d8dfc 54void 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 62int 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 84int 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
92int fcgi_streambuf::uflow()
93{
ac8d264a 94 if (this->bufsize)
95 {
96 int c = underflow();
97 gbump(1);
98 return c;
99 }
100 else
101 {
102 return FCGX_GetChar(this->fcgx);
103 }
4c4f72f0 104}
105
98e2ddaa 106int fcgi_streambuf::underflow()
f684a497 107{
108 if (this->bufsize)
109 {
110 if (in_avail() == 0)
111 {
112 int glen = FCGX_GetStr(eback(), this->bufsize, this->fcgx);
113 if (glen <= 0) return EOF;
114
115 setg(eback(), eback(), eback() + glen);
116 }
117
118 return (unsigned char) *gptr();
119 }
120 else
121 {
ac8d264a 122 return FCGX_UnGetChar(FCGX_GetChar(this->fcgx), this->fcgx);
f684a497 123 }
124}
125
0cf44b19 126void fcgi_streambuf::reset(void)
127{
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);
131}
132
134d8dfc 133std::streambuf * fcgi_streambuf::setbuf(char_type * b, streamsize bs)
f684a497 134{
0cf44b19 135 // XXX support moving data from an old buffer
25413d1c 136 if (this->bufsize) return 0;
0cf44b19 137
25413d1c 138 this->buf = b;
139 this->bufsize = bs;
0cf44b19 140
141 // the base setbuf() *has* to be called
25413d1c 142 streambuf::setbuf(b, bs);
f684a497 143
0cf44b19 144 reset();
f684a497 145
146 return this;
0cf44b19 147}
148
25413d1c 149int fcgi_streambuf::attach(FCGX_Stream * fs)
0cf44b19 150{
25413d1c 151 this->fcgx = fs;
0cf44b19 152
153 if (this->bufsize)
154 {
155 reset();
156 }
157
158 return 0;
f684a497 159}
160
134d8dfc 161streamsize fcgi_streambuf::xsgetn(char_type * s, streamsize n)
0cf44b19 162{
134d8dfc 163 if (n > INT_MAX) return 0;
0cf44b19 164 return (this->bufsize)
165 ? streambuf::xsgetn(s, n)
134d8dfc 166 : (streamsize) FCGX_GetStr((char *) s, (int) n, this->fcgx);
0cf44b19 167}
168
134d8dfc 169streamsize fcgi_streambuf::xsputn(const char_type * s, streamsize n)
0cf44b19 170{
134d8dfc 171 if (n > INT_MAX) return 0;
0cf44b19 172 return (this->bufsize)
173 ? streambuf::xsputn(s, n)
134d8dfc 174 : (streamsize) FCGX_PutStr((char *) s, (int) n, this->fcgx);
0cf44b19 175}
176
177// deprecated
25413d1c 178fcgi_istream::fcgi_istream(FCGX_Stream * fs) :
f684a497 179 istream(&fcgi_strmbuf)
180{
25413d1c 181 fcgi_strmbuf.attach(fs);
f684a497 182}
183
0cf44b19 184// deprecated
25413d1c 185void fcgi_istream::attach(FCGX_Stream * fs)
f684a497 186{
25413d1c 187 fcgi_strmbuf.attach(fs);
f684a497 188}
189
0cf44b19 190// deprecated
25413d1c 191fcgi_ostream::fcgi_ostream(FCGX_Stream * fs) :
0cf44b19 192 ostream(&fcgi_strmbuf)
f684a497 193{
25413d1c 194 fcgi_strmbuf.attach(fs);
f684a497 195}
196
0cf44b19 197// deprecated
25413d1c 198void fcgi_ostream::attach(FCGX_Stream * fs)
f684a497 199{
25413d1c 200 fcgi_strmbuf.attach(fs);
f684a497 201}