X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=include%2Ffcgio.h;h=20d222ab6b5254acea2f182fe7473fed7b98ad19;hb=3c752ddfc824ddd3581756c04b8267b0d6922fca;hp=dfe55ac878cc5a71e9c59cd9bcc23158b5cc6a02;hpb=378bd843b7f5879f55c7eafc72abfa0931c22860;p=catagits%2Ffcgi2.git diff --git a/include/fcgio.h b/include/fcgio.h index dfe55ac..20d222a 100644 --- a/include/fcgio.h +++ b/include/fcgio.h @@ -1,70 +1,7 @@ // -// $Id: fcgio.h,v 1.4 2001/06/20 16:05:55 robs Exp $ +// Provides support for FastCGI via C++ iostreams. // -// Allows you communicate with FastCGI streams using C++ iostream -// objects -// -// defines classes fcgi_streambuf, fcgi_ostream, fcgi_istream -// you can redefine cin, cout, cerr or use your own custom -// FCGI stream names. -// -// ORIGINAL AUTHOR: George Feinberg -// -// -// REWRITTEN BY: Michael Richards 06/20/1999 -// -added cin support -// -added ability to replace cin/cout so existing code only -// needs to include the header file and use the normal -// cin/cout. This has been altered as of 2/2000, see below. -// -added buffered read support which is required for ungets. -// -// -// REWRITTEN AGAIN BY: Michael Shell 02/23/2000 -// -// Previous versions of this code had problems. -// Two hellish bugs have been fixed and there is now full -// buffering for both input and output streams. -// -// - fixed signed char bug in underflow() that would -// cause a false EOF to be flagged when reading binary -// data. Uploading short binary files via -#include "fcgio.h" // fcgio.h includes fcgiapp.h - // however you must include fcgi_stdio.h if - // you want to use it as fcgio.h does not - // include it for you - -#undef cin // remember you have to undo the stuff predefined -#undef cout // for cin, cout, cerr if you wish to use these -#undef cerr // names for your FastCGI streams - -int main(void) -{ - - int count = 0; - - // I can create/declare my objects here, but I don't dare use them - // until I set them up with attach(). - - // note that version 1.0 of fcgio used fcgio_istream & fcgio_ostream - // we made a little change to the names in V2.00 for clarity. - fcgi_istream cin; // you do not *HAVE* to use these names, you - fcgi_ostream cout; // could use other stream names of your choice - fcgi_ostream cerr; // don't forget that the input is - // fcgi_*I*stream class - - FCGX_Request request; // here is our request structure - - // get everything ready for the customers - FCGX_Init(); - - FCGX_InitRequest(&request,0,0); - - - // let the games begin - while(FCGX_Accept_r(&request) >= 0) - { - count++; - - cout.attach(request.out); // now I know my pointer values for - cerr.attach(request.err); // this request. attach to them - cin.attach(request.in); - // attach will initialize everything - // alternatively, you could declare the streams here and the - // constructor with the (FCGX_Stream *str) parameter would - // do the same job as attach - - // If you are using fcgi_stdio.h, the equivalent command would - // be cout.attach(FCGI_stdout->fcgx_stream); - // and so forth for cin,cerr using FCGI_stdin and FCGI_stderr - // respectively. - - - // now I can fire at will: - cout << "Content-type: text/html\r\n\r\n" - << " FastCGI cin, cout, cerr tester \r\n" - << "

FastCGI C++ IOstream test: " - << "It works!

\r\n"; - cout << "

Total served by this task: " - << count << "

