#include #include #include //for getenv, EXIT_SUCCESS, EXIT_FAILURE #include //for class string #include //for class map using namespace std; map m; //will hold information from form bool get_input(); string display_color(const string& s); int main() { cout << "Content-type: text/html\n\n"; //CGI MIME-type header cout << "\n" "\n" "\n" "Gateway\n" "\n" "\n" "\n" "

Gateway

\n"; if (get_input()) { //Input successfully loaded into the map m. cout << "
    \n"; //ordered list for (const auto& pair: m) { cout << "
  1. " << pair.first << "=" << pair.second << display_color(pair.second) << "
  2. \n"; } cout << "
\n"; } cout << "\n" "\n"; return EXIT_SUCCESS; } bool get_input() { const char *const p {getenv("CONTENT_LENGTH")}; if (p == nullptr) { cout << "Environment has no CONTENT_LENGTH\n"; return false; } const int content_length {stoi(p)}; //convert "string to integer" string s; s.resize(content_length); //Make s big enough to hold all the data. cin.read(&s[0], content_length); //Read the data into s. if (!cin) { cout << "Unable to input " << content_length << " bytes.\n"; return false; } //Copy the data into ss. //The data can then be read from ss the way we read data from cin. stringstream ss {s}; string line; while (getline(ss, line, '&')) { const size_t pos {line.find('=')}; if (pos != std::string::npos) { //If we found the '=', //The key is everything before the '='. //The value is everything after the '='. const string key {line.substr(0, pos)}; const string value {line.substr(pos + 1)}; m[key] = value; //m.operator[](key) = value; } } return true; } //If s is of the form %23rrggbb, return an HTML SPAN element to display a sample //of that color. The %23 is the ASCII code of the character '#'. string display_color(const string& s) { string html; if (s.substr(0, 3) == "%23" && s.size() == 3 + 6) { html = "          "; } return html; }