#ifdef _WIN32
#define DLLAPI __declspec(dllexport)
#endif
#include <limits.h>
#include "fcgio.h"
using std::streambuf;
using std::istream;
using std::ostream;
using std::streamsize;
fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs, char * b, int bs)
{
init(fs, b, bs);
}
fcgi_streambuf::fcgi_streambuf(char_type * b, streamsize bs)
{
init(0, b, bs);
}
fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs)
{
init(fs, 0, 0);
}
fcgi_streambuf::~fcgi_streambuf(void)
{
overflow(EOF);
}
void fcgi_streambuf::init(FCGX_Stream * fs, char_type * b, streamsize bs)
{
this->fcgx = fs;
this->buf = 0;
this->bufsize = 0;
setbuf(b, bs);
}
int fcgi_streambuf::overflow(int c)
{
if (this->bufsize)
{
int plen = pptr() - pbase();
if (plen)
{
if (FCGX_PutStr(pbase(), plen, this->fcgx) != plen) return EOF;
pbump(-plen);
}
}
if (c != EOF)
{
if (FCGX_PutChar(c, this->fcgx) != c) return EOF;
}
return 0;
}
int fcgi_streambuf::sync()
{
if (overflow(EOF)) return EOF;
if (FCGX_FFlush(this->fcgx)) return EOF;
return 0;
}
int fcgi_streambuf::uflow()
{
int rv = underflow();
if (this->bufsize) gbump(1);
return rv;
}
int fcgi_streambuf::underflow()
{
if (this->bufsize)
{
if (in_avail() == 0)
{
int glen = FCGX_GetStr(eback(), this->bufsize, this->fcgx);
if (glen <= 0) return EOF;
setg(eback(), eback(), eback() + glen);
}
return (unsigned char) *gptr();
}
else
{
return FCGX_GetChar(this->fcgx);
}
}
void fcgi_streambuf::reset(void)
{
setg(this->buf, this->buf, this->buf);
setp(this->buf, this->buf + this->bufsize);
}
std::streambuf * fcgi_streambuf::setbuf(char_type * b, streamsize bs)
{
if (this->bufsize) return 0;
this->buf = b;
this->bufsize = bs;
streambuf::setbuf(b, bs);
reset();
return this;
}
int fcgi_streambuf::attach(FCGX_Stream * fs)
{
this->fcgx = fs;
if (this->bufsize)
{
reset();
}
return 0;
}
streamsize fcgi_streambuf::xsgetn(char_type * s, streamsize n)
{
if (n > INT_MAX) return 0;
return (this->bufsize)
? streambuf::xsgetn(s, n)
: (streamsize) FCGX_GetStr((char *) s, (int) n, this->fcgx);
}
streamsize fcgi_streambuf::xsputn(const char_type * s, streamsize n)
{
if (n > INT_MAX) return 0;
return (this->bufsize)
? streambuf::xsputn(s, n)
: (streamsize) FCGX_PutStr((char *) s, (int) n, this->fcgx);
}
fcgi_istream::fcgi_istream(FCGX_Stream * fs) :
istream(&fcgi_strmbuf)
{
fcgi_strmbuf.attach(fs);
}
void fcgi_istream::attach(FCGX_Stream * fs)
{
fcgi_strmbuf.attach(fs);
}
fcgi_ostream::fcgi_ostream(FCGX_Stream * fs) :
ostream(&fcgi_strmbuf)
{
fcgi_strmbuf.attach(fs);
}
void fcgi_ostream::attach(FCGX_Stream * fs)
{
fcgi_strmbuf.attach(fs);
}