Coverage Report

Created: 2024-11-20 10:55

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