• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "core/fxcrt/fx_basic.h"
6 #include "testing/fx_string_testhelpers.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 
TEST(fxcrt,WideStringOperatorSubscript)9 TEST(fxcrt, WideStringOperatorSubscript) {
10   // CFX_WideString includes the NUL terminator for non-empty strings.
11   CFX_WideString abc(L"abc");
12   EXPECT_EQ(L'a', abc[0]);
13   EXPECT_EQ(L'b', abc[1]);
14   EXPECT_EQ(L'c', abc[2]);
15   EXPECT_EQ(L'\0', abc[3]);
16 }
17 
TEST(fxcrt,WideStringOperatorLT)18 TEST(fxcrt, WideStringOperatorLT) {
19   CFX_WideString empty;
20   CFX_WideString a(L"a");
21   CFX_WideString abc(L"\x0110qq");  // Comes before despite endianness.
22   CFX_WideString def(L"\x1001qq");  // Comes after despite endianness.
23 
24   EXPECT_FALSE(empty < empty);
25   EXPECT_FALSE(a < a);
26   EXPECT_FALSE(abc < abc);
27   EXPECT_FALSE(def < def);
28 
29   EXPECT_TRUE(empty < a);
30   EXPECT_FALSE(a < empty);
31 
32   EXPECT_TRUE(empty < abc);
33   EXPECT_FALSE(abc < empty);
34 
35   EXPECT_TRUE(empty < def);
36   EXPECT_FALSE(def < empty);
37 
38   EXPECT_TRUE(a < abc);
39   EXPECT_FALSE(abc < a);
40 
41   EXPECT_TRUE(a < def);
42   EXPECT_FALSE(def < a);
43 
44   EXPECT_TRUE(abc < def);
45   EXPECT_FALSE(def < abc);
46 }
47 
TEST(fxcrt,WideStringOperatorEQ)48 TEST(fxcrt, WideStringOperatorEQ) {
49   CFX_WideString null_string;
50   EXPECT_TRUE(null_string == null_string);
51 
52   CFX_WideString empty_string(L"");
53   EXPECT_TRUE(empty_string == empty_string);
54   EXPECT_TRUE(empty_string == null_string);
55   EXPECT_TRUE(null_string == empty_string);
56 
57   CFX_WideString deleted_string(L"hello");
58   deleted_string.Delete(0, 5);
59   EXPECT_TRUE(deleted_string == deleted_string);
60   EXPECT_TRUE(deleted_string == null_string);
61   EXPECT_TRUE(deleted_string == empty_string);
62   EXPECT_TRUE(null_string == deleted_string);
63   EXPECT_TRUE(null_string == empty_string);
64 
65   CFX_WideString wide_string(L"hello");
66   EXPECT_TRUE(wide_string == wide_string);
67   EXPECT_FALSE(wide_string == null_string);
68   EXPECT_FALSE(wide_string == empty_string);
69   EXPECT_FALSE(wide_string == deleted_string);
70   EXPECT_FALSE(null_string == wide_string);
71   EXPECT_FALSE(empty_string == wide_string);
72   EXPECT_FALSE(deleted_string == wide_string);
73 
74   CFX_WideString wide_string_same1(L"hello");
75   EXPECT_TRUE(wide_string == wide_string_same1);
76   EXPECT_TRUE(wide_string_same1 == wide_string);
77 
78   CFX_WideString wide_string_same2(wide_string);
79   EXPECT_TRUE(wide_string == wide_string_same2);
80   EXPECT_TRUE(wide_string_same2 == wide_string);
81 
82   CFX_WideString wide_string1(L"he");
83   CFX_WideString wide_string2(L"hellp");
84   CFX_WideString wide_string3(L"hellod");
85   EXPECT_FALSE(wide_string == wide_string1);
86   EXPECT_FALSE(wide_string == wide_string2);
87   EXPECT_FALSE(wide_string == wide_string3);
88   EXPECT_FALSE(wide_string1 == wide_string);
89   EXPECT_FALSE(wide_string2 == wide_string);
90   EXPECT_FALSE(wide_string3 == wide_string);
91 
92   CFX_WideStringC null_string_c;
93   CFX_WideStringC empty_string_c(L"");
94   EXPECT_TRUE(null_string == null_string_c);
95   EXPECT_TRUE(null_string == empty_string_c);
96   EXPECT_TRUE(empty_string == null_string_c);
97   EXPECT_TRUE(empty_string == empty_string_c);
98   EXPECT_TRUE(deleted_string == null_string_c);
99   EXPECT_TRUE(deleted_string == empty_string_c);
100   EXPECT_TRUE(null_string_c == null_string);
101   EXPECT_TRUE(empty_string_c == null_string);
102   EXPECT_TRUE(null_string_c == empty_string);
103   EXPECT_TRUE(empty_string_c == empty_string);
104   EXPECT_TRUE(null_string_c == deleted_string);
105   EXPECT_TRUE(empty_string_c == deleted_string);
106 
107   CFX_WideStringC wide_string_c_same1(L"hello");
108   EXPECT_TRUE(wide_string == wide_string_c_same1);
109   EXPECT_TRUE(wide_string_c_same1 == wide_string);
110 
111   CFX_WideStringC wide_string_c1(L"he");
112   CFX_WideStringC wide_string_c2(L"hellp");
113   CFX_WideStringC wide_string_c3(L"hellod");
114   EXPECT_FALSE(wide_string == wide_string_c1);
115   EXPECT_FALSE(wide_string == wide_string_c2);
116   EXPECT_FALSE(wide_string == wide_string_c3);
117   EXPECT_FALSE(wide_string_c1 == wide_string);
118   EXPECT_FALSE(wide_string_c2 == wide_string);
119   EXPECT_FALSE(wide_string_c3 == wide_string);
120 
121   const wchar_t* c_null_string = nullptr;
122   const wchar_t* c_empty_string = L"";
123   EXPECT_TRUE(null_string == c_null_string);
124   EXPECT_TRUE(null_string == c_empty_string);
125   EXPECT_TRUE(empty_string == c_null_string);
126   EXPECT_TRUE(empty_string == c_empty_string);
127   EXPECT_TRUE(deleted_string == c_null_string);
128   EXPECT_TRUE(deleted_string == c_empty_string);
129   EXPECT_TRUE(c_null_string == null_string);
130   EXPECT_TRUE(c_empty_string == null_string);
131   EXPECT_TRUE(c_null_string == empty_string);
132   EXPECT_TRUE(c_empty_string == empty_string);
133   EXPECT_TRUE(c_null_string == deleted_string);
134   EXPECT_TRUE(c_empty_string == deleted_string);
135 
136   const wchar_t* c_string_same1 = L"hello";
137   EXPECT_TRUE(wide_string == c_string_same1);
138   EXPECT_TRUE(c_string_same1 == wide_string);
139 
140   const wchar_t* c_string1 = L"he";
141   const wchar_t* c_string2 = L"hellp";
142   const wchar_t* c_string3 = L"hellod";
143   EXPECT_FALSE(wide_string == c_string1);
144   EXPECT_FALSE(wide_string == c_string2);
145   EXPECT_FALSE(wide_string == c_string3);
146   EXPECT_FALSE(c_string1 == wide_string);
147   EXPECT_FALSE(c_string2 == wide_string);
148   EXPECT_FALSE(c_string3 == wide_string);
149 }
150 
TEST(fxcrt,WideStringOperatorNE)151 TEST(fxcrt, WideStringOperatorNE) {
152   CFX_WideString null_string;
153   EXPECT_FALSE(null_string != null_string);
154 
155   CFX_WideString empty_string(L"");
156   EXPECT_FALSE(empty_string != empty_string);
157   EXPECT_FALSE(empty_string != null_string);
158   EXPECT_FALSE(null_string != empty_string);
159 
160   CFX_WideString deleted_string(L"hello");
161   deleted_string.Delete(0, 5);
162   EXPECT_FALSE(deleted_string != deleted_string);
163   EXPECT_FALSE(deleted_string != null_string);
164   EXPECT_FALSE(deleted_string != empty_string);
165   EXPECT_FALSE(null_string != deleted_string);
166   EXPECT_FALSE(null_string != empty_string);
167 
168   CFX_WideString wide_string(L"hello");
169   EXPECT_FALSE(wide_string != wide_string);
170   EXPECT_TRUE(wide_string != null_string);
171   EXPECT_TRUE(wide_string != empty_string);
172   EXPECT_TRUE(wide_string != deleted_string);
173   EXPECT_TRUE(null_string != wide_string);
174   EXPECT_TRUE(empty_string != wide_string);
175   EXPECT_TRUE(deleted_string != wide_string);
176 
177   CFX_WideString wide_string_same1(L"hello");
178   EXPECT_FALSE(wide_string != wide_string_same1);
179   EXPECT_FALSE(wide_string_same1 != wide_string);
180 
181   CFX_WideString wide_string_same2(wide_string);
182   EXPECT_FALSE(wide_string != wide_string_same2);
183   EXPECT_FALSE(wide_string_same2 != wide_string);
184 
185   CFX_WideString wide_string1(L"he");
186   CFX_WideString wide_string2(L"hellp");
187   CFX_WideString wide_string3(L"hellod");
188   EXPECT_TRUE(wide_string != wide_string1);
189   EXPECT_TRUE(wide_string != wide_string2);
190   EXPECT_TRUE(wide_string != wide_string3);
191   EXPECT_TRUE(wide_string1 != wide_string);
192   EXPECT_TRUE(wide_string2 != wide_string);
193   EXPECT_TRUE(wide_string3 != wide_string);
194 
195   CFX_WideStringC null_string_c;
196   CFX_WideStringC empty_string_c(L"");
197   EXPECT_FALSE(null_string != null_string_c);
198   EXPECT_FALSE(null_string != empty_string_c);
199   EXPECT_FALSE(empty_string != null_string_c);
200   EXPECT_FALSE(empty_string != empty_string_c);
201   EXPECT_FALSE(deleted_string != null_string_c);
202   EXPECT_FALSE(deleted_string != empty_string_c);
203   EXPECT_FALSE(null_string_c != null_string);
204   EXPECT_FALSE(empty_string_c != null_string);
205   EXPECT_FALSE(null_string_c != empty_string);
206   EXPECT_FALSE(empty_string_c != empty_string);
207 
208   CFX_WideStringC wide_string_c_same1(L"hello");
209   EXPECT_FALSE(wide_string != wide_string_c_same1);
210   EXPECT_FALSE(wide_string_c_same1 != wide_string);
211 
212   CFX_WideStringC wide_string_c1(L"he");
213   CFX_WideStringC wide_string_c2(L"hellp");
214   CFX_WideStringC wide_string_c3(L"hellod");
215   EXPECT_TRUE(wide_string != wide_string_c1);
216   EXPECT_TRUE(wide_string != wide_string_c2);
217   EXPECT_TRUE(wide_string != wide_string_c3);
218   EXPECT_TRUE(wide_string_c1 != wide_string);
219   EXPECT_TRUE(wide_string_c2 != wide_string);
220   EXPECT_TRUE(wide_string_c3 != wide_string);
221 
222   const wchar_t* c_null_string = nullptr;
223   const wchar_t* c_empty_string = L"";
224   EXPECT_FALSE(null_string != c_null_string);
225   EXPECT_FALSE(null_string != c_empty_string);
226   EXPECT_FALSE(empty_string != c_null_string);
227   EXPECT_FALSE(empty_string != c_empty_string);
228   EXPECT_FALSE(deleted_string != c_null_string);
229   EXPECT_FALSE(deleted_string != c_empty_string);
230   EXPECT_FALSE(c_null_string != null_string);
231   EXPECT_FALSE(c_empty_string != null_string);
232   EXPECT_FALSE(c_null_string != empty_string);
233   EXPECT_FALSE(c_empty_string != empty_string);
234   EXPECT_FALSE(c_null_string != deleted_string);
235   EXPECT_FALSE(c_empty_string != deleted_string);
236 
237   const wchar_t* c_string_same1 = L"hello";
238   EXPECT_FALSE(wide_string != c_string_same1);
239   EXPECT_FALSE(c_string_same1 != wide_string);
240 
241   const wchar_t* c_string1 = L"he";
242   const wchar_t* c_string2 = L"hellp";
243   const wchar_t* c_string3 = L"hellod";
244   EXPECT_TRUE(wide_string != c_string1);
245   EXPECT_TRUE(wide_string != c_string2);
246   EXPECT_TRUE(wide_string != c_string3);
247   EXPECT_TRUE(c_string1 != wide_string);
248   EXPECT_TRUE(c_string2 != wide_string);
249   EXPECT_TRUE(c_string3 != wide_string);
250 }
251 
TEST(fxcrt,WideStringConcatInPlace)252 TEST(fxcrt, WideStringConcatInPlace) {
253   CFX_WideString fred;
254   fred.Concat(L"FRED", 4);
255   EXPECT_EQ(L"FRED", fred);
256 
257   fred.Concat(L"DY", 2);
258   EXPECT_EQ(L"FREDDY", fred);
259 
260   fred.Delete(3, 3);
261   EXPECT_EQ(L"FRE", fred);
262 
263   fred.Concat(L"D", 1);
264   EXPECT_EQ(L"FRED", fred);
265 
266   CFX_WideString copy = fred;
267   fred.Concat(L"DY", 2);
268   EXPECT_EQ(L"FREDDY", fred);
269   EXPECT_EQ(L"FRED", copy);
270 
271   // Test invalid arguments.
272   copy = fred;
273   fred.Concat(L"freddy", -6);
274   CFX_WideString not_aliased(L"xxxxxx");
275   EXPECT_EQ(L"FREDDY", fred);
276   EXPECT_EQ(L"xxxxxx", not_aliased);
277 }
278 
TEST(fxcrt,WideStringRemove)279 TEST(fxcrt, WideStringRemove) {
280   CFX_WideString freed(L"FREED");
281   freed.Remove(L'E');
282   EXPECT_EQ(L"FRD", freed);
283   freed.Remove(L'F');
284   EXPECT_EQ(L"RD", freed);
285   freed.Remove(L'D');
286   EXPECT_EQ(L"R", freed);
287   freed.Remove(L'X');
288   EXPECT_EQ(L"R", freed);
289   freed.Remove(L'R');
290   EXPECT_EQ(L"", freed);
291 
292   CFX_WideString empty;
293   empty.Remove(L'X');
294   EXPECT_EQ(L"", empty);
295 }
296 
TEST(fxcrt,WideStringRemoveCopies)297 TEST(fxcrt, WideStringRemoveCopies) {
298   CFX_WideString freed(L"FREED");
299   const FX_WCHAR* old_buffer = freed.c_str();
300 
301   // No change with single reference - no copy.
302   freed.Remove(L'Q');
303   EXPECT_EQ(L"FREED", freed);
304   EXPECT_EQ(old_buffer, freed.c_str());
305 
306   // Change with single reference - no copy.
307   freed.Remove(L'E');
308   EXPECT_EQ(L"FRD", freed);
309   EXPECT_EQ(old_buffer, freed.c_str());
310 
311   // No change with multiple references - no copy.
312   CFX_WideString shared(freed);
313   freed.Remove(L'Q');
314   EXPECT_EQ(L"FRD", freed);
315   EXPECT_EQ(old_buffer, freed.c_str());
316   EXPECT_EQ(old_buffer, shared.c_str());
317 
318   // Change with multiple references -- must copy.
319   freed.Remove(L'D');
320   EXPECT_EQ(L"FR", freed);
321   EXPECT_NE(old_buffer, freed.c_str());
322   EXPECT_EQ(L"FRD", shared);
323   EXPECT_EQ(old_buffer, shared.c_str());
324 }
325 
TEST(fxcrt,WideStringReplace)326 TEST(fxcrt, WideStringReplace) {
327   CFX_WideString fred(L"FRED");
328   fred.Replace(L"FR", L"BL");
329   EXPECT_EQ(L"BLED", fred);
330   fred.Replace(L"D", L"DDY");
331   EXPECT_EQ(L"BLEDDY", fred);
332   fred.Replace(L"LEDD", L"");
333   EXPECT_EQ(L"BY", fred);
334   fred.Replace(L"X", L"CLAMS");
335   EXPECT_EQ(L"BY", fred);
336   fred.Replace(L"BY", L"HI");
337   EXPECT_EQ(L"HI", fred);
338   fred.Replace(L"", L"CLAMS");
339   EXPECT_EQ(L"HI", fred);
340   fred.Replace(L"HI", L"");
341   EXPECT_EQ(L"", fred);
342 }
343 
TEST(fxcrt,WideStringInsert)344 TEST(fxcrt, WideStringInsert) {
345   CFX_WideString fred(L"FRED");
346   fred.Insert(-1, 'X');
347   EXPECT_EQ(L"XFRED", fred);
348 
349   fred.Insert(0, 'S');
350   EXPECT_EQ(L"SXFRED", fred);
351 
352   fred.Insert(2, 'T');
353   EXPECT_EQ(L"SXTFRED", fred);
354 
355   fred.Insert(5, 'U');
356   EXPECT_EQ(L"SXTFRUED", fred);
357 
358   fred.Insert(8, 'V');
359   EXPECT_EQ(L"SXTFRUEDV", fred);
360 
361   fred.Insert(12, 'P');
362   EXPECT_EQ(L"SXTFRUEDVP", fred);
363 
364   {
365     CFX_WideString empty;
366     empty.Insert(-1, 'X');
367     EXPECT_EQ(L"X", empty);
368   }
369   {
370     CFX_WideString empty;
371     empty.Insert(0, 'X');
372     EXPECT_EQ(L"X", empty);
373   }
374   {
375     CFX_WideString empty;
376     empty.Insert(5, 'X');
377     EXPECT_EQ(L"X", empty);
378   }
379 }
380 
TEST(fxcrt,WideStringDelete)381 TEST(fxcrt, WideStringDelete) {
382   CFX_WideString fred(L"FRED");
383   fred.Delete(0, 2);
384   EXPECT_EQ(L"ED", fred);
385   fred.Delete(1);
386   EXPECT_EQ(L"E", fred);
387   fred.Delete(-1);
388   EXPECT_EQ(L"", fred);
389   fred.Delete(1);
390   EXPECT_EQ(L"", fred);
391 
392   CFX_WideString empty;
393   empty.Delete(0);
394   EXPECT_EQ(L"", empty);
395   empty.Delete(-1);
396   EXPECT_EQ(L"", empty);
397   empty.Delete(1);
398   EXPECT_EQ(L"", empty);
399 }
400 
TEST(fxcrt,WideStringMid)401 TEST(fxcrt, WideStringMid) {
402   CFX_WideString fred(L"FRED");
403   EXPECT_EQ(L"", fred.Mid(0, 0));
404   EXPECT_EQ(L"", fred.Mid(3, 0));
405   EXPECT_EQ(L"FRED", fred.Mid(0));
406   EXPECT_EQ(L"RED", fred.Mid(1));
407   EXPECT_EQ(L"ED", fred.Mid(2));
408   EXPECT_EQ(L"D", fred.Mid(3));
409   EXPECT_EQ(L"F", fred.Mid(0, 1));
410   EXPECT_EQ(L"R", fred.Mid(1, 1));
411   EXPECT_EQ(L"E", fred.Mid(2, 1));
412   EXPECT_EQ(L"D", fred.Mid(3, 1));
413   EXPECT_EQ(L"FR", fred.Mid(0, 2));
414   EXPECT_EQ(L"FRED", fred.Mid(0, 4));
415   EXPECT_EQ(L"FRED", fred.Mid(0, 10));
416 
417   EXPECT_EQ(L"FR", fred.Mid(-1, 2));
418   EXPECT_EQ(L"RED", fred.Mid(1, 4));
419   EXPECT_EQ(L"", fred.Mid(4, 1));
420 
421   CFX_WideString empty;
422   EXPECT_EQ(L"", empty.Mid(0, 0));
423   EXPECT_EQ(L"", empty.Mid(0));
424   EXPECT_EQ(L"", empty.Mid(1));
425   EXPECT_EQ(L"", empty.Mid(-1));
426 }
427 
TEST(fxcrt,WideStringLeft)428 TEST(fxcrt, WideStringLeft) {
429   CFX_WideString fred(L"FRED");
430   EXPECT_EQ(L"", fred.Left(0));
431   EXPECT_EQ(L"F", fred.Left(1));
432   EXPECT_EQ(L"FR", fred.Left(2));
433   EXPECT_EQ(L"FRE", fred.Left(3));
434   EXPECT_EQ(L"FRED", fred.Left(4));
435 
436   EXPECT_EQ(L"FRED", fred.Left(5));
437   EXPECT_EQ(L"", fred.Left(-1));
438 
439   CFX_WideString empty;
440   EXPECT_EQ(L"", empty.Left(0));
441   EXPECT_EQ(L"", empty.Left(1));
442   EXPECT_EQ(L"", empty.Left(-1));
443 }
444 
TEST(fxcrt,WideStringRight)445 TEST(fxcrt, WideStringRight) {
446   CFX_WideString fred(L"FRED");
447   EXPECT_EQ(L"", fred.Right(0));
448   EXPECT_EQ(L"D", fred.Right(1));
449   EXPECT_EQ(L"ED", fred.Right(2));
450   EXPECT_EQ(L"RED", fred.Right(3));
451   EXPECT_EQ(L"FRED", fred.Right(4));
452 
453   EXPECT_EQ(L"FRED", fred.Right(5));
454   EXPECT_EQ(L"", fred.Right(-1));
455 
456   CFX_WideString empty;
457   EXPECT_EQ(L"", empty.Right(0));
458   EXPECT_EQ(L"", empty.Right(1));
459   EXPECT_EQ(L"", empty.Right(-1));
460 }
461 
TEST(fxcrt,WideStringUpperLower)462 TEST(fxcrt, WideStringUpperLower) {
463   CFX_WideString fred(L"F-Re.42D");
464   fred.MakeLower();
465   EXPECT_EQ(L"f-re.42d", fred);
466   fred.MakeUpper();
467   EXPECT_EQ(L"F-RE.42D", fred);
468 
469   CFX_WideString empty;
470   empty.MakeLower();
471   EXPECT_EQ(L"", empty);
472   empty.MakeUpper();
473   EXPECT_EQ(L"", empty);
474 }
475 
TEST(fxcrt,WideStringTrimRight)476 TEST(fxcrt, WideStringTrimRight) {
477   CFX_WideString fred(L"  FRED  ");
478   fred.TrimRight();
479   EXPECT_EQ(L"  FRED", fred);
480   fred.TrimRight(L'E');
481   EXPECT_EQ(L"  FRED", fred);
482   fred.TrimRight(L'D');
483   EXPECT_EQ(L"  FRE", fred);
484   fred.TrimRight(L"ERP");
485   EXPECT_EQ(L"  F", fred);
486 
487   CFX_WideString blank(L"   ");
488   blank.TrimRight(L"ERP");
489   EXPECT_EQ(L"   ", blank);
490   blank.TrimRight(L'E');
491   EXPECT_EQ(L"   ", blank);
492   blank.TrimRight();
493   EXPECT_EQ(L"", blank);
494 
495   CFX_WideString empty;
496   empty.TrimRight(L"ERP");
497   EXPECT_EQ(L"", empty);
498   empty.TrimRight(L'E');
499   EXPECT_EQ(L"", empty);
500   empty.TrimRight();
501   EXPECT_EQ(L"", empty);
502 }
503 
TEST(fxcrt,WideStringTrimRightCopies)504 TEST(fxcrt, WideStringTrimRightCopies) {
505   {
506     // With a single reference, no copy takes place.
507     CFX_WideString fred(L"  FRED  ");
508     const FX_WCHAR* old_buffer = fred.c_str();
509     fred.TrimRight();
510     EXPECT_EQ(L"  FRED", fred);
511     EXPECT_EQ(old_buffer, fred.c_str());
512   }
513   {
514     // With multiple references, we must copy.
515     CFX_WideString fred(L"  FRED  ");
516     CFX_WideString other_fred = fred;
517     const FX_WCHAR* old_buffer = fred.c_str();
518     fred.TrimRight();
519     EXPECT_EQ(L"  FRED", fred);
520     EXPECT_EQ(L"  FRED  ", other_fred);
521     EXPECT_NE(old_buffer, fred.c_str());
522   }
523   {
524     // With multiple references, but no modifications, no copy.
525     CFX_WideString fred(L"FRED");
526     CFX_WideString other_fred = fred;
527     const FX_WCHAR* old_buffer = fred.c_str();
528     fred.TrimRight();
529     EXPECT_EQ(L"FRED", fred);
530     EXPECT_EQ(L"FRED", other_fred);
531     EXPECT_EQ(old_buffer, fred.c_str());
532   }
533 }
534 
TEST(fxcrt,WideStringTrimLeft)535 TEST(fxcrt, WideStringTrimLeft) {
536   CFX_WideString fred(L"  FRED  ");
537   fred.TrimLeft();
538   EXPECT_EQ(L"FRED  ", fred);
539   fred.TrimLeft(L'E');
540   EXPECT_EQ(L"FRED  ", fred);
541   fred.TrimLeft(L'F');
542   EXPECT_EQ(L"RED  ", fred);
543   fred.TrimLeft(L"ERP");
544   EXPECT_EQ(L"D  ", fred);
545 
546   CFX_WideString blank(L"   ");
547   blank.TrimLeft(L"ERP");
548   EXPECT_EQ(L"   ", blank);
549   blank.TrimLeft(L'E');
550   EXPECT_EQ(L"   ", blank);
551   blank.TrimLeft();
552   EXPECT_EQ(L"", blank);
553 
554   CFX_WideString empty;
555   empty.TrimLeft(L"ERP");
556   EXPECT_EQ(L"", empty);
557   empty.TrimLeft(L'E');
558   EXPECT_EQ(L"", empty);
559   empty.TrimLeft();
560   EXPECT_EQ(L"", empty);
561 }
562 
TEST(fxcrt,WideStringTrimLeftCopies)563 TEST(fxcrt, WideStringTrimLeftCopies) {
564   {
565     // With a single reference, no copy takes place.
566     CFX_WideString fred(L"  FRED  ");
567     const FX_WCHAR* old_buffer = fred.c_str();
568     fred.TrimLeft();
569     EXPECT_EQ(L"FRED  ", fred);
570     EXPECT_EQ(old_buffer, fred.c_str());
571   }
572   {
573     // With multiple references, we must copy.
574     CFX_WideString fred(L"  FRED  ");
575     CFX_WideString other_fred = fred;
576     const FX_WCHAR* old_buffer = fred.c_str();
577     fred.TrimLeft();
578     EXPECT_EQ(L"FRED  ", fred);
579     EXPECT_EQ(L"  FRED  ", other_fred);
580     EXPECT_NE(old_buffer, fred.c_str());
581   }
582   {
583     // With multiple references, but no modifications, no copy.
584     CFX_WideString fred(L"FRED");
585     CFX_WideString other_fred = fred;
586     const FX_WCHAR* old_buffer = fred.c_str();
587     fred.TrimLeft();
588     EXPECT_EQ(L"FRED", fred);
589     EXPECT_EQ(L"FRED", other_fred);
590     EXPECT_EQ(old_buffer, fred.c_str());
591   }
592 }
593 
TEST(fxcrt,WideStringReserve)594 TEST(fxcrt, WideStringReserve) {
595   {
596     CFX_WideString str;
597     str.Reserve(6);
598     const FX_WCHAR* old_buffer = str.c_str();
599     str += L"ABCDEF";
600     EXPECT_EQ(old_buffer, str.c_str());
601     str += L"Blah Blah Blah Blah Blah Blah";
602     EXPECT_NE(old_buffer, str.c_str());
603   }
604   {
605     CFX_WideString str(L"A");
606     str.Reserve(6);
607     const FX_WCHAR* old_buffer = str.c_str();
608     str += L"BCDEF";
609     EXPECT_EQ(old_buffer, str.c_str());
610     str += L"Blah Blah Blah Blah Blah Blah";
611     EXPECT_NE(old_buffer, str.c_str());
612   }
613 }
614 
TEST(fxcrt,WideStringGetBuffer)615 TEST(fxcrt, WideStringGetBuffer) {
616   {
617     CFX_WideString str;
618     FX_WCHAR* buffer = str.GetBuffer(12);
619     wcscpy(buffer, L"clams");
620     str.ReleaseBuffer();
621     EXPECT_EQ(L"clams", str);
622   }
623   {
624     CFX_WideString str(L"cl");
625     FX_WCHAR* buffer = str.GetBuffer(12);
626     wcscpy(buffer + 2, L"ams");
627     str.ReleaseBuffer();
628     EXPECT_EQ(L"clams", str);
629   }
630 }
631 
TEST(fxcrt,WideStringReleaseBuffer)632 TEST(fxcrt, WideStringReleaseBuffer) {
633   {
634     CFX_WideString str;
635     str.Reserve(12);
636     str += L"clams";
637     const FX_WCHAR* old_buffer = str.c_str();
638     str.ReleaseBuffer(4);
639     EXPECT_EQ(old_buffer, str.c_str());
640     EXPECT_EQ(L"clam", str);
641   }
642   {
643     CFX_WideString str(L"c");
644     str.Reserve(12);
645     str += L"lams";
646     const FX_WCHAR* old_buffer = str.c_str();
647     str.ReleaseBuffer(4);
648     EXPECT_EQ(old_buffer, str.c_str());
649     EXPECT_EQ(L"clam", str);
650   }
651   {
652     CFX_WideString str;
653     str.Reserve(200);
654     str += L"clams";
655     const FX_WCHAR* old_buffer = str.c_str();
656     str.ReleaseBuffer(4);
657     EXPECT_NE(old_buffer, str.c_str());
658     EXPECT_EQ(L"clam", str);
659   }
660   {
661     CFX_WideString str(L"c");
662     str.Reserve(200);
663     str += L"lams";
664     const FX_WCHAR* old_buffer = str.c_str();
665     str.ReleaseBuffer(4);
666     EXPECT_NE(old_buffer, str.c_str());
667     EXPECT_EQ(L"clam", str);
668   }
669 }
670 
TEST(fxcrt,WideStringUTF16LE_Encode)671 TEST(fxcrt, WideStringUTF16LE_Encode) {
672   struct UTF16LEEncodeCase {
673     CFX_WideString ws;
674     CFX_ByteString bs;
675   } utf16le_encode_cases[] = {
676       {L"", CFX_ByteString("\0\0", 2)},
677       {L"abc", CFX_ByteString("a\0b\0c\0\0\0", 8)},
678       {L"abcdef", CFX_ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)},
679       {L"abc\0def", CFX_ByteString("a\0b\0c\0\0\0", 8)},
680       {L"\xaabb\xccdd", CFX_ByteString("\xbb\xaa\xdd\xcc\0\0", 6)},
681       {L"\x3132\x6162", CFX_ByteString("\x32\x31\x62\x61\0\0", 6)},
682   };
683 
684   for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) {
685     EXPECT_EQ(utf16le_encode_cases[i].bs,
686               utf16le_encode_cases[i].ws.UTF16LE_Encode())
687         << " for case number " << i;
688   }
689 }
690 
TEST(fxcrt,WideStringCOperatorSubscript)691 TEST(fxcrt, WideStringCOperatorSubscript) {
692   // CFX_WideStringC includes the NUL terminator for non-empty strings.
693   CFX_WideStringC abc(L"abc");
694   EXPECT_EQ(L'a', abc.CharAt(0));
695   EXPECT_EQ(L'b', abc.CharAt(1));
696   EXPECT_EQ(L'c', abc.CharAt(2));
697   EXPECT_EQ(L'\0', abc.CharAt(3));
698 }
699 
TEST(fxcrt,WideStringCOperatorLT)700 TEST(fxcrt, WideStringCOperatorLT) {
701   CFX_WideStringC empty;
702   CFX_WideStringC a(L"a");
703   CFX_WideStringC abc(L"\x0110qq");  // Comes before despite endianness.
704   CFX_WideStringC def(L"\x1001qq");  // Comes after despite endianness.
705 
706   EXPECT_FALSE(empty < empty);
707   EXPECT_FALSE(a < a);
708   EXPECT_FALSE(abc < abc);
709   EXPECT_FALSE(def < def);
710 
711   EXPECT_TRUE(empty < a);
712   EXPECT_FALSE(a < empty);
713 
714   EXPECT_TRUE(empty < abc);
715   EXPECT_FALSE(abc < empty);
716 
717   EXPECT_TRUE(empty < def);
718   EXPECT_FALSE(def < empty);
719 
720   EXPECT_TRUE(a < abc);
721   EXPECT_FALSE(abc < a);
722 
723   EXPECT_TRUE(a < def);
724   EXPECT_FALSE(def < a);
725 
726   EXPECT_TRUE(abc < def);
727   EXPECT_FALSE(def < abc);
728 }
729 
TEST(fxcrt,WideStringCOperatorEQ)730 TEST(fxcrt, WideStringCOperatorEQ) {
731   CFX_WideStringC wide_string_c(L"hello");
732   EXPECT_TRUE(wide_string_c == wide_string_c);
733 
734   CFX_WideStringC wide_string_c_same1(L"hello");
735   EXPECT_TRUE(wide_string_c == wide_string_c_same1);
736   EXPECT_TRUE(wide_string_c_same1 == wide_string_c);
737 
738   CFX_WideStringC wide_string_c_same2(wide_string_c);
739   EXPECT_TRUE(wide_string_c == wide_string_c_same2);
740   EXPECT_TRUE(wide_string_c_same2 == wide_string_c);
741 
742   CFX_WideStringC wide_string_c1(L"he");
743   CFX_WideStringC wide_string_c2(L"hellp");
744   CFX_WideStringC wide_string_c3(L"hellod");
745   EXPECT_FALSE(wide_string_c == wide_string_c1);
746   EXPECT_FALSE(wide_string_c == wide_string_c2);
747   EXPECT_FALSE(wide_string_c == wide_string_c3);
748   EXPECT_FALSE(wide_string_c1 == wide_string_c);
749   EXPECT_FALSE(wide_string_c2 == wide_string_c);
750   EXPECT_FALSE(wide_string_c3 == wide_string_c);
751 
752   CFX_WideString wide_string_same1(L"hello");
753   EXPECT_TRUE(wide_string_c == wide_string_same1);
754   EXPECT_TRUE(wide_string_same1 == wide_string_c);
755 
756   CFX_WideString wide_string1(L"he");
757   CFX_WideString wide_string2(L"hellp");
758   CFX_WideString wide_string3(L"hellod");
759   EXPECT_FALSE(wide_string_c == wide_string1);
760   EXPECT_FALSE(wide_string_c == wide_string2);
761   EXPECT_FALSE(wide_string_c == wide_string3);
762   EXPECT_FALSE(wide_string1 == wide_string_c);
763   EXPECT_FALSE(wide_string2 == wide_string_c);
764   EXPECT_FALSE(wide_string3 == wide_string_c);
765 
766   const wchar_t* c_string_same1 = L"hello";
767   EXPECT_TRUE(wide_string_c == c_string_same1);
768   EXPECT_TRUE(c_string_same1 == wide_string_c);
769 
770   const wchar_t* c_string1 = L"he";
771   const wchar_t* c_string2 = L"hellp";
772   const wchar_t* c_string3 = L"hellod";
773   EXPECT_FALSE(wide_string_c == c_string1);
774   EXPECT_FALSE(wide_string_c == c_string2);
775   EXPECT_FALSE(wide_string_c == c_string3);
776 
777   EXPECT_FALSE(c_string1 == wide_string_c);
778   EXPECT_FALSE(c_string2 == wide_string_c);
779   EXPECT_FALSE(c_string3 == wide_string_c);
780 }
781 
TEST(fxcrt,WideStringCOperatorNE)782 TEST(fxcrt, WideStringCOperatorNE) {
783   CFX_WideStringC wide_string_c(L"hello");
784   EXPECT_FALSE(wide_string_c != wide_string_c);
785 
786   CFX_WideStringC wide_string_c_same1(L"hello");
787   EXPECT_FALSE(wide_string_c != wide_string_c_same1);
788   EXPECT_FALSE(wide_string_c_same1 != wide_string_c);
789 
790   CFX_WideStringC wide_string_c_same2(wide_string_c);
791   EXPECT_FALSE(wide_string_c != wide_string_c_same2);
792   EXPECT_FALSE(wide_string_c_same2 != wide_string_c);
793 
794   CFX_WideStringC wide_string_c1(L"he");
795   CFX_WideStringC wide_string_c2(L"hellp");
796   CFX_WideStringC wide_string_c3(L"hellod");
797   EXPECT_TRUE(wide_string_c != wide_string_c1);
798   EXPECT_TRUE(wide_string_c != wide_string_c2);
799   EXPECT_TRUE(wide_string_c != wide_string_c3);
800   EXPECT_TRUE(wide_string_c1 != wide_string_c);
801   EXPECT_TRUE(wide_string_c2 != wide_string_c);
802   EXPECT_TRUE(wide_string_c3 != wide_string_c);
803 
804   CFX_WideString wide_string_same1(L"hello");
805   EXPECT_FALSE(wide_string_c != wide_string_same1);
806   EXPECT_FALSE(wide_string_same1 != wide_string_c);
807 
808   CFX_WideString wide_string1(L"he");
809   CFX_WideString wide_string2(L"hellp");
810   CFX_WideString wide_string3(L"hellod");
811   EXPECT_TRUE(wide_string_c != wide_string1);
812   EXPECT_TRUE(wide_string_c != wide_string2);
813   EXPECT_TRUE(wide_string_c != wide_string3);
814   EXPECT_TRUE(wide_string1 != wide_string_c);
815   EXPECT_TRUE(wide_string2 != wide_string_c);
816   EXPECT_TRUE(wide_string3 != wide_string_c);
817 
818   const wchar_t* c_string_same1 = L"hello";
819   EXPECT_FALSE(wide_string_c != c_string_same1);
820   EXPECT_FALSE(c_string_same1 != wide_string_c);
821 
822   const wchar_t* c_string1 = L"he";
823   const wchar_t* c_string2 = L"hellp";
824   const wchar_t* c_string3 = L"hellod";
825   EXPECT_TRUE(wide_string_c != c_string1);
826   EXPECT_TRUE(wide_string_c != c_string2);
827   EXPECT_TRUE(wide_string_c != c_string3);
828 
829   EXPECT_TRUE(c_string1 != wide_string_c);
830   EXPECT_TRUE(c_string2 != wide_string_c);
831   EXPECT_TRUE(c_string3 != wide_string_c);
832 }
833 
TEST(fxcrt,WideStringCFind)834 TEST(fxcrt, WideStringCFind) {
835   CFX_WideStringC null_string;
836   EXPECT_EQ(-1, null_string.Find(L'a'));
837   EXPECT_EQ(-1, null_string.Find(0));
838 
839   CFX_WideStringC empty_string(L"");
840   EXPECT_EQ(-1, empty_string.Find(L'a'));
841   EXPECT_EQ(-1, empty_string.Find(0));
842 
843   CFX_WideStringC single_string(L"a");
844   EXPECT_EQ(0, single_string.Find(L'a'));
845   EXPECT_EQ(-1, single_string.Find(L'b'));
846   EXPECT_EQ(-1, single_string.Find(0));
847 
848   CFX_WideStringC longer_string(L"abccc");
849   EXPECT_EQ(0, longer_string.Find(L'a'));
850   EXPECT_EQ(2, longer_string.Find(L'c'));
851   EXPECT_EQ(-1, longer_string.Find(0));
852 
853   CFX_WideStringC hibyte_string(
854       L"ab\xff08"
855       L"def");
856   EXPECT_EQ(2, hibyte_string.Find(L'\xff08'));
857 }
858 
TEST(fxcrt,WideStringFormatWidth)859 TEST(fxcrt, WideStringFormatWidth) {
860   {
861     CFX_WideString str;
862     str.Format(L"%5d", 1);
863     EXPECT_EQ(L"    1", str);
864   }
865 
866   {
867     CFX_WideString str;
868     str.Format(L"%d", 1);
869     EXPECT_EQ(L"1", str);
870   }
871 
872   {
873     CFX_WideString str;
874     str.Format(L"%*d", 5, 1);
875     EXPECT_EQ(L"    1", str);
876   }
877 
878   {
879     CFX_WideString str;
880     str.Format(L"%-1d", 1);
881     EXPECT_EQ(L"1", str);
882   }
883 
884   {
885     CFX_WideString str;
886     str.Format(L"%0d", 1);
887     EXPECT_EQ(L"1", str);
888   }
889 
890   {
891     CFX_WideString str;
892     str.Format(L"%1048576d", 1);
893     EXPECT_EQ(L"Bad width", str);
894   }
895 }
896 
TEST(fxcrt,WideStringFormatPrecision)897 TEST(fxcrt, WideStringFormatPrecision) {
898   {
899     CFX_WideString str;
900     str.Format(L"%.2f", 1.12345);
901     EXPECT_EQ(L"1.12", str);
902   }
903 
904   {
905     CFX_WideString str;
906     str.Format(L"%.*f", 3, 1.12345);
907     EXPECT_EQ(L"1.123", str);
908   }
909 
910   {
911     CFX_WideString str;
912     str.Format(L"%f", 1.12345);
913     EXPECT_EQ(L"1.123450", str);
914   }
915 
916   {
917     CFX_WideString str;
918     str.Format(L"%-1f", 1.12345);
919     EXPECT_EQ(L"1.123450", str);
920   }
921 
922   {
923     CFX_WideString str;
924     str.Format(L"%0f", 1.12345);
925     EXPECT_EQ(L"1.123450", str);
926   }
927 
928   {
929     CFX_WideString str;
930     str.Format(L"%.1048576f", 1.2);
931     EXPECT_EQ(L"Bad precision", str);
932   }
933 }
934 
TEST(fxcrt,EmptyWideString)935 TEST(fxcrt, EmptyWideString) {
936   CFX_WideString empty_str;
937   EXPECT_TRUE(empty_str.IsEmpty());
938   EXPECT_EQ(0, empty_str.GetLength());
939   const FX_WCHAR* cstr = empty_str.c_str();
940   EXPECT_EQ(0, FXSYS_wcslen(cstr));
941 }
942