5 static char *twobyte_memmem(const unsigned char *h
, size_t k
, const unsigned char *n
)
7 uint16_t nw
= n
[0]<<8 | n
[1], hw
= h
[0]<<8 | h
[1];
8 for (h
+=2, k
-=2; k
; k
--, hw
= hw
<<8 | *h
++)
9 if (hw
== nw
) return (char *)h
-2;
10 return hw
== nw
? (char *)h
-2 : 0;
13 static char *threebyte_memmem(const unsigned char *h
, size_t k
, const unsigned char *n
)
15 uint32_t nw
= (uint32_t)n
[0]<<24 | n
[1]<<16 | n
[2]<<8;
16 uint32_t hw
= (uint32_t)h
[0]<<24 | h
[1]<<16 | h
[2]<<8;
17 for (h
+=3, k
-=3; k
; k
--, hw
= (hw
|*h
++)<<8)
18 if (hw
== nw
) return (char *)h
-3;
19 return hw
== nw
? (char *)h
-3 : 0;
22 static char *fourbyte_memmem(const unsigned char *h
, size_t k
, const unsigned char *n
)
24 uint32_t nw
= (uint32_t)n
[0]<<24 | n
[1]<<16 | n
[2]<<8 | n
[3];
25 uint32_t hw
= (uint32_t)h
[0]<<24 | h
[1]<<16 | h
[2]<<8 | h
[3];
26 for (h
+=4, k
-=4; k
; k
--, hw
= hw
<<8 | *h
++)
27 if (hw
== nw
) return (char *)h
-4;
28 return hw
== nw
? (char *)h
-4 : 0;
31 #define MAX(a,b) ((a)>(b)?(a):(b))
32 #define MIN(a,b) ((a)<(b)?(a):(b))
34 #define BITOP(a,b,op) \
35 ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
37 static char *twoway_memmem(const unsigned char *h
, const unsigned char *z
, const unsigned char *n
, size_t l
)
39 size_t i
, ip
, jp
, k
, p
, ms
, p0
, mem
, mem0
;
40 size_t byteset
[32 / sizeof(size_t)] = { 0 };
43 /* Computing length of needle and fill shift table */
45 BITOP(byteset
, n
[i
], |=), shift
[n
[i
]] = i
+1;
47 /* Compute maximal suffix */
48 ip
= -1; jp
= 0; k
= p
= 1;
50 if (n
[ip
+k
] == n
[jp
+k
]) {
55 } else if (n
[ip
+k
] > n
[jp
+k
]) {
67 /* And with the opposite comparison */
68 ip
= -1; jp
= 0; k
= p
= 1;
70 if (n
[ip
+k
] == n
[jp
+k
]) {
75 } else if (n
[ip
+k
] < n
[jp
+k
]) {
84 if (ip
+1 > ms
+1) ms
= ip
;
87 /* Periodic needle? */
88 if (memcmp(n
, n
+p
, ms
+1)) {
90 p
= MAX(ms
, l
-ms
-1) + 1;
96 /* If remainder of haystack is shorter than needle, done */
97 if (z
-h
< l
) return 0;
99 /* Check last byte first; advance by shift on mismatch */
100 if (BITOP(byteset
, h
[l
-1], &)) {
103 if (k
< mem
) k
= mem
;
114 /* Compare right half */
115 for (k
=MAX(ms
+1,mem
); k
<l
&& n
[k
] == h
[k
]; k
++);
121 /* Compare left half */
122 for (k
=ms
+1; k
>mem
&& n
[k
-1] == h
[k
-1]; k
--);
123 if (k
<= mem
) return (char *)h
;
129 void *memmem(const void *h0
, size_t k
, const void *n0
, size_t l
)
131 const unsigned char *h
= h0
, *n
= n0
;
133 /* Return immediately on empty needle */
134 if (!l
) return (void *)h
;
136 /* Return immediately when needle is longer than haystack */
139 /* Use faster algorithms for short needles */
140 h
= memchr(h0
, *n
, k
);
141 if (!h
|| l
==1) return (void *)h
;
142 k
-= h
- (const unsigned char *)h0
;
144 if (l
==2) return twobyte_memmem(h
, k
, n
);
145 if (l
==3) return threebyte_memmem(h
, k
, n
);
146 if (l
==4) return fourbyte_memmem(h
, k
, n
);
148 return twoway_memmem(h
, h
+k
, n
, l
);