Listing 2 - Cgi class implementation.

  1: #include <iostream.h>
  2: #include <stdlib.h>
  3: #include <string.h>
  4: 
  5: #include "cgi++.h"
  6: 
  7: typedef struct _varval {
  8:   char* var;
  9:   char* val;
 10: } varval;
 11: 
 12: char x2c(char *what)
 13: {
 14:   register char digit;
 15: 
 16:   digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
 17:   digit *= 16;
 18:   digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
 19:   return digit;
 20: }
 21: 
 22: Cgi::Cgi()
 23: {
 24:   _nbPairs = 0;
 25:   _method = -1;
 26: 
 27:   char* method = getenv("REQUEST_METHOD");
 28:   if (method == NULL) return;
 29: 
 30:   if (strcmp(method, "GET") == 0) {
 31:     _method = GET;
 32: 
 33:     char* input = getenv("QUERY_STRING");
 34:     if (input == NULL) return;
 35:     parseInput(input);
 36:     return;
 37:   }
 38:   if (strcmp(method, "POST") == 0) {
 39:     _method = POST;
 40: 
 41:     int length = atoi(getenv("CONTENT_LENGTH"));
 42:     char* input = new char[length+1];
 43:     input[length] = 0;
 44:     cin.getline(input, length+1, EOF);
 45:     parseInput(input);
 46:     delete[] input;
 47:   }
 48: }
 49: 
 50: void Cgi::parseInput(char* input)
 51: {
 52:   int length = strlen(input);
 53:   if (length <= 0) return;
 54: 
 55:   // Count the number of var-val pairs and allocate memory for storing them.
 56:   for (int i=0; i<length; i++)
 57:     if (input[i] == '&') _nbPairs++;
 58:   _nbPairs++;
 59:   _pairs = new varval[_nbPairs];
 60: 
 61:   // Parse the input data.
 62:   char tmp[1024];
 63:   int t = 0, p = 0;
 64:   for (int i=0;; i++, t++) {
 65:     switch (input[i]) {
 66:     case '+':      // Unescape space character.
 67:       tmp[t] = ' ';
 68:       break;
 69:     case '%':      // Unescape URL-encoded characters.
 70:       tmp[t] = x2c(&input[i+1]);
 71:       i += 2;
 72:       break;
 73:     case '=':      // Var/val separator charactor.
 74:       _pairs[p].var = new char[t+1];
 75:       strncpy(_pairs[p].var, tmp, t);
 76:       _pairs[p].var[t] = 0;
 77:       t = -1;
 78:       break;
 79:     case '&':      // Var-val pairs separator character.
 80:       _pairs[p].val = new char[t+1];
 81:       strncpy(_pairs[p].val, tmp, t);
 82:       _pairs[p].val[t] = 0;
 83:       t = -1;
 84:       p++;
 85:       break;
 86:     case 0:        // End of data input.
 87:       _pairs[p].val = new char[t+1];
 88:       strncpy(_pairs[p].val, tmp, t);
 89:       _pairs[p].val[t] = 0;
 90:       return;
 91:     default:       // Copy into tmp.
 92:       tmp[t] = input[i];
 93:       break;
 94:     }
 95:   }
 96: }
 97: 
 98: Cgi::~Cgi()
 99: {
100:   if (_nbPairs > 0) {
101:     for (int i=0; i<_nbPairs; i++) {
102:       delete[] _pairs[i].var;
103:       delete[] _pairs[i].val;
104:     }
105:     delete[] _pairs;
106:   }
107: }
108: 
109: int Cgi::method() const
110: {
111:   return _method;
112: }
113: 
114: int Cgi::exist() const
115: {
116:   return _nbPairs;
117: }
118: 
119: int Cgi::exist(const char* param) const
120: {
121:   for (int i=0; i<_nbPairs; i++)
122:     if (strcmp(param, _pairs[i].var) == 0) return 1;
123:   return 0;
124: }
125: 
126: char* Cgi::value(const char* param)
127: {
128:   for (int i=0; i<_nbPairs; i++)
129:     if (strcmp(param, _pairs[i].var) == 0) return _pairs[i].val;
130:   return NULL;
131: }