6#include <QtCore/qdebug.h>
32 if (
sum > (std::numeric_limits<unsigned>::max() - 32))
42 if (
const int minLen = std::min(lhs.
size(), rhs.
size())) {
55FieldLookupTable::SearchEntry::SearchEntry()
63FieldLookupTable::SearchEntry::SearchEntry(
const HeaderField *
f,
66 const FieldLookupTable *
t)
75bool FieldLookupTable::SearchEntry::operator < (
const SearchEntry &rhs)
const
80 int cmp =
compare(field->name, rhs.field->name);
84 cmp =
compare(field->value, rhs.field->value);
97 const quint32 leftChunkIndex =
table->indexOfChunk(chunk);
98 const quint32 rightChunkIndex = rhs.table->indexOfChunk(rhs.chunk);
101 if (leftChunkIndex != rightChunkIndex)
102 return leftChunkIndex > rightChunkIndex;
105 return offset > rhs.offset;
108FieldLookupTable::FieldLookupTable(
quint32 maxSize,
bool use)
109 : maxTableSize(maxSize),
110 tableCapacity(maxSize),
123 if (!entrySize.first)
126 if (entrySize.second > tableCapacity) {
131 while (nDynamic && tableCapacity -
dataSize < entrySize.second)
136 chunks.push_front(ChunkPtr(
new Chunk(
ChunkSize)));
146 auto &newField = front();
147 newField.name =
name;
148 newField.value =
value;
151 const auto result = searchIndex.insert(frontKey());
167 const auto res = searchIndex.erase(backKey());
230 const auto staticPos = findInStaticPart(
field, CompareMode::nameAndValue);
231 if (staticPos !=
table.end()) {
232 if (staticPos->name ==
name && staticPos->value ==
value)
238 qCritical(
"lookup in dynamic table requires search index enabled");
242 const SearchEntry
key(&
field,
nullptr, 0,
this);
243 const auto pos = searchIndex.lower_bound(
key);
244 if (
pos != searchIndex.end()) {
246 if (found.name ==
name && found.value ==
value)
247 return keyToIndex(*
pos);
258 const auto staticPos = findInStaticPart(
field, CompareMode::nameOnly);
259 if (staticPos !=
table.end()) {
260 if (staticPos->name ==
name)
266 qCritical(
"lookup in dynamic table requires search index enabled");
270 const SearchEntry
key(&
field,
nullptr, 0,
this);
271 const auto pos = searchIndex.lower_bound(
key);
272 if (
pos != searchIndex.end()) {
274 if (found.name ==
name)
275 return keyToIndex(*
pos);
298 Q_ASSERT(chunkIndex < chunks.size());
302 *
value = found.value;
321 Q_ASSERT(nDynamic && begin !=
end && chunks.size());
322 return (*chunks[0])[begin];
325HeaderField &FieldLookupTable::front()
327 Q_ASSERT(nDynamic && begin !=
end && chunks.size());
328 return (*chunks[0])[begin];
331const HeaderField &FieldLookupTable::back()
const
337 Q_ASSERT(chunkIndex < chunks.size());
339 return (*chunks[chunkIndex])[
offset];
342quint32 FieldLookupTable::indexOfChunk(
const Chunk *chunk)
const
346 for (size_type
i = 0;
i < chunks.size(); ++
i) {
347 if (chunks[
i].
get() == chunk)
351 Q_UNREACHABLE_RETURN(0);
354quint32 FieldLookupTable::keyToIndex(
const SearchEntry &
key)
const
358 const auto chunkIndex = indexOfChunk(
key.chunk);
369 return SearchEntry(&front(), chunks.front().get(), begin,
this);
376 const HeaderField &
field = back();
379 const auto chunk = chunks[absIndex /
ChunkSize].get();
391 if (
size > maxTableSize)
394 tableCapacity =
size;
395 while (nDynamic &&
dataSize > tableCapacity)
416 static std::vector<HeaderField>
table = {
421 {
":path",
"/index.html"},
423 {
":scheme",
"https"},
431 {
"accept-charset",
""},
432 {
"accept-encoding",
"gzip, deflate"},
433 {
"accept-language",
""},
434 {
"accept-ranges",
""},
436 {
"access-control-allow-origin",
""},
439 {
"authorization",
""},
440 {
"cache-control",
""},
441 {
"content-disposition",
""},
442 {
"content-encoding",
""},
443 {
"content-language",
""},
444 {
"content-length",
""},
445 {
"content-location",
""},
446 {
"content-range",
""},
447 {
"content-type",
""},
456 {
"if-modified-since",
""},
457 {
"if-none-match",
""},
459 {
"if-unmodified-since",
""},
460 {
"last-modified",
""},
463 {
"max-forwards",
""},
464 {
"proxy-authenticate",
""},
465 {
"proxy-authorization",
""},
472 {
"strict-transport-security",
""},
473 {
"transfer-encoding",
""},
477 {
"www-authenticate",
""}
483std::vector<HeaderField>::const_iterator FieldLookupTable::findInStaticPart(
const HeaderField &field, CompareMode
mode)
486 const auto acceptPos =
table.begin() + 18;
487 if (
field.name ==
"accept") {
488 if (
mode == CompareMode::nameAndValue &&
field.value !=
"")
493 auto predicate = [
mode](
const HeaderField &lhs,
const HeaderField &rhs) {
494 const int cmp =
compare(lhs.name, rhs.name);
497 else if (
mode == CompareMode::nameAndValue)
498 return compare(lhs.value, rhs.value) < 0;
503 if (staticPos != acceptPos)
bool fieldName(quint32 index, QByteArray *dst) const
void setMaxDynamicTableSize(quint32 size)
quint32 numberOfDynamicEntries() const
friend struct SearchEntry
bool fieldValue(quint32 index, QByteArray *dst) const
bool updateDynamicTableSize(quint32 size)
quint32 numberOfEntries() const
static const std::vector< HeaderField > & staticPart()
quint32 indexOf(const QByteArray &name, const QByteArray &value) const
bool indexIsValid(quint32 index) const
quint32 numberOfStaticEntries() const
bool field(quint32 index, QByteArray *name, QByteArray *value) const
quint32 dynamicDataSize() const
bool prependField(const QByteArray &name, const QByteArray &value)
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QPair< bool, quint32 > HeaderSize
HeaderSize entry_size(QByteArrayView name, QByteArrayView value)
Combined button and popup list for selecting options.
static QDBusError::ErrorType get(const char *name)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLintptr offset
GLenum GLenum GLsizei void * table
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static int compare(quint64 a, quint64 b)