1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the core module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qbytearraymatcher.h"
31
static inline void bm_init_skiptable(const uchar *cc, int l, uint *skiptable)
34
register uint *st = skiptable;
35
while (i++ < 256 / 8) {
36
*st++ = l; *st++ = l; *st++ = l; *st++ = l;
37
*st++ = l; *st++ = l; *st++ = l; *st++ = l;
43
static inline int bm_find(const uchar *cc, int l, int index, const uchar *puc, uint pl,
44
const uint *skiptable)
47
return index > l ? -1 : index;
48
const uint pl_minus_one = pl - 1;
50
register const uchar *current = cc + index + pl_minus_one;
51
const uchar *end = cc + l;
52
while (current < end) {
53
uint skip = skiptable[*current];
57
if (*(current - skip) != puc[pl_minus_one - skip])
61
if (skip > pl_minus_one) // we have a match
62
return (current - cc) - skip + 1;
64
// in case we don't have a match we are a bit inefficient as we only skip by one
65
// when we have the non matching char in the string.
66
if (skiptable[*(current - skip)] == pl)
71
if (current > end - skip)
75
return -1; // not found
78
/*! \class QByteArrayMatcher
79
\brief The QByteArrayMatcher class holds a sequence of bytes that
80
can be quickly matched in a byte array.
85
This class is useful when you have a sequence of bytes that you
86
want to repeatedly match against some byte arrays (perhaps in a
87
loop), or when you want to search for the same sequence of bytes
88
multiple times in the same byte array. Using a matcher object and
89
indexIn() is faster than matching a plain QByteArray with
90
QByteArray::indexOf() if repeated matching takes place. This
91
class offers no benefit if you are doing one-off byte array
94
Create the QByteArrayMatcher with the QByteArray you want to
95
search for. Then call indexIn() on the QByteArray that you want to
98
\sa QByteArray, QStringMatcher
102
Constructs an empty byte array matcher that won't match anything.
103
Call setPattern() to give it a pattern to match.
105
QByteArrayMatcher::QByteArrayMatcher()
108
qMemSet(q_skiptable, 0, sizeof(q_skiptable));
112
Constructs a byte array matcher that will search for \a pattern.
113
Call indexIn() to perform a search.
115
QByteArrayMatcher::QByteArrayMatcher(const QByteArray &pattern)
122
Copies the \a other byte array matcher to this byte array matcher.
124
QByteArrayMatcher::QByteArrayMatcher(const QByteArrayMatcher &other)
131
Destroys the byte array matcher.
133
QByteArrayMatcher::~QByteArrayMatcher()
138
Assigns the \a other byte array matcher to this byte array matcher.
140
QByteArrayMatcher &QByteArrayMatcher::operator=(const QByteArrayMatcher &other)
142
q_pattern = other.q_pattern;
143
qMemCopy(q_skiptable, other.q_skiptable, sizeof(q_skiptable));
148
Sets the byte array that this byte array matcher will search for
151
\sa pattern(), indexIn()
153
void QByteArrayMatcher::setPattern(const QByteArray &pattern)
155
bm_init_skiptable(reinterpret_cast<const uchar *>(pattern.constData()), pattern.size(),
161
Searches the byte array \a ba, from byte position \a from (default
162
0, i.e. from the first byte), for the byte array pattern() that
163
was set in the constructor or in the most recent call to
164
setPattern(). Returns the position where the pattern() matched in
165
\a ba, or -1 if no match was found.
167
int QByteArrayMatcher::indexIn(const QByteArray &ba, int from) const
171
return bm_find(reinterpret_cast<const uchar *>(ba.constData()), ba.size(), from,
172
reinterpret_cast<const uchar *>(q_pattern.constData()), q_pattern.size(),
177
\fn QByteArray QByteArrayMatcher::pattern() const
179
Returns the byte array pattern that this byte array matcher will