1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <google/protobuf/stubs/stringpiece.h>
31 
32 #include <iterator>
33 #include <map>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include <google/protobuf/testing/googletest.h>
39 #include <google/protobuf/stubs/hash.h>
40 #include <gtest/gtest.h>
41 
42 namespace google {
43 namespace protobuf {
44 namespace {
TEST(StringPiece,Ctor)45 TEST(StringPiece, Ctor) {
46   {
47     // Null.
48     StringPiece s10;
49     EXPECT_TRUE(s10.data() == nullptr);
50     EXPECT_EQ(0, s10.length());
51   }
52 
53   {
54     // const char* without length.
55     const char* hello = "hello";
56     StringPiece s20(hello);
57     EXPECT_TRUE(s20.data() == hello);
58     EXPECT_EQ(5, s20.length());
59 
60     // const char* with length.
61     StringPiece s21(hello, 4);
62     EXPECT_TRUE(s21.data() == hello);
63     EXPECT_EQ(4, s21.length());
64 
65     // Not recommended, but valid C++
66     StringPiece s22(hello, 6);
67     EXPECT_TRUE(s22.data() == hello);
68     EXPECT_EQ(6, s22.length());
69   }
70 
71   {
72     // std::string.
73     std::string hola = "hola";
74     StringPiece s30(hola);
75     EXPECT_TRUE(s30.data() == hola.data());
76     EXPECT_EQ(4, s30.length());
77 
78     // std::string with embedded '\0'.
79     hola.push_back('\0');
80     hola.append("h2");
81     hola.push_back('\0');
82     StringPiece s31(hola);
83     EXPECT_TRUE(s31.data() == hola.data());
84     EXPECT_EQ(8, s31.length());
85   }
86 
87 #if defined(HAS_GLOBAL_STRING)
88   {
89     // ::string
90     std::string bonjour = "bonjour";
91     StringPiece s40(bonjour);
92     EXPECT_TRUE(s40.data() == bonjour.data());
93     EXPECT_EQ(7, s40.length());
94   }
95 #endif
96 
97   // TODO(mec): StringPiece(StringPiece x, int pos);
98   // TODO(mec): StringPiece(StringPiece x, int pos, int len);
99   // TODO(mec): StringPiece(const StringPiece&);
100 }
101 
TEST(StringPiece,STLComparator)102 TEST(StringPiece, STLComparator) {
103   std::string s1("foo");
104   std::string s2("bar");
105   std::string s3("baz");
106 
107   StringPiece p1(s1);
108   StringPiece p2(s2);
109   StringPiece p3(s3);
110 
111   typedef std::map<StringPiece, int> TestMap;
112   TestMap map;
113 
114   map.insert(std::make_pair(p1, 0));
115   map.insert(std::make_pair(p2, 1));
116   map.insert(std::make_pair(p3, 2));
117   EXPECT_EQ(map.size(), 3);
118 
119   TestMap::const_iterator iter = map.begin();
120   EXPECT_EQ(iter->second, 1);
121   ++iter;
122   EXPECT_EQ(iter->second, 2);
123   ++iter;
124   EXPECT_EQ(iter->second, 0);
125   ++iter;
126   EXPECT_TRUE(iter == map.end());
127 
128   TestMap::iterator new_iter = map.find("zot");
129   EXPECT_TRUE(new_iter == map.end());
130 
131   new_iter = map.find("bar");
132   EXPECT_TRUE(new_iter != map.end());
133 
134   map.erase(new_iter);
135   EXPECT_EQ(map.size(), 2);
136 
137   iter = map.begin();
138   EXPECT_EQ(iter->second, 2);
139   ++iter;
140   EXPECT_EQ(iter->second, 0);
141   ++iter;
142   EXPECT_TRUE(iter == map.end());
143 }
144 
TEST(StringPiece,ComparisonOperators)145 TEST(StringPiece, ComparisonOperators) {
146 #define COMPARE(result, op, x, y) \
147   EXPECT_EQ(result, StringPiece((x)) op StringPiece((y))); \
148   EXPECT_EQ(result, StringPiece((x)).compare(StringPiece((y))) op 0)
149 
150   COMPARE(true, ==, "",   "");
151   COMPARE(true, ==, "", nullptr);
152   COMPARE(true, ==, nullptr, "");
153   COMPARE(true, ==, "a",  "a");
154   COMPARE(true, ==, "aa", "aa");
155   COMPARE(false, ==, "a",  "");
156   COMPARE(false, ==, "",   "a");
157   COMPARE(false, ==, "a",  "b");
158   COMPARE(false, ==, "a",  "aa");
159   COMPARE(false, ==, "aa", "a");
160 
161   COMPARE(false, !=, "",   "");
162   COMPARE(false, !=, "a",  "a");
163   COMPARE(false, !=, "aa", "aa");
164   COMPARE(true, !=, "a",  "");
165   COMPARE(true, !=, "",   "a");
166   COMPARE(true, !=, "a",  "b");
167   COMPARE(true, !=, "a",  "aa");
168   COMPARE(true, !=, "aa", "a");
169 
170   COMPARE(true, <, "a",  "b");
171   COMPARE(true, <, "a",  "aa");
172   COMPARE(true, <, "aa", "b");
173   COMPARE(true, <, "aa", "bb");
174   COMPARE(false, <, "a",  "a");
175   COMPARE(false, <, "b",  "a");
176   COMPARE(false, <, "aa", "a");
177   COMPARE(false, <, "b",  "aa");
178   COMPARE(false, <, "bb", "aa");
179 
180   COMPARE(true, <=, "a",  "a");
181   COMPARE(true, <=, "a",  "b");
182   COMPARE(true, <=, "a",  "aa");
183   COMPARE(true, <=, "aa", "b");
184   COMPARE(true, <=, "aa", "bb");
185   COMPARE(false, <=, "b",  "a");
186   COMPARE(false, <=, "aa", "a");
187   COMPARE(false, <=, "b",  "aa");
188   COMPARE(false, <=, "bb", "aa");
189 
190   COMPARE(false, >=, "a",  "b");
191   COMPARE(false, >=, "a",  "aa");
192   COMPARE(false, >=, "aa", "b");
193   COMPARE(false, >=, "aa", "bb");
194   COMPARE(true, >=, "a",  "a");
195   COMPARE(true, >=, "b",  "a");
196   COMPARE(true, >=, "aa", "a");
197   COMPARE(true, >=, "b",  "aa");
198   COMPARE(true, >=, "bb", "aa");
199 
200   COMPARE(false, >, "a",  "a");
201   COMPARE(false, >, "a",  "b");
202   COMPARE(false, >, "a",  "aa");
203   COMPARE(false, >, "aa", "b");
204   COMPARE(false, >, "aa", "bb");
205   COMPARE(true, >, "b",  "a");
206   COMPARE(true, >, "aa", "a");
207   COMPARE(true, >, "b",  "aa");
208   COMPARE(true, >, "bb", "aa");
209 
210   std::string x;
211   for (int i = 0; i < 256; i++) {
212     x += 'a';
213     std::string y = x;
214     COMPARE(true, ==, x, y);
215     for (int j = 0; j < i; j++) {
216       std::string z = x;
217       z[j] = 'b';       // Differs in position 'j'
218       COMPARE(false, ==, x, z);
219       COMPARE(true, <, x, z);
220       COMPARE(true, >, z, x);
221       if (j + 1 < i) {
222         z[j + 1] = 'A';  // Differs in position 'j+1' as well
223         COMPARE(false, ==, x, z);
224         COMPARE(true, <, x, z);
225         COMPARE(true, >, z, x);
226         z[j + 1] = 'z';  // Differs in position 'j+1' as well
227         COMPARE(false, ==, x, z);
228         COMPARE(true, <, x, z);
229         COMPARE(true, >, z, x);
230       }
231     }
232   }
233 
234 #undef COMPARE
235 }
236 
TEST(StringPiece,STL1)237 TEST(StringPiece, STL1) {
238   const StringPiece a("abcdefghijklmnopqrstuvwxyz");
239   const StringPiece b("abc");
240   const StringPiece c("xyz");
241   const StringPiece d("foobar");
242   const StringPiece e;
243   std::string temp("123");
244   temp += '\0';
245   temp += "456";
246   const StringPiece f(temp);
247 
248   EXPECT_EQ(a[6], 'g');
249   EXPECT_EQ(b[0], 'a');
250   EXPECT_EQ(c[2], 'z');
251   EXPECT_EQ(f[3], '\0');
252   EXPECT_EQ(f[5], '5');
253 
254   EXPECT_EQ(*d.data(), 'f');
255   EXPECT_EQ(d.data()[5], 'r');
256   EXPECT_TRUE(e.data() == nullptr);
257 
258   EXPECT_EQ(*a.begin(), 'a');
259   EXPECT_EQ(*(b.begin() + 2), 'c');
260   EXPECT_EQ(*(c.end() - 1), 'z');
261 
262   EXPECT_EQ(*a.rbegin(), 'z');
263   EXPECT_EQ(*(b.rbegin() + 2), 'a');
264   EXPECT_EQ(*(c.rend() - 1), 'x');
265   EXPECT_TRUE(a.rbegin() + 26 == a.rend());
266 
267   EXPECT_EQ(a.size(), 26);
268   EXPECT_EQ(b.size(), 3);
269   EXPECT_EQ(c.size(), 3);
270   EXPECT_EQ(d.size(), 6);
271   EXPECT_EQ(e.size(), 0);
272   EXPECT_EQ(f.size(), 7);
273 
274   EXPECT_TRUE(!d.empty());
275   EXPECT_TRUE(d.begin() != d.end());
276   EXPECT_TRUE(d.begin() + 6 == d.end());
277 
278   EXPECT_TRUE(e.empty());
279   EXPECT_TRUE(e.begin() == e.end());
280 
281   EXPECT_GE(a.max_size(), a.capacity());
282   EXPECT_GE(a.capacity(), a.size());
283 
284   char buf[4] = { '%', '%', '%', '%' };
285   EXPECT_EQ(a.copy(buf, 4), 4);
286   EXPECT_EQ(buf[0], a[0]);
287   EXPECT_EQ(buf[1], a[1]);
288   EXPECT_EQ(buf[2], a[2]);
289   EXPECT_EQ(buf[3], a[3]);
290   EXPECT_EQ(a.copy(buf, 3, 7), 3);
291   EXPECT_EQ(buf[0], a[7]);
292   EXPECT_EQ(buf[1], a[8]);
293   EXPECT_EQ(buf[2], a[9]);
294   EXPECT_EQ(buf[3], a[3]);
295   EXPECT_EQ(c.copy(buf, 99), 3);
296   EXPECT_EQ(buf[0], c[0]);
297   EXPECT_EQ(buf[1], c[1]);
298   EXPECT_EQ(buf[2], c[2]);
299   EXPECT_EQ(buf[3], a[3]);
300 }
301 
302 // Separated from STL1() because some compilers produce an overly
303 // large stack frame for the combined function.
TEST(StringPiece,STL2)304 TEST(StringPiece, STL2) {
305   const StringPiece a("abcdefghijklmnopqrstuvwxyz");
306   const StringPiece b("abc");
307   const StringPiece c("xyz");
308   const StringPiece e;
309   const StringPiece f("123" "\0" "456", 7);
310 
311   EXPECT_EQ(StringPiece::npos, std::string::npos);
312 
313   EXPECT_EQ(a.find(b), 0);
314   EXPECT_EQ(a.find(b, 1), StringPiece::npos);
315   EXPECT_EQ(a.find(c), 23);
316   EXPECT_EQ(a.find(c, 9), 23);
317   EXPECT_EQ(a.find(c, StringPiece::npos), StringPiece::npos);
318   EXPECT_EQ(b.find(c), StringPiece::npos);
319   EXPECT_EQ(b.find(c, StringPiece::npos), StringPiece::npos);
320   EXPECT_EQ(a.find(e), 0);
321   EXPECT_EQ(a.find(e, 17), 17);
322   StringPiece g("xx not found bb");
323   EXPECT_EQ(a.find(g), StringPiece::npos);
324   // empty string nonsense
325   EXPECT_EQ(e.find(b), StringPiece::npos);
326   EXPECT_EQ(e.find(b, 7), StringPiece::npos);
327 
328   size_t empty_search_pos = std::string().find(std::string());
329   EXPECT_EQ(e.find(e), empty_search_pos);
330   EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4));
331 
332   EXPECT_EQ(a.find('a'), 0);
333   EXPECT_EQ(a.find('c'), 2);
334   EXPECT_EQ(a.find('z'), 25);
335   EXPECT_EQ(a.find('$'), StringPiece::npos);
336   EXPECT_EQ(a.find('\0'), StringPiece::npos);
337   EXPECT_EQ(f.find('\0'), 3);
338   EXPECT_EQ(f.find('3'), 2);
339   EXPECT_EQ(f.find('5'), 5);
340   EXPECT_EQ(g.find('o'), 4);
341   EXPECT_EQ(g.find('o', 4), 4);
342   EXPECT_EQ(g.find('o', 5), 8);
343   EXPECT_EQ(a.find('b', 5), StringPiece::npos);
344   // empty string nonsense
345   EXPECT_EQ(e.find('\0'), StringPiece::npos);
346   EXPECT_EQ(e.find('\0', 7), StringPiece::npos);
347   EXPECT_EQ(e.find('x'), StringPiece::npos);
348   EXPECT_EQ(e.find('x', 7), StringPiece::npos);
349 
350   EXPECT_EQ(a.rfind(b), 0);
351   EXPECT_EQ(a.rfind(b, 1), 0);
352   EXPECT_EQ(a.rfind(c), 23);
353   EXPECT_EQ(a.rfind(c, 22), StringPiece::npos);
354   EXPECT_EQ(a.rfind(c, 1), StringPiece::npos);
355   EXPECT_EQ(a.rfind(c, 0), StringPiece::npos);
356   EXPECT_EQ(b.rfind(c), StringPiece::npos);
357   EXPECT_EQ(b.rfind(c, 0), StringPiece::npos);
358   EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string()));
359   EXPECT_EQ(a.rfind(e, 17), 17);
360   EXPECT_EQ(a.rfind(g), StringPiece::npos);
361   EXPECT_EQ(e.rfind(b), StringPiece::npos);
362   EXPECT_EQ(e.rfind(b, 7), StringPiece::npos);
363   // empty string nonsense
364   EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string()));
365   EXPECT_EQ(e.rfind(e), std::string().rfind(std::string()));
366 
367   EXPECT_EQ(g.rfind('o'), 8);
368   EXPECT_EQ(g.rfind('q'), StringPiece::npos);
369   EXPECT_EQ(g.rfind('o', 8), 8);
370   EXPECT_EQ(g.rfind('o', 7), 4);
371   EXPECT_EQ(g.rfind('o', 3), StringPiece::npos);
372   EXPECT_EQ(f.rfind('\0'), 3);
373   EXPECT_EQ(f.rfind('\0', 12), 3);
374   EXPECT_EQ(f.rfind('3'), 2);
375   EXPECT_EQ(f.rfind('5'), 5);
376   // empty string nonsense
377   EXPECT_EQ(e.rfind('o'), StringPiece::npos);
378   EXPECT_EQ(e.rfind('o', 7), StringPiece::npos);
379 
380   EXPECT_EQ(a.find_first_of(b), 0);
381   EXPECT_EQ(a.find_first_of(b, 0), 0);
382   EXPECT_EQ(a.find_first_of(b, 1), 1);
383   EXPECT_EQ(a.find_first_of(b, 2), 2);
384   EXPECT_EQ(a.find_first_of(b, 3), StringPiece::npos);
385   EXPECT_EQ(a.find_first_of(c), 23);
386   EXPECT_EQ(a.find_first_of(c, 23), 23);
387   EXPECT_EQ(a.find_first_of(c, 24), 24);
388   EXPECT_EQ(a.find_first_of(c, 25), 25);
389   EXPECT_EQ(a.find_first_of(c, 26), StringPiece::npos);
390   EXPECT_EQ(g.find_first_of(b), 13);
391   EXPECT_EQ(g.find_first_of(c), 0);
392   EXPECT_EQ(a.find_first_of(f), StringPiece::npos);
393   EXPECT_EQ(f.find_first_of(a), StringPiece::npos);
394   // empty string nonsense
395   EXPECT_EQ(a.find_first_of(e), StringPiece::npos);
396   EXPECT_EQ(e.find_first_of(b), StringPiece::npos);
397   EXPECT_EQ(e.find_first_of(e), StringPiece::npos);
398 
399   EXPECT_EQ(a.find_first_not_of(b), 3);
400   EXPECT_EQ(a.find_first_not_of(c), 0);
401   EXPECT_EQ(b.find_first_not_of(a), StringPiece::npos);
402   EXPECT_EQ(c.find_first_not_of(a), StringPiece::npos);
403   EXPECT_EQ(f.find_first_not_of(a), 0);
404   EXPECT_EQ(a.find_first_not_of(f), 0);
405   EXPECT_EQ(a.find_first_not_of(e), 0);
406   // empty string nonsense
407   EXPECT_EQ(e.find_first_not_of(a), StringPiece::npos);
408   EXPECT_EQ(e.find_first_not_of(e), StringPiece::npos);
409 
410   StringPiece h("====");
411   EXPECT_EQ(h.find_first_not_of('='), StringPiece::npos);
412   EXPECT_EQ(h.find_first_not_of('=', 3), StringPiece::npos);
413   EXPECT_EQ(h.find_first_not_of('\0'), 0);
414   EXPECT_EQ(g.find_first_not_of('x'), 2);
415   EXPECT_EQ(f.find_first_not_of('\0'), 0);
416   EXPECT_EQ(f.find_first_not_of('\0', 3), 4);
417   EXPECT_EQ(f.find_first_not_of('\0', 2), 2);
418   // empty string nonsense
419   EXPECT_EQ(e.find_first_not_of('x'), StringPiece::npos);
420   EXPECT_EQ(e.find_first_not_of('\0'), StringPiece::npos);
421 
422   //  StringPiece g("xx not found bb");
423   StringPiece i("56");
424   EXPECT_EQ(h.find_last_of(a), StringPiece::npos);
425   EXPECT_EQ(g.find_last_of(a), g.size()-1);
426   EXPECT_EQ(a.find_last_of(b), 2);
427   EXPECT_EQ(a.find_last_of(c), a.size()-1);
428   EXPECT_EQ(f.find_last_of(i), 6);
429   EXPECT_EQ(a.find_last_of('a'), 0);
430   EXPECT_EQ(a.find_last_of('b'), 1);
431   EXPECT_EQ(a.find_last_of('z'), 25);
432   EXPECT_EQ(a.find_last_of('a', 5), 0);
433   EXPECT_EQ(a.find_last_of('b', 5), 1);
434   EXPECT_EQ(a.find_last_of('b', 0), StringPiece::npos);
435   EXPECT_EQ(a.find_last_of('z', 25), 25);
436   EXPECT_EQ(a.find_last_of('z', 24), StringPiece::npos);
437   EXPECT_EQ(f.find_last_of(i, 5), 5);
438   EXPECT_EQ(f.find_last_of(i, 6), 6);
439   EXPECT_EQ(f.find_last_of(a, 4), StringPiece::npos);
440   // empty string nonsense
441   EXPECT_EQ(f.find_last_of(e), StringPiece::npos);
442   EXPECT_EQ(f.find_last_of(e, 4), StringPiece::npos);
443   EXPECT_EQ(e.find_last_of(e), StringPiece::npos);
444   EXPECT_EQ(e.find_last_of(f), StringPiece::npos);
445   EXPECT_EQ(e.find_last_of(e, 4), StringPiece::npos);
446   EXPECT_EQ(e.find_last_of(f, 4), StringPiece::npos);
447 
448   EXPECT_EQ(a.find_last_not_of(b), a.size()-1);
449   EXPECT_EQ(a.find_last_not_of(c), 22);
450   EXPECT_EQ(b.find_last_not_of(a), StringPiece::npos);
451   EXPECT_EQ(b.find_last_not_of(b), StringPiece::npos);
452   EXPECT_EQ(f.find_last_not_of(i), 4);
453   EXPECT_EQ(a.find_last_not_of(c, 24), 22);
454   EXPECT_EQ(a.find_last_not_of(b, 3), 3);
455   EXPECT_EQ(a.find_last_not_of(b, 2), StringPiece::npos);
456   // empty string nonsense
457   EXPECT_EQ(f.find_last_not_of(e), f.size()-1);
458   EXPECT_EQ(f.find_last_not_of(e, 4), 4);
459   EXPECT_EQ(e.find_last_not_of(e), StringPiece::npos);
460   EXPECT_EQ(e.find_last_not_of(f), StringPiece::npos);
461   EXPECT_EQ(e.find_last_not_of(e, 4), StringPiece::npos);
462   EXPECT_EQ(e.find_last_not_of(f, 4), StringPiece::npos);
463 
464   EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1);
465   EXPECT_EQ(h.find_last_not_of('='), StringPiece::npos);
466   EXPECT_EQ(b.find_last_not_of('c'), 1);
467   EXPECT_EQ(h.find_last_not_of('x', 2), 2);
468   EXPECT_EQ(h.find_last_not_of('=', 2), StringPiece::npos);
469   EXPECT_EQ(b.find_last_not_of('b', 1), 0);
470   // empty string nonsense
471   EXPECT_EQ(e.find_last_not_of('x'), StringPiece::npos);
472   EXPECT_EQ(e.find_last_not_of('\0'), StringPiece::npos);
473 
474   EXPECT_EQ(a.substr(0, 3), b);
475   EXPECT_EQ(a.substr(23), c);
476   EXPECT_EQ(a.substr(23, 3), c);
477   EXPECT_EQ(a.substr(23, 99), c);
478   EXPECT_EQ(a.substr(0), a);
479   EXPECT_EQ(a.substr(3, 2), "de");
480   // empty string nonsense
481   EXPECT_EQ(a.substr(99, 2), e);
482   EXPECT_EQ(e.substr(99), e);
483   EXPECT_EQ(e.substr(0, 99), e);
484   EXPECT_EQ(e.substr(99, 99), e);
485   // use of npos
486   EXPECT_EQ(a.substr(0, StringPiece::npos), a);
487   EXPECT_EQ(a.substr(23, StringPiece::npos), c);
488   EXPECT_EQ(a.substr(StringPiece::npos, 0), e);
489   EXPECT_EQ(a.substr(StringPiece::npos, 1), e);
490   EXPECT_EQ(a.substr(StringPiece::npos, StringPiece::npos), e);
491 }
492 
TEST(StringPiece,Custom)493 TEST(StringPiece, Custom) {
494   StringPiece a("foobar");
495   std::string s1("123");
496   s1 += '\0';
497   s1 += "456";
498   StringPiece b(s1);
499   StringPiece e;
500   std::string s2;
501 
502   // CopyToString
503   a.CopyToString(&s2);
504   EXPECT_EQ(s2.size(), 6);
505   EXPECT_EQ(s2, "foobar");
506   b.CopyToString(&s2);
507   EXPECT_EQ(s2.size(), 7);
508   EXPECT_EQ(s1, s2);
509   e.CopyToString(&s2);
510   EXPECT_TRUE(s2.empty());
511 
512   // AppendToString
513   s2.erase();
514   a.AppendToString(&s2);
515   EXPECT_EQ(s2.size(), 6);
516   EXPECT_EQ(s2, "foobar");
517   a.AppendToString(&s2);
518   EXPECT_EQ(s2.size(), 12);
519   EXPECT_EQ(s2, "foobarfoobar");
520 
521   // starts_with
522   EXPECT_TRUE(a.starts_with(a));
523   EXPECT_TRUE(a.starts_with("foo"));
524   EXPECT_TRUE(a.starts_with(e));
525   EXPECT_TRUE(b.starts_with(s1));
526   EXPECT_TRUE(b.starts_with(b));
527   EXPECT_TRUE(b.starts_with(e));
528   EXPECT_TRUE(e.starts_with(""));
529   EXPECT_TRUE(!a.starts_with(b));
530   EXPECT_TRUE(!b.starts_with(a));
531   EXPECT_TRUE(!e.starts_with(a));
532 
533   // ends with
534   EXPECT_TRUE(a.ends_with(a));
535   EXPECT_TRUE(a.ends_with("bar"));
536   EXPECT_TRUE(a.ends_with(e));
537   EXPECT_TRUE(b.ends_with(s1));
538   EXPECT_TRUE(b.ends_with(b));
539   EXPECT_TRUE(b.ends_with(e));
540   EXPECT_TRUE(e.ends_with(""));
541   EXPECT_TRUE(!a.ends_with(b));
542   EXPECT_TRUE(!b.ends_with(a));
543   EXPECT_TRUE(!e.ends_with(a));
544 
545   // remove_prefix
546   StringPiece c(a);
547   c.remove_prefix(3);
548   EXPECT_EQ(c, "bar");
549   c = a;
550   c.remove_prefix(0);
551   EXPECT_EQ(c, a);
552   c.remove_prefix(c.size());
553   EXPECT_EQ(c, e);
554 
555   // remove_suffix
556   c = a;
557   c.remove_suffix(3);
558   EXPECT_EQ(c, "foo");
559   c = a;
560   c.remove_suffix(0);
561   EXPECT_EQ(c, a);
562   c.remove_suffix(c.size());
563   EXPECT_EQ(c, e);
564 
565   c = StringPiece("foobar", 7);
566 
567   // as_string
568   std::string s3(a.as_string().c_str(), 7);
569   EXPECT_EQ(c, s3);
570   std::string s4(e.as_string());
571   EXPECT_TRUE(s4.empty());
572 
573   // ToString
574   {
575     std::string s5(a.ToString().c_str(), 7);
576     EXPECT_EQ(c, s5);
577     std::string s6(e.ToString());
578     EXPECT_TRUE(s6.empty());
579   }
580 
581   // Consume
582   {
583     StringPiece str("foobar");
584     EXPECT_TRUE(str.Consume("foo"));
585     EXPECT_EQ(str, "bar");
586     EXPECT_FALSE(str.Consume("foo"));
587     EXPECT_FALSE(str.Consume("barbar"));
588     EXPECT_FALSE(str.Consume("ar"));
589     EXPECT_EQ(str, "bar");
590   }
591 
592   {
593     StringPiece str("foobar");
594     EXPECT_TRUE(str.ConsumeFromEnd("bar"));
595     EXPECT_EQ(str, "foo");
596     EXPECT_FALSE(str.ConsumeFromEnd("bar"));
597     EXPECT_FALSE(str.ConsumeFromEnd("foofoo"));
598     EXPECT_FALSE(str.ConsumeFromEnd("fo"));
599     EXPECT_EQ(str, "foo");
600   }
601 }
602 
TEST(StringPiece,Contains)603 TEST(StringPiece, Contains) {
604   StringPiece a("abcdefg");
605   StringPiece b("abcd");
606   StringPiece c("efg");
607   StringPiece d("gh");
608   EXPECT_TRUE(a.contains(b));
609   EXPECT_TRUE(a.contains(c));
610   EXPECT_TRUE(!a.contains(d));
611 }
612 
TEST(StringPiece,NullInput)613 TEST(StringPiece, NullInput) {
614   // we used to crash here, but now we don't.
615   StringPiece s(nullptr);
616   EXPECT_EQ(s.data(), (const char*)nullptr);
617   EXPECT_EQ(s.size(), 0);
618 
619   // .ToString() on a StringPiece with nullptr should produce the empty string.
620   EXPECT_EQ("", s.ToString());
621   EXPECT_EQ("", s.as_string());
622 }
623 
TEST(StringPiece,Comparisons2)624 TEST(StringPiece, Comparisons2) {
625   StringPiece abc("abcdefghijklmnopqrstuvwxyz");
626 
627   // check comparison operations on strings longer than 4 bytes.
628   EXPECT_EQ(abc, StringPiece("abcdefghijklmnopqrstuvwxyz"));
629   EXPECT_EQ(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyz")), 0);
630 
631   EXPECT_LT(abc, StringPiece("abcdefghijklmnopqrstuvwxzz"));
632   EXPECT_LT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxzz")), 0);
633 
634   EXPECT_GT(abc, StringPiece("abcdefghijklmnopqrstuvwxyy"));
635   EXPECT_GT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyy")), 0);
636 
637   // starts_with
638   EXPECT_TRUE(abc.starts_with(abc));
639   EXPECT_TRUE(abc.starts_with("abcdefghijklm"));
640   EXPECT_TRUE(!abc.starts_with("abcdefguvwxyz"));
641 
642   // ends_with
643   EXPECT_TRUE(abc.ends_with(abc));
644   EXPECT_TRUE(!abc.ends_with("abcdefguvwxyz"));
645   EXPECT_TRUE(abc.ends_with("nopqrstuvwxyz"));
646 }
647 
TEST(ComparisonOpsTest,StringCompareNotAmbiguous)648 TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {
649   EXPECT_EQ("hello", std::string("hello"));
650   EXPECT_LT("hello", std::string("world"));
651 }
652 
TEST(ComparisonOpsTest,HeterogenousStringPieceEquals)653 TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) {
654   EXPECT_EQ(StringPiece("hello"), std::string("hello"));
655   EXPECT_EQ("hello", StringPiece("hello"));
656 }
657 
TEST(FindOneCharTest,EdgeCases)658 TEST(FindOneCharTest, EdgeCases) {
659   StringPiece a("xxyyyxx");
660 
661   // Set a = "xyyyx".
662   a.remove_prefix(1);
663   a.remove_suffix(1);
664 
665   EXPECT_EQ(0, a.find('x'));
666   EXPECT_EQ(0, a.find('x', 0));
667   EXPECT_EQ(4, a.find('x', 1));
668   EXPECT_EQ(4, a.find('x', 4));
669   EXPECT_EQ(StringPiece::npos, a.find('x', 5));
670 
671   EXPECT_EQ(4, a.rfind('x'));
672   EXPECT_EQ(4, a.rfind('x', 5));
673   EXPECT_EQ(4, a.rfind('x', 4));
674   EXPECT_EQ(0, a.rfind('x', 3));
675   EXPECT_EQ(0, a.rfind('x', 0));
676 
677   // Set a = "yyy".
678   a.remove_prefix(1);
679   a.remove_suffix(1);
680 
681   EXPECT_EQ(StringPiece::npos, a.find('x'));
682   EXPECT_EQ(StringPiece::npos, a.rfind('x'));
683 }
684 
685 #ifdef PROTOBUF_HAS_DEATH_TEST
686 #ifndef NDEBUG
TEST(NonNegativeLenTest,NonNegativeLen)687 TEST(NonNegativeLenTest, NonNegativeLen) {
688   EXPECT_DEATH(StringPiece("xyz", -1), "string length exceeds max size");
689 }
690 #endif  // ndef DEBUG
691 #endif  // PROTOBUF_HAS_DEATH_TEST
692 
693 }  // namespace
694 }  // namespace protobuf
695 }  // namespace google
696