Main Page | Namespace List | Class List | Directories | File List | Class Members | File Members

cgi_in.H

Go to the documentation of this file.
00001 /******************************************************************************
00002 *                          cgi_in.h                            2000-10-31 AgF *
00003 *                CGI interface for C++ programs                               *
00004 *******************************************************************************
00005 
00006 This header file defines the class CGI_Interface and the object cgi to
00007 facilitate web interface through CGI (Comman Gateway Interface).
00008 
00009 The constructor outputs a cgi header and reads input parameters from both
00010 POST and GET methods.
00011 
00012 Instructions:
00013 -------------
00014 Write #include <cgi_in.h> in the beginning of your C++ program to get easy
00015 access to input parameters.
00016 
00017 The member functions cgi.GetString(char * key), cgi.GetInt(char * key),
00018 and cgi.GetFloat(char * key) are used for getting the values for any input
00019 parameter, where key is the name of the parameter (case sensitive).
00020 
00021 Using with multiple modules:
00022 ----------------------------
00023 If your C++ program consists of multiple modules compiled separately,
00024 then #define NOTMAIN in all but one of the modules to avoid multiple
00025 instances of the object cgi.
00026 
00027 Testing on a PC:
00028 ----------------
00029 If the program is compiled on a PC (DOS or Windows) it will not attempt to
00030 read CGI input, which only exists on a web server. Instead, it will read
00031 the input from a file named input.txt. This file should have the format:
00032 PARAMETER1=VALUE1
00033 PARAMETER2=VALUE2
00034 PARAMETER3=VALUE3
00035 
00036 modified by Dan Spinosa 2005
00037 
00038 *****************************************************************************/
00039 
00040 #include <iostream>
00041 #include <string.h>
00042 #include <stdlib.h>
00043 
00044 const int MAXKEYS = 1000;          // max. number input parameters
00045 const int MAXINPUTLEN = 13000;    // max. total length of all inputs and keys
00046 
00047 using namespace std;
00048 
00049 // class CGI_Interface facilitates input/output
00051 class CGI_Interface {
00052 public:
00053    CGI_Interface();               // constructor
00054    char * GetString(char * key);  // get input parameter named 'key' as string
00055    int GetInt(char * key);        // get input parameter named 'key' as integer
00056    float GetFloat(char * key);    // get input parameter named 'key' as float
00057    int NumberOfKeys();            // get number of keys
00058    char * GetNextKey();           // call repeatedly to get all key names
00059    void BeginKey();               // reset GetNextKey
00060 protected:
00061    char InputBuffer[MAXINPUTLEN]; // stores all input
00062    char * keys[MAXKEYS];          // all keys (= field names)
00063    char * values[MAXKEYS];        // corresponding values
00064    int NumKeys;                   // number of keys
00065    int KeyIndex;                  // index for GetNextKey
00066 };
00067 
00068 //#ifdef __unix__  // check if compiled under unix (this is normal use)
00069 // constructor
00070 CGI_Interface::CGI_Interface() {
00071    //cout << "CGI INTERFACE CONSTRUCTOR" << endl;
00072    char * p; int len;
00073    //if it wasn't passed in (as a hack)
00074    // read input from cin
00075    cin.get(InputBuffer, MAXINPUTLEN, 0);
00076    // append input from QUERY_STRING
00077    p = getenv("QUERY_STRING"); 
00078    len = strlen(InputBuffer);
00079 
00080      
00081    if (p && *p && len + 4 < MAXINPUTLEN) {
00082       if (len > 1) strcat(InputBuffer,"&");
00083       strncat(InputBuffer, p, MAXINPUTLEN-len-1);
00084    }
00085    // InputBuffer has the form:
00086    // key1=value1&key2=value2&key3=value3 ...
00087    // split the string into keys and values:
00088    NumKeys = KeyIndex = 0; p = InputBuffer;
00089    while (NumKeys < MAXKEYS) {
00090       keys[NumKeys] = p;                 // pointer to key
00091       p = strchr (p, '=');               // search for '='
00092       if (p==0) break;                   // stop if '=' not found
00093       *p = 0;                            // end key string
00094       values[NumKeys++] = ++p;           // point to value
00095       p = strchr (p, '&');               // search for '&' separator
00096       if (p==0) break;                   // stop if '&' not found
00097       *p = 0; p++;                       // end value string
00098    }
00099    
00100    // translate special characters in values:
00101    for (int i=0; i<NumKeys; i++) {
00102       // replace all '+' with space
00103       p = values[i];
00104       while (1) {
00105          p = strchr(p,'+');
00106          if (p==0) break;
00107          *p = ' ';
00108       }
00109       // replace %XX with character that has hexadecimal code XX
00110       p = values[i];
00111       while (1) {
00112          p = strchr(p,'%');
00113          if (p==0) break;
00114          int hi = p[1] | 0x20;
00115          int lo = p[2] | 0x20;
00116          if (hi > '9') hi -= 87; else hi -= 48;
00117          if (lo > '9') lo -= 87; else lo -= 48;
00118          *p = (char)(hi * 16 + lo);
00119          strcpy (p+1, p+3); p++;
00120       }
00121    }
00122    // write cgi header to tell that the output is html:
00123    //cout << "Content-type: text/html\n\n";
00124 }
00125 
00126    /*
00127 #else // not compiled under unix. Assume it is compiled on PC for testing only
00128 
00129 #include <PC fstream.h>
00130 // PC test version of constructor
00131 CGI_Interface::CGI_Interface() {
00132    int len, spaceleft = MAXINPUTLEN-1; char * p, * q;
00133    NumKeys = KeyIndex = 0;
00134    // get input from file named input.txt
00135    ifstream inputfile("input.txt", ios::in);
00136    if (inputfile) {
00137       p = InputBuffer;
00138       // read from inputfile until end of file or InputBuffer full
00139       while (!inputfile.eof() && spaceleft > 1) {
00140          *p = 0;
00141          inputfile.getline(p, spaceleft);
00142          if (*p) {
00143             len = strlen(p);
00144             keys[NumKeys] = p;           // point to key
00145             q = strchr(p, '=');          // find '='
00146             if (q) {
00147                values[NumKeys++] = q+1;  // value comes after '='
00148                *q = 0;}                  // end key string
00149             p += len; spaceleft -= len;}}
00150       inputfile.close();}
00151    else {
00152       cout << "\nFile input.txt not found<p>\n";}}
00153 #endif
00154 */
00155 
00156 // get input as string
00157 char * CGI_Interface::GetString(char * key) {
00158    for (int i=0; i<NumKeys; i++) {
00159       if (strcmp(keys[i],key)==0) {
00160          return values[i];
00161       }
00162    }
00163    return "";
00164 }
00165 
00166 // get input as integer
00167 int CGI_Interface::GetInt(char * key) {
00168    for (int i=0; i<NumKeys; i++) {
00169       if (strcmp(keys[i],key)==0) {
00170          return atoi(values[i]);
00171       }
00172    }
00173    return 0;
00174 }
00175 
00176 // get input as float
00177 float CGI_Interface::GetFloat(char * key) {
00178    for (int i=0; i<NumKeys; i++) {
00179       if (strcmp(keys[i],key)==0) {
00180          return float(atof(values[i]));
00181       }
00182    }
00183    return 0.;
00184 }
00185 
00186 // get number of keys
00187 int CGI_Interface::NumberOfKeys() {
00188    return NumKeys;
00189 }
00190 
00191 // call repeatedly to get all keys
00192 char * CGI_Interface::GetNextKey() {
00193    if (KeyIndex >= NumKeys) return 0;
00194    return keys[KeyIndex++];
00195 }
00196 
00197 // reset GetNextKey
00198 void CGI_Interface::BeginKey() {
00199    KeyIndex = 0;
00200 }
00201 
00202 // define cgi interface object and call constructor
00203 #ifndef NOTMAIN
00204 //CGI_Interface cgi;
00205 #endif
00206 
00207 

Generated on Mon May 16 11:08:36 2005 for BikeQuest by  doxygen 1.4.0