Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qurlquery.cpp
Go to the documentation of this file.
1
// Copyright (C) 2021 Intel Corporation.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:critical reason:data-parser
4
5
#
include
"qurlquery.h"
6
#
include
"qurl_p.h"
7
8
#
include
<
QtCore
/
qhashfunctions
.
h
>
9
#
include
<
QtCore
/
qstringlist
.
h
>
10
11
#
include
<
algorithm
>
12
13
QT_BEGIN_NAMESPACE
14
15
/*!
16
\class QUrlQuery
17
\inmodule QtCore
18
\since 5.0
19
20
\brief The QUrlQuery class provides a way to manipulate a key-value pairs in
21
a URL's query.
22
23
\reentrant
24
\ingroup io
25
\ingroup network
26
\ingroup shared
27
28
\compares equality
29
30
It is used to parse the query strings found in URLs like the following:
31
32
\image qurl-querystring.png {Illustration of a URL with part after question mark
33
highlighted as query string.}
34
35
Query strings like the above are used to transmit options in the URL and are
36
usually decoded into multiple key-value pairs. The one above would contain
37
two entries in its list, with keys "type" and "color". QUrlQuery can also be
38
used to create a query string suitable for use in QUrl::setQuery() from the
39
individual components of the query.
40
41
The most common way of parsing a query string is to initialize it in the
42
constructor by passing it the query string. Otherwise, the setQuery() method
43
can be used to set the query to be parsed. That method can also be used to
44
parse a query with non-standard delimiters, after having set them using the
45
setQueryDelimiters() function.
46
47
The encoded query string can be obtained again using query(). This will take
48
all the internally-stored items and encode the string using the delimiters.
49
50
\section1 Encoding
51
52
All of the getter methods in QUrlQuery support an optional parameter of type
53
QUrl::ComponentFormattingOptions, including query(), which dictate how to
54
encode the data in question. Except for QUrl::FullyDecoded, the returned value must
55
still be considered a percent-encoded string, as there are certain values
56
which cannot be expressed in decoded form (like control characters, byte
57
sequences not decodable to UTF-8). For that reason, the percent character is
58
always represented by the string "%25".
59
60
All of the setter methods and the query methods like hasQueryItem() in
61
QUrlQuery take encoded forms only. Unlike in QUrl, there's no optional
62
parameter to specify that the strings being passed are decoded. If
63
improperly-encoded strings are passed to the setter or query methods,
64
QUrlQuery will attempt to recover instead of failing. That is to say, all
65
functions in this class parse their string arguments as if the
66
QUrl::TolerantMode decoding mode was specified.
67
68
Application code should strive to always ensure proper encoding and not rely
69
on TolerantMode parsing fixing the strings. Notably, all user input must be
70
first percent-encoded using QUrl::toPercentEncoding() or similar functions
71
before being passed to the functions in this class.
72
73
\section2 Handling of spaces and plus ("+")
74
75
Web browsers usually encode spaces found in HTML FORM elements to a plus sign
76
("+") and plus signs to its percent-encoded form (%2B). However, the Internet
77
specifications governing URLs do not consider spaces and the plus character
78
equivalent.
79
80
For that reason, QUrlQuery never encodes the space character to "+" and will
81
never decode "+" to a space character. Instead, space characters will be
82
rendered "%20" in encoded form.
83
84
To support encoding like that of HTML forms, QUrlQuery also never decodes the
85
"%2B" sequence to a plus sign nor encode a plus sign. In fact, any "%2B" or
86
"+" sequences found in the keys, values, or query string are left exactly
87
like written (except for the uppercasing of "%2b" to "%2B").
88
89
\section2 Full decoding
90
91
With QUrl::FullyDecoded formatting, all percent-encoded sequences will be
92
decoded fully and the '%' character is used to represent itself.
93
QUrl::FullyDecoded should be used with care, since it may cause data loss.
94
See the documentation of QUrl::FullyDecoded for information on what data may
95
be lost.
96
97
This formatting mode should be used only when dealing with text presented to
98
the user in contexts where percent-encoding is not desired. Note that
99
QUrlQuery setters and query methods do not support the counterpart
100
QUrl::DecodedMode parsing, so using QUrl::FullyDecoded to obtain a listing of
101
keys may result in keys not found in the object.
102
103
\section1 Non-standard delimiters
104
105
By default, QUrlQuery uses an equal sign ("=") to separate a key from its
106
value, and an ampersand ("&") to separate key-value pairs from each other. It
107
is possible to change the delimiters that QUrlQuery uses for parsing and for
108
reconstructing the query by calling setQueryDelimiters().
109
110
Non-standard delimiters should be chosen from among what RFC 3986 calls
111
"sub-delimiters". They are:
112
113
\snippet code/src_corelib_io_qurlquery.cpp 0
114
115
Use of other characters is not supported and may result in unexpected
116
behaviour. QUrlQuery does not verify that you passed a valid delimiter.
117
118
\sa QUrl
119
*/
120
121
/*!
122
\fn QUrlQuery &QUrlQuery::operator=(QUrlQuery &&other)
123
124
Move-assigns \a other to this QUrlQuery instance.
125
126
\since 5.2
127
*/
128
129
/*!
130
\fn QUrlQuery::QUrlQuery(std::initializer_list<std::pair<QString, QString>> list)
131
132
\since 5.13
133
134
Constructs a QUrlQuery object from the \a list of key/value pair.
135
*/
136
137
typedef
QList<std::pair<QString, QString> > Map;
138
139
class
QUrlQueryPrivate
:
public
QSharedData
140
{
141
public
:
142
QUrlQueryPrivate
(
const
QString &query = QString())
143
:
valueDelimiter
(
QUrlQuery
::
defaultQueryValueDelimiter
()),
144
pairDelimiter
(
QUrlQuery
::
defaultQueryPairDelimiter
())
145
{
if
(!query.isEmpty()) setQuery(query); }
146
147
QString
recodeFromUser
(
const
QString &input)
const
;
148
QString
recodeToUser
(
const
QString &input, QUrl::ComponentFormattingOptions encoding)
const
;
149
150
void
setQuery
(
const
QString &query);
151
152
void
addQueryItem
(
const
QString &key,
const
QString &value)
153
{ itemList.append(std::make_pair(recodeFromUser(key), recodeFromUser(value))); }
154
int
findRecodedKey
(
const
QString &key,
int
from = 0)
const
155
{
156
for
(
int
i = from; i < itemList.size(); ++i)
157
if
(itemList.at(i).first == key)
158
return
i;
159
return
itemList.size();
160
}
161
Map
::
const_iterator
findKey
(
const
QString &key)
const
162
{
return
itemList.constBegin() + findRecodedKey(recodeFromUser(key)); }
163
Map
::
iterator
findKey
(
const
QString &key)
164
{
return
itemList.begin() + findRecodedKey(recodeFromUser(key)); }
165
166
Map
itemList
;
167
QChar
valueDelimiter
;
168
QChar
pairDelimiter
;
169
};
170
QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QUrlQueryPrivate)
171
172
template
<>
void
QSharedDataPointer<QUrlQueryPrivate>::detach()
173
{
174
if
(d && d->ref.loadRelaxed() == 1)
175
return
;
176
QUrlQueryPrivate *x = (d ?
new
QUrlQueryPrivate(*d)
177
:
new
QUrlQueryPrivate);
178
x->ref.ref();
179
if
(d && !d->ref.deref())
180
delete
d.get();
181
d.reset(x);
182
}
183
184
// Here's how we do the encoding in QUrlQuery
185
// The RFC says these are the delimiters:
186
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
187
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
188
// / "*" / "+" / "," / ";" / "="
189
// And the definition of query is:
190
// query = *( pchar / "/" / "?" )
191
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
192
//
193
// The strict definition of query says that it can have unencoded any
194
// unreserved, sub-delim, ":", "@", "/" and "?". Or, by exclusion, excluded
195
// delimiters are "#", "[" and "]" -- if those are present, they must be
196
// percent-encoded. The fact that "[" and "]" should be encoded is probably a
197
// mistake in the spec, so we ignore it and leave the decoded.
198
//
199
// The internal storage in the Map is equivalent to PrettyDecoded. That means
200
// the getter methods, when called with the default encoding value, will not
201
// have to recode anything (except for toString()).
202
//
203
// QUrlQuery handling of delimiters is quite simple: we never touch any of
204
// them, except for the "#" character and the pair and value delimiters. Those
205
// are always kept in their decoded forms.
206
//
207
// But when recreating the query string, in toString(), we must take care of
208
// the special delimiters: the pair and value delimiters, as well as the "#"
209
// character if unambiguous decoding is requested.
210
211
#
define
decode
(
x
)
ushort
(
x
)
212
#
define
leave
(
x
)
ushort
(
0x100
|
(
x
)
)
213
#
define
encode
(
x
)
ushort
(
0x200
|
(
x
)
)
214
215
inline
QString
QUrlQueryPrivate
::
recodeFromUser
(
const
QString &input)
const
216
{
217
// note: duplicated in setQuery()
218
QString
output;
219
ushort prettyDecodedActions[] = {
220
decode
(pairDelimiter.unicode()),
221
decode
(valueDelimiter.unicode()),
222
decode
(
'#'
),
223
0
224
};
225
if
(qt_urlRecode(output, input,
226
QUrl::DecodeReserved,
227
prettyDecodedActions))
228
return
output;
229
return
input;
230
}
231
232
inline
bool
idempotentRecodeToUser
(QUrl::ComponentFormattingOptions encoding)
233
{
234
return
encoding == QUrl::PrettyDecoded;
235
}
236
237
inline
QString
QUrlQueryPrivate
::
recodeToUser
(
const
QString &input, QUrl::ComponentFormattingOptions encoding)
const
238
{
239
// our internal formats are stored in "PrettyDecoded" form
240
// and there are no ambiguous characters
241
if
(idempotentRecodeToUser(encoding))
242
return
input;
243
244
if
(!(encoding & QUrl::EncodeDelimiters)) {
245
QString
output;
246
if
(qt_urlRecode(output, input,
247
encoding,
nullptr
))
248
return
output;
249
return
input;
250
}
251
252
// re-encode the "#" character and the query delimiter pair
253
ushort actions[] = {
encode
(pairDelimiter.unicode()),
encode
(valueDelimiter.unicode()),
254
encode
(
'#'
), 0 };
255
QString
output;
256
if
(qt_urlRecode(output, input, encoding, actions))
257
return
output;
258
return
input;
259
}
260
261
void
QUrlQueryPrivate
::
setQuery
(
const
QString &query)
262
{
263
ushort prettyDecodedActions[] = {
264
decode
(pairDelimiter.unicode()),
265
decode
(valueDelimiter.unicode()),
266
decode
(
'#'
),
267
0
268
};
269
270
itemList.clear();
271
const
QChar *pos = query.constData();
272
const
QChar *
const
end = pos + query.size();
273
while
(pos != end) {
274
const
QChar *begin = pos;
275
const
QChar *delimiter =
nullptr
;
276
while
(pos != end) {
277
// scan for the component parts of this pair
278
if
(!delimiter && *pos == valueDelimiter)
279
delimiter = pos;
280
if
(*pos == pairDelimiter)
281
break
;
282
++pos;
283
}
284
if
(!delimiter)
285
delimiter = pos;
286
287
// pos is the end of this pair (the end of the string or the pair delimiter)
288
// delimiter points to the value delimiter or to the end of this pair
289
290
QString
key;
291
if
(!qt_urlRecode(key, QStringView{begin, delimiter},
292
QUrl::DecodeReserved,
293
prettyDecodedActions))
294
key = QString(begin, delimiter - begin);
295
296
if
(delimiter == pos) {
297
// the value delimiter wasn't found, store a null value
298
itemList.append(std::make_pair(key, QString()));
299
}
else
if
(delimiter + 1 == pos) {
300
// if the delimiter was found but the value is empty, store empty-but-not-null
301
itemList.append(std::make_pair(key, QString(0, Qt::Uninitialized)));
302
}
else
{
303
QString
value;
304
if
(!qt_urlRecode(value, QStringView{delimiter + 1, pos},
305
QUrl::DecodeReserved,
306
prettyDecodedActions))
307
value = QString(delimiter + 1, pos - delimiter - 1);
308
itemList.append(std::make_pair(key, value));
309
}
310
311
if
(pos != end)
312
++pos;
313
}
314
}
315
316
// allow QUrlQueryPrivate to detach from null
317
template
<>
inline
QUrlQueryPrivate *
318
QSharedDataPointer<QUrlQueryPrivate>::clone()
319
{
320
return
d ?
new
QUrlQueryPrivate(*d) :
new
QUrlQueryPrivate;
321
}
322
323
/*!
324
Constructs an empty QUrlQuery object. A query can be set afterwards by
325
calling setQuery() or items can be added by using addQueryItem().
326
327
\sa setQuery(), addQueryItem()
328
*/
329
QUrlQuery::QUrlQuery()
330
: d(
nullptr
)
331
{
332
}
333
334
/*!
335
Constructs a QUrlQuery object and parses the \a queryString query string,
336
using the default query delimiters. To parse a query string using other
337
delimiters, you should first set them using setQueryDelimiters() and then
338
set the query with setQuery().
339
*/
340
QUrlQuery::QUrlQuery(
const
QString &queryString)
341
: d(queryString.isEmpty() ?
nullptr
:
new
QUrlQueryPrivate(queryString))
342
{
343
}
344
345
/*!
346
Constructs a QUrlQuery object and parses the query string found in the \a
347
url URL, using the default query delimiters. To parse a query string using
348
other delimiters, you should first set them using setQueryDelimiters() and
349
then set the query with setQuery().
350
351
\sa QUrl::query()
352
*/
353
QUrlQuery::QUrlQuery(
const
QUrl &url)
354
: d(
nullptr
)
355
{
356
// use internals to avoid unnecessary recoding
357
// ### FIXME: actually do it
358
if
(url.hasQuery())
359
d =
new
QUrlQueryPrivate(url.query());
360
}
361
362
/*!
363
Copies the contents of the \a other QUrlQuery object, including the query
364
delimiters.
365
*/
366
QUrlQuery::QUrlQuery(
const
QUrlQuery &other)
367
: d(other.d)
368
{
369
}
370
371
/*!
372
\fn QUrlQuery::QUrlQuery(QUrlQuery &&other) noexcept
373
\since 6.5
374
Moves the contents of the \a other QUrlQuery object, including the query
375
delimiters.
376
*/
377
378
/*!
379
Copies the contents of the \a other QUrlQuery object, including the query
380
delimiters.
381
*/
382
QUrlQuery &QUrlQuery::operator =(
const
QUrlQuery &other)
383
{
384
d = other.d;
385
return
*
this
;
386
}
387
388
/*!
389
\fn void QUrlQuery::swap(QUrlQuery &other)
390
\memberswap{URL query instance}
391
*/
392
393
/*!
394
Destroys this QUrlQuery object.
395
*/
396
QUrlQuery::~QUrlQuery()
397
{
398
// d auto-deletes
399
}
400
401
/*!
402
\fn bool QUrlQuery::operator==(const QUrlQuery &lhs, const QUrlQuery &rhs)
403
404
Returns \c true if QUrlQuery objects \a lhs and \a rhs contain the same
405
contents, in the same order, and use the same query delimiters.
406
*/
407
408
bool
comparesEqual
(
const
QUrlQuery &lhs,
const
QUrlQuery &rhs)
409
{
410
if
(lhs.d == rhs.d)
411
return
true
;
412
if
(lhs.d && rhs.d)
413
// keep in sync with qHash(QUrlQuery):
414
return
lhs.d->valueDelimiter == rhs.d->valueDelimiter &&
415
lhs.d->pairDelimiter == rhs.d->pairDelimiter &&
416
lhs.d->itemList == rhs.d->itemList;
417
418
const
QUrlQueryPrivate
*x = lhs.d ? lhs.d.data() : rhs.d.data();
419
return
x->valueDelimiter == QUrlQuery::defaultQueryValueDelimiter() &&
420
x->pairDelimiter == QUrlQuery::defaultQueryPairDelimiter() &&
421
x->itemList.isEmpty();
422
}
423
424
/*!
425
\since 5.6
426
\qhashold{QUrlQuery}
427
*/
428
size_t
qHash
(
const
QUrlQuery &key, size_t seed)
noexcept
429
{
430
if
(
const
QUrlQueryPrivate
*d = key.d) {
431
// keep in sync with operator==:
432
return
qHashMulti(seed, d->valueDelimiter, d->pairDelimiter, d->itemList);
433
}
434
return
seed;
435
}
436
437
/*!
438
Returns \c true if this QUrlQuery object contains no key-value pairs, such as
439
after being default-constructed or after parsing an empty query string.
440
441
\sa setQuery(), clear()
442
*/
443
bool
QUrlQuery::isEmpty()
const
444
{
445
return
d ? d->itemList.isEmpty() :
true
;
446
}
447
448
/*!
449
\internal
450
*/
451
bool
QUrlQuery::isDetached()
const
452
{
453
return
d && d->ref.loadRelaxed() == 1;
454
}
455
456
/*!
457
Clears this QUrlQuery object by removing all of the key-value pairs
458
currently stored. If the query delimiters have been changed, this function
459
will leave them with their changed values.
460
461
\sa isEmpty(), setQueryDelimiters()
462
*/
463
void
QUrlQuery::clear()
464
{
465
if
(d.constData())
466
d->itemList.clear();
467
}
468
469
/*!
470
Parses the query string in \a queryString and sets the internal items to
471
the values found there. If any delimiters have been specified with
472
setQueryDelimiters(), this function will use them instead of the default
473
delimiters to parse the string.
474
*/
475
void
QUrlQuery::setQuery(
const
QString &queryString)
476
{
477
d->setQuery(queryString);
478
}
479
480
static
void
recodeAndAppend
(QString &to,
const
QString &input,
481
QUrl::ComponentFormattingOptions encoding,
const
ushort *tableModifications)
482
{
483
if
(!qt_urlRecode(to, input, encoding, tableModifications))
484
to += input;
485
}
486
487
/*!
488
Returns the reconstructed query string, formed from the key-value pairs
489
currently stored in this QUrlQuery object and separated by the query
490
delimiters chosen for this object. The keys and values are encoded using
491
the options given by the \a encoding parameter.
492
493
For this function, the only ambiguous delimiter is the hash ("#"), as in
494
URLs it is used to separate the query string from the fragment that may
495
follow.
496
497
The order of the key-value pairs in the returned string is exactly the same
498
as in the original query.
499
500
\sa setQuery(), QUrl::setQuery(), QUrl::fragment(), {encoding}{Encoding}
501
*/
502
QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding)
const
503
{
504
if
(!d)
505
return
QString();
506
507
// unlike the component encoding, for the whole query we need to modify a little:
508
// - the "#" character is unambiguous, so we encode it in EncodeDelimiters mode
509
// - the query delimiter pair must always be encoded
510
511
// start with what's always encoded
512
ushort tableActions[] = {
513
encode
(d->pairDelimiter.unicode()),
// 0
514
encode
(d->valueDelimiter.unicode()),
// 1
515
0,
// 2
516
0
517
};
518
if
(encoding & QUrl::EncodeDelimiters) {
519
tableActions[2] =
encode
(
'#'
);
520
}
521
522
QString result;
523
Map::const_iterator it = d->itemList.constBegin();
524
Map::const_iterator end = d->itemList.constEnd();
525
526
{
527
int
size = 0;
528
for
( ; it != end; ++it)
529
size += it->first.size() + 1 + it->second.size() + 1;
530
result.reserve(size + size / 4);
531
}
532
533
for
(it = d->itemList.constBegin(); it != end; ++it) {
534
if
(!result.isEmpty())
535
result += QChar(d->pairDelimiter);
536
recodeAndAppend(result, it->first, encoding, tableActions);
537
if
(!it->second.isNull()) {
538
result += QChar(d->valueDelimiter);
539
recodeAndAppend(result, it->second, encoding, tableActions);
540
}
541
}
542
return
result;
543
}
544
545
/*!
546
Sets the characters used for delimiting between keys and values,
547
and between key-value pairs in the URL's query string. The default
548
value delimiter is '=' and the default pair delimiter is '&'.
549
550
\image qurl-querystring.png {Illustration of a URL with part after
551
question mark highlighted as query string.}
552
553
\a valueDelimiter will be used for separating keys from values,
554
and \a pairDelimiter will be used to separate key-value pairs.
555
Any occurrences of these delimiting characters in the encoded
556
representation of the keys and values of the query string are
557
percent encoded when returned in query().
558
559
If \a valueDelimiter is set to ',' and \a pairDelimiter is ';',
560
the above query string would instead be represented like this:
561
562
\snippet code/src_corelib_io_qurl.cpp 4
563
564
\note Non-standard delimiters should be chosen from among what RFC 3986 calls
565
"sub-delimiters". They are:
566
567
\snippet code/src_corelib_io_qurlquery.cpp 0
568
569
Use of other characters is not supported and may result in unexpected
570
behavior. This method does not verify that you passed a valid delimiter.
571
572
\sa queryValueDelimiter(), queryPairDelimiter()
573
*/
574
void
QUrlQuery::setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter)
575
{
576
d->valueDelimiter = valueDelimiter;
577
d->pairDelimiter = pairDelimiter;
578
}
579
580
/*!
581
Returns the character used to delimit between keys and values when
582
reconstructing the query string in query() or when parsing in setQuery().
583
584
\sa setQueryDelimiters(), queryPairDelimiter()
585
*/
586
QChar QUrlQuery::queryValueDelimiter()
const
587
{
588
return
d ? d->valueDelimiter : defaultQueryValueDelimiter();
589
}
590
591
/*!
592
Returns the character used to delimit between keys-value pairs when
593
reconstructing the query string in query() or when parsing in setQuery().
594
595
\sa setQueryDelimiters(), queryValueDelimiter()
596
*/
597
QChar QUrlQuery::queryPairDelimiter()
const
598
{
599
return
d ? d->pairDelimiter : defaultQueryPairDelimiter();
600
}
601
602
/*!
603
Sets the items in this QUrlQuery object to \a query. The order of the
604
elements in \a query is preserved.
605
606
\note This method does not treat spaces (ASCII 0x20) and plus ("+") signs
607
as the same, like HTML forms do. If you need spaces to be represented as
608
plus signs, use actual plus signs.
609
610
\note The keys and values are expected to be in percent-encoded form. This
611
function will try to recover if improperly-encoded inputs are provided, but
612
that may produce data loss. See \l{QUrlQuery#Encoding} for more information.
613
614
\sa queryItems(), isEmpty()
615
*/
616
void
QUrlQuery::setQueryItems(
const
QList<std::pair<QString, QString> > &query)
617
{
618
clear();
619
if
(query.isEmpty())
620
return
;
621
622
QUrlQueryPrivate *dd = d;
623
QList<std::pair<QString, QString> >::const_iterator it = query.constBegin(),
624
end = query.constEnd();
625
for
( ; it != end; ++it)
626
dd->addQueryItem(it->first, it->second);
627
}
628
629
/*!
630
Returns the query string of the URL, as a map of keys and values, using the
631
options specified in \a encoding to encode the items. The order of the
632
elements is the same as the one found in the query string or set with
633
setQueryItems().
634
635
\sa setQueryItems(), {encoding}{Encoding}
636
*/
637
QList<std::pair<QString, QString> > QUrlQuery::queryItems(QUrl::ComponentFormattingOptions encoding)
const
638
{
639
if
(!d)
640
return
QList<std::pair<QString, QString> >();
641
if
(idempotentRecodeToUser(encoding))
642
return
d->itemList;
643
644
QList<std::pair<QString, QString> > result;
645
Map::const_iterator it = d->itemList.constBegin();
646
Map::const_iterator end = d->itemList.constEnd();
647
result.reserve(d->itemList.size());
648
for
( ; it != end; ++it)
649
result << std::make_pair(d->recodeToUser(it->first, encoding),
650
d->recodeToUser(it->second, encoding));
651
return
result;
652
}
653
654
/*!
655
Returns \c true if there is a query string pair whose key is equal
656
to \a key from the URL.
657
658
\note The key expected to be in percent-encoded form. This function will
659
try to recover if an improperly-encoded input is provided, but that may
660
produce data loss. See \l{QUrlQuery#Encoding} for more information.
661
662
\sa addQueryItem(), queryItemValue()
663
*/
664
bool
QUrlQuery::hasQueryItem(
const
QString &key)
const
665
{
666
if
(!d)
667
return
false
;
668
return
d->findKey(key) != d->itemList.constEnd();
669
}
670
671
/*!
672
Appends the pair \a key = \a value to the end of the query string of the
673
URL. This method does not overwrite existing items that might exist with
674
the same key.
675
676
\note This method does not treat spaces (ASCII 0x20) and plus ("+") signs
677
as the same, like HTML forms do. If you need spaces to be represented as
678
plus signs, use actual plus signs.
679
680
\note The key and value strings are expected to be in percent-encoded form.
681
This function will try to recover if improperly-encoded inputs are
682
provided, but that may produce data loss. See \l{QUrlQuery#Encoding} for
683
more information.
684
685
\sa hasQueryItem(), queryItemValue()
686
*/
687
void
QUrlQuery::addQueryItem(
const
QString &key,
const
QString &value)
688
{
689
d->addQueryItem(key, value);
690
}
691
692
/*!
693
Returns the query value associated with key \a key from the URL, using the
694
options specified in \a encoding to encode the return value. If the key \a
695
key is not found, this function returns an empty string. If you need to
696
distinguish between an empty value and a non-existent key, you should check
697
for the key's presence first using hasQueryItem().
698
699
If the key \a key is multiply defined, this function will return the first
700
one found, in the order they were present in the query string or added
701
using addQueryItem().
702
703
\note The key is expected to be in percent-encoded form. This function will
704
try to recover if an improperly-encoded input is provided, but that may
705
produce data loss. See \l{QUrlQuery#Encoding} for more information.
706
707
\sa addQueryItem(), allQueryItemValues(), {encoding}{Encoding}
708
*/
709
QString QUrlQuery::queryItemValue(
const
QString &key, QUrl::ComponentFormattingOptions encoding)
const
710
{
711
QString result;
712
if
(d) {
713
Map::const_iterator it = d->findKey(key);
714
if
(it != d->itemList.constEnd())
715
result = d->recodeToUser(it->second, encoding);
716
}
717
return
result;
718
}
719
720
/*!
721
Returns the a list of query string values whose key is equal to \a key from
722
the URL, using the options specified in \a encoding to encode the return
723
value. If the key \a key is not found, this function returns an empty list.
724
725
\note The key is expected to be in percent-encoded form. This function will
726
try to recover if an improperly-encoded input is provided, but that may
727
produce data loss. See \l{QUrlQuery#Encoding} for more information.
728
729
\sa queryItemValue(), addQueryItem()
730
*/
731
QStringList QUrlQuery::allQueryItemValues(
const
QString &key, QUrl::ComponentFormattingOptions encoding)
const
732
{
733
QStringList result;
734
if
(d) {
735
QString encodedKey = d->recodeFromUser(key);
736
int
idx = d->findRecodedKey(encodedKey);
737
while
(idx < d->itemList.size()) {
738
result << d->recodeToUser(d->itemList.at(idx).second, encoding);
739
idx = d->findRecodedKey(encodedKey, idx + 1);
740
}
741
}
742
return
result;
743
}
744
745
/*!
746
Removes the query string pair whose key is equal to \a key from the URL. If
747
there are multiple items with a key equal to \a key, it removes the first
748
item in the order they were present in the query string or added with
749
addQueryItem().
750
751
\note The key is expected to be in percent-encoded form. This function will
752
try to recover if an improperly-encoded input is provided, but that may
753
produce data loss. See \l{QUrlQuery#Encoding} for more information.
754
755
\sa removeAllQueryItems()
756
*/
757
void
QUrlQuery::removeQueryItem(
const
QString &key)
758
{
759
if
(d.constData()) {
760
auto
*p = d.data();
761
Map::iterator it = p->findKey(key);
762
if
(it != p->itemList.end())
763
p->itemList.erase(it);
764
}
765
}
766
767
/*!
768
Removes all the query string pairs whose key is equal to \a key
769
from the URL.
770
771
\note The key is expected to be in percent-encoded form. This function will
772
try to recover if an improperly-encoded input is provided, but that may
773
produce data loss. See \l{QUrlQuery#Encoding} for more information.
774
775
\sa removeQueryItem()
776
*/
777
void
QUrlQuery::removeAllQueryItems(
const
QString &key)
778
{
779
if
(d.constData()) {
780
auto
*p = d.data();
781
const
QString encodedKey = p->recodeFromUser(key);
782
auto
firstEqualsEncodedKey = [&encodedKey](
const
std::pair<QString, QString> &item) {
783
return
item.first == encodedKey;
784
};
785
p->itemList.removeIf(firstEqualsEncodedKey);
786
}
787
}
788
789
/*!
790
\fn QUrlQuery::defaultQueryValueDelimiter()
791
Returns the default character for separating keys from values in the query,
792
an equal sign ("=").
793
794
\note Prior to Qt 6, this function returned QChar.
795
796
\sa setQueryDelimiters(), queryValueDelimiter(), defaultQueryPairDelimiter()
797
*/
798
799
/*!
800
\fn QUrlQuery::defaultQueryPairDelimiter()
801
Returns the default character for separating keys-value pairs from each
802
other, an ampersand ("&").
803
804
\note Prior to Qt 6, this function returned QChar.
805
806
\sa setQueryDelimiters(), queryPairDelimiter(), defaultQueryValueDelimiter()
807
*/
808
809
/*!
810
\typedef QUrlQuery::DataPtr
811
\internal
812
*/
813
814
/*!
815
\fn DataPtr &QUrlQuery::data_ptr()
816
\internal
817
*/
818
819
/*!
820
\fn QString QUrlQuery::toString(QUrl::ComponentFormattingOptions encoding = QUrl::PrettyDecoded) const
821
822
Returns this QUrlQuery as a QString. \a encoding can be used to specify the URL string encoding of the return value.
823
*/
824
825
/*!
826
\fn bool QUrlQuery::operator!=(const QUrlQuery &lhs, const QUrlQuery &rhs)
827
828
Returns \c true if the QUrlQuery object \a rhs is not equal to \a lhs.
829
Otherwise, returns \c false.
830
831
\sa operator==()
832
*/
833
QT_END_NAMESPACE
834
835
#
undef
decode
836
#
undef
leave
837
#
undef
encode
QString
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition
qstring.h:177
QUrlQueryPrivate
Definition
qurlquery.cpp:140
QUrlQueryPrivate::pairDelimiter
QChar pairDelimiter
Definition
qurlquery.cpp:168
QUrlQueryPrivate::QUrlQueryPrivate
QUrlQueryPrivate(const QString &query=QString())
Definition
qurlquery.cpp:142
QUrlQueryPrivate::itemList
Map itemList
Definition
qurlquery.cpp:166
QUrlQueryPrivate::findRecodedKey
int findRecodedKey(const QString &key, int from=0) const
Definition
qurlquery.cpp:154
QUrlQueryPrivate::addQueryItem
void addQueryItem(const QString &key, const QString &value)
Definition
qurlquery.cpp:152
QUrlQueryPrivate::setQuery
void setQuery(const QString &query)
Definition
qurlquery.cpp:261
QUrlQueryPrivate::recodeFromUser
QString recodeFromUser(const QString &input) const
Definition
qurlquery.cpp:215
QUrlQueryPrivate::recodeToUser
QString recodeToUser(const QString &input, QUrl::ComponentFormattingOptions encoding) const
Definition
qurlquery.cpp:237
QUrlQueryPrivate::findKey
Map::const_iterator findKey(const QString &key) const
Definition
qurlquery.cpp:161
QUrlQueryPrivate::valueDelimiter
QChar valueDelimiter
Definition
qurlquery.cpp:167
QUrlQueryPrivate::findKey
Map::iterator findKey(const QString &key)
Definition
qurlquery.cpp:163
comparesEqual
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
Definition
qfileinfo.cpp:469
qHash
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition
qsize.h:192
decode
#define decode(x)
Definition
qurlquery.cpp:211
recodeAndAppend
static void recodeAndAppend(QString &to, const QString &input, QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications)
Definition
qurlquery.cpp:480
encode
#define encode(x)
Definition
qurlquery.cpp:213
idempotentRecodeToUser
bool idempotentRecodeToUser(QUrl::ComponentFormattingOptions encoding)
Definition
qurlquery.cpp:232
qtbase
src
corelib
io
qurlquery.cpp
Generated on
for Qt by
1.18.0