tlx
Loading...
Searching...
No Matches
parse_uri_form_data.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * tlx/string/parse_uri_form_data.hpp
3 *
4 * Part of tlx - http://panthema.net/tlx
5 *
6 * Copyright (C) 2020 Timo Bingmann <tb@panthema.net>
7 *
8 * All rights reserved. Published under the Boost Software License, Version 1.0
9 ******************************************************************************/
10
11#ifndef TLX_STRING_PARSE_URI_FORM_DATA_HEADER
12#define TLX_STRING_PARSE_URI_FORM_DATA_HEADER
13
14#include <cstring>
15#include <string>
16#include <vector>
17
18namespace tlx {
19
20//! \addtogroup tlx_string
21//! \{
22
23/*!
24 * Helper function to decode %20 and + in urlencoded form data like
25 * "query=string+with+spaces&submit=yes%21&".
26 */
27static inline
29 const char* str, const char* end = nullptr) {
30 std::string out;
31 if (end == nullptr)
32 out.reserve(strlen(str));
33 else
34 out.reserve(end - str);
35 char a, b;
36
37 while (*str && str != end) {
38 if (*str == '%' && (a = str[1]) != 0 && (b = str[2]) != 0) {
39 if (a >= '0' && a <= '9')
40 a -= '0';
41 else if (a >= 'a' && a <= 'f')
42 a -= 'a' - 10;
43 else if (a >= 'A' && a <= 'F')
44 a -= 'A' - 10;
45 else {
46 // invalid hex digits, copy '%' and continue
47 out += *str++;
48 continue;
49 }
50
51 if (b >= '0' && b <= '9')
52 b -= '0';
53 else if (b >= 'a' && b <= 'f')
54 b -= 'a' - 10;
55 else if (b >= 'A' && b <= 'F')
56 b -= 'A' - 10;
57 else {
58 // invalid hex digits, copy '%' and continue
59 out += *str++;
60 continue;
61 }
62
63 out += static_cast<char>(16 * a + b);
64 str += 3;
65 }
66 else if (*str == '+') {
67 out += ' ';
68 str++;
69 }
70 else {
71 out += *str++;
72 }
73 }
74 return out;
75}
76
77/*!
78 * Parse a urlencoded form data like "query=string+with+spaces&submit=yes%21&"
79 * into a list of keys and values. The keys and values are returned as pairs in
80 * the two vectors, to avoid using std::pair or another struct.
81 */
82static inline
83void parse_uri_form_data(const char* query_string,
84 std::vector<std::string>* key,
85 std::vector<std::string>* value) {
86
87 key->clear(), value->clear();
88 const char* c = query_string;
89
90 while (*c != 0) {
91 const char* begin = c;
92 while (*c != '=' && *c != 0) {
93 ++c;
94 }
95
96 if (c == begin)
97 return;
98
99 std::string k = parse_uri_form_data_decode(begin, c);
100
101 if (*c == 0) {
102 key->emplace_back(std::move(k));
103 value->emplace_back(std::string());
104 return;
105 }
106
107 begin = ++c;
108 while (*c != '&' && *c != 0) {
109 ++c;
110 }
111
112 std::string v = parse_uri_form_data_decode(begin, c);
113
114 key->emplace_back(std::move(k));
115 value->emplace_back(std::move(v));
116
117 if (*c != '&')
118 break;
119 ++c;
120 }
121}
122
123/*!
124 * Parse a urlencoded form data like "query=string+with+spaces&submit=yes%21&"
125 * into a list of keys and values. The keys and values are returned as pairs in
126 * the two vectors, to avoid using std::pair or another struct.
127 */
128static inline
129void parse_uri_form_data(const std::string& query_string,
130 std::vector<std::string>* key,
131 std::vector<std::string>* value) {
132 return parse_uri_form_data(query_string.c_str(), key, value);
133}
134
135//! \}
136
137} // namespace tlx
138
139#endif // !TLX_STRING_PARSE_URI_FORM_DATA_HEADER
140
141/******************************************************************************/
static std::string parse_uri_form_data_decode(const char *str, const char *end=nullptr)
Helper function to decode %20 and + in urlencoded form data like "query=string+with+spaces&submit=yes...
static void parse_uri_form_data(const char *query_string, std::vector< std::string > *key, std::vector< std::string > *value)
Parse a urlencoded form data like "query=string+with+spaces&submit=yes%21&" into a list of keys and v...