use streamsize and char_type, export the C++ API via the class not its methods
[catagits/fcgi2.git] / libfcgi / fcgio.cpp
CommitLineData
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 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{
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 100int 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 120void 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 127std::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 143int 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 155streamsize 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 163streamsize 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 172fcgi_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 179void fcgi_istream::attach(FCGX_Stream * fs)
f684a497 180{
25413d1c 181 fcgi_strmbuf.attach(fs);
f684a497 182}
183
0cf44b19 184// deprecated
25413d1c 185fcgi_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 192void fcgi_ostream::attach(FCGX_Stream * fs)
f684a497 193{
25413d1c 194 fcgi_strmbuf.attach(fs);
f684a497 195}