C++ support - provided by Michael Richards <mimiker@scifair.acadiau.ca>n(Apollo Softw...
roberts [Sun, 15 Aug 1999 03:37:59 +0000 (03:37 +0000)]
include/fcgio.h [new file with mode: 0644]
libfcgi/fcgio.cpp [new file with mode: 0644]

diff --git a/include/fcgio.h b/include/fcgio.h
new file mode 100644 (file)
index 0000000..f573c11
--- /dev/null
@@ -0,0 +1,96 @@
+// fcgio.h - defines classes fcgio_buf, fcgio_ostream, fcgio_istream
+//           and replaces cin, cout and cerr with FastCGI versions
+//           you must include this file in any source file which 
+//           uses cin, cout or cerr. It must also appear at the end
+//           of your includes
+//
+// $Id: fcgio.h,v 1.1 1999/08/15 03:37:59 roberts Exp $
+//
+// This work is based on routines written by George Feinberg. They 
+// have been mostly re-written and extensively changed by 
+// Michael Richards.
+//
+// Copyright (c) 1999 by Apollo Software. All rights reserved.
+//
+// You are free to use this software without charge or royalty
+// as long as this notice is not removed or altered, and recognition 
+// is given to the author(s)
+//
+   
+#ifndef FCGIO_H
+#define FCGIO_H
+   
+#include <iostream.h>
+#include <fcgiapp.h>
+   
+
+// FastCGI streambuf replacement. Implements low level io to the 
+// FastCGI c functions so our higher level iostreams will talk
+// in the fcgi protocol
+class fcgio_buf : public streambuf {
+  // construction
+  public:
+    fcgio_buf( FCGX_Stream *str) { fcgi_str = str; }
+    ~fcgio_buf() {}
+   
+    // from streambuf
+    // tells the stream to go flush itself
+    virtual int sync();
+    // handles allocation of buffers by failing since buffer support isn't used
+    virtual int doallocate() { return 0; }
+   
+    virtual int xsgetn(char *s, int n);
+    virtual int xsputn(const char* s, int n);
+    virtual int overflow(int);
+    virtual int underflow();
+    virtual streambuf* setbuf(char* s, int n);
+   
+  private:
+    FCGX_Stream * fcgi_str;
+};
+
+   
+// Here's the ostream class definition. All it has to do is
+// call ios::init() passing an instance of fcgio_buf
+class fcgio_ostream : public ostream {
+  public:
+    fcgio_ostream(FCGX_Stream *str);
+    ~fcgio_ostream() { buf.sync(); }
+
+  private:
+    fcgio_buf buf;
+};
+
+
+// Here's the istream class definition. All it has to do is
+// call ios::init() passing an instance of fcgio_buf
+class fcgio_istream : public istream {
+  public:
+    fcgio_istream(FCGX_Stream *str);
+    ~fcgio_istream() {}
+
+  private:
+    // FastCGI stuff used for the FCGX_ functions
+    fcgio_buf buf;
+    // buffer for getting data
+    const int buffersize=100;
+    char buffer[buffersize];
+};
+
+
+// replace cin and cout with our own versions
+#ifndef USE_CIN_COUT_CERR
+  #undef cout   
+  #define cout (*FCGIX_cout)
+  extern fcgio_ostream *FCGIX_cout;
+
+  #undef cerr   
+  #define cerr (*FCGIX_cerr)
+  extern fcgio_ostream *FCGIX_cerr;
+
+  #undef cin
+  #define cin (*FCGIX_cin)
+  extern fcgio_istream *FCGIX_cin;
+#endif
+
+#endif __FCCIO_H__
diff --git a/libfcgi/fcgio.cpp b/libfcgi/fcgio.cpp
new file mode 100644 (file)
index 0000000..f43ac6c
--- /dev/null
@@ -0,0 +1,122 @@
+// FILE NAME: fcgio.cpp
+//
+// $Id: fcgio.cpp,v 1.1 1999/08/15 03:37:59 roberts Exp $
+//
+// 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
+//          -added buffered read support which is required by getline
+//
+// ORIGINAL AUTHOR: George Feinberg
+//
+// NOTES: encapsulates FCGI function in an ostream and replaces cin,
+//        cout and cerr
+//
+// This work is based on routines written by George Feinberg. They   
+// have been mostly re-written and extensively changed by
+// Michael Richards.
+//    
+// Copyright (c) 1999 by Apollo Software. All rights reserved.
+//
+// You are free to use this software without charge or royalty
+// as long as this notice is not removed or altered, and recognition
+// is given to the author(s)   
+//   
+
+#include <fcgiapp.h>
+#include "fcgio.h"
+
+
+// the definition that replaces cout and cin
+#ifndef USE_CIN_COUT_CERR
+  fcgio_ostream *FCGIX_cout;
+  fcgio_ostream *FCGIX_cerr;
+  fcgio_istream *FCGIX_cin;
+#endif
+   
+/*---------------------------------------------------------------------*/
+   
+
+// gets a number of characters at once for a more efficient implementation
+int fcgio_buf::xsgetn(char *s, int n) {
+  return FCGX_GetStr(s, n, fcgi_str);
+}
+   
+
+// writes a gob of data out, This is called for things like:
+// output << "hello world"
+// output.write(string, n);
+int fcgio_buf::xsputn(const char* s, int n) {
+  return FCGX_PutStr(s, n, fcgi_str);
+}
+   
+
+// overflow is called for "endl" and every time the put buffer
+// is full. Since we are using a single char put buffer, we just
+// pump the waiting character out and return the number of chars
+// we just got rid of (1). Returns EOF on error
+int fcgio_buf::overflow(int c) {
+  if (c)
+    return FCGX_PutChar(c, fcgi_str);
+  else
+    return EOF;
+}
+
+
+// Underflow is called to get characters to fill up the get buffer
+// so something that uses the stream can get the data. If there
+// is nothing else to read, this returns EOF
+int fcgio_buf::underflow() {
+  // if it is unbuffered, then get & return a char
+  if (unbuffered())
+    return FCGX_GetChar(fcgi_str);
+
+  // read as much data as we can, then adjust the get area so it
+  // reflects the data we just read
+  int numread=FCGX_GetStr(eback(), blen(), fcgi_str);
+  if (numread==0) return EOF;
+  setg(eback(),eback(),eback()+numread);
+
+  return *eback();
+}
+
+
+// sets up any buffering used for input or output   
+streambuf* fcgio_buf::setbuf(char *p, int n) {
+  // if setbuf is offered a buffer, then use it, otherwise, set the stream to unbuffered
+  setb(p,p+n,0);
+  // output is not buffered
+  setp(0,0);
+  setg(p,p+n,p+n);
+
+  unbuffered(p==NULL);
+  return this;
+}
+
+
+// flush all the output using FCGX_FFlush
+int fcgio_buf::sync() {
+  return FCGX_FFlush(fcgi_str); 
+}
+
+
+// constructor calls ios::init to assign our streambuf to
+// the ostream derived class. Also sets up buffering
+fcgio_ostream::fcgio_ostream(FCGX_Stream *str) : buf(str) {
+  // init is a protected member of ios
+  init(&buf);
+  buf.setbuf(NULL,0);
+}
+
+
+// constructor calls ios::init to assign our streambuf to
+// the ostream derived class. Also sets up buffering
+fcgio_istream::fcgio_istream(FCGX_Stream *str) : buf(str) {
+  // init is a protected member of ios
+  init(&buf);
+  // set up the buffers
+  buf.setbuf(buffer,buffersize);
+}
+
+