• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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() == NULL);
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     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   string s1("foo");
104   string s2("bar");
105   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, ==, "", NULL);
152   COMPARE(true, ==, NULL, "");
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   string x;
211   for (int i = 0; i < 256; i++) {
212     x += 'a';
213     string y = x;
214     COMPARE(true, ==, x, y);
215     for (int j = 0; j < i; j++) {
216       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   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() == NULL);
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   StringPiece d("foobar");
309   const StringPiece e;
310   const StringPiece f("123" "\0" "456", 7);
311 
312   d.clear();
313   EXPECT_EQ(d.size(), 0);
314   EXPECT_TRUE(d.empty());
315   EXPECT_TRUE(d.data() == NULL);
316   EXPECT_TRUE(d.begin() == d.end());
317 
318   EXPECT_EQ(StringPiece::npos, string::npos);
319 
320   EXPECT_EQ(a.find(b), 0);
321   EXPECT_EQ(a.find(b, 1), StringPiece::npos);
322   EXPECT_EQ(a.find(c), 23);
323   EXPECT_EQ(a.find(c, 9), 23);
324   EXPECT_EQ(a.find(c, StringPiece::npos), StringPiece::npos);
325   EXPECT_EQ(b.find(c), StringPiece::npos);
326   EXPECT_EQ(b.find(c, StringPiece::npos), StringPiece::npos);
327   EXPECT_EQ(a.find(d), 0);
328   EXPECT_EQ(a.find(e), 0);
329   EXPECT_EQ(a.find(d, 12), 12);
330   EXPECT_EQ(a.find(e, 17), 17);
331   StringPiece g("xx not found bb");
332   EXPECT_EQ(a.find(g), StringPiece::npos);
333   // empty string nonsense
334   EXPECT_EQ(d.find(b), StringPiece::npos);
335   EXPECT_EQ(e.find(b), StringPiece::npos);
336   EXPECT_EQ(d.find(b, 4), StringPiece::npos);
337   EXPECT_EQ(e.find(b, 7), StringPiece::npos);
338 
339   size_t empty_search_pos = string().find(string());
340   EXPECT_EQ(d.find(d), empty_search_pos);
341   EXPECT_EQ(d.find(e), empty_search_pos);
342   EXPECT_EQ(e.find(d), empty_search_pos);
343   EXPECT_EQ(e.find(e), empty_search_pos);
344   EXPECT_EQ(d.find(d, 4), string().find(string(), 4));
345   EXPECT_EQ(d.find(e, 4), string().find(string(), 4));
346   EXPECT_EQ(e.find(d, 4), string().find(string(), 4));
347   EXPECT_EQ(e.find(e, 4), string().find(string(), 4));
348 
349   EXPECT_EQ(a.find('a'), 0);
350   EXPECT_EQ(a.find('c'), 2);
351   EXPECT_EQ(a.find('z'), 25);
352   EXPECT_EQ(a.find('$'), StringPiece::npos);
353   EXPECT_EQ(a.find('\0'), StringPiece::npos);
354   EXPECT_EQ(f.find('\0'), 3);
355   EXPECT_EQ(f.find('3'), 2);
356   EXPECT_EQ(f.find('5'), 5);
357   EXPECT_EQ(g.find('o'), 4);
358   EXPECT_EQ(g.find('o', 4), 4);
359   EXPECT_EQ(g.find('o', 5), 8);
360   EXPECT_EQ(a.find('b', 5), StringPiece::npos);
361   // empty string nonsense
362   EXPECT_EQ(d.find('\0'), StringPiece::npos);
363   EXPECT_EQ(e.find('\0'), StringPiece::npos);
364   EXPECT_EQ(d.find('\0', 4), StringPiece::npos);
365   EXPECT_EQ(e.find('\0', 7), StringPiece::npos);
366   EXPECT_EQ(d.find('x'), StringPiece::npos);
367   EXPECT_EQ(e.find('x'), StringPiece::npos);
368   EXPECT_EQ(d.find('x', 4), StringPiece::npos);
369   EXPECT_EQ(e.find('x', 7), StringPiece::npos);
370 
371   EXPECT_EQ(a.rfind(b), 0);
372   EXPECT_EQ(a.rfind(b, 1), 0);
373   EXPECT_EQ(a.rfind(c), 23);
374   EXPECT_EQ(a.rfind(c, 22), StringPiece::npos);
375   EXPECT_EQ(a.rfind(c, 1), StringPiece::npos);
376   EXPECT_EQ(a.rfind(c, 0), StringPiece::npos);
377   EXPECT_EQ(b.rfind(c), StringPiece::npos);
378   EXPECT_EQ(b.rfind(c, 0), StringPiece::npos);
379   EXPECT_EQ(a.rfind(d), a.as_string().rfind(string()));
380   EXPECT_EQ(a.rfind(e), a.as_string().rfind(string()));
381   EXPECT_EQ(a.rfind(d, 12), 12);
382   EXPECT_EQ(a.rfind(e, 17), 17);
383   EXPECT_EQ(a.rfind(g), StringPiece::npos);
384   EXPECT_EQ(d.rfind(b), StringPiece::npos);
385   EXPECT_EQ(e.rfind(b), StringPiece::npos);
386   EXPECT_EQ(d.rfind(b, 4), StringPiece::npos);
387   EXPECT_EQ(e.rfind(b, 7), StringPiece::npos);
388   // empty string nonsense
389   EXPECT_EQ(d.rfind(d, 4), string().rfind(string()));
390   EXPECT_EQ(e.rfind(d, 7), string().rfind(string()));
391   EXPECT_EQ(d.rfind(e, 4), string().rfind(string()));
392   EXPECT_EQ(e.rfind(e, 7), string().rfind(string()));
393   EXPECT_EQ(d.rfind(d), string().rfind(string()));
394   EXPECT_EQ(e.rfind(d), string().rfind(string()));
395   EXPECT_EQ(d.rfind(e), string().rfind(string()));
396   EXPECT_EQ(e.rfind(e), string().rfind(string()));
397 
398   EXPECT_EQ(g.rfind('o'), 8);
399   EXPECT_EQ(g.rfind('q'), StringPiece::npos);
400   EXPECT_EQ(g.rfind('o', 8), 8);
401   EXPECT_EQ(g.rfind('o', 7), 4);
402   EXPECT_EQ(g.rfind('o', 3), StringPiece::npos);
403   EXPECT_EQ(f.rfind('\0'), 3);
404   EXPECT_EQ(f.rfind('\0', 12), 3);
405   EXPECT_EQ(f.rfind('3'), 2);
406   EXPECT_EQ(f.rfind('5'), 5);
407   // empty string nonsense
408   EXPECT_EQ(d.rfind('o'), StringPiece::npos);
409   EXPECT_EQ(e.rfind('o'), StringPiece::npos);
410   EXPECT_EQ(d.rfind('o', 4), StringPiece::npos);
411   EXPECT_EQ(e.rfind('o', 7), StringPiece::npos);
412 
413   EXPECT_EQ(a.find_first_of(b), 0);
414   EXPECT_EQ(a.find_first_of(b, 0), 0);
415   EXPECT_EQ(a.find_first_of(b, 1), 1);
416   EXPECT_EQ(a.find_first_of(b, 2), 2);
417   EXPECT_EQ(a.find_first_of(b, 3), StringPiece::npos);
418   EXPECT_EQ(a.find_first_of(c), 23);
419   EXPECT_EQ(a.find_first_of(c, 23), 23);
420   EXPECT_EQ(a.find_first_of(c, 24), 24);
421   EXPECT_EQ(a.find_first_of(c, 25), 25);
422   EXPECT_EQ(a.find_first_of(c, 26), StringPiece::npos);
423   EXPECT_EQ(g.find_first_of(b), 13);
424   EXPECT_EQ(g.find_first_of(c), 0);
425   EXPECT_EQ(a.find_first_of(f), StringPiece::npos);
426   EXPECT_EQ(f.find_first_of(a), StringPiece::npos);
427   // empty string nonsense
428   EXPECT_EQ(a.find_first_of(d), StringPiece::npos);
429   EXPECT_EQ(a.find_first_of(e), StringPiece::npos);
430   EXPECT_EQ(d.find_first_of(b), StringPiece::npos);
431   EXPECT_EQ(e.find_first_of(b), StringPiece::npos);
432   EXPECT_EQ(d.find_first_of(d), StringPiece::npos);
433   EXPECT_EQ(e.find_first_of(d), StringPiece::npos);
434   EXPECT_EQ(d.find_first_of(e), StringPiece::npos);
435   EXPECT_EQ(e.find_first_of(e), StringPiece::npos);
436 
437   EXPECT_EQ(a.find_first_not_of(b), 3);
438   EXPECT_EQ(a.find_first_not_of(c), 0);
439   EXPECT_EQ(b.find_first_not_of(a), StringPiece::npos);
440   EXPECT_EQ(c.find_first_not_of(a), StringPiece::npos);
441   EXPECT_EQ(f.find_first_not_of(a), 0);
442   EXPECT_EQ(a.find_first_not_of(f), 0);
443   EXPECT_EQ(a.find_first_not_of(d), 0);
444   EXPECT_EQ(a.find_first_not_of(e), 0);
445   // empty string nonsense
446   EXPECT_EQ(d.find_first_not_of(a), StringPiece::npos);
447   EXPECT_EQ(e.find_first_not_of(a), StringPiece::npos);
448   EXPECT_EQ(d.find_first_not_of(d), StringPiece::npos);
449   EXPECT_EQ(e.find_first_not_of(d), StringPiece::npos);
450   EXPECT_EQ(d.find_first_not_of(e), StringPiece::npos);
451   EXPECT_EQ(e.find_first_not_of(e), StringPiece::npos);
452 
453   StringPiece h("====");
454   EXPECT_EQ(h.find_first_not_of('='), StringPiece::npos);
455   EXPECT_EQ(h.find_first_not_of('=', 3), StringPiece::npos);
456   EXPECT_EQ(h.find_first_not_of('\0'), 0);
457   EXPECT_EQ(g.find_first_not_of('x'), 2);
458   EXPECT_EQ(f.find_first_not_of('\0'), 0);
459   EXPECT_EQ(f.find_first_not_of('\0', 3), 4);
460   EXPECT_EQ(f.find_first_not_of('\0', 2), 2);
461   // empty string nonsense
462   EXPECT_EQ(d.find_first_not_of('x'), StringPiece::npos);
463   EXPECT_EQ(e.find_first_not_of('x'), StringPiece::npos);
464   EXPECT_EQ(d.find_first_not_of('\0'), StringPiece::npos);
465   EXPECT_EQ(e.find_first_not_of('\0'), StringPiece::npos);
466 
467   //  StringPiece g("xx not found bb");
468   StringPiece i("56");
469   EXPECT_EQ(h.find_last_of(a), StringPiece::npos);
470   EXPECT_EQ(g.find_last_of(a), g.size()-1);
471   EXPECT_EQ(a.find_last_of(b), 2);
472   EXPECT_EQ(a.find_last_of(c), a.size()-1);
473   EXPECT_EQ(f.find_last_of(i), 6);
474   EXPECT_EQ(a.find_last_of('a'), 0);
475   EXPECT_EQ(a.find_last_of('b'), 1);
476   EXPECT_EQ(a.find_last_of('z'), 25);
477   EXPECT_EQ(a.find_last_of('a', 5), 0);
478   EXPECT_EQ(a.find_last_of('b', 5), 1);
479   EXPECT_EQ(a.find_last_of('b', 0), StringPiece::npos);
480   EXPECT_EQ(a.find_last_of('z', 25), 25);
481   EXPECT_EQ(a.find_last_of('z', 24), StringPiece::npos);
482   EXPECT_EQ(f.find_last_of(i, 5), 5);
483   EXPECT_EQ(f.find_last_of(i, 6), 6);
484   EXPECT_EQ(f.find_last_of(a, 4), StringPiece::npos);
485   // empty string nonsense
486   EXPECT_EQ(f.find_last_of(d), StringPiece::npos);
487   EXPECT_EQ(f.find_last_of(e), StringPiece::npos);
488   EXPECT_EQ(f.find_last_of(d, 4), StringPiece::npos);
489   EXPECT_EQ(f.find_last_of(e, 4), StringPiece::npos);
490   EXPECT_EQ(d.find_last_of(d), StringPiece::npos);
491   EXPECT_EQ(d.find_last_of(e), StringPiece::npos);
492   EXPECT_EQ(e.find_last_of(d), StringPiece::npos);
493   EXPECT_EQ(e.find_last_of(e), StringPiece::npos);
494   EXPECT_EQ(d.find_last_of(f), StringPiece::npos);
495   EXPECT_EQ(e.find_last_of(f), StringPiece::npos);
496   EXPECT_EQ(d.find_last_of(d, 4), StringPiece::npos);
497   EXPECT_EQ(d.find_last_of(e, 4), StringPiece::npos);
498   EXPECT_EQ(e.find_last_of(d, 4), StringPiece::npos);
499   EXPECT_EQ(e.find_last_of(e, 4), StringPiece::npos);
500   EXPECT_EQ(d.find_last_of(f, 4), StringPiece::npos);
501   EXPECT_EQ(e.find_last_of(f, 4), StringPiece::npos);
502 
503   EXPECT_EQ(a.find_last_not_of(b), a.size()-1);
504   EXPECT_EQ(a.find_last_not_of(c), 22);
505   EXPECT_EQ(b.find_last_not_of(a), StringPiece::npos);
506   EXPECT_EQ(b.find_last_not_of(b), StringPiece::npos);
507   EXPECT_EQ(f.find_last_not_of(i), 4);
508   EXPECT_EQ(a.find_last_not_of(c, 24), 22);
509   EXPECT_EQ(a.find_last_not_of(b, 3), 3);
510   EXPECT_EQ(a.find_last_not_of(b, 2), StringPiece::npos);
511   // empty string nonsense
512   EXPECT_EQ(f.find_last_not_of(d), f.size()-1);
513   EXPECT_EQ(f.find_last_not_of(e), f.size()-1);
514   EXPECT_EQ(f.find_last_not_of(d, 4), 4);
515   EXPECT_EQ(f.find_last_not_of(e, 4), 4);
516   EXPECT_EQ(d.find_last_not_of(d), StringPiece::npos);
517   EXPECT_EQ(d.find_last_not_of(e), StringPiece::npos);
518   EXPECT_EQ(e.find_last_not_of(d), StringPiece::npos);
519   EXPECT_EQ(e.find_last_not_of(e), StringPiece::npos);
520   EXPECT_EQ(d.find_last_not_of(f), StringPiece::npos);
521   EXPECT_EQ(e.find_last_not_of(f), StringPiece::npos);
522   EXPECT_EQ(d.find_last_not_of(d, 4), StringPiece::npos);
523   EXPECT_EQ(d.find_last_not_of(e, 4), StringPiece::npos);
524   EXPECT_EQ(e.find_last_not_of(d, 4), StringPiece::npos);
525   EXPECT_EQ(e.find_last_not_of(e, 4), StringPiece::npos);
526   EXPECT_EQ(d.find_last_not_of(f, 4), StringPiece::npos);
527   EXPECT_EQ(e.find_last_not_of(f, 4), StringPiece::npos);
528 
529   EXPECT_EQ(h.find_last_not_of('x'), h.size() - 1);
530   EXPECT_EQ(h.find_last_not_of('='), StringPiece::npos);
531   EXPECT_EQ(b.find_last_not_of('c'), 1);
532   EXPECT_EQ(h.find_last_not_of('x', 2), 2);
533   EXPECT_EQ(h.find_last_not_of('=', 2), StringPiece::npos);
534   EXPECT_EQ(b.find_last_not_of('b', 1), 0);
535   // empty string nonsense
536   EXPECT_EQ(d.find_last_not_of('x'), StringPiece::npos);
537   EXPECT_EQ(e.find_last_not_of('x'), StringPiece::npos);
538   EXPECT_EQ(d.find_last_not_of('\0'), StringPiece::npos);
539   EXPECT_EQ(e.find_last_not_of('\0'), StringPiece::npos);
540 
541   EXPECT_EQ(a.substr(0, 3), b);
542   EXPECT_EQ(a.substr(23), c);
543   EXPECT_EQ(a.substr(23, 3), c);
544   EXPECT_EQ(a.substr(23, 99), c);
545   EXPECT_EQ(a.substr(0), a);
546   EXPECT_EQ(a.substr(3, 2), "de");
547   // empty string nonsense
548   EXPECT_EQ(a.substr(99, 2), e);
549   EXPECT_EQ(d.substr(99), e);
550   EXPECT_EQ(d.substr(0, 99), e);
551   EXPECT_EQ(d.substr(99, 99), e);
552   // use of npos
553   EXPECT_EQ(a.substr(0, StringPiece::npos), a);
554   EXPECT_EQ(a.substr(23, StringPiece::npos), c);
555   EXPECT_EQ(a.substr(StringPiece::npos, 0), e);
556   EXPECT_EQ(a.substr(StringPiece::npos, 1), e);
557   EXPECT_EQ(a.substr(StringPiece::npos, StringPiece::npos), e);
558 
559   // Substring constructors.
560   EXPECT_EQ(StringPiece(a, 0, 3), b);
561   EXPECT_EQ(StringPiece(a, 23), c);
562   EXPECT_EQ(StringPiece(a, 23, 3), c);
563   EXPECT_EQ(StringPiece(a, 23, 99), c);
564   EXPECT_EQ(StringPiece(a, 0), a);
565   EXPECT_EQ(StringPiece(a, 3, 2), "de");
566   // empty string nonsense
567   EXPECT_EQ(StringPiece(d, 0, 99), e);
568   // Verify that they work taking an actual string, not just a StringPiece.
569   string a2 = a.as_string();
570   EXPECT_EQ(StringPiece(a2, 0, 3), b);
571   EXPECT_EQ(StringPiece(a2, 23), c);
572   EXPECT_EQ(StringPiece(a2, 23, 3), c);
573   EXPECT_EQ(StringPiece(a2, 23, 99), c);
574   EXPECT_EQ(StringPiece(a2, 0), a);
575   EXPECT_EQ(StringPiece(a2, 3, 2), "de");
576 }
577 
TEST(StringPiece,Custom)578 TEST(StringPiece, Custom) {
579   StringPiece a("foobar");
580   string s1("123");
581   s1 += '\0';
582   s1 += "456";
583   StringPiece b(s1);
584   StringPiece e;
585   string s2;
586 
587   // CopyToString
588   a.CopyToString(&s2);
589   EXPECT_EQ(s2.size(), 6);
590   EXPECT_EQ(s2, "foobar");
591   b.CopyToString(&s2);
592   EXPECT_EQ(s2.size(), 7);
593   EXPECT_EQ(s1, s2);
594   e.CopyToString(&s2);
595   EXPECT_TRUE(s2.empty());
596 
597   // AppendToString
598   s2.erase();
599   a.AppendToString(&s2);
600   EXPECT_EQ(s2.size(), 6);
601   EXPECT_EQ(s2, "foobar");
602   a.AppendToString(&s2);
603   EXPECT_EQ(s2.size(), 12);
604   EXPECT_EQ(s2, "foobarfoobar");
605 
606   // starts_with
607   EXPECT_TRUE(a.starts_with(a));
608   EXPECT_TRUE(a.starts_with("foo"));
609   EXPECT_TRUE(a.starts_with(e));
610   EXPECT_TRUE(b.starts_with(s1));
611   EXPECT_TRUE(b.starts_with(b));
612   EXPECT_TRUE(b.starts_with(e));
613   EXPECT_TRUE(e.starts_with(""));
614   EXPECT_TRUE(!a.starts_with(b));
615   EXPECT_TRUE(!b.starts_with(a));
616   EXPECT_TRUE(!e.starts_with(a));
617 
618   // ends with
619   EXPECT_TRUE(a.ends_with(a));
620   EXPECT_TRUE(a.ends_with("bar"));
621   EXPECT_TRUE(a.ends_with(e));
622   EXPECT_TRUE(b.ends_with(s1));
623   EXPECT_TRUE(b.ends_with(b));
624   EXPECT_TRUE(b.ends_with(e));
625   EXPECT_TRUE(e.ends_with(""));
626   EXPECT_TRUE(!a.ends_with(b));
627   EXPECT_TRUE(!b.ends_with(a));
628   EXPECT_TRUE(!e.ends_with(a));
629 
630   // remove_prefix
631   StringPiece c(a);
632   c.remove_prefix(3);
633   EXPECT_EQ(c, "bar");
634   c = a;
635   c.remove_prefix(0);
636   EXPECT_EQ(c, a);
637   c.remove_prefix(c.size());
638   EXPECT_EQ(c, e);
639 
640   // remove_suffix
641   c = a;
642   c.remove_suffix(3);
643   EXPECT_EQ(c, "foo");
644   c = a;
645   c.remove_suffix(0);
646   EXPECT_EQ(c, a);
647   c.remove_suffix(c.size());
648   EXPECT_EQ(c, e);
649 
650   // set
651   c.set("foobar", 6);
652   EXPECT_EQ(c, a);
653   c.set("foobar", 0);
654   EXPECT_EQ(c, e);
655   c.set("foobar", 7);
656   EXPECT_NE(c, a);
657 
658   c.set("foobar");
659   EXPECT_EQ(c, a);
660 
661   c.set(static_cast<const void*>("foobar"), 6);
662   EXPECT_EQ(c, a);
663   c.set(static_cast<const void*>("foobar"), 0);
664   EXPECT_EQ(c, e);
665   c.set(static_cast<const void*>("foobar"), 7);
666   EXPECT_NE(c, a);
667 
668   // as_string
669   string s3(a.as_string().c_str(), 7);
670   EXPECT_EQ(c, s3);
671   string s4(e.as_string());
672   EXPECT_TRUE(s4.empty());
673 
674   // ToString
675   {
676     string s5(a.ToString().c_str(), 7);
677     EXPECT_EQ(c, s5);
678     string s6(e.ToString());
679     EXPECT_TRUE(s6.empty());
680   }
681 
682   // Consume
683   a.set("foobar");
684   EXPECT_TRUE(a.Consume("foo"));
685   EXPECT_EQ(a, "bar");
686   EXPECT_FALSE(a.Consume("foo"));
687   EXPECT_FALSE(a.Consume("barbar"));
688   EXPECT_FALSE(a.Consume("ar"));
689   EXPECT_EQ(a, "bar");
690 
691   a.set("foobar");
692   EXPECT_TRUE(a.ConsumeFromEnd("bar"));
693   EXPECT_EQ(a, "foo");
694   EXPECT_FALSE(a.ConsumeFromEnd("bar"));
695   EXPECT_FALSE(a.ConsumeFromEnd("foofoo"));
696   EXPECT_FALSE(a.ConsumeFromEnd("fo"));
697   EXPECT_EQ(a, "foo");
698 }
699 
TEST(StringPiece,Contains)700 TEST(StringPiece, Contains) {
701   StringPiece a("abcdefg");
702   StringPiece b("abcd");
703   StringPiece c("efg");
704   StringPiece d("gh");
705   EXPECT_TRUE(a.contains(b));
706   EXPECT_TRUE(a.contains(c));
707   EXPECT_TRUE(!a.contains(d));
708 }
709 
TEST(StringPiece,NULLInput)710 TEST(StringPiece, NULLInput) {
711   // we used to crash here, but now we don't.
712   StringPiece s(NULL);
713   EXPECT_EQ(s.data(), (const char*)NULL);
714   EXPECT_EQ(s.size(), 0);
715 
716   s.set(NULL);
717   EXPECT_EQ(s.data(), (const char*)NULL);
718   EXPECT_EQ(s.size(), 0);
719 
720   // .ToString() on a StringPiece with NULL should produce the empty string.
721   EXPECT_EQ("", s.ToString());
722   EXPECT_EQ("", s.as_string());
723 }
724 
TEST(StringPiece,Comparisons2)725 TEST(StringPiece, Comparisons2) {
726   StringPiece abc("abcdefghijklmnopqrstuvwxyz");
727 
728   // check comparison operations on strings longer than 4 bytes.
729   EXPECT_EQ(abc, StringPiece("abcdefghijklmnopqrstuvwxyz"));
730   EXPECT_EQ(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyz")), 0);
731 
732   EXPECT_LT(abc, StringPiece("abcdefghijklmnopqrstuvwxzz"));
733   EXPECT_LT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxzz")), 0);
734 
735   EXPECT_GT(abc, StringPiece("abcdefghijklmnopqrstuvwxyy"));
736   EXPECT_GT(abc.compare(StringPiece("abcdefghijklmnopqrstuvwxyy")), 0);
737 
738   // starts_with
739   EXPECT_TRUE(abc.starts_with(abc));
740   EXPECT_TRUE(abc.starts_with("abcdefghijklm"));
741   EXPECT_TRUE(!abc.starts_with("abcdefguvwxyz"));
742 
743   // ends_with
744   EXPECT_TRUE(abc.ends_with(abc));
745   EXPECT_TRUE(!abc.ends_with("abcdefguvwxyz"));
746   EXPECT_TRUE(abc.ends_with("nopqrstuvwxyz"));
747 }
748 
TEST(ComparisonOpsTest,StringCompareNotAmbiguous)749 TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {
750   EXPECT_EQ("hello", string("hello"));
751   EXPECT_LT("hello", string("world"));
752 }
753 
TEST(ComparisonOpsTest,HeterogenousStringPieceEquals)754 TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) {
755   EXPECT_EQ(StringPiece("hello"), string("hello"));
756   EXPECT_EQ("hello", StringPiece("hello"));
757 }
758 
TEST(FindOneCharTest,EdgeCases)759 TEST(FindOneCharTest, EdgeCases) {
760   StringPiece a("xxyyyxx");
761 
762   // Set a = "xyyyx".
763   a.remove_prefix(1);
764   a.remove_suffix(1);
765 
766   EXPECT_EQ(0, a.find('x'));
767   EXPECT_EQ(0, a.find('x', 0));
768   EXPECT_EQ(4, a.find('x', 1));
769   EXPECT_EQ(4, a.find('x', 4));
770   EXPECT_EQ(StringPiece::npos, a.find('x', 5));
771 
772   EXPECT_EQ(4, a.rfind('x'));
773   EXPECT_EQ(4, a.rfind('x', 5));
774   EXPECT_EQ(4, a.rfind('x', 4));
775   EXPECT_EQ(0, a.rfind('x', 3));
776   EXPECT_EQ(0, a.rfind('x', 0));
777 
778   // Set a = "yyy".
779   a.remove_prefix(1);
780   a.remove_suffix(1);
781 
782   EXPECT_EQ(StringPiece::npos, a.find('x'));
783   EXPECT_EQ(StringPiece::npos, a.rfind('x'));
784 }
785 
786 #ifndef NDEBUG
TEST(NonNegativeLenTest,NonNegativeLen)787 TEST(NonNegativeLenTest, NonNegativeLen) {
788   EXPECT_DEATH(StringPiece("xyz", -1), "len >= 0");
789 }
790 #endif  // ndef DEBUG
791 
792 }  // namespace
793 }  // namespace protobuf
794 }  // namespace google
795