Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-08 09:20:07

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:critical reason:data-parser
0004 
0005 #ifndef QBYTEARRAYMATCHER_H
0006 #define QBYTEARRAYMATCHER_H
0007 
0008 #include <QtCore/qbytearray.h>
0009 
0010 #include <QtCore/q20algorithm.h>
0011 #include <iterator>
0012 #include <limits>
0013 
0014 QT_BEGIN_NAMESPACE
0015 
0016 
0017 class QByteArrayMatcherPrivate;
0018 
0019 class Q_CORE_EXPORT QByteArrayMatcher
0020 {
0021 public:
0022     QByteArrayMatcher();
0023     explicit QByteArrayMatcher(const QByteArray &pattern);
0024     explicit QByteArrayMatcher(QByteArrayView pattern)
0025         : QByteArrayMatcher(pattern.data(), pattern.size())
0026     {}
0027     explicit QByteArrayMatcher(const char *pattern, qsizetype length = -1);
0028     QByteArrayMatcher(const QByteArrayMatcher &other);
0029     ~QByteArrayMatcher();
0030 
0031     QByteArrayMatcher &operator=(const QByteArrayMatcher &other);
0032 
0033     void setPattern(const QByteArray &pattern);
0034 
0035 #if QT_CORE_REMOVED_SINCE(6, 3)
0036     qsizetype indexIn(const QByteArray &ba, qsizetype from = 0) const;
0037 #else
0038     Q_WEAK_OVERLOAD
0039     qsizetype indexIn(const QByteArray &ba, qsizetype from = 0) const
0040     { return indexIn(QByteArrayView{ba}, from); }
0041 #endif
0042     qsizetype indexIn(const char *str, qsizetype len, qsizetype from = 0) const;
0043     qsizetype indexIn(QByteArrayView data, qsizetype from = 0) const;
0044     inline QByteArray pattern() const
0045     {
0046         if (q_pattern.isNull())
0047             return QByteArray(reinterpret_cast<const char*>(p.p), p.l);
0048         return q_pattern;
0049     }
0050 
0051 private:
0052     QByteArrayMatcherPrivate *d;
0053     QByteArray q_pattern;
0054     struct Data {
0055         uchar q_skiptable[256];
0056         const uchar *p;
0057         qsizetype l;
0058     };
0059     union {
0060         uint dummy[256];
0061         Data p;
0062     };
0063 };
0064 
0065 class QStaticByteArrayMatcherBase
0066 {
0067     alignas(16)
0068     struct Skiptable {
0069         uchar data[256];
0070     } m_skiptable;
0071 protected:
0072     explicit constexpr QStaticByteArrayMatcherBase(const char *pattern, size_t n) noexcept
0073         : m_skiptable(generate(pattern, n)) {}
0074     // compiler-generated copy/more ctors/assignment operators are ok!
0075     ~QStaticByteArrayMatcherBase() = default;
0076 
0077 #if QT_CORE_REMOVED_SINCE(6, 3) && QT_POINTER_SIZE != 4
0078     Q_CORE_EXPORT int indexOfIn(const char *needle, uint nlen, const char *haystack, int hlen, int from) const noexcept;
0079 #endif
0080     Q_CORE_EXPORT qsizetype indexOfIn(const char *needle, size_t nlen,
0081                                       const char *haystack, qsizetype hlen,
0082                                       qsizetype from) const noexcept;
0083 
0084 private:
0085     static constexpr Skiptable generate(const char *pattern, size_t n) noexcept
0086     {
0087         const auto uchar_max = (std::numeric_limits<uchar>::max)();
0088         uchar max = n > uchar_max ? uchar_max : uchar(n);
0089         Skiptable table = {};
0090         q20::fill(std::begin(table.data), std::end(table.data), max);
0091         pattern += n - max;
0092         while (max--)
0093             table.data[uchar(*pattern++)] = max;
0094         return table;
0095     }
0096 };
0097 
0098 template <size_t N>
0099 class QStaticByteArrayMatcher : QStaticByteArrayMatcherBase
0100 {
0101     char m_pattern[N];
0102     // N includes the terminating '\0'!
0103     static_assert(N > 2, "QStaticByteArrayMatcher makes no sense for finding a single-char pattern");
0104 public:
0105     explicit constexpr QStaticByteArrayMatcher(const char (&patternToMatch)[N]) noexcept
0106         : QStaticByteArrayMatcherBase(patternToMatch, N - 1), m_pattern()
0107     {
0108         for (size_t i = 0; i < N; ++i)
0109             m_pattern[i] = patternToMatch[i];
0110     }
0111 
0112     Q_WEAK_OVERLOAD
0113     qsizetype indexIn(const QByteArray &haystack, qsizetype from = 0) const noexcept
0114     { return this->indexOfIn(m_pattern, N - 1, haystack.data(), haystack.size(), from); }
0115     qsizetype indexIn(const char *haystack, qsizetype hlen, qsizetype from = 0) const noexcept
0116     { return this->indexOfIn(m_pattern, N - 1, haystack, hlen, from); }
0117     qsizetype indexIn(QByteArrayView haystack, qsizetype from = 0) const noexcept
0118     { return this->indexOfIn(m_pattern, N - 1, haystack.data(), haystack.size(), from); }
0119 
0120     QByteArray pattern() const { return QByteArray(m_pattern, qsizetype(N - 1)); }
0121 };
0122 
0123 template <size_t N>
0124 constexpr QStaticByteArrayMatcher<N> qMakeStaticByteArrayMatcher(const char (&pattern)[N]) noexcept
0125 { return QStaticByteArrayMatcher<N>(pattern); }
0126 
0127 QT_END_NAMESPACE
0128 
0129 #endif // QBYTEARRAYMATCHER_H