\r\n"; - -// didn't use cin or cerr in this example. - -// it is good practice to flush the buffers. -// use cout.flush() if you don't want the line feed. - - cout << endl; - -// there is no cxxx.close() and you do not need it with the fcgio -// interface. You would need to call cxxx.close() if cxxx was an -// fstream based object and attached to a file descripter you got -// from a command like fd=open(blah). (GNU (Linux) based fstreams -// support this) Then you need to call cxxx.close() before you -// close the physical file with close(fd). If doing this with -// fstream objects, you should call cxxx.clear() after -// attach(fd) as the file descriptor attach is not as complete in -// initialization as our fcgi_iostream attach() -// If you don't understand any of this, don't worry about it and -// forget I even mentioned it. - - // all done with this request - FCGX_Finish_r(&request); - - // do the next request - } - return (1); -} - -*/ - -// END EXAMPLE CODE - -/*------------------------------------------------------------------*/ - +// FITNESS FOR A PARTICULAR PURPOSE. If it breaks, you get to keep +// both halves. #ifndef FCGIO_H #define FCGIO_H -#include +#include +#include "fcgiapp.h" + +#ifndef DLLAPI #ifdef _WIN32 -#define DLLAPI __declspec(dllexport) +#define DLLAPI __declspec(dllimport) +#else +#define DLLAPI +#endif #endif -#include - -// we aren't pulling from the heap, so it is best not o make it too big -#define FCGIO_BUFSIZE 200 +#if ! HAVE_STREAMBUF_CHAR_TYPE +typedef char char_type; +#endif -// FastCGI streambuf replacement. Implements low level I/O to the -// FastCGI C functions so our higher level iostreams will talk -// in the FastCGI protocol -class fcgi_streambuf : public streambuf +/* + * fcgi_streambuf + */ +class DLLAPI fcgi_streambuf : public std::streambuf { - public: - // constructor - fcgi_streambuf(void); - ~fcgi_streambuf(); +public: - // handles allocation of buffers by doing nothing since buffer - // allocation isn't needed - virtual int doallocate(); + // Note that if no buf is assigned (the default), iostream methods + // such as peek(), unget() and putback() will fail. If a buf is + // assigned, I/O is a bit less effecient and output streams will + // have to be flushed (or the streambuf destroyed) before the next + // call to "accept". + fcgi_streambuf(FCGX_Stream * fcgx, char * buf, int len); + + fcgi_streambuf(char_type * buf, std::streamsize len); + + fcgi_streambuf(FCGX_Stream * fcgx = 0); - // gets data (upto the given maximum) from the get buffer and - // copies it to the given char array. Returns the number of chars - // written or -1 on error. A returned value less than the given - // maximum, assuming the user requested at least one char, - // indicates that the get buffer is empty. The underflow() method - // is never called to refill the get buffer, so this method can be - // used to drain the get buffer. It is used to form an istream - // drain() method which is the input equivalent to flush(). - virtual int drain_strm(char *,int); + ~fcgi_streambuf(void); - // let's us know if this strembuf has been initialized - virtual int isstrmdefined(void); + int attach(FCGX_Stream * fcgx); - // (for writers) empties the put buffer and possibly an - // overflow char into the FCGI interface - virtual int overflow(int); - - // bogus routine in case somebody thinks they know - // better and calls it. We currently are happy with - // our static buffer. - virtual streambuf * setbuf(char *, int); +protected: - // initializes the buffering and FCGI interface - virtual void stream_initialize(FCGX_Stream *,int); + // Consume the put area (if buffered) and c (if c is not EOF). + virtual int overflow(int); - // (for writers) flushes the put buffer into the FCGI - // interface and then flushes the FCGI interface + // Flush the put area (if buffered) and the FCGX buffer to the client. virtual int sync(); - // (for readers) fills the get buffer with data from the - // FCGI interface + // Remove and return the current character. + virtual int uflow(); + + // Fill the get area (if buffered) and return the current character. virtual int underflow(); - private: - // pointer to our underlying FCGI interface - FCGX_Stream * fcgx_strm; + // Use a buffer. The only reasons that a buffer would be useful is + // to support the use of the unget()/putback() or seek() methods. Using + // a buffer will result in less efficient I/O. Note: the underlying + // FastCGI library (FCGX) maintains its own input and output buffers. + virtual std::streambuf * setbuf(char_type * buf, std::streamsize len); - // our buffer - static int buffersize; - char buffer[FCGIO_BUFSIZE]; + virtual std::streamsize xsgetn(char_type * s, std::streamsize n); + virtual std::streamsize xsputn(const char_type * s, std::streamsize n); - // little flag so that we can tell if the - // fcgi_str pointer was ever set - int defined; -}; +private: -int fcgi_streambuf::buffersize = FCGIO_BUFSIZE; + FCGX_Stream * fcgx; -// Here's the istream class definition. -class fcgi_istream : public istream -{ - public: - fcgi_istream(); - fcgi_istream(FCGX_Stream *str); - ~fcgi_istream(); + // buf is just handy to have around + char_type * buf; - // connects the fcgi_streambuf of an existing fcgi_istream - // object to a given FCGI interface - virtual void attach(FCGX_Stream *str); + // this isn't kept by the base class + std::streamsize bufsize; + + void init(FCGX_Stream * fcgx, char_type * buf, std::streamsize bufsize); - // allows you to drain down the streambuf buffer. It will not - // read any chars from the FCGI interface. You can repeatedly - // call drain() to empty the get buffer prior to using a - // FCGI library function to ensure syncronization of the - // reads. i.e. it flushes the input stream - // This method should be considered both nonstandard and - // experimental. It's use is entirely optional to the user, - // but could be very helpful for applications which use - // both istream and FCGI library based reads on a single - // FCGI interface and need a way to sync the reads. - // It copies upto the given number of chars into the given - // char array. It returns the number of chars written or - // -1 on error. If the number of chars written is less than - // the number the user requested, the get buffer is empty. - // This method does not alter or check any of the input - // status flags such as EOF or FAIL since it does not interact - // with the underlying FCGI interface at all - it only reads from - // the get buffer. - virtual int drain(char *,int); + void reset(void); +}; - // lets us know if this object has been initialized - virtual int isdefined(void); +/* + * fcgi_istream - deprecated + */ +class DLLAPI fcgi_istream : public std::istream +{ +public: - private: - // FastCGI streambuf - fcgi_streambuf fcgi_strmbuf; + // deprecated + fcgi_istream(FCGX_Stream * fcgx = 0); + + // deprecated + ~fcgi_istream(void) {} -}; + // deprecated + virtual void attach(FCGX_Stream * fcgx); +private: + fcgi_streambuf fcgi_strmbuf; +}; -// Here's the ostream class definition. -class fcgi_ostream : public ostream +/* + * fcgi_ostream - deprecated + */ +class DLLAPI fcgi_ostream : public std::ostream { - public: - fcgi_ostream(void); - fcgi_ostream(FCGX_Stream *str); - ~fcgi_ostream(); +public: + + // deprecated + fcgi_ostream(FCGX_Stream * fcgx = 0); + + // deprecated + ~fcgi_ostream(void) {} - // connects the fcgi_streambuf of an existing fcgi_ostream - // object to a given FCGI interface - virtual void attach(FCGX_Stream *str); + // deprecated + virtual void attach(FCGX_Stream *fcgx); - // lets us know if this object has been initialized - virtual int isdefined(void); +private: - private: - // FastCGI streambuf fcgi_streambuf fcgi_strmbuf; }; -#endif FCGIO_H +#endif /* FCGIO_H */