diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2015-05-28 21:14:52 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2015-05-28 21:16:14 +0200 |
| commit | 720295848ea0d909cb39c004cbeaf1055fa7cffc (patch) | |
| tree | 3a4c0332f8145986ddfc1c83e89b9cf8a1491546 /src/header_parser.cc | |
| parent | 978bb2523f2eef42eca8dbe35e0ad351a4953aa7 (diff) | |
Start of CGI interface
Diffstat (limited to 'src/header_parser.cc')
| -rw-r--r-- | src/header_parser.cc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/header_parser.cc b/src/header_parser.cc new file mode 100644 index 0000000..163d65f --- /dev/null +++ b/src/header_parser.cc @@ -0,0 +1,107 @@ +#include "common.hh" + +#include "header_parser.hh" + +namespace stuff { + +namespace { + +bool read_token(std::string::const_iterator* begin, + const std::string::const_iterator& end, + std::string* out) { + auto i = *begin; + if (i == end) return false; + auto last = i; + out->clear(); + do { + if ((*i >= '^' && *i <= 'z') || + (*i >= '0' && *i <= '9') || + (*i >= '#' && *i <= '\'') || + *i == '!' || *i == '*' || *i == '+' || *i == '-' || *i == '.' || + *i == '|' || *i == '~') { + ++i; + } else if (*i >= 'A' && *i <= 'Z') { + out->insert(out->end(), last, i); + out->push_back('a' + *i - 'A'); + last = ++i; + } else { + break; + } + } while (i != end); + out->insert(out->end(), last, i); + *begin = i; + return true; +} + +bool read_quoted(std::string::const_iterator* begin, + const std::string::const_iterator& end, + std::string* out) { + auto i = *begin; + if (i == end || *i != '"') return false; + auto last = ++i; + out->clear(); + while (true) { + if (*i == '"') { + out->insert(out->end(), last, i); + *begin = ++i; + return true; + } else if (*i == '\\') { + out->insert(out->end(), last, i); + if (++i == end) return false; + if ((*i >= ' ' && *i <= '~') || + *i == '\t' || + (*i & 0x80)) { + out->push_back(*i); + last = ++i; + } else { + return false; + } + } else if ((*i >= '^' && *i <= '~') || + (*i >= '#' && *i <= '[') || + *i == '\t' || *i == ' ' || + (*i & 0x80)) { + ++i; + } else { + return false; + } + } +} + +} // namespace + +bool HeaderParser::parse(const std::string& in, std::string* token, + std::map<std::string, std::string>* parameters) { + auto i = in.begin(); + while (i != in.end() && (*i == ' ' || *i == '\t')) ++i; + if (!read_token(&i, in.end(), token)) return false; + while (true) { + if (i == in.end() || *i != '/') break; + std::string tmp; + token->push_back('/'); + ++i; + if (!read_token(&i, in.end(), &tmp)) return false; + token->append(tmp); + } + if (parameters) parameters->clear(); + while (i != in.end()) { + while (i != in.end() && (*i == ' ' || *i == '\t')) ++i; + if (i == in.end()) break; + if (*i != ';') return false; + ++i; + while (i != in.end() && (*i == ' ' || *i == '\t')) ++i; + if (i == in.end()) return false; + std::string key, value; + if (!read_token(&i, in.end(), &key)) return false; + if (i == in.end() || *i != '=') return false; + ++i; + if (i != in.end() && *i == '"') { + if (!read_quoted(&i, in.end(), &value)) return false; + } else { + if (!read_token(&i, in.end(), &value)) return false; + } + if (parameters) (*parameters)[key] = value; + } + return true; +} + +} // namespace stuff |
