1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "nsASCIIMask.h"
10 #include "nsString.h"
11 #include "nsStringBuffer.h"
12 #include "nsReadableUtils.h"
13 #include "nsCRTGlue.h"
14 #include "mozilla/RefPtr.h"
15 #include "mozilla/Unused.h"
16 #include "nsTArray.h"
17 #include "gtest/gtest.h"
18 #include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH
19 #include "gtest/BlackBox.h"
20 #include "nsBidiUtils.h"
21 
22 namespace TestStrings {
23 
24 using mozilla::fallible;
25 using mozilla::BlackBox;
26 
test_assign_helper(const nsACString & in,nsACString & _retval)27 void test_assign_helper(const nsACString& in, nsACString &_retval)
28 {
29   _retval = in;
30 }
31 
32 // Simple helper struct to test if conditionally enabled string functions are
33 // working.
34 template <typename T>
35 struct EnableTest
36 {
37   template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
IsChar16TestStrings::EnableTest38   bool IsChar16() { return true; }
39 
40   template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
IsChar16TestStrings::EnableTest41   bool IsChar16(int dummy = 42) { return false; }
42 
43   template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
IsCharTestStrings::EnableTest44   bool IsChar() { return false; }
45 
46   template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>>
IsCharTestStrings::EnableTest47   bool IsChar(int dummy = 42) { return true; }
48 };
49 
TEST(Strings,IsChar)50 TEST(Strings, IsChar)
51 {
52   EnableTest<char> charTest;
53   EXPECT_TRUE(charTest.IsChar());
54   EXPECT_FALSE(charTest.IsChar16());
55 
56   EnableTest<char16_t> char16Test;
57   EXPECT_TRUE(char16Test.IsChar16());
58   EXPECT_FALSE(char16Test.IsChar());
59 
60 #ifdef COMPILATION_FAILURE_TEST
61   nsAutoCString a_ctest;
62   nsAutoString a_test;
63 
64   a_ctest.AssignLiteral("hello");
65   // This should cause a compilation failure.
66   a_ctest.AssignLiteral(u"hello");
67   a_test.AssignLiteral(u"hello");
68   a_test.AssignLiteral("hello");
69 #endif
70 }
71 
TEST(Strings,DependentStrings)72 TEST(Strings, DependentStrings)
73 {
74   // A few tests that make sure copying nsTDependentStrings behaves properly.
75   using DataFlags = mozilla::detail::StringDataFlags;
76 
77   {
78     // Test copy ctor.
79     nsDependentCString tmp("foo");
80     auto data = tmp.Data();
81     nsDependentCString foo(tmp);
82     // Neither string should be using a shared buffer.
83     EXPECT_FALSE(tmp.GetDataFlags() & DataFlags::SHARED);
84     EXPECT_FALSE(foo.GetDataFlags() & DataFlags::SHARED);
85     // Both strings should be pointing to the original buffer.
86     EXPECT_EQ(data, tmp.Data());
87     EXPECT_EQ(data, foo.Data());
88   }
89   {
90     // Test move ctor.
91     nsDependentCString tmp("foo");
92     auto data = tmp.Data();
93     nsDependentCString foo(mozilla::Move(tmp));
94     // Neither string should be using a shared buffer.
95     EXPECT_FALSE(tmp.GetDataFlags() & DataFlags::SHARED);
96     EXPECT_FALSE(foo.GetDataFlags() & DataFlags::SHARED);
97     // First string should be reset, the second should be pointing to the
98     // original buffer.
99     EXPECT_NE(data, tmp.Data());
100     EXPECT_EQ(data, foo.Data());
101     EXPECT_TRUE(tmp.IsEmpty());
102   }
103   {
104     // Test copying to a nsCString.
105     nsDependentCString tmp("foo");
106     auto data = tmp.Data();
107     nsCString foo(tmp);
108     // Original string should not be shared, copy should be shared.
109     EXPECT_FALSE(tmp.GetDataFlags() & DataFlags::SHARED);
110     EXPECT_TRUE(foo.GetDataFlags() & DataFlags::SHARED);
111     // First string should remain the same, the second should be pointing to
112     // a new buffer.
113     EXPECT_EQ(data, tmp.Data());
114     EXPECT_NE(data, foo.Data());
115   }
116 }
117 
TEST(Strings,assign)118 TEST(Strings, assign)
119 {
120   nsCString result;
121   test_assign_helper(NS_LITERAL_CSTRING("a") + NS_LITERAL_CSTRING("b"), result);
122   EXPECT_STREQ(result.get(), "ab");
123 }
124 
TEST(Strings,assign_c)125 TEST(Strings, assign_c)
126 {
127   nsCString c; c.Assign('c');
128   EXPECT_STREQ(c.get(), "c");
129 }
130 
TEST(Strings,test1)131 TEST(Strings, test1)
132 {
133   NS_NAMED_LITERAL_STRING(empty, "");
134   const nsAString& aStr = empty;
135 
136   nsAutoString buf(aStr);
137 
138   int32_t n = buf.FindChar(',');
139   EXPECT_EQ(n, kNotFound);
140 
141   n = buf.Length();
142 
143   buf.Cut(0, n + 1);
144   n = buf.FindChar(',');
145 
146   EXPECT_EQ(n, kNotFound);
147 }
148 
TEST(Strings,test2)149 TEST(Strings, test2)
150 {
151   nsCString data("hello world");
152   const nsACString& aStr = data;
153 
154   nsCString temp(aStr);
155   temp.Cut(0, 6);
156 
157   EXPECT_STREQ(temp.get(), "world");
158 }
159 
TEST(Strings,find)160 TEST(Strings, find)
161 {
162   nsCString src("<!DOCTYPE blah blah blah>");
163 
164   int32_t i = src.Find("DOCTYPE", true, 2, 1);
165   EXPECT_EQ(i, 2);
166 }
167 
TEST(Strings,rfind)168 TEST(Strings, rfind)
169 {
170   const char text[] = "<!DOCTYPE blah blah blah>";
171   const char term[] = "bLaH";
172   nsCString src(text);
173   int32_t i;
174 
175   i = src.RFind(term, true, 3, -1);
176   EXPECT_EQ(i, kNotFound);
177 
178   i = src.RFind(term, true, -1, -1);
179   EXPECT_EQ(i, 20);
180 
181   i = src.RFind(term, true, 13, -1);
182   EXPECT_EQ(i, 10);
183 
184   i = src.RFind(term, true, 22, 3);
185   EXPECT_EQ(i, 20);
186 }
187 
TEST(Strings,rfind_2)188 TEST(Strings, rfind_2)
189 {
190   const char text[] = "<!DOCTYPE blah blah blah>";
191   nsCString src(text);
192   int32_t i = src.RFind("TYPE", false, 5, -1);
193   EXPECT_EQ(i, 5);
194 }
195 
TEST(Strings,rfind_3)196 TEST(Strings, rfind_3)
197 {
198   const char text[] = "urn:mozilla:locale:en-US:necko";
199   nsAutoCString value(text);
200   int32_t i = value.RFind(":");
201   EXPECT_EQ(i, 24);
202 }
203 
TEST(Strings,rfind_4)204 TEST(Strings, rfind_4)
205 {
206   nsCString value("a.msf");
207   int32_t i = value.RFind(".msf");
208   EXPECT_EQ(i, 1);
209 }
210 
TEST(Strings,findinreadable)211 TEST(Strings, findinreadable)
212 {
213   const char text[] = "jar:jar:file:///c:/software/mozilla/mozilla_2006_02_21.jar!/browser/chrome/classic.jar!/";
214   nsAutoCString value(text);
215 
216   nsACString::const_iterator begin, end;
217   value.BeginReading(begin);
218   value.EndReading(end);
219   nsACString::const_iterator delim_begin (begin),
220                              delim_end   (end);
221 
222   // Search for last !/ at the end of the string
223   EXPECT_TRUE(FindInReadable(NS_LITERAL_CSTRING("!/"), delim_begin, delim_end));
224   char *r = ToNewCString(Substring(delim_begin, delim_end));
225   // Should match the first "!/" but not the last
226   EXPECT_NE(delim_end, end);
227   EXPECT_STREQ(r, "!/");
228   free(r);
229 
230   delim_begin = begin;
231   delim_end = end;
232 
233   // Search for first jar:
234   EXPECT_TRUE(FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
235 
236   r = ToNewCString(Substring(delim_begin, delim_end));
237   // Should not match the first jar:, but the second one
238   EXPECT_EQ(delim_begin, begin);
239   EXPECT_STREQ(r, "jar:");
240   free(r);
241 
242   // Search for jar: in a Substring
243   delim_begin = begin; delim_begin++;
244   delim_end = end;
245   EXPECT_TRUE(FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
246 
247   r = ToNewCString(Substring(delim_begin, delim_end));
248   // Should not match the first jar:, but the second one
249   EXPECT_NE(delim_begin, begin);
250   EXPECT_STREQ(r, "jar:");
251   free(r);
252 
253   // Should not find a match
254   EXPECT_FALSE(FindInReadable(NS_LITERAL_CSTRING("gecko"), delim_begin, delim_end));
255 
256   // When no match is found, range should be empty
257   EXPECT_EQ(delim_begin, delim_end);
258 
259   // Should not find a match (search not beyond Substring)
260   delim_begin = begin; for (int i=0;i<6;i++) delim_begin++;
261   delim_end = end;
262   EXPECT_FALSE(FindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
263 
264   // When no match is found, range should be empty
265   EXPECT_EQ(delim_begin, delim_end);
266 
267   // Should not find a match (search not beyond Substring)
268   delim_begin = begin;
269   delim_end = end; for (int i=0;i<7;i++) delim_end--;
270   EXPECT_FALSE(FindInReadable(NS_LITERAL_CSTRING("classic"), delim_begin, delim_end));
271 
272   // When no match is found, range should be empty
273   EXPECT_EQ(delim_begin, delim_end);
274 }
275 
TEST(Strings,rfindinreadable)276 TEST(Strings, rfindinreadable)
277 {
278   const char text[] = "jar:jar:file:///c:/software/mozilla/mozilla_2006_02_21.jar!/browser/chrome/classic.jar!/";
279   nsAutoCString value(text);
280 
281   nsACString::const_iterator begin, end;
282   value.BeginReading(begin);
283   value.EndReading(end);
284   nsACString::const_iterator delim_begin (begin),
285                              delim_end   (end);
286 
287   // Search for last !/ at the end of the string
288   EXPECT_TRUE(RFindInReadable(NS_LITERAL_CSTRING("!/"), delim_begin, delim_end));
289   char *r = ToNewCString(Substring(delim_begin, delim_end));
290   // Should match the last "!/"
291   EXPECT_EQ(delim_end, end);
292   EXPECT_STREQ(r, "!/");
293   free(r);
294 
295   delim_begin = begin;
296   delim_end = end;
297 
298   // Search for last jar: but not the first one...
299   EXPECT_TRUE(RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
300 
301   r = ToNewCString(Substring(delim_begin, delim_end));
302   // Should not match the first jar:, but the second one
303   EXPECT_NE(delim_begin, begin);
304   EXPECT_STREQ(r, "jar:");
305   free(r);
306 
307   // Search for jar: in a Substring
308   delim_begin = begin;
309   delim_end = begin; for (int i=0;i<6;i++) delim_end++;
310   EXPECT_TRUE(RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
311 
312   r = ToNewCString(Substring(delim_begin, delim_end));
313   // Should not match the first jar:, but the second one
314   EXPECT_EQ(delim_begin, begin);
315   EXPECT_STREQ(r, "jar:");
316   free(r);
317 
318   // Should not find a match
319   delim_begin = begin;
320   delim_end = end;
321   EXPECT_FALSE(RFindInReadable(NS_LITERAL_CSTRING("gecko"), delim_begin, delim_end));
322 
323   // When no match is found, range should be empty
324   EXPECT_EQ(delim_begin, delim_end);
325 
326   // Should not find a match (search not before Substring)
327   delim_begin = begin; for (int i=0;i<6;i++) delim_begin++;
328   delim_end = end;
329   EXPECT_FALSE(RFindInReadable(NS_LITERAL_CSTRING("jar:"), delim_begin, delim_end));
330 
331   // When no match is found, range should be empty
332   EXPECT_EQ(delim_begin, delim_end);
333 
334   // Should not find a match (search not beyond Substring)
335   delim_begin = begin;
336   delim_end = end; for (int i=0;i<7;i++) delim_end--;
337   EXPECT_FALSE(RFindInReadable(NS_LITERAL_CSTRING("classic"), delim_begin, delim_end));
338 
339   // When no match is found, range should be empty
340   EXPECT_EQ(delim_begin, delim_end);
341 }
342 
TEST(Strings,distance)343 TEST(Strings, distance)
344 {
345   const char text[] = "abc-xyz";
346   nsCString s(text);
347   nsCString::const_iterator begin, end;
348   s.BeginReading(begin);
349   s.EndReading(end);
350   size_t d = Distance(begin, end);
351   EXPECT_EQ(d, sizeof(text) - 1);
352 }
353 
TEST(Strings,length)354 TEST(Strings, length)
355 {
356   const char text[] = "abc-xyz";
357   nsCString s(text);
358   size_t d = s.Length();
359   EXPECT_EQ(d, sizeof(text) - 1);
360 }
361 
TEST(Strings,trim)362 TEST(Strings, trim)
363 {
364   const char text[] = " a\t    $   ";
365   const char set[] = " \t$";
366 
367   nsCString s(text);
368   s.Trim(set);
369   EXPECT_STREQ(s.get(), "a");
370 
371   s.AssignLiteral("\t  \t\t  \t");
372   s.Trim(set);
373   EXPECT_STREQ(s.get(), "");
374 
375   s.AssignLiteral(" ");
376   s.Trim(set);
377   EXPECT_STREQ(s.get(), "");
378 
379   s.AssignLiteral(" ");
380   s.Trim(set, false, true);
381   EXPECT_STREQ(s.get(), "");
382 
383   s.AssignLiteral(" ");
384   s.Trim(set, true, false);
385   EXPECT_STREQ(s.get(), "");
386 }
387 
TEST(Strings,replace_substr)388 TEST(Strings, replace_substr)
389 {
390   const char text[] = "abc-ppp-qqq-ppp-xyz";
391   nsCString s(text);
392   s.ReplaceSubstring("ppp", "www");
393   EXPECT_STREQ(s.get(), "abc-www-qqq-www-xyz");
394 
395   s.AssignLiteral("foobar");
396   s.ReplaceSubstring("foo", "bar");
397   s.ReplaceSubstring("bar", "");
398   EXPECT_STREQ(s.get(), "");
399 
400   s.AssignLiteral("foofoofoo");
401   s.ReplaceSubstring("foo", "foo");
402   EXPECT_STREQ(s.get(), "foofoofoo");
403 
404   s.AssignLiteral("foofoofoo");
405   s.ReplaceSubstring("of", "fo");
406   EXPECT_STREQ(s.get(), "fofoofooo");
407 }
408 
TEST(Strings,replace_substr_2)409 TEST(Strings, replace_substr_2)
410 {
411   const char *oldName = nullptr;
412   const char *newName = "user";
413   nsString acctName; acctName.AssignLiteral("forums.foo.com");
414   nsAutoString newAcctName, oldVal, newVal;
415   CopyASCIItoUTF16(oldName, oldVal);
416   CopyASCIItoUTF16(newName, newVal);
417   newAcctName.Assign(acctName);
418 
419   // here, oldVal is empty.  we are testing that this function
420   // does not hang.  see bug 235355.
421   newAcctName.ReplaceSubstring(oldVal, newVal);
422 
423   // we expect that newAcctName will be unchanged.
424   EXPECT_TRUE(newAcctName.Equals(acctName));
425 }
426 
TEST(Strings,replace_substr_3)427 TEST(Strings, replace_substr_3)
428 {
429   nsCString s;
430   s.AssignLiteral("abcabcabc");
431   s.ReplaceSubstring("ca", "X");
432   EXPECT_STREQ(s.get(), "abXbXbc");
433 
434   s.AssignLiteral("abcabcabc");
435   s.ReplaceSubstring("ca", "XYZ");
436   EXPECT_STREQ(s.get(), "abXYZbXYZbc");
437 
438   s.AssignLiteral("abcabcabc");
439   s.ReplaceSubstring("ca", "XY");
440   EXPECT_STREQ(s.get(), "abXYbXYbc");
441 
442   s.AssignLiteral("abcabcabc");
443   s.ReplaceSubstring("ca", "XYZ!");
444   EXPECT_STREQ(s.get(), "abXYZ!bXYZ!bc");
445 
446   s.AssignLiteral("abcdabcdabcd");
447   s.ReplaceSubstring("bcd", "X");
448   EXPECT_STREQ(s.get(), "aXaXaX");
449 
450   s.AssignLiteral("abcdabcdabcd");
451   s.ReplaceSubstring("bcd", "XYZ!");
452   EXPECT_STREQ(s.get(), "aXYZ!aXYZ!aXYZ!");
453 
454   s.AssignLiteral("abcdabcdabcd");
455   s.ReplaceSubstring("bcd", "XY");
456   EXPECT_STREQ(s.get(), "aXYaXYaXY");
457 
458   s.AssignLiteral("abcdabcdabcd");
459   s.ReplaceSubstring("bcd", "XYZABC");
460   EXPECT_STREQ(s.get(), "aXYZABCaXYZABCaXYZABC");
461 
462   s.AssignLiteral("abcdabcdabcd");
463   s.ReplaceSubstring("bcd", "XYZ");
464   EXPECT_STREQ(s.get(), "aXYZaXYZaXYZ");
465 
466   s.AssignLiteral("abcdabcdabcd");
467   s.ReplaceSubstring("bcd", "XYZ!");
468   EXPECT_STREQ(s.get(), "aXYZ!aXYZ!aXYZ!");
469 
470   s.AssignLiteral("abcdabcdabcd");
471   s.ReplaceSubstring("ab", "X");
472   EXPECT_STREQ(s.get(), "XcdXcdXcd");
473 
474   s.AssignLiteral("abcdabcdabcd");
475   s.ReplaceSubstring("ab", "XYZABC");
476   EXPECT_STREQ(s.get(), "XYZABCcdXYZABCcdXYZABCcd");
477 
478   s.AssignLiteral("abcdabcdabcd");
479   s.ReplaceSubstring("ab", "XY");
480   EXPECT_STREQ(s.get(), "XYcdXYcdXYcd");
481 
482   s.AssignLiteral("abcdabcdabcd");
483   s.ReplaceSubstring("ab", "XYZ!");
484   EXPECT_STREQ(s.get(), "XYZ!cdXYZ!cdXYZ!cd");
485 
486   s.AssignLiteral("abcdabcdabcd");
487   s.ReplaceSubstring("notfound", "X");
488   EXPECT_STREQ(s.get(), "abcdabcdabcd");
489 
490   s.AssignLiteral("abcdabcdabcd");
491   s.ReplaceSubstring("notfound", "longlongstring");
492   EXPECT_STREQ(s.get(), "abcdabcdabcd");
493 }
494 
TEST(Strings,strip_ws)495 TEST(Strings, strip_ws)
496 {
497   const char* texts[] = {"",
498                          " a    $   ",
499                          "Some\fother\t thing\r\n",
500                          "And   \f\t\r\n even\nmore\r \f"};
501   const char* results[] = {"",
502                            "a$",
503                            "Someotherthing",
504                            "Andevenmore"};
505   for (size_t i=0; i<sizeof(texts)/sizeof(texts[0]); i++) {
506     nsCString s(texts[i]);
507     s.StripWhitespace();
508     EXPECT_STREQ(s.get(), results[i]);
509   }
510 }
511 
TEST(Strings,equals_ic)512 TEST(Strings, equals_ic)
513 {
514   nsCString s;
515   EXPECT_FALSE(s.LowerCaseEqualsLiteral("view-source"));
516 }
517 
TEST(Strings,concat)518 TEST(Strings, concat)
519 {
520   nsCString bar("bar");
521   const nsACString& barRef = bar;
522 
523   const nsPromiseFlatCString& result =
524       PromiseFlatCString(NS_LITERAL_CSTRING("foo") +
525                          NS_LITERAL_CSTRING(",") +
526                          barRef);
527   EXPECT_STREQ(result.get(), "foo,bar");
528 }
529 
TEST(Strings,concat_2)530 TEST(Strings, concat_2)
531 {
532   nsCString fieldTextStr("xyz");
533   nsCString text("text");
534   const nsACString& aText = text;
535 
536   nsAutoCString result( fieldTextStr + aText );
537 
538   EXPECT_STREQ(result.get(), "xyztext");
539 }
540 
TEST(Strings,concat_3)541 TEST(Strings, concat_3)
542 {
543   nsCString result;
544   nsCString ab("ab"), c("c");
545 
546   result = ab + result + c;
547   EXPECT_STREQ(result.get(), "abc");
548 }
549 
TEST(Strings,empty_assign)550 TEST(Strings, empty_assign)
551 {
552   nsCString a;
553   a.AssignLiteral("");
554 
555   a.AppendLiteral("");
556 
557   nsCString b;
558   b.SetCapacity(0);
559 }
560 
TEST(Strings,set_length)561 TEST(Strings, set_length)
562 {
563   const char kText[] = "Default Plugin";
564   nsCString buf;
565   buf.SetCapacity(sizeof(kText)-1);
566   buf.Assign(kText);
567   buf.SetLength(sizeof(kText)-1);
568   EXPECT_STREQ(buf.get(), kText);
569 }
570 
TEST(Strings,substring)571 TEST(Strings, substring)
572 {
573   nsCString super("hello world"), sub("hello");
574 
575   // this tests that |super| starts with |sub|,
576 
577   EXPECT_TRUE(sub.Equals(StringHead(super, sub.Length())));
578 
579   // and verifies that |sub| does not start with |super|.
580 
581   EXPECT_FALSE(super.Equals(StringHead(sub, super.Length())));
582 }
583 
584 #define test_append_expect(str, int, suffix, expect) \
585   str.Truncate(); \
586   str.AppendInt(suffix = int); \
587   EXPECT_TRUE(str.EqualsLiteral(expect));
588 
589 #define test_appends_expect(int, suffix, expect) \
590   test_append_expect(str, int, suffix, expect) \
591   test_append_expect(cstr, int, suffix, expect)
592 
593 #define test_appendbase(str, prefix, int, suffix, base) \
594   str.Truncate(); \
595   str.AppendInt(suffix = prefix ## int ## suffix, base); \
596   EXPECT_TRUE(str.EqualsLiteral(#int));
597 
598 #define test_appendbases(prefix, int, suffix, base) \
599   test_appendbase(str, prefix, int, suffix, base) \
600   test_appendbase(cstr, prefix, int, suffix, base)
601 
TEST(Strings,appendint)602 TEST(Strings, appendint)
603 {
604   nsString str;
605   nsCString cstr;
606   int32_t L;
607   uint32_t UL;
608   int64_t LL;
609   uint64_t ULL;
610   test_appends_expect(INT32_MAX, L, "2147483647")
611   test_appends_expect(INT32_MIN, L, "-2147483648")
612   test_appends_expect(UINT32_MAX, UL, "4294967295")
613   test_appends_expect(INT64_MAX, LL, "9223372036854775807")
614   test_appends_expect(INT64_MIN, LL, "-9223372036854775808")
615   test_appends_expect(UINT64_MAX, ULL, "18446744073709551615")
616   test_appendbases(0, 17777777777, L, 8)
617   test_appendbases(0, 20000000000, L, 8)
618   test_appendbases(0, 37777777777, UL, 8)
619   test_appendbases(0, 777777777777777777777, LL, 8)
620   test_appendbases(0, 1000000000000000000000, LL, 8)
621   test_appendbases(0, 1777777777777777777777, ULL, 8)
622   test_appendbases(0x, 7fffffff, L, 16)
623   test_appendbases(0x, 80000000, L, 16)
624   test_appendbases(0x, ffffffff, UL, 16)
625   test_appendbases(0x, 7fffffffffffffff, LL, 16)
626   test_appendbases(0x, 8000000000000000, LL, 16)
627   test_appendbases(0x, ffffffffffffffff, ULL, 16)
628 }
629 
TEST(Strings,appendint64)630 TEST(Strings, appendint64)
631 {
632   nsCString str;
633 
634   int64_t max = INT64_MAX;
635   static const char max_expected[] = "9223372036854775807";
636   int64_t min = INT64_MIN;
637   static const char min_expected[] = "-9223372036854775808";
638   static const char min_expected_oct[] = "1000000000000000000000";
639   int64_t maxint_plus1 = 1LL << 32;
640   static const char maxint_plus1_expected[] = "4294967296";
641   static const char maxint_plus1_expected_x[] = "100000000";
642 
643   str.AppendInt(max);
644 
645   EXPECT_TRUE(str.Equals(max_expected));
646 
647   str.Truncate();
648   str.AppendInt(min);
649   EXPECT_TRUE(str.Equals(min_expected));
650   str.Truncate();
651   str.AppendInt(min, 8);
652   EXPECT_TRUE(str.Equals(min_expected_oct));
653 
654 
655   str.Truncate();
656   str.AppendInt(maxint_plus1);
657   EXPECT_TRUE(str.Equals(maxint_plus1_expected));
658   str.Truncate();
659   str.AppendInt(maxint_plus1, 16);
660   EXPECT_TRUE(str.Equals(maxint_plus1_expected_x));
661 }
662 
TEST(Strings,appendfloat)663 TEST(Strings, appendfloat)
664 {
665   nsCString str;
666   double bigdouble = 11223344556.66;
667   static const char double_expected[] = "11223344556.66";
668   static const char float_expected[] = "0.01";
669 
670   // AppendFloat is used to append doubles, therefore the precision must be
671   // large enough (see bug 327719)
672   str.AppendFloat( bigdouble );
673   EXPECT_TRUE(str.Equals(double_expected));
674 
675   str.Truncate();
676   // AppendFloat is used to append floats (bug 327719 #27)
677   str.AppendFloat( 0.1f * 0.1f );
678   EXPECT_TRUE(str.Equals(float_expected));
679 }
680 
TEST(Strings,findcharinset)681 TEST(Strings, findcharinset)
682 {
683   nsCString buf("hello, how are you?");
684 
685   int32_t index = buf.FindCharInSet(",?", 5);
686   EXPECT_EQ(index, 5);
687 
688   index = buf.FindCharInSet("helo", 0);
689   EXPECT_EQ(index, 0);
690 
691   index = buf.FindCharInSet("z?", 6);
692   EXPECT_EQ(index, (int32_t) buf.Length() - 1);
693 }
694 
TEST(Strings,rfindcharinset)695 TEST(Strings, rfindcharinset)
696 {
697   nsCString buf("hello, how are you?");
698 
699   int32_t index = buf.RFindCharInSet(",?", 5);
700   EXPECT_EQ(index, 5);
701 
702   index = buf.RFindCharInSet("helo", 0);
703   EXPECT_EQ(index, 0);
704 
705   index = buf.RFindCharInSet("z?", 6);
706   EXPECT_EQ(index, kNotFound);
707 
708   index = buf.RFindCharInSet("l", 5);
709   EXPECT_EQ(index, 3);
710 
711   buf.AssignLiteral("abcdefghijkabc");
712 
713   index = buf.RFindCharInSet("ab");
714   EXPECT_EQ(index, 12);
715 
716   index = buf.RFindCharInSet("ab", 11);
717   EXPECT_EQ(index, 11);
718 
719   index = buf.RFindCharInSet("ab", 10);
720   EXPECT_EQ(index, 1);
721 
722   index = buf.RFindCharInSet("ab", 0);
723   EXPECT_EQ(index, 0);
724 
725   index = buf.RFindCharInSet("cd", 1);
726   EXPECT_EQ(index, kNotFound);
727 
728   index = buf.RFindCharInSet("h");
729   EXPECT_EQ(index, 7);
730 }
731 
TEST(Strings,stringbuffer)732 TEST(Strings, stringbuffer)
733 {
734   const char kData[] = "hello world";
735 
736   RefPtr<nsStringBuffer> buf;
737 
738   buf = nsStringBuffer::Alloc(sizeof(kData));
739   EXPECT_TRUE(!!buf);
740 
741   buf = nsStringBuffer::Alloc(sizeof(kData));
742   EXPECT_TRUE(!!buf);
743   char *data = (char *) buf->Data();
744   memcpy(data, kData, sizeof(kData));
745 
746   nsCString str;
747   buf->ToString(sizeof(kData)-1, str);
748 
749   nsStringBuffer *buf2;
750   buf2 = nsStringBuffer::FromString(str);
751 
752   EXPECT_EQ(buf, buf2);
753 }
754 
TEST(Strings,voided)755 TEST(Strings, voided)
756 {
757   const char kData[] = "hello world";
758 
759   nsCString str;
760   EXPECT_TRUE(!str.IsVoid());
761   EXPECT_TRUE(str.IsEmpty());
762   EXPECT_STREQ(str.get(), "");
763 
764   str.SetIsVoid(true);
765   EXPECT_TRUE(str.IsVoid());
766   EXPECT_TRUE(str.IsEmpty());
767   EXPECT_STREQ(str.get(), "");
768 
769   str.Assign(kData);
770   EXPECT_TRUE(!str.IsVoid());
771   EXPECT_TRUE(!str.IsEmpty());
772   EXPECT_STREQ(str.get(), kData);
773 
774   str.SetIsVoid(true);
775   EXPECT_TRUE(str.IsVoid());
776   EXPECT_TRUE(str.IsEmpty());
777   EXPECT_STREQ(str.get(), "");
778 
779   str.SetIsVoid(false);
780   EXPECT_TRUE(!str.IsVoid());
781   EXPECT_TRUE(str.IsEmpty());
782   EXPECT_STREQ(str.get(), "");
783 
784   str.Assign(kData);
785   EXPECT_TRUE(!str.IsVoid());
786   EXPECT_TRUE(!str.IsEmpty());
787   EXPECT_STREQ(str.get(), kData);
788 
789   str.Adopt(nullptr);
790   EXPECT_TRUE(str.IsVoid());
791   EXPECT_TRUE(str.IsEmpty());
792   EXPECT_STREQ(str.get(), "");
793 }
794 
TEST(Strings,voided_autostr)795 TEST(Strings, voided_autostr)
796 {
797   const char kData[] = "hello world";
798 
799   nsAutoCString str;
800   EXPECT_FALSE(str.IsVoid());
801   EXPECT_TRUE(str.IsEmpty());
802 
803   str.Assign(kData);
804   EXPECT_STREQ(str.get(), kData);
805 
806   str.SetIsVoid(true);
807   EXPECT_TRUE(str.IsVoid());
808   EXPECT_TRUE(str.IsEmpty());
809 
810   str.Assign(kData);
811   EXPECT_FALSE(str.IsVoid());
812   EXPECT_FALSE(str.IsEmpty());
813   EXPECT_STREQ(str.get(), kData);
814 }
815 
TEST(Strings,voided_assignment)816 TEST(Strings, voided_assignment)
817 {
818   nsCString a, b;
819   b.SetIsVoid(true);
820   a = b;
821   EXPECT_TRUE(a.IsVoid());
822   EXPECT_EQ(a.get(), b.get());
823 }
824 
TEST(Strings,empty_assignment)825 TEST(Strings, empty_assignment)
826 {
827   nsCString a, b;
828   a = b;
829   EXPECT_EQ(a.get(), b.get());
830 }
831 
832 struct ToIntegerTest
833 {
834   const char *str;
835   uint32_t radix;
836   int32_t result;
837   nsresult rv;
838 };
839 
840 static const ToIntegerTest kToIntegerTests[] = {
841   { "123", 10, 123, NS_OK },
842   { "7b", 16, 123, NS_OK },
843   { "90194313659", 10, 0, NS_ERROR_ILLEGAL_VALUE },
844   { nullptr, 0, 0, NS_OK }
845 };
846 
TEST(Strings,string_tointeger)847 TEST(Strings, string_tointeger)
848 {
849   nsresult rv;
850   for (const ToIntegerTest* t = kToIntegerTests; t->str; ++t) {
851     int32_t result = nsAutoCString(t->str).ToInteger(&rv, t->radix);
852     EXPECT_EQ(rv, t->rv);
853     EXPECT_EQ(result, t->result);
854     result = nsAutoCString(t->str).ToInteger(&rv, t->radix);
855     EXPECT_EQ(rv, t->rv);
856     EXPECT_EQ(result, t->result);
857   }
858 }
859 
test_parse_string_helper(const char * str,char separator,int len,const char * s1,const char * s2)860 static void test_parse_string_helper(const char* str, char separator, int len,
861                                        const char* s1, const char* s2)
862 {
863   nsCString data(str);
864   nsTArray<nsCString> results;
865   EXPECT_TRUE(ParseString(data, separator, results));
866   EXPECT_EQ(int(results.Length()), len);
867   const char* strings[] = { s1, s2 };
868   for (int i = 0; i < len; ++i) {
869     EXPECT_TRUE(results[i].Equals(strings[i]));
870   }
871 }
872 
test_parse_string_helper0(const char * str,char separator)873 static void test_parse_string_helper0(const char* str, char separator)
874 {
875   test_parse_string_helper(str, separator, 0, nullptr, nullptr);
876 }
877 
test_parse_string_helper1(const char * str,char separator,const char * s1)878 static void test_parse_string_helper1(const char* str, char separator, const char* s1)
879 {
880   test_parse_string_helper(str, separator, 1, s1, nullptr);
881 }
882 
test_parse_string_helper2(const char * str,char separator,const char * s1,const char * s2)883 static void test_parse_string_helper2(const char* str, char separator, const char* s1, const char* s2)
884 {
885   test_parse_string_helper(str, separator, 2, s1, s2);
886 }
887 
TEST(String,parse_string)888 TEST(String, parse_string)
889 {
890   test_parse_string_helper1("foo, bar", '_', "foo, bar");
891   test_parse_string_helper2("foo, bar", ',', "foo", " bar");
892   test_parse_string_helper2("foo, bar ", ' ', "foo,", "bar");
893   test_parse_string_helper2("foo,bar", 'o', "f", ",bar");
894   test_parse_string_helper0("", '_');
895   test_parse_string_helper0("  ", ' ');
896   test_parse_string_helper1(" foo", ' ', "foo");
897   test_parse_string_helper1("  foo", ' ', "foo");
898 }
899 
test_strip_chars_helper(const char16_t * str,const char16_t * strip,const nsAString & result)900 static void test_strip_chars_helper(const char16_t* str, const char16_t* strip, const nsAString& result)
901 {
902   nsAutoString data(str);
903   data.StripChars(strip);
904   EXPECT_TRUE(data.Equals(result));
905 }
906 
TEST(String,strip_chars)907 TEST(String, strip_chars)
908 {
909   test_strip_chars_helper(u"foo \r \nbar",
910                           u" \n\r",
911                           NS_LITERAL_STRING("foobar"));
912   test_strip_chars_helper(u"\r\nfoo\r\n",
913                           u" \n\r",
914                           NS_LITERAL_STRING("foo"));
915   test_strip_chars_helper(u"foo",
916                           u" \n\r",
917                           NS_LITERAL_STRING("foo"));
918   test_strip_chars_helper(u"foo",
919                           u"fo",
920                           NS_LITERAL_STRING(""));
921   test_strip_chars_helper(u"foo",
922                           u"foo",
923                           NS_LITERAL_STRING(""));
924   test_strip_chars_helper(u" foo",
925                           u" ",
926                           NS_LITERAL_STRING("foo"));
927 }
928 
TEST(Strings,huge_capacity)929 TEST(Strings, huge_capacity)
930 {
931   nsString a, b, c, d, e, f, g, h, i, j, k, l, m, n;
932   nsCString n1;
933 
934   // Ignore the result if the address space is less than 64-bit because
935   // some of the allocations above will exhaust the address space.
936   if (sizeof(void*) >= 8) {
937     EXPECT_TRUE(a.SetCapacity(1, fallible));
938     EXPECT_FALSE(a.SetCapacity(nsString::size_type(-1)/2, fallible));
939     EXPECT_TRUE(a.SetCapacity(0, fallible));  // free the allocated memory
940 
941     EXPECT_TRUE(b.SetCapacity(1, fallible));
942     EXPECT_FALSE(b.SetCapacity(nsString::size_type(-1)/2 - 1, fallible));
943     EXPECT_TRUE(b.SetCapacity(0, fallible));
944 
945     EXPECT_TRUE(c.SetCapacity(1, fallible));
946     EXPECT_FALSE(c.SetCapacity(nsString::size_type(-1)/2, fallible));
947     EXPECT_TRUE(c.SetCapacity(0, fallible));
948 
949     EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2 - 1, fallible));
950     EXPECT_FALSE(d.SetCapacity(nsString::size_type(-1)/2, fallible));
951     EXPECT_TRUE(d.SetCapacity(0, fallible));
952 
953     EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4, fallible));
954     EXPECT_FALSE(e.SetCapacity(nsString::size_type(-1)/4 + 1, fallible));
955     EXPECT_TRUE(e.SetCapacity(0, fallible));
956 
957     EXPECT_FALSE(f.SetCapacity(nsString::size_type(-1)/2, fallible));
958     EXPECT_TRUE(f.SetCapacity(0, fallible));
959 
960     EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1000, fallible));
961     EXPECT_FALSE(g.SetCapacity(nsString::size_type(-1)/4 + 1001, fallible));
962     EXPECT_TRUE(g.SetCapacity(0, fallible));
963 
964     EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/4+1, fallible));
965     EXPECT_FALSE(h.SetCapacity(nsString::size_type(-1)/2, fallible));
966     EXPECT_TRUE(h.SetCapacity(0, fallible));
967 
968     EXPECT_TRUE(i.SetCapacity(1, fallible));
969     EXPECT_TRUE(i.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible));
970     EXPECT_FALSE(i.SetCapacity(nsString::size_type(-1)/4 + 1, fallible));
971     EXPECT_TRUE(i.SetCapacity(0, fallible));
972 
973     EXPECT_TRUE(j.SetCapacity(nsString::size_type(-1)/4 - 1000, fallible));
974     EXPECT_FALSE(j.SetCapacity(nsString::size_type(-1)/4 + 1, fallible));
975     EXPECT_TRUE(j.SetCapacity(0, fallible));
976 
977     EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/8 - 1000, fallible));
978     EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 1001, fallible));
979     EXPECT_TRUE(k.SetCapacity(nsString::size_type(-1)/4 - 998, fallible));
980     EXPECT_FALSE(k.SetCapacity(nsString::size_type(-1)/4 + 1, fallible));
981     EXPECT_TRUE(k.SetCapacity(0, fallible));
982 
983     EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8, fallible));
984     EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 1, fallible));
985     EXPECT_TRUE(l.SetCapacity(nsString::size_type(-1)/8 + 2, fallible));
986     EXPECT_TRUE(l.SetCapacity(0, fallible));
987 
988     EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1000, fallible));
989     EXPECT_TRUE(m.SetCapacity(nsString::size_type(-1)/8 + 1001, fallible));
990     EXPECT_TRUE(m.SetCapacity(0, fallible));
991 
992     EXPECT_TRUE(n.SetCapacity(nsString::size_type(-1)/8+1, fallible));
993     EXPECT_FALSE(n.SetCapacity(nsString::size_type(-1)/4, fallible));
994     EXPECT_TRUE(n.SetCapacity(0, fallible));
995 
996     EXPECT_TRUE(n.SetCapacity(0, fallible));
997     EXPECT_TRUE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 2, fallible));
998     EXPECT_TRUE(n.SetCapacity(0, fallible));
999     EXPECT_FALSE(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 1, fallible));
1000     EXPECT_TRUE(n.SetCapacity(0, fallible));
1001     EXPECT_TRUE(n1.SetCapacity(0, fallible));
1002     EXPECT_TRUE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 2, fallible));
1003     EXPECT_TRUE(n1.SetCapacity(0, fallible));
1004     EXPECT_FALSE(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 1, fallible));
1005     EXPECT_TRUE(n1.SetCapacity(0, fallible));
1006   }
1007 }
1008 
test_tofloat_helper(const nsString & aStr,float aExpected,bool aSuccess)1009 static void test_tofloat_helper(const nsString& aStr, float aExpected, bool aSuccess)
1010 {
1011   nsresult result;
1012   EXPECT_EQ(aStr.ToFloat(&result), aExpected);
1013   if (aSuccess) {
1014     EXPECT_EQ(result, NS_OK);
1015   } else {
1016     EXPECT_NE(result, NS_OK);
1017   }
1018 }
1019 
TEST(Strings,tofloat)1020 TEST(Strings, tofloat)
1021 {
1022   test_tofloat_helper(NS_LITERAL_STRING("42"), 42.f, true);
1023   test_tofloat_helper(NS_LITERAL_STRING("42.0"), 42.f, true);
1024   test_tofloat_helper(NS_LITERAL_STRING("-42"), -42.f, true);
1025   test_tofloat_helper(NS_LITERAL_STRING("+42"), 42, true);
1026   test_tofloat_helper(NS_LITERAL_STRING("13.37"), 13.37f, true);
1027   test_tofloat_helper(NS_LITERAL_STRING("1.23456789"), 1.23456789f, true);
1028   test_tofloat_helper(NS_LITERAL_STRING("1.98765432123456"), 1.98765432123456f, true);
1029   test_tofloat_helper(NS_LITERAL_STRING("0"), 0.f, true);
1030   test_tofloat_helper(NS_LITERAL_STRING("1.e5"), 100000, true);
1031   test_tofloat_helper(NS_LITERAL_STRING(""), 0.f, false);
1032   test_tofloat_helper(NS_LITERAL_STRING("42foo"), 42.f, false);
1033   test_tofloat_helper(NS_LITERAL_STRING("foo"), 0.f, false);
1034 }
1035 
test_todouble_helper(const nsString & aStr,double aExpected,bool aSuccess)1036 static void test_todouble_helper(const nsString& aStr, double aExpected, bool aSuccess)
1037 {
1038   nsresult result;
1039   EXPECT_EQ(aStr.ToDouble(&result), aExpected);
1040   if (aSuccess) {
1041     EXPECT_EQ(result, NS_OK);
1042   } else {
1043     EXPECT_NE(result, NS_OK);
1044   }
1045 }
1046 
TEST(Strings,todouble)1047 TEST(Strings, todouble)
1048 {
1049   test_todouble_helper(NS_LITERAL_STRING("42"), 42, true);
1050   test_todouble_helper(NS_LITERAL_STRING("42.0"), 42, true);
1051   test_todouble_helper(NS_LITERAL_STRING("-42"), -42, true);
1052   test_todouble_helper(NS_LITERAL_STRING("+42"), 42, true);
1053   test_todouble_helper(NS_LITERAL_STRING("13.37"), 13.37, true);
1054   test_todouble_helper(NS_LITERAL_STRING("1.23456789"), 1.23456789, true);
1055   test_todouble_helper(NS_LITERAL_STRING("1.98765432123456"), 1.98765432123456, true);
1056   test_todouble_helper(NS_LITERAL_STRING("123456789.98765432123456"), 123456789.98765432123456, true);
1057   test_todouble_helper(NS_LITERAL_STRING("0"), 0, true);
1058   test_todouble_helper(NS_LITERAL_STRING("1.e5"), 100000, true);
1059   test_todouble_helper(NS_LITERAL_STRING(""), 0, false);
1060   test_todouble_helper(NS_LITERAL_STRING("42foo"), 42, false);
1061   test_todouble_helper(NS_LITERAL_STRING("foo"), 0, false);
1062 }
1063 
TEST(Strings,Split)1064 TEST(Strings, Split)
1065 {
1066    nsCString one("one"),
1067              two("one;two"),
1068              three("one--three"),
1069              empty(""),
1070              delimStart("-two"),
1071              delimEnd("one-");
1072 
1073   nsString wide(u"hello world");
1074 
1075   size_t counter = 0;
1076   for (const nsACString& token : one.Split(',')) {
1077     EXPECT_TRUE(token.EqualsLiteral("one"));
1078     counter++;
1079   }
1080   EXPECT_EQ(counter, (size_t)1);
1081 
1082   counter = 0;
1083   for (const nsACString& token : two.Split(';')) {
1084     if (counter == 0) {
1085       EXPECT_TRUE(token.EqualsLiteral("one"));
1086     } else if (counter == 1) {
1087       EXPECT_TRUE(token.EqualsLiteral("two"));
1088     }
1089     counter++;
1090   }
1091   EXPECT_EQ(counter, (size_t)2);
1092 
1093   counter = 0;
1094   for (const nsACString& token : three.Split('-')) {
1095     if (counter == 0) {
1096       EXPECT_TRUE(token.EqualsLiteral("one"));
1097     } else if (counter == 1) {
1098       EXPECT_TRUE(token.EqualsLiteral(""));
1099     } else if (counter == 2) {
1100       EXPECT_TRUE(token.EqualsLiteral("three"));
1101     }
1102     counter++;
1103   }
1104   EXPECT_EQ(counter, (size_t)3);
1105 
1106   counter = 0;
1107   for (const nsACString& token : empty.Split(',')) {
1108     mozilla::Unused << token;
1109     counter++;
1110   }
1111   EXPECT_EQ(counter, (size_t)0);
1112 
1113   counter = 0;
1114   for (const nsACString& token : delimStart.Split('-')) {
1115     if (counter == 0) {
1116       EXPECT_TRUE(token.EqualsLiteral(""));
1117     } else if (counter == 1) {
1118       EXPECT_TRUE(token.EqualsLiteral("two"));
1119     }
1120     counter++;
1121   }
1122   EXPECT_EQ(counter, (size_t)2);
1123 
1124   counter = 0;
1125   for (const nsACString& token : delimEnd.Split('-')) {
1126     if (counter == 0) {
1127       EXPECT_TRUE(token.EqualsLiteral("one"));
1128     } else if (counter == 1) {
1129       EXPECT_TRUE(token.EqualsLiteral(""));
1130     }
1131     counter++;
1132   }
1133   EXPECT_EQ(counter, (size_t)2);
1134 
1135   counter = 0;
1136   for (const nsAString& token : wide.Split(' ')) {
1137     if (counter == 0) {
1138       EXPECT_TRUE(token.Equals(NS_LITERAL_STRING("hello")));
1139     } else if (counter == 1) {
1140       EXPECT_TRUE(token.Equals(NS_LITERAL_STRING("world")));
1141     }
1142     counter++;
1143   }
1144   EXPECT_EQ(counter, (size_t)2);
1145 }
1146 
TestSomeChars(char c)1147 constexpr bool TestSomeChars(char c)
1148 {
1149   return c == 'a' || c == 'c' || c == 'e' || c == '7' ||
1150          c == 'G' || c == 'Z' || c == '\b' || c == '?';
1151 }
TEST(Strings,ASCIIMask)1152 TEST(Strings,ASCIIMask)
1153 {
1154   const ASCIIMaskArray& maskCRLF = mozilla::ASCIIMask::MaskCRLF();
1155   EXPECT_TRUE(maskCRLF['\n'] && mozilla::ASCIIMask::IsMasked(maskCRLF, '\n'));
1156   EXPECT_TRUE(maskCRLF['\r'] && mozilla::ASCIIMask::IsMasked(maskCRLF, '\r'));
1157   EXPECT_FALSE(maskCRLF['g'] || mozilla::ASCIIMask::IsMasked(maskCRLF, 'g'));
1158   EXPECT_FALSE(maskCRLF[' '] || mozilla::ASCIIMask::IsMasked(maskCRLF, ' '));
1159   EXPECT_FALSE(maskCRLF['\0'] || mozilla::ASCIIMask::IsMasked(maskCRLF, '\0'));
1160   EXPECT_FALSE(mozilla::ASCIIMask::IsMasked(maskCRLF, 14324));
1161 
1162   const ASCIIMaskArray& mask0to9 = mozilla::ASCIIMask::Mask0to9();
1163   EXPECT_TRUE(mask0to9['9'] && mozilla::ASCIIMask::IsMasked(mask0to9, '9'));
1164   EXPECT_TRUE(mask0to9['0'] && mozilla::ASCIIMask::IsMasked(mask0to9, '0'));
1165   EXPECT_TRUE(mask0to9['4'] && mozilla::ASCIIMask::IsMasked(mask0to9, '4'));
1166   EXPECT_FALSE(mask0to9['g'] || mozilla::ASCIIMask::IsMasked(mask0to9, 'g'));
1167   EXPECT_FALSE(mask0to9[' '] || mozilla::ASCIIMask::IsMasked(mask0to9, ' '));
1168   EXPECT_FALSE(mask0to9['\n'] || mozilla::ASCIIMask::IsMasked(mask0to9, '\n'));
1169   EXPECT_FALSE(mask0to9['\0'] || mozilla::ASCIIMask::IsMasked(mask0to9, '\0'));
1170   EXPECT_FALSE(mozilla::ASCIIMask::IsMasked(maskCRLF, 14324));
1171 
1172   const ASCIIMaskArray& maskWS = mozilla::ASCIIMask::MaskWhitespace();
1173   EXPECT_TRUE(maskWS[' '] && mozilla::ASCIIMask::IsMasked(maskWS, ' '));
1174   EXPECT_TRUE(maskWS['\t'] && mozilla::ASCIIMask::IsMasked(maskWS, '\t'));
1175   EXPECT_FALSE(maskWS['8'] || mozilla::ASCIIMask::IsMasked(maskWS, '8'));
1176   EXPECT_FALSE(maskWS['\0'] || mozilla::ASCIIMask::IsMasked(maskWS, '\0'));
1177   EXPECT_FALSE(mozilla::ASCIIMask::IsMasked(maskCRLF, 14324));
1178 
1179   constexpr ASCIIMaskArray maskSome = mozilla::CreateASCIIMask(TestSomeChars);
1180   EXPECT_TRUE(maskSome['a'] && mozilla::ASCIIMask::IsMasked(maskSome, 'a'));
1181   EXPECT_TRUE(maskSome['c'] && mozilla::ASCIIMask::IsMasked(maskSome, 'c'));
1182   EXPECT_TRUE(maskSome['e'] && mozilla::ASCIIMask::IsMasked(maskSome, 'e'));
1183   EXPECT_TRUE(maskSome['7'] && mozilla::ASCIIMask::IsMasked(maskSome, '7'));
1184   EXPECT_TRUE(maskSome['G'] && mozilla::ASCIIMask::IsMasked(maskSome, 'G'));
1185   EXPECT_TRUE(maskSome['Z'] && mozilla::ASCIIMask::IsMasked(maskSome, 'Z'));
1186   EXPECT_TRUE(maskSome['\b'] && mozilla::ASCIIMask::IsMasked(maskSome, '\b'));
1187   EXPECT_TRUE(maskSome['?'] && mozilla::ASCIIMask::IsMasked(maskSome, '?'));
1188   EXPECT_FALSE(maskSome['8'] || mozilla::ASCIIMask::IsMasked(maskSome, '8'));
1189   EXPECT_FALSE(maskSome['\0'] || mozilla::ASCIIMask::IsMasked(maskSome, '\0'));
1190   EXPECT_FALSE(mozilla::ASCIIMask::IsMasked(maskCRLF, 14324));
1191 }
1192 
1193 template <typename T> void
CompressWhitespaceHelper()1194 CompressWhitespaceHelper()
1195 {
1196   T s;
1197   s.AssignLiteral("abcabcabc");
1198   s.CompressWhitespace(true, true);
1199   EXPECT_TRUE(s.EqualsLiteral("abcabcabc"));
1200 
1201   s.AssignLiteral("   \n\rabcabcabc\r\n");
1202   s.CompressWhitespace(true, true);
1203   EXPECT_TRUE(s.EqualsLiteral("abcabcabc"));
1204 
1205   s.AssignLiteral("   \n\rabc   abc   abc\r\n");
1206   s.CompressWhitespace(true, true);
1207   EXPECT_TRUE(s.EqualsLiteral("abc abc abc"));
1208 
1209   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1210   s.CompressWhitespace(true, true);
1211   EXPECT_TRUE(s.EqualsLiteral("abc abc abc"));
1212 
1213   s.AssignLiteral("   \n\rabc\r  \nabc\n   \rabc\r\n");
1214   s.CompressWhitespace(true, true);
1215   EXPECT_TRUE(s.EqualsLiteral("abc abc abc"));
1216 
1217   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1218   s.CompressWhitespace(false, true);
1219   EXPECT_TRUE(s.EqualsLiteral(" abc abc abc"));
1220 
1221   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1222   s.CompressWhitespace(true, false);
1223   EXPECT_TRUE(s.EqualsLiteral("abc abc abc "));
1224 
1225   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1226   s.CompressWhitespace(false, false);
1227   EXPECT_TRUE(s.EqualsLiteral(" abc abc abc "));
1228 
1229   s.AssignLiteral("  \r\n  ");
1230   s.CompressWhitespace(true, true);
1231   EXPECT_TRUE(s.EqualsLiteral(""));
1232 
1233   s.AssignLiteral("  \r\n  \t");
1234   s.CompressWhitespace(true, true);
1235   EXPECT_TRUE(s.EqualsLiteral(""));
1236 
1237   s.AssignLiteral("\n  \r\n  \t");
1238   s.CompressWhitespace(false, false);
1239   EXPECT_TRUE(s.EqualsLiteral(" "));
1240 
1241   s.AssignLiteral("\n  \r\n  \t");
1242   s.CompressWhitespace(false, true);
1243   EXPECT_TRUE(s.EqualsLiteral(""));
1244 
1245   s.AssignLiteral("\n  \r\n  \t");
1246   s.CompressWhitespace(true, false);
1247   EXPECT_TRUE(s.EqualsLiteral(""));
1248 
1249   s.AssignLiteral("");
1250   s.CompressWhitespace(false, false);
1251   EXPECT_TRUE(s.EqualsLiteral(""));
1252 
1253   s.AssignLiteral("");
1254   s.CompressWhitespace(false, true);
1255   EXPECT_TRUE(s.EqualsLiteral(""));
1256 
1257   s.AssignLiteral("");
1258   s.CompressWhitespace(true, false);
1259   EXPECT_TRUE(s.EqualsLiteral(""));
1260 
1261   s.AssignLiteral("");
1262   s.CompressWhitespace(true, true);
1263   EXPECT_TRUE(s.EqualsLiteral(""));
1264 }
1265 
TEST(Strings,CompressWhitespace)1266 TEST(Strings, CompressWhitespace)
1267 {
1268   CompressWhitespaceHelper<nsCString>();
1269 }
1270 
TEST(Strings,CompressWhitespaceW)1271 TEST(Strings, CompressWhitespaceW)
1272 {
1273   CompressWhitespaceHelper<nsString>();
1274 
1275   nsString str, result;
1276   str.AssignLiteral(u"\u263A    is\r\n   ;-)");
1277   result.AssignLiteral(u"\u263A is ;-)");
1278   str.CompressWhitespace(true, true);
1279   EXPECT_TRUE(str == result);
1280 }
1281 
1282 template <typename T> void
StripCRLFHelper()1283 StripCRLFHelper()
1284 {
1285   T s;
1286   s.AssignLiteral("abcabcabc");
1287   s.StripCRLF();
1288   EXPECT_TRUE(s.EqualsLiteral("abcabcabc"));
1289 
1290   s.AssignLiteral("   \n\rabcabcabc\r\n");
1291   s.StripCRLF();
1292   EXPECT_TRUE(s.EqualsLiteral("   abcabcabc"));
1293 
1294   s.AssignLiteral("   \n\rabc   abc   abc\r\n");
1295   s.StripCRLF();
1296   EXPECT_TRUE(s.EqualsLiteral("   abc   abc   abc"));
1297 
1298   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1299   s.StripCRLF();
1300   EXPECT_TRUE(s.EqualsLiteral("   abc   abc   abc"));
1301 
1302   s.AssignLiteral("   \n\rabc\r  \nabc\n   \rabc\r\n");
1303   s.StripCRLF();
1304   EXPECT_TRUE(s.EqualsLiteral("   abc  abc   abc"));
1305 
1306   s.AssignLiteral("   \n\rabc\r   abc\n   abc\r\n");
1307   s.StripCRLF();
1308   EXPECT_TRUE(s.EqualsLiteral("   abc   abc   abc"));
1309 
1310   s.AssignLiteral("  \r\n  ");
1311   s.StripCRLF();
1312   EXPECT_TRUE(s.EqualsLiteral("    "));
1313 
1314   s.AssignLiteral("  \r\n  \t");
1315   s.StripCRLF();
1316   EXPECT_TRUE(s.EqualsLiteral("    \t"));
1317 
1318   s.AssignLiteral("\n  \r\n  \t");
1319   s.StripCRLF();
1320   EXPECT_TRUE(s.EqualsLiteral("    \t"));
1321 
1322   s.AssignLiteral("");
1323   s.StripCRLF();
1324   EXPECT_TRUE(s.EqualsLiteral(""));
1325 }
1326 
TEST(Strings,StripCRLF)1327 TEST(Strings, StripCRLF)
1328 {
1329   StripCRLFHelper<nsCString>();
1330 }
1331 
TEST(Strings,StripCRLFW)1332 TEST(Strings, StripCRLFW)
1333 {
1334   StripCRLFHelper<nsString>();
1335 
1336   nsString str, result;
1337   str.AssignLiteral(u"\u263A    is\r\n   ;-)");
1338   result.AssignLiteral(u"\u263A    is   ;-)");
1339   str.StripCRLF();
1340   EXPECT_TRUE(str == result);
1341 }
1342 
1343 #define TestExample1 "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,\n totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi\r architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur\n aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui\r\n\r dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"
1344 
1345 #define TestExample2 "At vero eos et accusamus et iusto odio dignissimos ducimus\n\n qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt\r\r  \n mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda       est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
1346 
1347 #define TestExample3 " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ac tellus eget velit viverra viverra id sit amet neque. Sed id consectetur mi, vestibulum aliquet arcu. Curabitur sagittis accumsan convallis. Sed eu condimentum ipsum, a laoreet tortor. Orci varius natoque penatibus et magnis dis    \r\r\n\n parturient montes, nascetur ridiculus mus. Sed non tellus nec ante sodales placerat a nec risus. Cras vel bibendum sapien, nec ullamcorper felis. Pellentesque congue eget nisi sit amet vehicula. Morbi pulvinar turpis justo, in commodo dolor vulputate id. Curabitur in dui urna. Vestibulum placerat dui in sem congue, ut faucibus nibh rutrum. Duis mattis turpis facilisis ullamcorper tincidunt. Vestibulum pharetra tortor at enim sagittis, dapibus consectetur ex blandit. Curabitur ac fringilla quam. In ornare lectus ut ipsum mattis venenatis. Etiam in mollis lectus, sed luctus risus.\nCras dapibus\f\t  \n finibus justo sit amet dictum. Aliquam non elit diam. Fusce magna nulla, bibendum in massa a, commodo finibus lectus. Sed rutrum a augue id imperdiet. Aliquam sagittis sodales felis, a tristique ligula. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis volutpat interdum lorem et congue. Phasellus porttitor posuere justo eget euismod. Nam a condimentum turpis, sit amet gravida lacus. Vestibulum dolor diam, lobortis ac metus et, convallis dapibus tellus. Ut nec metus in velit malesuada tincidunt et eget justo. Curabitur ut libero bibendum, porttitor diam vitae, aliquet justo. "
1348 
1349 #define TestExample4 " Donec feugiat volutpat massa. Cras ornare lacinia porta. Fusce in feugiat nunc. Praesent non felis varius diam feugiat ultrices ultricies a risus. Donec maximus nisi nisl, non consectetur nulla eleifend in. Nulla in massa interdum, eleifend orci a, vestibulum est. Mauris aliquet, massa et convallis mollis, felis augue vestibulum augue, in lobortis metus eros a quam. Nam              ac diam ornare, vestibulum elit sit amet, consectetur ante. Praesent massa mauris, pulvinar sit amet sapien vel, tempus gravida neque. Praesent id quam sit amet est maximus molestie eget at turpis. Nunc sit amet orci id arcu dapibus fermentum non eu erat.\f\tSuspendisse commodo nunc sem, eu congue eros condimentum vel. Nullam sit amet posuere arcu. Nulla facilisi. Mauris dapibus iaculis massa sed gravida. Nullam vitae urna at tortor feugiat auctor ut sit amet dolor. Proin rutrum at nunc et faucibus. Quisque suscipit id nibh a aliquet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam a dapibus erat, id imperdiet mauris. Nulla blandit libero non magna dapibus tristique. Integer hendrerit imperdiet lorem, quis facilisis lacus semper ut. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae Nullam dignissim elit in congue ultricies. Quisque erat odio, maximus mollis laoreet id, iaculis at turpis. "
1350 
1351 #define TestExample5 "Donec id risus urna. Nunc consequat lacinia urna id bibendum. Nulla faucibus faucibus enim. Cras ex risus, ultrices id semper vitae, luctus ut nulla. Sed vehicula tellus sed purus imperdiet efficitur. Suspendisse feugiat\n\n\n     imperdiet odio, sed porta lorem feugiat nec. Curabitur laoreet massa venenatis\r\n risus ornare\r\n, vitae feugiat tortor accumsan. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas id scelerisque mauris, eget facilisis erat. Ut nec pulvinar risus, sed iaculis ante. Mauris tincidunt, risus et pretium elementum, leo nisi consectetur ligula, tincidunt suscipit erat velit eget libero. Sed ac est tempus, consequat dolor mattis, mattis mi. "
1352 
1353 // Note the five calls in the loop, so divide by 100k
__anon41071c4d0102null1354 MOZ_GTEST_BENCH(Strings, PerfStripWhitespace, [] {
1355     nsCString test1(TestExample1);
1356     nsCString test2(TestExample2);
1357     nsCString test3(TestExample3);
1358     nsCString test4(TestExample4);
1359     nsCString test5(TestExample5);
1360     for (int i = 0; i < 20000; i++) {
1361       test1.StripWhitespace();
1362       test2.StripWhitespace();
1363       test3.StripWhitespace();
1364       test4.StripWhitespace();
1365       test5.StripWhitespace();
1366     }
1367 });
1368 
__anon41071c4d0202null1369 MOZ_GTEST_BENCH(Strings, PerfStripCharsWhitespace, [] {
1370     // This is the unoptimized (original) version of
1371     // StripWhitespace using StripChars.
1372     nsCString test1(TestExample1);
1373     nsCString test2(TestExample2);
1374     nsCString test3(TestExample3);
1375     nsCString test4(TestExample4);
1376     nsCString test5(TestExample5);
1377     for (int i = 0; i < 20000; i++) {
1378       test1.StripChars("\f\t\r\n ");
1379       test2.StripChars("\f\t\r\n ");
1380       test3.StripChars("\f\t\r\n ");
1381       test4.StripChars("\f\t\r\n ");
1382       test5.StripChars("\f\t\r\n ");
1383     }
1384 });
1385 
__anon41071c4d0302null1386 MOZ_GTEST_BENCH(Strings, PerfCompressWhitespace, [] {
1387     nsCString test1(TestExample1);
1388     nsCString test2(TestExample2);
1389     nsCString test3(TestExample3);
1390     nsCString test4(TestExample4);
1391     nsCString test5(TestExample5);
1392     for (int i = 0; i < 20000; i++) {
1393       test1.CompressWhitespace();
1394       test2.CompressWhitespace();
1395       test3.CompressWhitespace();
1396       test4.CompressWhitespace();
1397       test5.CompressWhitespace();
1398     }
1399 });
1400 
__anon41071c4d0402null1401 MOZ_GTEST_BENCH(Strings, PerfStripCRLF, [] {
1402     nsCString test1(TestExample1);
1403     nsCString test2(TestExample2);
1404     nsCString test3(TestExample3);
1405     nsCString test4(TestExample4);
1406     nsCString test5(TestExample5);
1407     for (int i = 0; i < 20000; i++) {
1408       test1.StripCRLF();
1409       test2.StripCRLF();
1410       test3.StripCRLF();
1411       test4.StripCRLF();
1412       test5.StripCRLF();
1413     }
1414 });
1415 
__anon41071c4d0502null1416 MOZ_GTEST_BENCH(Strings, PerfStripCharsCRLF, [] {
1417     // This is the unoptimized (original) version of
1418     // stripping \r\n using StripChars.
1419     nsCString test1(TestExample1);
1420     nsCString test2(TestExample2);
1421     nsCString test3(TestExample3);
1422     nsCString test4(TestExample4);
1423     nsCString test5(TestExample5);
1424     for (int i = 0; i < 20000; i++) {
1425       test1.StripChars("\r\n");
1426       test2.StripChars("\r\n");
1427       test3.StripChars("\r\n");
1428       test4.StripChars("\r\n");
1429       test5.StripChars("\r\n");
1430     }
1431 });
1432 
1433 // Setup overhead test
1434 #define OneASCII "a"
1435 
1436 // Maximal non-SIMD legth
1437 #define FifteenASCII "Lorem ipsum dol"
1438 
1439 // Around hundred is common length for IsUTF8 check
1440 #define HundredASCII "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ac tellus eget velit viverra viverra i"
1441 
__anon41071c4d0602null1442 MOZ_GTEST_BENCH(Strings, PerfIsUTF8One, [] {
1443     nsCString test(OneASCII);
1444     for (int i = 0; i < 200000; i++) {
1445       bool b = IsUTF8(*BlackBox(&test));
1446       BlackBox(&b);
1447     }
1448 });
1449 
__anon41071c4d0702null1450 MOZ_GTEST_BENCH(Strings, PerfIsUTF8Fifteen, [] {
1451     nsCString test(FifteenASCII);
1452     for (int i = 0; i < 200000; i++) {
1453       bool b = IsUTF8(*BlackBox(&test));
1454       BlackBox(&b);
1455     }
1456 });
1457 
__anon41071c4d0802null1458 MOZ_GTEST_BENCH(Strings, PerfIsUTF8Hundred, [] {
1459     nsCString test(HundredASCII);
1460     for (int i = 0; i < 200000; i++) {
1461       bool b = IsUTF8(*BlackBox(&test));
1462       BlackBox(&b);
1463     }
1464 });
1465 
__anon41071c4d0902null1466 MOZ_GTEST_BENCH(Strings, PerfIsUTF8Example3, [] {
1467     nsCString test(TestExample3);
1468     for (int i = 0; i < 100000; i++) {
1469       bool b = IsUTF8(*BlackBox(&test));
1470       BlackBox(&b);
1471     }
1472 });
1473 
__anon41071c4d0a02null1474 MOZ_GTEST_BENCH(Strings, PerfIsASCII8One, [] {
1475     nsCString test(OneASCII);
1476     for (int i = 0; i < 200000; i++) {
1477       bool b = IsASCII(*BlackBox(&test));
1478       BlackBox(&b);
1479     }
1480 });
1481 
__anon41071c4d0b02null1482 MOZ_GTEST_BENCH(Strings, PerfIsASCIIFifteen, [] {
1483     nsCString test(FifteenASCII);
1484     for (int i = 0; i < 200000; i++) {
1485       bool b = IsASCII(*BlackBox(&test));
1486       BlackBox(&b);
1487     }
1488 });
1489 
__anon41071c4d0c02null1490 MOZ_GTEST_BENCH(Strings, PerfIsASCIIHundred, [] {
1491     nsCString test(HundredASCII);
1492     for (int i = 0; i < 200000; i++) {
1493       bool b = IsASCII(*BlackBox(&test));
1494       BlackBox(&b);
1495     }
1496 });
1497 
__anon41071c4d0d02null1498 MOZ_GTEST_BENCH(Strings, PerfIsASCIIExample3, [] {
1499     nsCString test(TestExample3);
1500     for (int i = 0; i < 100000; i++) {
1501       bool b = IsASCII(*BlackBox(&test));
1502       BlackBox(&b);
1503     }
1504 });
1505 
__anon41071c4d0e02null1506 MOZ_GTEST_BENCH(Strings, PerfHasRTLCharsExample3, [] {
1507     nsCString utf8(TestExample3);
1508     nsString test;
1509     CopyUTF8toUTF16(utf8, test);
1510     for (int i = 0; i < 100000; i++) {
1511       bool b = HasRTLChars(*BlackBox(&test));
1512       BlackBox(&b);
1513     }
1514 });
1515 
1516 // Originally ReadVPXFile in TestVPXDecoding.cpp
1517 static void
ReadFile(const char * aPath,nsACString & aBuffer)1518 ReadFile(const char* aPath, nsACString& aBuffer)
1519 {
1520   FILE* f = fopen(aPath, "rb");
1521   ASSERT_NE(f, (FILE *) nullptr);
1522 
1523   int r = fseek(f, 0, SEEK_END);
1524   ASSERT_EQ(r, 0);
1525 
1526   long size = ftell(f);
1527   ASSERT_NE(size, -1);
1528   aBuffer.SetLength(size);
1529 
1530   r = fseek(f, 0, SEEK_SET);
1531   ASSERT_EQ(r, 0);
1532 
1533   size_t got = fread(aBuffer.BeginWriting(), 1, size, f);
1534   ASSERT_EQ(got, size_t(size));
1535 
1536   r = fclose(f);
1537   ASSERT_EQ(r, 0);
1538 }
1539 
__anon41071c4d0f02null1540 MOZ_GTEST_BENCH(Strings, PerfHasRTLCharsDE, [] {
1541     nsCString utf8;
1542     ReadFile("de.txt", utf8);
1543     nsString test;
1544     CopyUTF8toUTF16(utf8, test);
1545     for (int i = 0; i < 100000; i++) {
1546       bool b = HasRTLChars(*BlackBox(&test));
1547       BlackBox(&b);
1548     }
1549 });
1550 
__anon41071c4d1002null1551 MOZ_GTEST_BENCH(Strings, PerfHasRTLCharsRU, [] {
1552     nsCString utf8;
1553     ReadFile("ru.txt", utf8);
1554     nsString test;
1555     CopyUTF8toUTF16(utf8, test);
1556     for (int i = 0; i < 100000; i++) {
1557       bool b = HasRTLChars(*BlackBox(&test));
1558       BlackBox(&b);
1559     }
1560 });
1561 
__anon41071c4d1102null1562 MOZ_GTEST_BENCH(Strings, PerfHasRTLCharsTH, [] {
1563     nsCString utf8;
1564     ReadFile("th.txt", utf8);
1565     nsString test;
1566     CopyUTF8toUTF16(utf8, test);
1567     for (int i = 0; i < 100000; i++) {
1568       bool b = HasRTLChars(*BlackBox(&test));
1569       BlackBox(&b);
1570     }
1571 });
1572 
__anon41071c4d1202null1573 MOZ_GTEST_BENCH(Strings, PerfHasRTLCharsJA, [] {
1574     nsCString utf8;
1575     ReadFile("ja.txt", utf8);
1576     nsString test;
1577     CopyUTF8toUTF16(utf8, test);
1578     for (int i = 0; i < 100000; i++) {
1579       bool b = HasRTLChars(*BlackBox(&test));
1580       BlackBox(&b);
1581     }
1582 });
1583 
1584 } // namespace TestStrings
1585