1
/* This file implements memmem, a function to find the first occurrence
2
of the contents of a memory area in another memory area.
3
Copyright (C) 2003 Martin Dickopp
5
This file is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This file is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this file; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
25
/* This function implements the Boyer-Moore algorithm.
26
It is assumed that chars have eight bits. */
27
void *memmem(const void *haystack, const size_t haystack_len,
28
const void *needle, const size_t needle_len)
30
const unsigned char *const haystack_endptr =
31
(const unsigned char *) haystack + haystack_len;
32
const unsigned char *const needle_endptr =
33
(const unsigned char *) needle + needle_len;
34
const unsigned char *haystack_shifting_ptr;
36
size_t *shift_good_suffix;
37
size_t shift_last_occurrence[256];
40
printf("memmem called\n");
41
if (needle_len > haystack_len)
44
haystack_shifting_ptr = (const unsigned char *) haystack + needle_len;
47
/* Compute good suffix function. */
48
shift_good_suffix = (size_t*)malloc(2 * needle_len * sizeof *shift_good_suffix);
49
if (shift_good_suffix != 0) {
50
const unsigned char *needle_ptr;
53
shift_good_suffix[0] = 0;
54
needle_ptr = (const unsigned char *) needle + 1;
55
for (i = 1, j = 0; i < needle_len; ++i) {
57
&& ((const unsigned char *) needle)[j] != *needle_ptr)
58
j = shift_good_suffix[j - 1];
59
if (((const unsigned char *) needle)[j] == *needle_ptr)
61
shift_good_suffix[i] = j;
65
shift_good_suffix[needle_len] = 0;
66
needle_ptr = (const unsigned char *) needle + needle_len - 1;
67
for (i = 1, j = 0; i < needle_len; ++i) {
70
&& ((const unsigned char *) needle)[needle_len - 1 -
72
j = shift_good_suffix[needle_len - 1 + j];
73
if (((const unsigned char *) needle)[needle_len - 1 - j] ==
76
shift_good_suffix[needle_len + i] = j;
79
for (i = 0; i < needle_len; ++i)
80
shift_good_suffix[i] = needle_len - shift_good_suffix[i];
82
for (i = 0; i < needle_len; ++i) {
83
j = needle_len - 1 - shift_good_suffix[needle_len + i];
84
if (shift_good_suffix[j] >
85
i + 1 - shift_good_suffix[needle_len + i])
86
shift_good_suffix[j] =
87
i + 1 - shift_good_suffix[needle_len + i];
92
/* Compute last occurence function. */
94
const unsigned char *needle_ptr = (const unsigned char *)needle;
97
for (i = 0; i < 256; ++i)
98
shift_last_occurrence[i] = 0;
99
for (i = 0; i < needle_len; ++i)
100
shift_last_occurrence[*needle_ptr++] = i + 1;
104
/* Matching algorithm. */
105
while (haystack_shifting_ptr <= haystack_endptr) {
106
const unsigned char *haystack_ptr = haystack_shifting_ptr;
107
const unsigned char *needle_ptr = needle_endptr;
108
size_t len = needle_len;
110
while (len > 0 && *--haystack_ptr == *--needle_ptr)
114
if (shift_good_suffix != 0)
115
free(shift_good_suffix);
116
return (void *) haystack_ptr;
120
const size_t shift1 =
121
shift_good_suffix != 0 ? shift_good_suffix[len - 1] : 1;
122
const size_t shift2 =
123
(len > shift_last_occurrence[*haystack_ptr]
124
? len - shift_last_occurrence[*haystack_ptr] : 1);
126
haystack_shifting_ptr += shift1 > shift2 ? shift1 : shift2;
131
if (shift_good_suffix != 0)
132
free(shift_good_suffix);
133
printf("memmem exited\n");