/cgi/parser.cpp

https://bitbucket.org/nileshgr/cxxcms/ · C++ · 81 lines · 53 code · 14 blank · 14 comment · 31 complexity · 06b05f595cb02e9e838a7f35d5d387eb MD5 · raw file

  1. #include <cgi/cgi.hpp>
  2. /*! \file parser.cpp
  3. \brief Implementation of CGI::Parser
  4. */
  5. namespace CGI {
  6. /*
  7. * Implementation of the Parser class
  8. */
  9. /*
  10. * Constructor has been defined in the header itself
  11. * because it should be inlined, it conatins just one function call to setQstr()
  12. */
  13. void Parser::_sanitize(std::string& s, size_t n) const {
  14. size_t i;
  15. for (i = n; i < s.size(); i++) {
  16. if (s.at(i) == '&' or s.at(i) == '=' or s.at(i) == ';') {
  17. if (i == 0) break;
  18. if (s.at(i-1) == '&' or s.at(i-1) == '=' or s.at(i-1) == ';') {
  19. s.erase(i,1);
  20. _sanitize(s,i);
  21. }
  22. }
  23. }
  24. while (s.at(0) == '=' or s.at(0) == '&' or s.at(0) == ';')
  25. s.erase(0,1);
  26. while (s.at(s.size()-1) == '=' or s.at(s.size()-1) == '&' or s.at(s.size()-1) == ';')
  27. s.erase(s.size()-1,1);
  28. }
  29. Dict_ptr_t Parser::parse() const {
  30. std::string copy = getQstr(), extract = "";
  31. _sanitize(copy);
  32. size_t delimiter = std::string::npos;
  33. Dict_ptr_t ret (new Dict_t);
  34. std::string key = "", value = "";
  35. while(copy.size()) {
  36. if((delimiter = copy.find('&')) != std::string::npos or
  37. (delimiter = copy.find(';')) != std::string::npos) {
  38. extract = copy.substr(0, delimiter);
  39. copy.erase(0, delimiter + 1);
  40. }
  41. else {
  42. extract = copy;
  43. copy.clear();
  44. }
  45. if((delimiter = extract.find('=')) != std::string::npos) {
  46. key = extract.substr(0, delimiter);
  47. value = extract.substr(delimiter + 1);
  48. extract.clear();
  49. }
  50. else {
  51. key = extract;
  52. value = "";
  53. extract.clear();
  54. }
  55. if((delimiter = key.find('%')) != std::string::npos)
  56. key.replace(delimiter, delimiter + 3, 1, decodeHex(key.substr(delimiter, delimiter + 3)));
  57. /*
  58. * For some strange reason value.find() returns pos + 1 for position for %
  59. * Hence a hack has been added here. If troublesome, remove -1 and change 4 to 3.
  60. */
  61. if((delimiter = value.find('%') != std::string::npos))
  62. value.replace(delimiter-1, delimiter + 4, 1, decodeHex(value.substr(delimiter-1, delimiter + 4)));
  63. ret->insert(Tuple_t(key, value));
  64. }
  65. return ret;
  66. }
  67. }