YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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