c24cedb404fb3edfb9c148ec11c8f36e096089a0
[metze/wireshark/wip.git] / wsutil / ws_mempbrk.c
1 /* ws_mempbrk.c
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "config.h"
23
24 #include <glib.h>
25 #include "ws_symbol_export.h"
26 #ifdef HAVE_SSE4_2
27 #include "ws_cpuid.h"
28 #endif
29 #include "ws_mempbrk.h"
30
31 const guint8 *
32 _ws_mempbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
33 {
34         gchar         tmp[256] = { 0 };
35         const guint8 *haystack_end;
36
37         while (*needles)
38                 tmp[*needles++] = 1;
39
40         haystack_end = haystack + haystacklen;
41         while (haystack < haystack_end) {
42                 if (tmp[*haystack])
43                         return haystack;
44                 haystack++;
45         }
46
47         return NULL;
48 }
49
50 WS_DLL_PUBLIC const guint8 *
51 ws_mempbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
52 {
53 #ifdef HAVE_SSE4_2
54         static int have_sse42 = -1;
55 #endif
56         if (*needles == 0)
57                 return NULL;
58
59 #ifdef HAVE_SSE4_2
60         if G_UNLIKELY(have_sse42 < 0)
61                 have_sse42 = ws_cpuid_sse42();
62
63         if (haystacklen >= 16 && have_sse42)
64                 return _ws_mempbrk_sse42(haystack, haystacklen, needles);
65 #endif
66
67         return _ws_mempbrk(haystack, haystacklen, needles);
68 }