annotate src/lib/str-find.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21323
diff changeset
1 /* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
7441
ffd549b542c5 str_find_init() allocated too little memory for temporary suffixes buffer.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
3 /* @UNSAFE: whole file */
ffd549b542c5 str_find_init() allocated too little memory for temporary suffixes buffer.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
4
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "lib.h"
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "str-find.h"
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 struct str_find_context {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 pool_t pool;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 unsigned char *key;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 unsigned int key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 unsigned int *matches;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 unsigned int match_count;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
16 size_t match_end_pos;
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
17
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 int badtab[UCHAR_MAX+1];
7997
0d66b44689ee Fixed compiling on some older pre-C99 compilers.
Timo Sirainen <tss@iki.fi>
parents: 7443
diff changeset
19 int goodtab[FLEXIBLE_ARRAY_MEMBER];
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 };
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 static void init_badtab(struct str_find_context *ctx)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 unsigned int i, len_1 = ctx->key_len - 1;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 for (i = 0; i <= UCHAR_MAX; i++)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 ctx->badtab[i] = ctx->key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 for (i = 0; i < len_1; i++)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 ctx->badtab[ctx->key[i]] = len_1 - i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 static void init_suffixes(struct str_find_context *ctx, unsigned int *suffixes)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 unsigned int len_1 = ctx->key_len - 1;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 int f = 0, g, i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 suffixes[len_1] = ctx->key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 g = len_1;
15909
f74bf0521d69 Avoid under/overflows in unsigned integer calculations.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
40 for (i = (int)ctx->key_len - 2; i >= 0; i--) {
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 if (i > g && (int)suffixes[i + len_1 - f] < i - g)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 suffixes[i] = suffixes[i + len_1 - f];
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 else {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 if (i < g)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 g = i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 f = i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 while (g >= 0 && ctx->key[g] == ctx->key[g + len_1 - f])
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 g--;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 suffixes[i] = f - g;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 static void init_goodtab(struct str_find_context *ctx)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 {
15909
f74bf0521d69 Avoid under/overflows in unsigned integer calculations.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
56 unsigned int *suffixes;
f74bf0521d69 Avoid under/overflows in unsigned integer calculations.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
57 int j, i, len_1 = ctx->key_len - 1;
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
7441
ffd549b542c5 str_find_init() allocated too little memory for temporary suffixes buffer.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
59 suffixes = t_buffer_get(sizeof(*suffixes) * ctx->key_len);
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 init_suffixes(ctx, suffixes);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 for (i = 0; i < (int)ctx->key_len; i++)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 ctx->goodtab[i] = ctx->key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 j = 0;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 for (i = len_1; i >= -1; i--) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 if (i < 0 || suffixes[i] == (unsigned int)i + 1) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 for (; j < len_1 - i; j++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 if (ctx->goodtab[j] == (int)ctx->key_len)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 ctx->goodtab[j] = len_1 - i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 for (i = 0; i <= (int)ctx->key_len - 2; i++)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 ctx->goodtab[len_1 - suffixes[i]] = len_1 - i;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 }
7441
ffd549b542c5 str_find_init() allocated too little memory for temporary suffixes buffer.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
77
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 struct str_find_context *str_find_init(pool_t pool, const char *key)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 struct str_find_context *ctx;
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
81 size_t key_len = strlen(key);
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
83 i_assert(key_len > 0);
21322
5ab8dc1a4a6f global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
84 i_assert(key_len < INT_MAX);
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
85
21323
d223fad9767f global: Make sure *_malloc() calculations won't cause integer overflows.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
86 ctx = p_malloc(pool, MALLOC_ADD(sizeof(struct str_find_context),
d223fad9767f global: Make sure *_malloc() calculations won't cause integer overflows.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21322
diff changeset
87 MALLOC_MULTIPLY(sizeof(ctx->goodtab[0]), key_len)));
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 ctx->pool = pool;
7443
00d3b46f61e6 matches[] wasn't also allocated enough memory.
Timo Sirainen <tss@iki.fi>
parents: 7441
diff changeset
89 ctx->matches = p_new(pool, unsigned int, key_len);
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 ctx->key_len = key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 ctx->key = p_malloc(pool, key_len);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 memcpy(ctx->key, key, key_len);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 init_goodtab(ctx);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 init_badtab(ctx);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96 return ctx;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 void str_find_deinit(struct str_find_context **_ctx)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 struct str_find_context *ctx = *_ctx;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 *_ctx = NULL;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 p_free(ctx->pool, ctx->matches);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 p_free(ctx->pool, ctx->key);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 p_free(ctx->pool, ctx);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 bool str_find_more(struct str_find_context *ctx,
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 const unsigned char *data, size_t size)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 unsigned int key_len = ctx->key_len;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 unsigned int i, j, a, b;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 int bad_value;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 for (i = j = 0; i < ctx->match_count; i++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 a = ctx->matches[i];
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 if (ctx->matches[i] + size >= key_len) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 /* we can fully determine this match now */
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 for (; a < key_len; a++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 if (ctx->key[a] != data[a - ctx->matches[i]])
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 break;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
125 if (a == key_len) {
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
126 ctx->match_end_pos = key_len - ctx->matches[i];
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 return TRUE;
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
128 }
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 } else {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 for (b = 0; b < size; b++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 if (ctx->key[a+b] != data[b])
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 break;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 if (b == size)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 ctx->matches[j++] = a + size;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 if (j > 0) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 i_assert(j + size < key_len);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 ctx->match_count = j;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 j = 0;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143 } else {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 /* Boyer-Moore searching */
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 j = 0;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 while (j + key_len <= size) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 i = key_len - 1;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 while (ctx->key[i] == data[i + j]) {
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
149 if (i == 0) {
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
150 ctx->match_end_pos = j + key_len;
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 return TRUE;
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
152 }
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 i--;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155
15909
f74bf0521d69 Avoid under/overflows in unsigned integer calculations.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
156 bad_value = (int)(ctx->badtab[data[i + j]] + i + 1) -
f74bf0521d69 Avoid under/overflows in unsigned integer calculations.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
157 (int)key_len;
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 j += I_MAX(ctx->goodtab[i], bad_value);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160 i_assert(j <= size);
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161 ctx->match_count = 0;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 for (; j < size; j++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 for (i = j; i < size; i++) {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 if (ctx->key[i-j] != data[i])
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 break;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 if (i == size)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 ctx->matches[ctx->match_count++] = size - j;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 return FALSE;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 }
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174
8995
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
175 size_t str_find_get_match_end_pos(struct str_find_context *ctx)
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
176 {
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
177 return ctx->match_end_pos;
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
178 }
c8ba50450f12 Added str_find_get_match_end_pos(). Added unit testing.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
179
5520
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 void str_find_reset(struct str_find_context *ctx)
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 {
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 ctx->match_count = 0;
f322edd67a4f Added Boyer-Moore string searching.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }