Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/QtCore/qbytearraymatcher.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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