/Users/deen/code/yugabyte-db/src/yb/gutil/strings/memutil.h
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 | | // (Please see comments in strutil.h near the include of <asm/string.h> |
19 | | // if you feel compelled to try to provide more efficient implementations |
20 | | // of these routines.) |
21 | | // |
22 | | // These routines provide mem versions of standard C string routines, |
23 | | // such a strpbrk. They function exactly the same as the str version, |
24 | | // so if you wonder what they are, replace the word "mem" by |
25 | | // "str" and check out the man page. I could return void*, as the |
26 | | // strutil.h mem*() routines tend to do, but I return char* instead |
27 | | // since this is by far the most common way these functions are called. |
28 | | // |
29 | | // The difference between the mem and str versions is the mem version |
30 | | // takes a pointer and a length, rather than a NULL-terminated string. |
31 | | // The memcase* routines defined here assume the locale is "C" |
32 | | // (they use ascii_tolower instead of tolower). |
33 | | // |
34 | | // These routines are based on the BSD library. |
35 | | // |
36 | | // Here's a list of routines from string.h, and their mem analogues. |
37 | | // Functions in lowercase are defined in string.h; those in UPPERCASE |
38 | | // are defined here: |
39 | | // |
40 | | // strlen -- |
41 | | // strcat strncat MEMCAT |
42 | | // strcpy strncpy memcpy |
43 | | // -- memccpy (very cool function, btw) |
44 | | // -- memmove |
45 | | // -- memset |
46 | | // strcmp strncmp memcmp |
47 | | // strcasecmp strncasecmp MEMCASECMP |
48 | | // strchr memchr |
49 | | // strcoll -- |
50 | | // strxfrm -- |
51 | | // strdup strndup MEMDUP |
52 | | // strrchr MEMRCHR |
53 | | // strspn MEMSPN |
54 | | // strcspn MEMCSPN |
55 | | // strpbrk MEMPBRK |
56 | | // strstr MEMSTR MEMMEM |
57 | | // (g)strcasestr MEMCASESTR MEMCASEMEM |
58 | | // strtok -- |
59 | | // strprefix MEMPREFIX (strprefix is from strutil.h) |
60 | | // strcaseprefix MEMCASEPREFIX (strcaseprefix is from strutil.h) |
61 | | // strsuffix MEMSUFFIX (strsuffix is from strutil.h) |
62 | | // strcasesuffix MEMCASESUFFIX (strcasesuffix is from strutil.h) |
63 | | // -- MEMIS |
64 | | // -- MEMCASEIS |
65 | | // strcount MEMCOUNT (strcount is from strutil.h) |
66 | | |
67 | | #ifndef YB_GUTIL_STRINGS_MEMUTIL_H |
68 | | #define YB_GUTIL_STRINGS_MEMUTIL_H |
69 | | |
70 | | #include <stddef.h> |
71 | | #include <string.h> // to get the POSIX mem*() routines |
72 | | |
73 | | #include "yb/gutil/port.h" // disable some warnings on Windows |
74 | | |
75 | | inline char *memcat(char *dest, size_t destlen, |
76 | 0 | const char *src, size_t srclen) { |
77 | 0 | return reinterpret_cast<char*>(memcpy(dest + destlen, src, srclen)); |
78 | 0 | } |
79 | | |
80 | | int memcasecmp(const char *s1, const char *s2, size_t len); |
81 | | char *memdup(const char *s, size_t slen); |
82 | | char *memrchr(const char *s, int c, size_t slen); |
83 | | size_t memspn(const char *s, size_t slen, const char *accept); |
84 | | size_t memcspn(const char *s, size_t slen, const char *reject); |
85 | | char *mempbrk(const char *s, size_t slen, const char *accept); |
86 | | |
87 | | // This is for internal use only. Don't call this directly |
88 | | template<bool case_sensitive> |
89 | | const char * int_memmatch(const char *phaystack, size_t haylen, |
90 | | const char *pneedle, size_t neelen); |
91 | | |
92 | | // These are the guys you can call directly |
93 | | inline const char * memstr(const char *phaystack, size_t haylen, |
94 | 0 | const char *pneedle) { |
95 | 0 | return int_memmatch<true>(phaystack, haylen, pneedle, strlen(pneedle)); |
96 | 0 | } |
97 | | |
98 | | inline const char * memcasestr(const char *phaystack, size_t haylen, |
99 | 0 | const char *pneedle) { |
100 | 0 | return int_memmatch<false>(phaystack, haylen, pneedle, strlen(pneedle)); |
101 | 0 | } |
102 | | |
103 | | inline const char * memmem(const char *phaystack, size_t haylen, |
104 | 0 | const char *pneedle, size_t needlelen) { |
105 | 0 | return int_memmatch<true>(phaystack, haylen, pneedle, needlelen); |
106 | 0 | } |
107 | | |
108 | | inline const char * memcasemem(const char *phaystack, size_t haylen, |
109 | 0 | const char *pneedle, size_t needlelen) { |
110 | 0 | return int_memmatch<false>(phaystack, haylen, pneedle, needlelen); |
111 | 0 | } |
112 | | |
113 | | // This is significantly faster for case-sensitive matches with very |
114 | | // few possible matches. See unit test for benchmarks. |
115 | | const char *memmatch(const char *phaystack, size_t haylen, |
116 | | const char *pneedle, size_t neelen); |
117 | | |
118 | | // The ""'s catch people who don't pass in a literal for "str" |
119 | | #define strliterallen(str) (sizeof("" str "")-1) |
120 | | |
121 | | // Must use a string literal for prefix. |
122 | | #define memprefix(str, len, prefix) \ |
123 | | ( (((len) >= strliterallen(prefix)) \ |
124 | | && memcmp(str, prefix, strliterallen(prefix)) == 0) \ |
125 | | ? str + strliterallen(prefix) \ |
126 | | : NULL ) |
127 | | |
128 | | #define memcaseprefix(str, len, prefix) \ |
129 | | ( (((len) >= strliterallen(prefix)) \ |
130 | | && memcasecmp(str, prefix, strliterallen(prefix)) == 0) \ |
131 | | ? str + strliterallen(prefix) \ |
132 | | : NULL ) |
133 | | |
134 | | // Must use a string literal for suffix. |
135 | | #define memsuffix(str, len, suffix) \ |
136 | | ( (((len) >= strliterallen(suffix)) \ |
137 | | && memcmp(str + (len) - strliterallen(suffix), suffix, \ |
138 | | strliterallen(suffix)) == 0) \ |
139 | | ? str + (len) - strliterallen(suffix) \ |
140 | | : NULL ) |
141 | | |
142 | | #define memcasesuffix(str, len, suffix) \ |
143 | | ( (((len) >= strliterallen(suffix)) \ |
144 | | && memcasecmp(str + (len) - strliterallen(suffix), suffix, \ |
145 | | strliterallen(suffix)) == 0) \ |
146 | | ? str + (len) - strliterallen(suffix) \ |
147 | | : NULL ) |
148 | | |
149 | | #define memis(str, len, literal) \ |
150 | | ( (((len) == strliterallen(literal)) \ |
151 | | && memcmp(str, literal, strliterallen(literal)) == 0) ) |
152 | | |
153 | | #define memcaseis(str, len, literal) \ |
154 | | ( (((len) == strliterallen(literal)) \ |
155 | | && memcasecmp(str, literal, strliterallen(literal)) == 0) ) |
156 | | |
157 | | |
158 | 0 | inline int memcount(const char* buf, size_t len, char c) { |
159 | 0 | int num = 0; |
160 | 0 | for (size_t i = 0; i < len; i++) { |
161 | 0 | if (buf[i] == c) |
162 | 0 | num++; |
163 | 0 | } |
164 | 0 | return num; |
165 | 0 | } |
166 | | |
167 | | #endif // YB_GUTIL_STRINGS_MEMUTIL_H |