Line data Source code
1 : // Copyright (c) 2011-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/edhttp
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 :
20 : // self
21 : //
22 : #include "edhttp/string_part.h"
23 :
24 :
25 :
26 : // advgetopt
27 : //
28 : #include <advgetopt/validator_double.h>
29 :
30 :
31 : // snaplogger
32 : //
33 : #include <snaplogger/message.h>
34 :
35 :
36 : // snapdev
37 : //
38 : #include <snapdev/trim_string.h>
39 :
40 :
41 : // last include
42 : //
43 : #include <snapdev/poison.h>
44 :
45 :
46 :
47 : namespace edhttp
48 : {
49 :
50 :
51 :
52 : /** \brief The string_part constructor without parameters is for the vector.
53 : *
54 : * When initializing a vector, the class has to have a constructor with
55 : * no parameters. Unfortunate since we would prefer to not allow string_part
56 : * objects without a name which is considered mandatory (would have to
57 : * test again once we convert the class to only use the STL library.)
58 : */
59 0 : string_part::string_part()
60 : {
61 0 : }
62 :
63 :
64 : /** \brief Create a named string_part.
65 : *
66 : * This function is used to create a valid string_part object.
67 : *
68 : * \param[in] name The name of the string_part object.
69 : *
70 : * \sa get_name()
71 : */
72 70 : string_part::string_part(std::string const & name)
73 140 : : f_name(name)
74 : {
75 70 : }
76 :
77 :
78 : /** \brief Retrieve the string_part name.
79 : *
80 : * The name of a string_part object cannot be changed once it was created.
81 : *
82 : * You may retrieve the name with this function, though.
83 : *
84 : * \bug
85 : * It is currently possible to create a string_part object without a name
86 : * so the class works with QVector.
87 : *
88 : * \return The name as passed in when create the string_part object.
89 : */
90 154 : std::string const & string_part::get_name() const
91 : {
92 154 : return f_name;
93 : }
94 :
95 :
96 : /** \brief Retrieve the value of this part.
97 : *
98 : * By default, a part is not expected to include a value, but there
99 : * are many strings in HTTP headers that accept a syntax where parameters
100 : * can be given a value. For example, in the Cache-Control field, we
101 : * can have a "max-age=123" parameter. This function returns the "123".
102 : * The name ("max-age") is returned by the get_name() function.
103 : *
104 : * In a weighted HTTP string such as a string of language definitions,
105 : * the named value has no value. It is expected to represent a flag
106 : * which is set (i.e. do not interpret a part with an empty string
107 : * as "false").
108 : *
109 : * \return The value of this part of the string.
110 : */
111 0 : std::string const & string_part::get_value() const
112 : {
113 0 : return f_value;
114 : }
115 :
116 :
117 : /** \brief This function is used to setup the value of a part.
118 : *
119 : * This function defines the value of a part. By default a part is just
120 : * defined and its value is the empty string (it is still viewed as being
121 : * "true", but without anything more than that.)
122 : *
123 : * The function is called by the parser when it finds a part name followed
124 : * by an equal sign.
125 : *
126 : * \param[in] value The new value of this part.
127 : */
128 0 : void string_part::set_value(std::string const & value)
129 : {
130 0 : f_value = value;
131 0 : }
132 :
133 :
134 : /** \brief Retrieve the level of this string_part object.
135 : *
136 : * This function retrieves the level of the string_part object. It is a floating
137 : * point value.
138 : *
139 : * The level is taken from the "q" parameter. For example, in:
140 : *
141 : * \code
142 : * fr; q=0.3
143 : * \endcode
144 : *
145 : * the level is viewed as 0.3.
146 : *
147 : * \return The string_part object level.
148 : */
149 76 : string_part::level_t string_part::get_level() const
150 : {
151 76 : return f_level;
152 : }
153 :
154 :
155 : /** \brief Change the level of this part.
156 : *
157 : * This function saves the new \p level parameter in this string_part object.
158 : * Items without a level (q=<value>) parameter are assigned the special
159 : * value DEFAULT_LEVEL, which is 1.0.
160 : *
161 : * \bug
162 : * The function does not limit the level. It is expected to be defined
163 : * between 0.0 and 1.0, though.
164 : *
165 : * \param[in] level The new string_part level.
166 : */
167 36 : void string_part::set_level(string_part::level_t const level)
168 : {
169 36 : f_level = level;
170 36 : }
171 :
172 :
173 : /** \brief Retrieve the value of a parameter.
174 : *
175 : * This function returns the value of a parameter given its name.
176 : *
177 : * If the parameter is not exist defined, then the function returns
178 : * an empty string. A parameter may exist and be set to the empty
179 : * string. There is no way to know at this point.
180 : *
181 : * \param[in] name The name of the parameter to retrieve.
182 : *
183 : * \return The value of the parameter or "" if undefined.
184 : */
185 48 : std::string string_part::get_parameter(std::string const & name) const
186 : {
187 48 : auto const it(f_param.find(name));
188 48 : if(it == f_param.end())
189 : {
190 48 : return std::string();
191 : }
192 0 : return it->second;
193 : }
194 :
195 :
196 : /** \brief Add a parameter.
197 : *
198 : * This function is used to add a parameter to the string_part object.
199 : *
200 : * A parameter has a name and a value.
201 : *
202 : * \param[in] name The name of the parameter to add.
203 : * \param[in] value The value of the parameter.
204 : */
205 36 : void string_part::add_parameter(std::string const & name, std::string const & value)
206 : {
207 36 : f_param[name] = value;
208 36 : }
209 :
210 :
211 : /** \brief Convert one part back into a weighted HTTP string.
212 : *
213 : * This function builds one part of a weighted HTTP string. The string
214 : * will look something like:
215 : *
216 : * \code
217 : * es; q=0.8
218 : * \endcode
219 : *
220 : * \return The part converted to one string.
221 : */
222 79 : std::string string_part::to_string() const
223 : {
224 79 : std::string result(f_name);
225 :
226 118 : for(auto const & it : f_param)
227 : {
228 78 : std::string p(it.first);
229 39 : if(!it.second.empty())
230 : {
231 39 : p += '=';
232 39 : p += it.second;
233 : }
234 39 : result += "; ";
235 39 : result += p;
236 : }
237 :
238 79 : return result;
239 : }
240 :
241 :
242 : /** \brief Operator used to sort elements.
243 : *
244 : * This operator overload is used by the different sort algorithms
245 : * that we can apply against this type. In most cases, it is a
246 : * std::stable_sort(),
247 : *
248 : * The function compares the level of the two string_part objects involved.
249 : *
250 : * Note that we sort from the largest to the smallest level. In other
251 : * words, if this string_part has level 1.0 and \p rhs has level 0.5, the
252 : * function returns true (i.e. 1.0 > 0.5).
253 : *
254 : * \param[in] rhs The right hand side string_part object to compare against.
255 : *
256 : * \return true if this string_part is considered smaller than \p rhs.
257 : */
258 23 : bool string_part::operator < (string_part const & rhs) const
259 : {
260 23 : return f_level > rhs.f_level;
261 : }
262 :
263 :
264 :
265 : } // namespace edhttp
266 : // vim: ts=4 sw=4 et
|