/Users/deen/code/yugabyte-db/src/yb/gutil/strings/memutil.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright 2001 and onwards Google, Inc. |
3 | | // |
4 | | // The following only applies to changes made to this file as part of YugaByte development. |
5 | | // |
6 | | // Portions Copyright (c) YugaByte, Inc. |
7 | | // |
8 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
9 | | // in compliance with the License. You may obtain a copy of the License at |
10 | | // |
11 | | // http://www.apache.org/licenses/LICENSE-2.0 |
12 | | // |
13 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
14 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
15 | | // or implied. See the License for the specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | |
19 | | #include "yb/gutil/strings/memutil.h" |
20 | | |
21 | | #include <stdlib.h> // for malloc, NULL |
22 | | |
23 | | #include "yb/gutil/strings/ascii_ctype.h" // for ascii_tolower |
24 | | |
25 | 0 | int memcasecmp(const char *s1, const char *s2, size_t len) { |
26 | 0 | const unsigned char *us1 = reinterpret_cast<const unsigned char *>(s1); |
27 | 0 | const unsigned char *us2 = reinterpret_cast<const unsigned char *>(s2); |
28 | |
|
29 | 0 | for (size_t i = 0; i < len; i++ ) { |
30 | 0 | const int diff = |
31 | 0 | static_cast<int>(static_cast<unsigned char>(ascii_tolower(us1[i]))) - |
32 | 0 | static_cast<int>(static_cast<unsigned char>(ascii_tolower(us2[i]))); |
33 | 0 | if (diff != 0) return diff; |
34 | 0 | } |
35 | 0 | return 0; |
36 | 0 | } |
37 | | |
38 | 0 | char *memdup(const char *s, size_t slen) { |
39 | 0 | void *copy; |
40 | 0 | if ( (copy=malloc(slen)) == nullptr ) |
41 | 0 | return nullptr; |
42 | 0 | memcpy(copy, s, slen); |
43 | 0 | return reinterpret_cast<char *>(copy); |
44 | 0 | } |
45 | | |
46 | 0 | char *memrchr(const char *s, int c, size_t slen) { |
47 | 0 | for (const char* e = s + slen-1; e >= s; e--) { |
48 | 0 | if (*e == c) |
49 | 0 | return const_cast<char *>(e); |
50 | 0 | } |
51 | 0 | return nullptr; |
52 | 0 | } |
53 | | |
54 | 0 | size_t memspn(const char *s, size_t slen, const char *accept) { |
55 | 0 | const char *p = s, *spanp; |
56 | 0 | char c, sc; |
57 | |
|
58 | 0 | cont: |
59 | 0 | c = *p++; |
60 | 0 | if ( slen-- == 0 ) |
61 | 0 | return p-1 - s; |
62 | 0 | for (spanp = accept; (sc=*spanp++) != '\0';) |
63 | 0 | if (sc == c) |
64 | 0 | goto cont; |
65 | 0 | return p-1 - s; |
66 | 0 | } |
67 | | |
68 | | |
69 | 0 | size_t memcspn(const char *s, size_t slen, const char *reject) { |
70 | 0 | const char *p = s, *spanp; |
71 | 0 | char c, sc; |
72 | |
|
73 | 0 | while ( slen-- != 0 ) { |
74 | 0 | c = *p++; |
75 | 0 | for (spanp = reject; (sc=*spanp++) != '\0';) |
76 | 0 | if (sc == c) |
77 | 0 | return p-1 - s; |
78 | 0 | } |
79 | 0 | return p - s; |
80 | 0 | } |
81 | | |
82 | 0 | char *mempbrk(const char *s, size_t slen, const char *accept) { |
83 | 0 | const char *scanp; |
84 | 0 | int sc; |
85 | |
|
86 | 0 | for ( ; slen; ++s, --slen ) { |
87 | 0 | for (scanp = accept; (sc=*scanp++) != '\0';) |
88 | 0 | if (sc == *s) |
89 | 0 | return const_cast<char *>(s); |
90 | 0 | } |
91 | 0 | return nullptr; |
92 | 0 | } |
93 | | |
94 | | template<bool case_sensitive> |
95 | | const char *int_memmatch(const char *phaystack, size_t haylen, |
96 | 0 | const char *pneedle, size_t neelen) { |
97 | 0 | if (0 == neelen) { |
98 | 0 | return phaystack; // even if haylen is 0 |
99 | 0 | } |
100 | 0 | const unsigned char *haystack = (const unsigned char *) phaystack; |
101 | 0 | const unsigned char *hayend = (const unsigned char *) phaystack + haylen; |
102 | 0 | const unsigned char *needlestart = (const unsigned char *) pneedle; |
103 | 0 | const unsigned char *needle = (const unsigned char *) pneedle; |
104 | 0 | const unsigned char *needleend = (const unsigned char *) pneedle + neelen; |
105 | |
|
106 | 0 | for (; haystack < hayend; ++haystack) { |
107 | 0 | unsigned char hay = case_sensitive ? *haystack : |
108 | 0 | static_cast<unsigned char>(ascii_tolower(*haystack)); |
109 | 0 | unsigned char nee = case_sensitive ? *needle : |
110 | 0 | static_cast<unsigned char>(ascii_tolower(*needle)); |
111 | 0 | if (hay == nee) { |
112 | 0 | if (++needle == needleend) { |
113 | 0 | return (const char *) (haystack + 1 - neelen); |
114 | 0 | } |
115 | 0 | } else if (needle != needlestart) { |
116 | | // must back up haystack in case a prefix matched (find "aab" in "aaab") |
117 | 0 | haystack -= needle - needlestart; // for loop will advance one more |
118 | 0 | needle = needlestart; |
119 | 0 | } |
120 | 0 | } |
121 | 0 | return nullptr; |
122 | 0 | } Unexecuted instantiation: _Z12int_memmatchILb1EEPKcS1_mS1_m Unexecuted instantiation: _Z12int_memmatchILb0EEPKcS1_mS1_m |
123 | | |
124 | | // explicit template instantiations |
125 | | template const char *int_memmatch<true>(const char *phaystack, size_t haylen, |
126 | | const char *pneedle, size_t neelen); |
127 | | template const char *int_memmatch<false>(const char *phaystack, size_t haylen, |
128 | | const char *pneedle, size_t neelen); |
129 | | |
130 | | // This is significantly faster for case-sensitive matches with very |
131 | | // few possible matches. See unit test for benchmarks. |
132 | | const char *memmatch(const char *phaystack, size_t haylen, |
133 | 837k | const char *pneedle, size_t neelen) { |
134 | 837k | if (0 == neelen) { |
135 | 0 | return phaystack; // even if haylen is 0 |
136 | 0 | } |
137 | 837k | if (haylen < neelen) |
138 | 104 | return nullptr; |
139 | | |
140 | 837k | const char* match; |
141 | 837k | const char* hayend = phaystack + haylen - neelen + 1; |
142 | | // A C-style cast is used here to work around the fact that memchr returns a |
143 | | // void* on Posix-compliant systems and const void* on Windows. |
144 | 838k | while ((match = (const char*)(memchr(phaystack, pneedle[0], |
145 | 470k | hayend - phaystack)))) { |
146 | 470k | if (memcmp(match, pneedle, neelen) == 0) |
147 | 469k | return match; |
148 | 775 | else |
149 | 775 | phaystack = match + 1; |
150 | 470k | } |
151 | 367k | return nullptr; |
152 | 837k | } |