1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Unit test for memutil.cc
16
17 #include "absl/strings/internal/memutil.h"
18
19 #include <cstdlib>
20
21 #include "gtest/gtest.h"
22 #include "absl/strings/ascii.h"
23
24 namespace {
25
memcasechr(const char * s,int c,size_t slen)26 static char* memcasechr(const char* s, int c, size_t slen) {
27 c = absl::ascii_tolower(c);
28 for (; slen; ++s, --slen) {
29 if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s);
30 }
31 return nullptr;
32 }
33
memcasematch(const char * phaystack,size_t haylen,const char * pneedle,size_t neelen)34 static const char* memcasematch(const char* phaystack, size_t haylen,
35 const char* pneedle, size_t neelen) {
36 if (0 == neelen) {
37 return phaystack; // even if haylen is 0
38 }
39 if (haylen < neelen) return nullptr;
40
41 const char* match;
42 const char* hayend = phaystack + haylen - neelen + 1;
43 while ((match = static_cast<char*>(
44 memcasechr(phaystack, pneedle[0], hayend - phaystack)))) {
45 if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0)
46 return match;
47 else
48 phaystack = match + 1;
49 }
50 return nullptr;
51 }
52
TEST(MemUtilTest,AllTests)53 TEST(MemUtilTest, AllTests) {
54 // check memutil functions
55 char a[1000];
56 absl::strings_internal::memcat(a, 0, "hello", sizeof("hello") - 1);
57 absl::strings_internal::memcat(a, 5, " there", sizeof(" there") - 1);
58
59 EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO there",
60 sizeof("hello there") - 1),
61 0);
62 EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf",
63 sizeof("hello there") - 1),
64 -1);
65 EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf",
66 sizeof("hello there") - 2),
67 0);
68 EXPECT_EQ(absl::strings_internal::memcasecmp(a, "whatever", 0), 0);
69
70 char* p = absl::strings_internal::memdup("hello", 5);
71 free(p);
72
73 p = absl::strings_internal::memrchr("hello there", 'e',
74 sizeof("hello there") - 1);
75 EXPECT_TRUE(p && p[-1] == 'r');
76 p = absl::strings_internal::memrchr("hello there", 'e',
77 sizeof("hello there") - 2);
78 EXPECT_TRUE(p && p[-1] == 'h');
79 p = absl::strings_internal::memrchr("hello there", 'u',
80 sizeof("hello there") - 1);
81 EXPECT_TRUE(p == nullptr);
82
83 int len = absl::strings_internal::memspn("hello there",
84 sizeof("hello there") - 1, "hole");
85 EXPECT_EQ(len, sizeof("hello") - 1);
86 len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
87 "u");
88 EXPECT_EQ(len, 0);
89 len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
90 "");
91 EXPECT_EQ(len, 0);
92 len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
93 "trole h");
94 EXPECT_EQ(len, sizeof("hello there") - 1);
95 len = absl::strings_internal::memspn("hello there!",
96 sizeof("hello there!") - 1, "trole h");
97 EXPECT_EQ(len, sizeof("hello there") - 1);
98 len = absl::strings_internal::memspn("hello there!",
99 sizeof("hello there!") - 2, "trole h!");
100 EXPECT_EQ(len, sizeof("hello there!") - 2);
101
102 len = absl::strings_internal::memcspn("hello there",
103 sizeof("hello there") - 1, "leho");
104 EXPECT_EQ(len, 0);
105 len = absl::strings_internal::memcspn("hello there",
106 sizeof("hello there") - 1, "u");
107 EXPECT_EQ(len, sizeof("hello there") - 1);
108 len = absl::strings_internal::memcspn("hello there",
109 sizeof("hello there") - 1, "");
110 EXPECT_EQ(len, sizeof("hello there") - 1);
111 len = absl::strings_internal::memcspn("hello there",
112 sizeof("hello there") - 1, " ");
113 EXPECT_EQ(len, 5);
114
115 p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
116 "leho");
117 EXPECT_TRUE(p && p[1] == 'e' && p[2] == 'l');
118 p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
119 "nu");
120 EXPECT_TRUE(p == nullptr);
121 p = absl::strings_internal::mempbrk("hello there!",
122 sizeof("hello there!") - 2, "!");
123 EXPECT_TRUE(p == nullptr);
124 p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
125 " t ");
126 EXPECT_TRUE(p && p[-1] == 'o' && p[1] == 't');
127
128 {
129 const char kHaystack[] = "0123456789";
130 EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 0, "", 0), kHaystack);
131 EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "012", 3),
132 kHaystack);
133 EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "0xx", 1),
134 kHaystack);
135 EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "789", 3),
136 kHaystack + 7);
137 EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "9xx", 1),
138 kHaystack + 9);
139 EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "9xx", 3) ==
140 nullptr);
141 EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "xxx", 1) ==
142 nullptr);
143 }
144 {
145 const char kHaystack[] = "aBcDeFgHiJ";
146 EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 0, "", 0),
147 kHaystack);
148 EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Abc", 3),
149 kHaystack);
150 EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Axx", 1),
151 kHaystack);
152 EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "hIj", 3),
153 kHaystack + 7);
154 EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 1),
155 kHaystack + 9);
156 EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 3) ==
157 nullptr);
158 EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "xxx", 1) ==
159 nullptr);
160 }
161 {
162 const char kHaystack[] = "0123456789";
163 EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 0, "", 0), kHaystack);
164 EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "012", 3),
165 kHaystack);
166 EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "0xx", 1),
167 kHaystack);
168 EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "789", 3),
169 kHaystack + 7);
170 EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 1),
171 kHaystack + 9);
172 EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 3) ==
173 nullptr);
174 EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "xxx", 1) ==
175 nullptr);
176 }
177 }
178
179 } // namespace
180