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: }