Home | History | Annotate | Download | only in fxcrt
      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/widestring.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "core/fxcrt/fx_string.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace fxcrt {
     14 
     15 TEST(WideString, ElementAccess) {
     16   const WideString abc(L"abc");
     17   EXPECT_EQ(L'a', abc[0]);
     18   EXPECT_EQ(L'b', abc[1]);
     19   EXPECT_EQ(L'c', abc[2]);
     20 #ifndef NDEBUG
     21   EXPECT_DEATH({ abc[4]; }, ".*");
     22 #endif
     23 
     24   WideString mutable_abc = abc;
     25   EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
     26   EXPECT_EQ(L'a', mutable_abc[0]);
     27   EXPECT_EQ(L'b', mutable_abc[1]);
     28   EXPECT_EQ(L'c', mutable_abc[2]);
     29   EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
     30   EXPECT_EQ(L"abc", abc);
     31 
     32   const wchar_t* c_str = abc.c_str();
     33   mutable_abc.SetAt(0, L'd');
     34   EXPECT_EQ(c_str, abc.c_str());
     35   EXPECT_NE(c_str, mutable_abc.c_str());
     36   EXPECT_EQ(L"abc", abc);
     37   EXPECT_EQ(L"dbc", mutable_abc);
     38 
     39   mutable_abc.SetAt(1, L'e');
     40   EXPECT_EQ(L"abc", abc);
     41   EXPECT_EQ(L"dec", mutable_abc);
     42 
     43   mutable_abc.SetAt(2, L'f');
     44   EXPECT_EQ(L"abc", abc);
     45   EXPECT_EQ(L"def", mutable_abc);
     46 #ifndef NDEBUG
     47   EXPECT_DEATH({ mutable_abc.SetAt(3, L'g'); }, ".*");
     48   EXPECT_EQ(L"abc", abc);
     49 #endif
     50 }
     51 
     52 TEST(WideString, OperatorLT) {
     53   WideString empty;
     54   WideString a(L"a");
     55   WideString abc(L"\x0110qq");  // Comes before despite endianness.
     56   WideString def(L"\x1001qq");  // Comes after despite endianness.
     57   WideStringView v_empty;
     58   WideStringView v_a(L"a");
     59   WideStringView v_abc(L"\x0110qq");
     60   WideStringView v_def(L"\x1001qq");
     61   const wchar_t* const c_null = nullptr;
     62   const wchar_t* const c_empty = L"";
     63   const wchar_t* const c_a = L"a";
     64   const wchar_t* const c_abc = L"\x0110qq";
     65   const wchar_t* const c_def = L"\x1001qq";
     66 
     67   EXPECT_FALSE(empty < empty);
     68   EXPECT_FALSE(a < a);
     69   EXPECT_FALSE(abc < abc);
     70   EXPECT_FALSE(def < def);
     71   EXPECT_FALSE(c_null < empty);
     72   EXPECT_FALSE(c_empty < empty);
     73   EXPECT_FALSE(c_a < a);
     74   EXPECT_FALSE(c_abc < abc);
     75   EXPECT_FALSE(c_def < def);
     76   EXPECT_FALSE(empty < c_null);
     77   EXPECT_FALSE(empty < c_empty);
     78   EXPECT_FALSE(a < c_a);
     79   EXPECT_FALSE(abc < c_abc);
     80   EXPECT_FALSE(def < c_def);
     81   EXPECT_FALSE(empty < v_empty);
     82   EXPECT_FALSE(a < v_a);
     83   EXPECT_FALSE(abc < v_abc);
     84   EXPECT_FALSE(def < v_def);
     85 
     86   EXPECT_TRUE(empty < a);
     87   EXPECT_FALSE(a < empty);
     88   EXPECT_TRUE(c_null < a);
     89   EXPECT_TRUE(c_empty < a);
     90   EXPECT_FALSE(c_a < empty);
     91   EXPECT_TRUE(empty < c_a);
     92   EXPECT_FALSE(a < c_null);
     93   EXPECT_FALSE(a < c_empty);
     94   EXPECT_TRUE(empty < v_a);
     95   EXPECT_FALSE(a < v_empty);
     96 
     97   EXPECT_TRUE(empty < abc);
     98   EXPECT_FALSE(abc < empty);
     99   EXPECT_TRUE(c_null < abc);
    100   EXPECT_TRUE(c_empty < abc);
    101   EXPECT_FALSE(c_abc < empty);
    102   EXPECT_TRUE(empty < c_abc);
    103   EXPECT_FALSE(abc < c_null);
    104   EXPECT_FALSE(abc < c_empty);
    105   EXPECT_TRUE(empty < v_abc);
    106   EXPECT_FALSE(abc < v_empty);
    107 
    108   EXPECT_TRUE(empty < def);
    109   EXPECT_FALSE(def < empty);
    110   EXPECT_TRUE(c_null < def);
    111   EXPECT_TRUE(c_empty < def);
    112   EXPECT_FALSE(c_def < empty);
    113   EXPECT_TRUE(empty < c_def);
    114   EXPECT_FALSE(def < c_null);
    115   EXPECT_FALSE(def < c_empty);
    116   EXPECT_TRUE(empty < v_def);
    117   EXPECT_FALSE(def < v_empty);
    118 
    119   EXPECT_TRUE(a < abc);
    120   EXPECT_FALSE(abc < a);
    121   EXPECT_TRUE(c_a < abc);
    122   EXPECT_FALSE(c_abc < a);
    123   EXPECT_TRUE(a < c_abc);
    124   EXPECT_FALSE(abc < c_a);
    125   EXPECT_TRUE(a < v_abc);
    126   EXPECT_FALSE(abc < v_a);
    127 
    128   EXPECT_TRUE(a < def);
    129   EXPECT_FALSE(def < a);
    130   EXPECT_TRUE(c_a < def);
    131   EXPECT_FALSE(c_def < a);
    132   EXPECT_TRUE(a < c_def);
    133   EXPECT_FALSE(def < c_a);
    134   EXPECT_TRUE(a < v_def);
    135   EXPECT_FALSE(def < v_a);
    136 
    137   EXPECT_TRUE(abc < def);
    138   EXPECT_FALSE(def < abc);
    139   EXPECT_TRUE(c_abc < def);
    140   EXPECT_FALSE(c_def < abc);
    141   EXPECT_TRUE(abc < c_def);
    142   EXPECT_FALSE(def < c_abc);
    143   EXPECT_TRUE(abc < v_def);
    144   EXPECT_FALSE(def < v_abc);
    145 }
    146 
    147 TEST(WideString, OperatorEQ) {
    148   WideString null_string;
    149   EXPECT_TRUE(null_string == null_string);
    150 
    151   WideString empty_string(L"");
    152   EXPECT_TRUE(empty_string == empty_string);
    153   EXPECT_TRUE(empty_string == null_string);
    154   EXPECT_TRUE(null_string == empty_string);
    155 
    156   WideString deleted_string(L"hello");
    157   deleted_string.Delete(0, 5);
    158   EXPECT_TRUE(deleted_string == deleted_string);
    159   EXPECT_TRUE(deleted_string == null_string);
    160   EXPECT_TRUE(deleted_string == empty_string);
    161   EXPECT_TRUE(null_string == deleted_string);
    162   EXPECT_TRUE(null_string == empty_string);
    163 
    164   WideString wide_string(L"hello");
    165   EXPECT_TRUE(wide_string == wide_string);
    166   EXPECT_FALSE(wide_string == null_string);
    167   EXPECT_FALSE(wide_string == empty_string);
    168   EXPECT_FALSE(wide_string == deleted_string);
    169   EXPECT_FALSE(null_string == wide_string);
    170   EXPECT_FALSE(empty_string == wide_string);
    171   EXPECT_FALSE(deleted_string == wide_string);
    172 
    173   WideString wide_string_same1(L"hello");
    174   EXPECT_TRUE(wide_string == wide_string_same1);
    175   EXPECT_TRUE(wide_string_same1 == wide_string);
    176 
    177   WideString wide_string_same2(wide_string);
    178   EXPECT_TRUE(wide_string == wide_string_same2);
    179   EXPECT_TRUE(wide_string_same2 == wide_string);
    180 
    181   WideString wide_string1(L"he");
    182   WideString wide_string2(L"hellp");
    183   WideString wide_string3(L"hellod");
    184   EXPECT_FALSE(wide_string == wide_string1);
    185   EXPECT_FALSE(wide_string == wide_string2);
    186   EXPECT_FALSE(wide_string == wide_string3);
    187   EXPECT_FALSE(wide_string1 == wide_string);
    188   EXPECT_FALSE(wide_string2 == wide_string);
    189   EXPECT_FALSE(wide_string3 == wide_string);
    190 
    191   WideStringView null_string_c;
    192   WideStringView empty_string_c(L"");
    193   EXPECT_TRUE(null_string == null_string_c);
    194   EXPECT_TRUE(null_string == empty_string_c);
    195   EXPECT_TRUE(empty_string == null_string_c);
    196   EXPECT_TRUE(empty_string == empty_string_c);
    197   EXPECT_TRUE(deleted_string == null_string_c);
    198   EXPECT_TRUE(deleted_string == empty_string_c);
    199   EXPECT_TRUE(null_string_c == null_string);
    200   EXPECT_TRUE(empty_string_c == null_string);
    201   EXPECT_TRUE(null_string_c == empty_string);
    202   EXPECT_TRUE(empty_string_c == empty_string);
    203   EXPECT_TRUE(null_string_c == deleted_string);
    204   EXPECT_TRUE(empty_string_c == deleted_string);
    205 
    206   WideStringView wide_string_c_same1(L"hello");
    207   EXPECT_TRUE(wide_string == wide_string_c_same1);
    208   EXPECT_TRUE(wide_string_c_same1 == wide_string);
    209 
    210   WideStringView wide_string_c1(L"he");
    211   WideStringView wide_string_c2(L"hellp");
    212   WideStringView wide_string_c3(L"hellod");
    213   EXPECT_FALSE(wide_string == wide_string_c1);
    214   EXPECT_FALSE(wide_string == wide_string_c2);
    215   EXPECT_FALSE(wide_string == wide_string_c3);
    216   EXPECT_FALSE(wide_string_c1 == wide_string);
    217   EXPECT_FALSE(wide_string_c2 == wide_string);
    218   EXPECT_FALSE(wide_string_c3 == wide_string);
    219 
    220   const wchar_t* const c_null_string = nullptr;
    221   const wchar_t* const c_empty_string = L"";
    222   EXPECT_TRUE(null_string == c_null_string);
    223   EXPECT_TRUE(null_string == c_empty_string);
    224   EXPECT_TRUE(empty_string == c_null_string);
    225   EXPECT_TRUE(empty_string == c_empty_string);
    226   EXPECT_TRUE(deleted_string == c_null_string);
    227   EXPECT_TRUE(deleted_string == c_empty_string);
    228   EXPECT_TRUE(c_null_string == null_string);
    229   EXPECT_TRUE(c_empty_string == null_string);
    230   EXPECT_TRUE(c_null_string == empty_string);
    231   EXPECT_TRUE(c_empty_string == empty_string);
    232   EXPECT_TRUE(c_null_string == deleted_string);
    233   EXPECT_TRUE(c_empty_string == deleted_string);
    234 
    235   const wchar_t* const c_string_same1 = L"hello";
    236   EXPECT_TRUE(wide_string == c_string_same1);
    237   EXPECT_TRUE(c_string_same1 == wide_string);
    238 
    239   const wchar_t* const c_string1 = L"he";
    240   const wchar_t* const c_string2 = L"hellp";
    241   const wchar_t* const c_string3 = L"hellod";
    242   EXPECT_FALSE(wide_string == c_string1);
    243   EXPECT_FALSE(wide_string == c_string2);
    244   EXPECT_FALSE(wide_string == c_string3);
    245   EXPECT_FALSE(c_string1 == wide_string);
    246   EXPECT_FALSE(c_string2 == wide_string);
    247   EXPECT_FALSE(c_string3 == wide_string);
    248 }
    249 
    250 TEST(WideString, OperatorNE) {
    251   WideString null_string;
    252   EXPECT_FALSE(null_string != null_string);
    253 
    254   WideString empty_string(L"");
    255   EXPECT_FALSE(empty_string != empty_string);
    256   EXPECT_FALSE(empty_string != null_string);
    257   EXPECT_FALSE(null_string != empty_string);
    258 
    259   WideString deleted_string(L"hello");
    260   deleted_string.Delete(0, 5);
    261   EXPECT_FALSE(deleted_string != deleted_string);
    262   EXPECT_FALSE(deleted_string != null_string);
    263   EXPECT_FALSE(deleted_string != empty_string);
    264   EXPECT_FALSE(null_string != deleted_string);
    265   EXPECT_FALSE(null_string != empty_string);
    266 
    267   WideString wide_string(L"hello");
    268   EXPECT_FALSE(wide_string != wide_string);
    269   EXPECT_TRUE(wide_string != null_string);
    270   EXPECT_TRUE(wide_string != empty_string);
    271   EXPECT_TRUE(wide_string != deleted_string);
    272   EXPECT_TRUE(null_string != wide_string);
    273   EXPECT_TRUE(empty_string != wide_string);
    274   EXPECT_TRUE(deleted_string != wide_string);
    275 
    276   WideString wide_string_same1(L"hello");
    277   EXPECT_FALSE(wide_string != wide_string_same1);
    278   EXPECT_FALSE(wide_string_same1 != wide_string);
    279 
    280   WideString wide_string_same2(wide_string);
    281   EXPECT_FALSE(wide_string != wide_string_same2);
    282   EXPECT_FALSE(wide_string_same2 != wide_string);
    283 
    284   WideString wide_string1(L"he");
    285   WideString wide_string2(L"hellp");
    286   WideString wide_string3(L"hellod");
    287   EXPECT_TRUE(wide_string != wide_string1);
    288   EXPECT_TRUE(wide_string != wide_string2);
    289   EXPECT_TRUE(wide_string != wide_string3);
    290   EXPECT_TRUE(wide_string1 != wide_string);
    291   EXPECT_TRUE(wide_string2 != wide_string);
    292   EXPECT_TRUE(wide_string3 != wide_string);
    293 
    294   WideStringView null_string_c;
    295   WideStringView empty_string_c(L"");
    296   EXPECT_FALSE(null_string != null_string_c);
    297   EXPECT_FALSE(null_string != empty_string_c);
    298   EXPECT_FALSE(empty_string != null_string_c);
    299   EXPECT_FALSE(empty_string != empty_string_c);
    300   EXPECT_FALSE(deleted_string != null_string_c);
    301   EXPECT_FALSE(deleted_string != empty_string_c);
    302   EXPECT_FALSE(null_string_c != null_string);
    303   EXPECT_FALSE(empty_string_c != null_string);
    304   EXPECT_FALSE(null_string_c != empty_string);
    305   EXPECT_FALSE(empty_string_c != empty_string);
    306 
    307   WideStringView wide_string_c_same1(L"hello");
    308   EXPECT_FALSE(wide_string != wide_string_c_same1);
    309   EXPECT_FALSE(wide_string_c_same1 != wide_string);
    310 
    311   WideStringView wide_string_c1(L"he");
    312   WideStringView wide_string_c2(L"hellp");
    313   WideStringView wide_string_c3(L"hellod");
    314   EXPECT_TRUE(wide_string != wide_string_c1);
    315   EXPECT_TRUE(wide_string != wide_string_c2);
    316   EXPECT_TRUE(wide_string != wide_string_c3);
    317   EXPECT_TRUE(wide_string_c1 != wide_string);
    318   EXPECT_TRUE(wide_string_c2 != wide_string);
    319   EXPECT_TRUE(wide_string_c3 != wide_string);
    320 
    321   const wchar_t* const c_null_string = nullptr;
    322   const wchar_t* const c_empty_string = L"";
    323   EXPECT_FALSE(null_string != c_null_string);
    324   EXPECT_FALSE(null_string != c_empty_string);
    325   EXPECT_FALSE(empty_string != c_null_string);
    326   EXPECT_FALSE(empty_string != c_empty_string);
    327   EXPECT_FALSE(deleted_string != c_null_string);
    328   EXPECT_FALSE(deleted_string != c_empty_string);
    329   EXPECT_FALSE(c_null_string != null_string);
    330   EXPECT_FALSE(c_empty_string != null_string);
    331   EXPECT_FALSE(c_null_string != empty_string);
    332   EXPECT_FALSE(c_empty_string != empty_string);
    333   EXPECT_FALSE(c_null_string != deleted_string);
    334   EXPECT_FALSE(c_empty_string != deleted_string);
    335 
    336   const wchar_t* const c_string_same1 = L"hello";
    337   EXPECT_FALSE(wide_string != c_string_same1);
    338   EXPECT_FALSE(c_string_same1 != wide_string);
    339 
    340   const wchar_t* const c_string1 = L"he";
    341   const wchar_t* const c_string2 = L"hellp";
    342   const wchar_t* const c_string3 = L"hellod";
    343   EXPECT_TRUE(wide_string != c_string1);
    344   EXPECT_TRUE(wide_string != c_string2);
    345   EXPECT_TRUE(wide_string != c_string3);
    346   EXPECT_TRUE(c_string1 != wide_string);
    347   EXPECT_TRUE(c_string2 != wide_string);
    348   EXPECT_TRUE(c_string3 != wide_string);
    349 }
    350 
    351 TEST(WideString, ConcatInPlace) {
    352   WideString fred;
    353   fred.Concat(L"FRED", 4);
    354   EXPECT_EQ(L"FRED", fred);
    355 
    356   fred.Concat(L"DY", 2);
    357   EXPECT_EQ(L"FREDDY", fred);
    358 
    359   fred.Delete(3, 3);
    360   EXPECT_EQ(L"FRE", fred);
    361 
    362   fred.Concat(L"D", 1);
    363   EXPECT_EQ(L"FRED", fred);
    364 
    365   WideString copy = fred;
    366   fred.Concat(L"DY", 2);
    367   EXPECT_EQ(L"FREDDY", fred);
    368   EXPECT_EQ(L"FRED", copy);
    369 }
    370 
    371 TEST(WideString, Remove) {
    372   WideString freed(L"FREED");
    373   freed.Remove(L'E');
    374   EXPECT_EQ(L"FRD", freed);
    375   freed.Remove(L'F');
    376   EXPECT_EQ(L"RD", freed);
    377   freed.Remove(L'D');
    378   EXPECT_EQ(L"R", freed);
    379   freed.Remove(L'X');
    380   EXPECT_EQ(L"R", freed);
    381   freed.Remove(L'R');
    382   EXPECT_EQ(L"", freed);
    383 
    384   WideString empty;
    385   empty.Remove(L'X');
    386   EXPECT_EQ(L"", empty);
    387 }
    388 
    389 TEST(WideString, RemoveCopies) {
    390   WideString freed(L"FREED");
    391   const wchar_t* old_buffer = freed.c_str();
    392 
    393   // No change with single reference - no copy.
    394   freed.Remove(L'Q');
    395   EXPECT_EQ(L"FREED", freed);
    396   EXPECT_EQ(old_buffer, freed.c_str());
    397 
    398   // Change with single reference - no copy.
    399   freed.Remove(L'E');
    400   EXPECT_EQ(L"FRD", freed);
    401   EXPECT_EQ(old_buffer, freed.c_str());
    402 
    403   // No change with multiple references - no copy.
    404   WideString shared(freed);
    405   freed.Remove(L'Q');
    406   EXPECT_EQ(L"FRD", freed);
    407   EXPECT_EQ(old_buffer, freed.c_str());
    408   EXPECT_EQ(old_buffer, shared.c_str());
    409 
    410   // Change with multiple references -- must copy.
    411   freed.Remove(L'D');
    412   EXPECT_EQ(L"FR", freed);
    413   EXPECT_NE(old_buffer, freed.c_str());
    414   EXPECT_EQ(L"FRD", shared);
    415   EXPECT_EQ(old_buffer, shared.c_str());
    416 }
    417 
    418 TEST(WideString, Replace) {
    419   WideString fred(L"FRED");
    420   fred.Replace(L"FR", L"BL");
    421   EXPECT_EQ(L"BLED", fred);
    422   fred.Replace(L"D", L"DDY");
    423   EXPECT_EQ(L"BLEDDY", fred);
    424   fred.Replace(L"LEDD", L"");
    425   EXPECT_EQ(L"BY", fred);
    426   fred.Replace(L"X", L"CLAMS");
    427   EXPECT_EQ(L"BY", fred);
    428   fred.Replace(L"BY", L"HI");
    429   EXPECT_EQ(L"HI", fred);
    430   fred.Replace(L"", L"CLAMS");
    431   EXPECT_EQ(L"HI", fred);
    432   fred.Replace(L"HI", L"");
    433   EXPECT_EQ(L"", fred);
    434 }
    435 
    436 TEST(WideString, Insert) {
    437   WideString fred(L"FRED");
    438   EXPECT_EQ(5u, fred.Insert(0, 'S'));
    439   EXPECT_EQ(L"SFRED", fred);
    440   EXPECT_EQ(6u, fred.Insert(1, 'T'));
    441   EXPECT_EQ(L"STFRED", fred);
    442   EXPECT_EQ(7u, fred.Insert(4, 'U'));
    443   EXPECT_EQ(L"STFRUED", fred);
    444   EXPECT_EQ(8u, fred.Insert(7, 'V'));
    445   EXPECT_EQ(L"STFRUEDV", fred);
    446   EXPECT_EQ(8u, fred.Insert(12, 'P'));
    447   EXPECT_EQ(L"STFRUEDV", fred);
    448   {
    449     WideString empty;
    450     EXPECT_EQ(1u, empty.Insert(0, 'X'));
    451     EXPECT_EQ(L"X", empty);
    452   }
    453   {
    454     WideString empty;
    455     EXPECT_EQ(0u, empty.Insert(5, 'X'));
    456     EXPECT_NE(L"X", empty);
    457   }
    458 }
    459 
    460 TEST(WideString, InsertAtFrontAndInsertAtBack) {
    461   {
    462     WideString empty;
    463     EXPECT_EQ(1u, empty.InsertAtFront('D'));
    464     EXPECT_EQ(L"D", empty);
    465     EXPECT_EQ(2u, empty.InsertAtFront('E'));
    466     EXPECT_EQ(L"ED", empty);
    467     EXPECT_EQ(3u, empty.InsertAtFront('R'));
    468     EXPECT_EQ(L"RED", empty);
    469     EXPECT_EQ(4u, empty.InsertAtFront('F'));
    470     EXPECT_EQ(L"FRED", empty);
    471   }
    472   {
    473     WideString empty;
    474     EXPECT_EQ(1u, empty.InsertAtBack('F'));
    475     EXPECT_EQ(L"F", empty);
    476     EXPECT_EQ(2u, empty.InsertAtBack('R'));
    477     EXPECT_EQ(L"FR", empty);
    478     EXPECT_EQ(3u, empty.InsertAtBack('E'));
    479     EXPECT_EQ(L"FRE", empty);
    480     EXPECT_EQ(4u, empty.InsertAtBack('D'));
    481     EXPECT_EQ(L"FRED", empty);
    482   }
    483   {
    484     WideString empty;
    485     EXPECT_EQ(1u, empty.InsertAtBack('E'));
    486     EXPECT_EQ(L"E", empty);
    487     EXPECT_EQ(2u, empty.InsertAtFront('R'));
    488     EXPECT_EQ(L"RE", empty);
    489     EXPECT_EQ(3u, empty.InsertAtBack('D'));
    490     EXPECT_EQ(L"RED", empty);
    491     EXPECT_EQ(4u, empty.InsertAtFront('F'));
    492     EXPECT_EQ(L"FRED", empty);
    493   }
    494 }
    495 
    496 TEST(WideString, Delete) {
    497   WideString fred(L"FRED");
    498   EXPECT_EQ(4u, fred.Delete(0, 0));
    499   EXPECT_EQ(L"FRED", fred);
    500   EXPECT_EQ(2u, fred.Delete(0, 2));
    501   EXPECT_EQ(L"ED", fred);
    502   EXPECT_EQ(1u, fred.Delete(1));
    503   EXPECT_EQ(L"E", fred);
    504   EXPECT_EQ(0u, fred.Delete(0));
    505   EXPECT_EQ(L"", fred);
    506   EXPECT_EQ(0u, fred.Delete(0));
    507   EXPECT_EQ(L"", fred);
    508 
    509   WideString empty;
    510   EXPECT_EQ(0u, empty.Delete(0));
    511   EXPECT_EQ(L"", empty);
    512   EXPECT_EQ(0u, empty.Delete(1));
    513   EXPECT_EQ(L"", empty);
    514 }
    515 
    516 TEST(WideString, Mid) {
    517   WideString fred(L"FRED");
    518   EXPECT_EQ(L"", fred.Mid(0, 0));
    519   EXPECT_EQ(L"", fred.Mid(3, 0));
    520   EXPECT_EQ(L"FRED", fred.Mid(0, 4));
    521   EXPECT_EQ(L"RED", fred.Mid(1, 3));
    522   EXPECT_EQ(L"ED", fred.Mid(2, 2));
    523   EXPECT_EQ(L"D", fred.Mid(3, 1));
    524   EXPECT_EQ(L"F", fred.Mid(0, 1));
    525   EXPECT_EQ(L"R", fred.Mid(1, 1));
    526   EXPECT_EQ(L"E", fred.Mid(2, 1));
    527   EXPECT_EQ(L"D", fred.Mid(3, 1));
    528   EXPECT_EQ(L"FR", fred.Mid(0, 2));
    529   EXPECT_EQ(L"FRED", fred.Mid(0, 4));
    530   EXPECT_EQ(L"", fred.Mid(0, 10));
    531 
    532   EXPECT_EQ(L"", fred.Mid(1, 4));
    533   EXPECT_EQ(L"", fred.Mid(4, 1));
    534 
    535   WideString empty;
    536   EXPECT_EQ(L"", empty.Mid(0, 0));
    537 }
    538 
    539 TEST(WideString, Left) {
    540   WideString fred(L"FRED");
    541   EXPECT_EQ(L"", fred.Left(0));
    542   EXPECT_EQ(L"F", fred.Left(1));
    543   EXPECT_EQ(L"FR", fred.Left(2));
    544   EXPECT_EQ(L"FRE", fred.Left(3));
    545   EXPECT_EQ(L"FRED", fred.Left(4));
    546 
    547   EXPECT_EQ(L"", fred.Left(5));
    548 
    549   WideString empty;
    550   EXPECT_EQ(L"", empty.Left(0));
    551   EXPECT_EQ(L"", empty.Left(1));
    552 }
    553 
    554 TEST(WideString, Right) {
    555   WideString fred(L"FRED");
    556   EXPECT_EQ(L"", fred.Right(0));
    557   EXPECT_EQ(L"D", fred.Right(1));
    558   EXPECT_EQ(L"ED", fred.Right(2));
    559   EXPECT_EQ(L"RED", fred.Right(3));
    560   EXPECT_EQ(L"FRED", fred.Right(4));
    561 
    562   EXPECT_EQ(L"", fred.Right(5));
    563 
    564   WideString empty;
    565   EXPECT_EQ(L"", empty.Right(0));
    566   EXPECT_EQ(L"", empty.Right(1));
    567 }
    568 
    569 TEST(WideString, Find) {
    570   WideString null_string;
    571   EXPECT_FALSE(null_string.Find(L'a').has_value());
    572   EXPECT_FALSE(null_string.Find(L'\0').has_value());
    573 
    574   WideString empty_string(L"");
    575   EXPECT_FALSE(empty_string.Find(L'a').has_value());
    576   EXPECT_FALSE(empty_string.Find(L'\0').has_value());
    577 
    578   Optional<size_t> result;
    579   WideString single_string(L"a");
    580   result = single_string.Find(L'a');
    581   ASSERT_TRUE(result.has_value());
    582   EXPECT_EQ(0u, result.value());
    583   EXPECT_FALSE(single_string.Find(L'b').has_value());
    584   EXPECT_FALSE(single_string.Find(L'\0').has_value());
    585 
    586   WideString longer_string(L"abccc");
    587   result = longer_string.Find(L'a');
    588   ASSERT_TRUE(result.has_value());
    589   EXPECT_EQ(0u, result.value());
    590   result = longer_string.Find(L'c');
    591   ASSERT_TRUE(result.has_value());
    592   EXPECT_EQ(2u, result.value());
    593   result = longer_string.Find(L'c', 3);
    594   ASSERT_TRUE(result.has_value());
    595   EXPECT_EQ(3u, result.value());
    596   EXPECT_FALSE(longer_string.Find(L'\0').has_value());
    597 
    598   result = longer_string.Find(L"ab");
    599   ASSERT_TRUE(result.has_value());
    600   EXPECT_EQ(0u, result.value());
    601   result = longer_string.Find(L"ccc");
    602   ASSERT_TRUE(result.has_value());
    603   EXPECT_EQ(2u, result.value());
    604   result = longer_string.Find(L"cc", 3);
    605   ASSERT_TRUE(result.has_value());
    606   EXPECT_EQ(3u, result.value());
    607   EXPECT_FALSE(longer_string.Find(L"d").has_value());
    608 
    609   WideString hibyte_string(
    610       L"ab\xff8c"
    611       L"def");
    612   result = hibyte_string.Find(L'\xff8c');
    613   ASSERT_TRUE(result.has_value());
    614   EXPECT_EQ(2u, result.value());
    615 }
    616 
    617 TEST(WideString, UpperLower) {
    618   WideString fred(L"F-Re.42D");
    619   fred.MakeLower();
    620   EXPECT_EQ(L"f-re.42d", fred);
    621   fred.MakeUpper();
    622   EXPECT_EQ(L"F-RE.42D", fred);
    623 
    624   WideString empty;
    625   empty.MakeLower();
    626   EXPECT_EQ(L"", empty);
    627   empty.MakeUpper();
    628   EXPECT_EQ(L"", empty);
    629 }
    630 
    631 TEST(WideString, Trim) {
    632   WideString fred(L"  FRED  ");
    633   fred.Trim();
    634   EXPECT_EQ(L"FRED", fred);
    635   fred.Trim(L'E');
    636   EXPECT_EQ(L"FRED", fred);
    637   fred.Trim(L'F');
    638   EXPECT_EQ(L"RED", fred);
    639   fred.Trim(L"ERP");
    640   EXPECT_EQ(L"D", fred);
    641 
    642   WideString blank(L"   ");
    643   blank.Trim(L"ERP");
    644   EXPECT_EQ(L"   ", blank);
    645   blank.Trim(L'E');
    646   EXPECT_EQ(L"   ", blank);
    647   blank.Trim();
    648   EXPECT_EQ(L"", blank);
    649 
    650   WideString empty;
    651   empty.Trim(L"ERP");
    652   EXPECT_EQ(L"", empty);
    653   empty.Trim(L'E');
    654   EXPECT_EQ(L"", empty);
    655   empty.Trim();
    656   EXPECT_EQ(L"", empty);
    657 
    658   WideString abc(L"  ABCCBA  ");
    659   abc.Trim(L"A");
    660   EXPECT_EQ(L"  ABCCBA  ", abc);
    661   abc.Trim(L" A");
    662   EXPECT_EQ(L"BCCB", abc);
    663 }
    664 
    665 TEST(WideString, TrimLeft) {
    666   WideString fred(L"  FRED  ");
    667   fred.TrimLeft();
    668   EXPECT_EQ(L"FRED  ", fred);
    669   fred.TrimLeft(L'E');
    670   EXPECT_EQ(L"FRED  ", fred);
    671   fred.TrimLeft(L'F');
    672   EXPECT_EQ(L"RED  ", fred);
    673   fred.TrimLeft(L"ERP");
    674   EXPECT_EQ(L"D  ", fred);
    675 
    676   WideString blank(L"   ");
    677   blank.TrimLeft(L"ERP");
    678   EXPECT_EQ(L"   ", blank);
    679   blank.TrimLeft(L'E');
    680   EXPECT_EQ(L"   ", blank);
    681   blank.TrimLeft();
    682   EXPECT_EQ(L"", blank);
    683 
    684   WideString empty;
    685   empty.TrimLeft(L"ERP");
    686   EXPECT_EQ(L"", empty);
    687   empty.TrimLeft(L'E');
    688   EXPECT_EQ(L"", empty);
    689   empty.TrimLeft();
    690   EXPECT_EQ(L"", empty);
    691 }
    692 
    693 TEST(WideString, TrimLeftCopies) {
    694   {
    695     // With a single reference, no copy takes place.
    696     WideString fred(L"  FRED  ");
    697     const wchar_t* old_buffer = fred.c_str();
    698     fred.TrimLeft();
    699     EXPECT_EQ(L"FRED  ", fred);
    700     EXPECT_EQ(old_buffer, fred.c_str());
    701   }
    702   {
    703     // With multiple references, we must copy.
    704     WideString fred(L"  FRED  ");
    705     WideString other_fred = fred;
    706     const wchar_t* old_buffer = fred.c_str();
    707     fred.TrimLeft();
    708     EXPECT_EQ(L"FRED  ", fred);
    709     EXPECT_EQ(L"  FRED  ", other_fred);
    710     EXPECT_NE(old_buffer, fred.c_str());
    711   }
    712   {
    713     // With multiple references, but no modifications, no copy.
    714     WideString fred(L"FRED");
    715     WideString other_fred = fred;
    716     const wchar_t* old_buffer = fred.c_str();
    717     fred.TrimLeft();
    718     EXPECT_EQ(L"FRED", fred);
    719     EXPECT_EQ(L"FRED", other_fred);
    720     EXPECT_EQ(old_buffer, fred.c_str());
    721   }
    722 }
    723 
    724 TEST(WideString, TrimRight) {
    725   WideString fred(L"  FRED  ");
    726   fred.TrimRight();
    727   EXPECT_EQ(L"  FRED", fred);
    728   fred.TrimRight(L'E');
    729   EXPECT_EQ(L"  FRED", fred);
    730   fred.TrimRight(L'D');
    731   EXPECT_EQ(L"  FRE", fred);
    732   fred.TrimRight(L"ERP");
    733   EXPECT_EQ(L"  F", fred);
    734 
    735   WideString blank(L"   ");
    736   blank.TrimRight(L"ERP");
    737   EXPECT_EQ(L"   ", blank);
    738   blank.TrimRight(L'E');
    739   EXPECT_EQ(L"   ", blank);
    740   blank.TrimRight();
    741   EXPECT_EQ(L"", blank);
    742 
    743   WideString empty;
    744   empty.TrimRight(L"ERP");
    745   EXPECT_EQ(L"", empty);
    746   empty.TrimRight(L'E');
    747   EXPECT_EQ(L"", empty);
    748   empty.TrimRight();
    749   EXPECT_EQ(L"", empty);
    750 }
    751 
    752 TEST(WideString, TrimRightCopies) {
    753   {
    754     // With a single reference, no copy takes place.
    755     WideString fred(L"  FRED  ");
    756     const wchar_t* old_buffer = fred.c_str();
    757     fred.TrimRight();
    758     EXPECT_EQ(L"  FRED", fred);
    759     EXPECT_EQ(old_buffer, fred.c_str());
    760   }
    761   {
    762     // With multiple references, we must copy.
    763     WideString fred(L"  FRED  ");
    764     WideString other_fred = fred;
    765     const wchar_t* old_buffer = fred.c_str();
    766     fred.TrimRight();
    767     EXPECT_EQ(L"  FRED", fred);
    768     EXPECT_EQ(L"  FRED  ", other_fred);
    769     EXPECT_NE(old_buffer, fred.c_str());
    770   }
    771   {
    772     // With multiple references, but no modifications, no copy.
    773     WideString fred(L"FRED");
    774     WideString other_fred = fred;
    775     const wchar_t* old_buffer = fred.c_str();
    776     fred.TrimRight();
    777     EXPECT_EQ(L"FRED", fred);
    778     EXPECT_EQ(L"FRED", other_fred);
    779     EXPECT_EQ(old_buffer, fred.c_str());
    780   }
    781 }
    782 
    783 TEST(WideString, Reserve) {
    784   {
    785     WideString str;
    786     str.Reserve(6);
    787     const wchar_t* old_buffer = str.c_str();
    788     str += L"ABCDEF";
    789     EXPECT_EQ(old_buffer, str.c_str());
    790     str += L"Blah Blah Blah Blah Blah Blah";
    791     EXPECT_NE(old_buffer, str.c_str());
    792   }
    793   {
    794     WideString str(L"A");
    795     str.Reserve(6);
    796     const wchar_t* old_buffer = str.c_str();
    797     str += L"BCDEF";
    798     EXPECT_EQ(old_buffer, str.c_str());
    799     str += L"Blah Blah Blah Blah Blah Blah";
    800     EXPECT_NE(old_buffer, str.c_str());
    801   }
    802 }
    803 
    804 TEST(WideString, GetBuffer) {
    805   {
    806     WideString str;
    807     wchar_t* buffer = str.GetBuffer(12);
    808     wcscpy(buffer, L"clams");
    809     str.ReleaseBuffer(str.GetStringLength());
    810     EXPECT_EQ(L"clams", str);
    811   }
    812   {
    813     WideString str(L"cl");
    814     wchar_t* buffer = str.GetBuffer(12);
    815     wcscpy(buffer + 2, L"ams");
    816     str.ReleaseBuffer(str.GetStringLength());
    817     EXPECT_EQ(L"clams", str);
    818   }
    819 }
    820 
    821 TEST(WideString, ReleaseBuffer) {
    822   {
    823     WideString str;
    824     str.Reserve(12);
    825     str += L"clams";
    826     const wchar_t* old_buffer = str.c_str();
    827     str.ReleaseBuffer(4);
    828     EXPECT_EQ(old_buffer, str.c_str());
    829     EXPECT_EQ(L"clam", str);
    830   }
    831   {
    832     WideString str(L"c");
    833     str.Reserve(12);
    834     str += L"lams";
    835     const wchar_t* old_buffer = str.c_str();
    836     str.ReleaseBuffer(4);
    837     EXPECT_EQ(old_buffer, str.c_str());
    838     EXPECT_EQ(L"clam", str);
    839   }
    840   {
    841     WideString str;
    842     str.Reserve(200);
    843     str += L"clams";
    844     const wchar_t* old_buffer = str.c_str();
    845     str.ReleaseBuffer(4);
    846     EXPECT_NE(old_buffer, str.c_str());
    847     EXPECT_EQ(L"clam", str);
    848   }
    849   {
    850     WideString str(L"c");
    851     str.Reserve(200);
    852     str += L"lams";
    853     const wchar_t* old_buffer = str.c_str();
    854     str.ReleaseBuffer(4);
    855     EXPECT_NE(old_buffer, str.c_str());
    856     EXPECT_EQ(L"clam", str);
    857   }
    858 }
    859 
    860 TEST(WideString, EmptyReverseIterator) {
    861   WideString empty;
    862   auto iter = empty.rbegin();
    863   EXPECT_TRUE(iter == empty.rend());
    864   EXPECT_FALSE(iter != empty.rend());
    865   EXPECT_FALSE(iter < empty.rend());
    866 }
    867 
    868 TEST(WideString, OneCharReverseIterator) {
    869   WideString one_str(L"a");
    870   auto iter = one_str.rbegin();
    871   EXPECT_FALSE(iter == one_str.rend());
    872   EXPECT_TRUE(iter != one_str.rend());
    873   EXPECT_TRUE(iter < one_str.rend());
    874 
    875   char ch = *iter++;
    876   EXPECT_EQ('a', ch);
    877   EXPECT_TRUE(iter == one_str.rend());
    878   EXPECT_FALSE(iter != one_str.rend());
    879   EXPECT_FALSE(iter < one_str.rend());
    880 }
    881 
    882 TEST(WideString, MultiCharReverseIterator) {
    883   WideString multi_str(L"abcd");
    884   auto iter = multi_str.rbegin();
    885   EXPECT_FALSE(iter == multi_str.rend());
    886 
    887   char ch = *iter++;
    888   EXPECT_EQ('d', ch);
    889   EXPECT_EQ('c', *iter);
    890   EXPECT_FALSE(iter == multi_str.rend());
    891 
    892   ch = *(++iter);
    893   EXPECT_EQ('b', ch);
    894   EXPECT_EQ('b', *iter);
    895   EXPECT_FALSE(iter == multi_str.rend());
    896 
    897   ch = *iter++;
    898   EXPECT_EQ('b', ch);
    899   EXPECT_EQ('a', *iter);
    900   EXPECT_FALSE(iter == multi_str.rend());
    901 
    902   ch = *iter++;
    903   EXPECT_EQ('a', ch);
    904   EXPECT_TRUE(iter == multi_str.rend());
    905 
    906   ch = *(--iter);
    907   EXPECT_EQ('a', ch);
    908   EXPECT_EQ('a', *iter);
    909   EXPECT_FALSE(iter == multi_str.rend());
    910 
    911   ch = *iter--;
    912   EXPECT_EQ('a', ch);
    913   EXPECT_EQ('b', *iter);
    914   EXPECT_FALSE(iter == multi_str.rend());
    915 
    916   ch = *iter--;
    917   EXPECT_EQ('b', ch);
    918   EXPECT_EQ('c', *iter);
    919   EXPECT_FALSE(iter == multi_str.rend());
    920 
    921   ch = *(--iter);
    922   EXPECT_EQ('d', ch);
    923   EXPECT_EQ('d', *iter);
    924   EXPECT_TRUE(iter == multi_str.rbegin());
    925 }
    926 
    927 TEST(WideString, UTF16LE_Encode) {
    928   struct UTF16LEEncodeCase {
    929     WideString ws;
    930     ByteString bs;
    931   } const utf16le_encode_cases[] = {
    932       {L"", ByteString("\0\0", 2)},
    933       {L"abc", ByteString("a\0b\0c\0\0\0", 8)},
    934       {L"abcdef", ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)},
    935       {L"abc\0def", ByteString("a\0b\0c\0\0\0", 8)},
    936       {L"\xaabb\xccdd", ByteString("\xbb\xaa\xdd\xcc\0\0", 6)},
    937       {L"\x3132\x6162", ByteString("\x32\x31\x62\x61\0\0", 6)},
    938   };
    939 
    940   for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) {
    941     EXPECT_EQ(utf16le_encode_cases[i].bs,
    942               utf16le_encode_cases[i].ws.UTF16LE_Encode())
    943         << " for case number " << i;
    944   }
    945 }
    946 
    947 TEST(WideStringView, FromVector) {
    948   std::vector<WideStringView::UnsignedType> null_vec;
    949   WideStringView null_string(null_vec);
    950   EXPECT_EQ(0u, null_string.GetLength());
    951 
    952   std::vector<WideStringView::UnsignedType> lower_a_vec(
    953       10, static_cast<WideStringView::UnsignedType>(L'a'));
    954   WideStringView lower_a_string(lower_a_vec);
    955   EXPECT_EQ(10u, lower_a_string.GetLength());
    956   EXPECT_EQ(L"aaaaaaaaaa", lower_a_string);
    957 
    958   std::vector<WideStringView::UnsignedType> cleared_vec;
    959   cleared_vec.push_back(42);
    960   cleared_vec.pop_back();
    961   WideStringView cleared_string(cleared_vec);
    962   EXPECT_EQ(0u, cleared_string.GetLength());
    963   EXPECT_EQ(nullptr, cleared_string.raw_str());
    964 }
    965 
    966 TEST(WideStringView, ElementAccess) {
    967   WideStringView abc(L"abc");
    968   EXPECT_EQ(L'a', static_cast<wchar_t>(abc[0]));
    969   EXPECT_EQ(L'b', static_cast<wchar_t>(abc[1]));
    970   EXPECT_EQ(L'c', static_cast<wchar_t>(abc[2]));
    971 #ifndef NDEBUG
    972   EXPECT_DEATH({ abc[4]; }, ".*");
    973 #endif
    974 }
    975 
    976 TEST(WideStringView, OperatorLT) {
    977   WideStringView empty;
    978   WideStringView a(L"a");
    979   WideStringView abc(L"\x0110qq");  // Comes InsertAtFront despite endianness.
    980   WideStringView def(L"\x1001qq");  // Comes InsertAtBack despite endianness.
    981   const wchar_t* const c_null = nullptr;
    982   const wchar_t* const c_empty = L"";
    983   const wchar_t* const c_a = L"a";
    984   const wchar_t* const c_abc = L"\x0110qq";
    985   const wchar_t* const c_def = L"\x1001qq";
    986 
    987   EXPECT_FALSE(empty < empty);
    988   EXPECT_FALSE(a < a);
    989   EXPECT_FALSE(abc < abc);
    990   EXPECT_FALSE(def < def);
    991   EXPECT_FALSE(c_null < empty);
    992   EXPECT_FALSE(c_empty < empty);
    993   EXPECT_FALSE(c_a < a);
    994   EXPECT_FALSE(c_abc < abc);
    995   EXPECT_FALSE(c_def < def);
    996   EXPECT_FALSE(empty < c_null);
    997   EXPECT_FALSE(empty < c_empty);
    998   EXPECT_FALSE(a < c_a);
    999   EXPECT_FALSE(abc < c_abc);
   1000   EXPECT_FALSE(def < c_def);
   1001 
   1002   EXPECT_TRUE(empty < a);
   1003   EXPECT_FALSE(a < empty);
   1004   EXPECT_TRUE(empty < c_a);
   1005   EXPECT_FALSE(a < c_null);
   1006   EXPECT_FALSE(a < c_empty);
   1007 
   1008   EXPECT_TRUE(empty < abc);
   1009   EXPECT_FALSE(abc < empty);
   1010   EXPECT_TRUE(empty < c_abc);
   1011   EXPECT_FALSE(abc < c_null);
   1012   EXPECT_FALSE(abc < c_empty);
   1013 
   1014   EXPECT_TRUE(empty < def);
   1015   EXPECT_FALSE(def < empty);
   1016   EXPECT_TRUE(empty < c_def);
   1017   EXPECT_FALSE(def < c_null);
   1018   EXPECT_FALSE(def < c_empty);
   1019 
   1020   EXPECT_TRUE(a < abc);
   1021   EXPECT_FALSE(abc < a);
   1022   EXPECT_TRUE(a < c_abc);
   1023   EXPECT_FALSE(abc < c_a);
   1024 
   1025   EXPECT_TRUE(a < def);
   1026   EXPECT_FALSE(def < a);
   1027   EXPECT_TRUE(a < c_def);
   1028   EXPECT_FALSE(def < c_a);
   1029 
   1030   EXPECT_TRUE(abc < def);
   1031   EXPECT_FALSE(def < abc);
   1032   EXPECT_TRUE(abc < c_def);
   1033   EXPECT_FALSE(def < c_abc);
   1034 }
   1035 
   1036 TEST(WideStringView, OperatorEQ) {
   1037   WideStringView wide_string_c(L"hello");
   1038   EXPECT_TRUE(wide_string_c == wide_string_c);
   1039 
   1040   WideStringView wide_string_c_same1(L"hello");
   1041   EXPECT_TRUE(wide_string_c == wide_string_c_same1);
   1042   EXPECT_TRUE(wide_string_c_same1 == wide_string_c);
   1043 
   1044   WideStringView wide_string_c_same2(wide_string_c);
   1045   EXPECT_TRUE(wide_string_c == wide_string_c_same2);
   1046   EXPECT_TRUE(wide_string_c_same2 == wide_string_c);
   1047 
   1048   WideStringView wide_string_c1(L"he");
   1049   WideStringView wide_string_c2(L"hellp");
   1050   WideStringView wide_string_c3(L"hellod");
   1051   EXPECT_FALSE(wide_string_c == wide_string_c1);
   1052   EXPECT_FALSE(wide_string_c == wide_string_c2);
   1053   EXPECT_FALSE(wide_string_c == wide_string_c3);
   1054   EXPECT_FALSE(wide_string_c1 == wide_string_c);
   1055   EXPECT_FALSE(wide_string_c2 == wide_string_c);
   1056   EXPECT_FALSE(wide_string_c3 == wide_string_c);
   1057 
   1058   WideString wide_string_same1(L"hello");
   1059   EXPECT_TRUE(wide_string_c == wide_string_same1);
   1060   EXPECT_TRUE(wide_string_same1 == wide_string_c);
   1061 
   1062   WideString wide_string1(L"he");
   1063   WideString wide_string2(L"hellp");
   1064   WideString wide_string3(L"hellod");
   1065   EXPECT_FALSE(wide_string_c == wide_string1);
   1066   EXPECT_FALSE(wide_string_c == wide_string2);
   1067   EXPECT_FALSE(wide_string_c == wide_string3);
   1068   EXPECT_FALSE(wide_string1 == wide_string_c);
   1069   EXPECT_FALSE(wide_string2 == wide_string_c);
   1070   EXPECT_FALSE(wide_string3 == wide_string_c);
   1071 
   1072   const wchar_t* const c_string_same1 = L"hello";
   1073   EXPECT_TRUE(wide_string_c == c_string_same1);
   1074   EXPECT_TRUE(c_string_same1 == wide_string_c);
   1075 
   1076   const wchar_t* const c_string1 = L"he";
   1077   const wchar_t* const c_string2 = L"hellp";
   1078   const wchar_t* const c_string3 = L"hellod";
   1079   EXPECT_FALSE(wide_string_c == c_string1);
   1080   EXPECT_FALSE(wide_string_c == c_string2);
   1081   EXPECT_FALSE(wide_string_c == c_string3);
   1082 
   1083   EXPECT_FALSE(c_string1 == wide_string_c);
   1084   EXPECT_FALSE(c_string2 == wide_string_c);
   1085   EXPECT_FALSE(c_string3 == wide_string_c);
   1086 }
   1087 
   1088 TEST(WideStringView, OperatorNE) {
   1089   WideStringView wide_string_c(L"hello");
   1090   EXPECT_FALSE(wide_string_c != wide_string_c);
   1091 
   1092   WideStringView wide_string_c_same1(L"hello");
   1093   EXPECT_FALSE(wide_string_c != wide_string_c_same1);
   1094   EXPECT_FALSE(wide_string_c_same1 != wide_string_c);
   1095 
   1096   WideStringView wide_string_c_same2(wide_string_c);
   1097   EXPECT_FALSE(wide_string_c != wide_string_c_same2);
   1098   EXPECT_FALSE(wide_string_c_same2 != wide_string_c);
   1099 
   1100   WideStringView wide_string_c1(L"he");
   1101   WideStringView wide_string_c2(L"hellp");
   1102   WideStringView wide_string_c3(L"hellod");
   1103   EXPECT_TRUE(wide_string_c != wide_string_c1);
   1104   EXPECT_TRUE(wide_string_c != wide_string_c2);
   1105   EXPECT_TRUE(wide_string_c != wide_string_c3);
   1106   EXPECT_TRUE(wide_string_c1 != wide_string_c);
   1107   EXPECT_TRUE(wide_string_c2 != wide_string_c);
   1108   EXPECT_TRUE(wide_string_c3 != wide_string_c);
   1109 
   1110   WideString wide_string_same1(L"hello");
   1111   EXPECT_FALSE(wide_string_c != wide_string_same1);
   1112   EXPECT_FALSE(wide_string_same1 != wide_string_c);
   1113 
   1114   WideString wide_string1(L"he");
   1115   WideString wide_string2(L"hellp");
   1116   WideString wide_string3(L"hellod");
   1117   EXPECT_TRUE(wide_string_c != wide_string1);
   1118   EXPECT_TRUE(wide_string_c != wide_string2);
   1119   EXPECT_TRUE(wide_string_c != wide_string3);
   1120   EXPECT_TRUE(wide_string1 != wide_string_c);
   1121   EXPECT_TRUE(wide_string2 != wide_string_c);
   1122   EXPECT_TRUE(wide_string3 != wide_string_c);
   1123 
   1124   const wchar_t* const c_string_same1 = L"hello";
   1125   EXPECT_FALSE(wide_string_c != c_string_same1);
   1126   EXPECT_FALSE(c_string_same1 != wide_string_c);
   1127 
   1128   const wchar_t* const c_string1 = L"he";
   1129   const wchar_t* const c_string2 = L"hellp";
   1130   const wchar_t* const c_string3 = L"hellod";
   1131   EXPECT_TRUE(wide_string_c != c_string1);
   1132   EXPECT_TRUE(wide_string_c != c_string2);
   1133   EXPECT_TRUE(wide_string_c != c_string3);
   1134 
   1135   EXPECT_TRUE(c_string1 != wide_string_c);
   1136   EXPECT_TRUE(c_string2 != wide_string_c);
   1137   EXPECT_TRUE(c_string3 != wide_string_c);
   1138 }
   1139 
   1140 TEST(WideStringView, Find) {
   1141   WideStringView null_string;
   1142   EXPECT_FALSE(null_string.Find(L'a').has_value());
   1143   EXPECT_FALSE(null_string.Find(L'\0').has_value());
   1144 
   1145   WideStringView empty_string(L"");
   1146   EXPECT_FALSE(empty_string.Find(L'a').has_value());
   1147   EXPECT_FALSE(empty_string.Find(L'\0').has_value());
   1148 
   1149   Optional<size_t> result;
   1150   WideStringView single_string(L"a");
   1151   result = single_string.Find(L'a');
   1152   ASSERT_TRUE(result.has_value());
   1153   EXPECT_EQ(0u, result.value());
   1154   EXPECT_FALSE(single_string.Find(L'b').has_value());
   1155   EXPECT_FALSE(single_string.Find(L'\0').has_value());
   1156 
   1157   WideStringView longer_string(L"abccc");
   1158   result = longer_string.Find(L'a');
   1159   ASSERT_TRUE(result.has_value());
   1160   EXPECT_EQ(0u, result.value());
   1161   result = longer_string.Find(L'c');
   1162   ASSERT_TRUE(result.has_value());
   1163   EXPECT_EQ(2u, result.value());
   1164   EXPECT_FALSE(longer_string.Find(L'd').has_value());
   1165   EXPECT_FALSE(longer_string.Find(L'\0').has_value());
   1166 
   1167   WideStringView hibyte_string(
   1168       L"ab\xFF8c"
   1169       L"def");
   1170   result = hibyte_string.Find(L'\xFF8c');
   1171   ASSERT_TRUE(result.has_value());
   1172   EXPECT_EQ(2u, result.value());
   1173 }
   1174 
   1175 TEST(WideStringView, NullIterator) {
   1176   WideStringView null_str;
   1177   int32_t sum = 0;
   1178   bool any_present = false;
   1179   for (const auto& c : null_str) {
   1180     sum += c;  // Avoid unused arg warnings.
   1181     any_present = true;
   1182   }
   1183   EXPECT_FALSE(any_present);
   1184   EXPECT_EQ(0, sum);
   1185 }
   1186 
   1187 TEST(WideStringView, EmptyIterator) {
   1188   WideStringView empty_str(L"");
   1189   int32_t sum = 0;
   1190   bool any_present = false;
   1191   for (const auto& c : empty_str) {
   1192     any_present = true;
   1193     sum += c;  // Avoid unused arg warnings.
   1194   }
   1195   EXPECT_FALSE(any_present);
   1196   EXPECT_EQ(0, sum);
   1197 }
   1198 
   1199 TEST(WideStringView, OneCharIterator) {
   1200   WideStringView one_str(L"a");
   1201   int32_t sum = 0;
   1202   bool any_present = false;
   1203   for (const auto& c : one_str) {
   1204     any_present = true;
   1205     sum += c;  // Avoid unused arg warnings.
   1206   }
   1207   EXPECT_TRUE(any_present);
   1208   EXPECT_EQ(static_cast<int32_t>(L'a'), sum);
   1209 }
   1210 
   1211 TEST(WideStringView, MultiCharIterator) {
   1212   WideStringView one_str(L"abc");
   1213   int32_t sum = 0;
   1214   bool any_present = false;
   1215   for (const auto& c : one_str) {
   1216     any_present = true;
   1217     sum += c;  // Avoid unused arg warnings.
   1218   }
   1219   EXPECT_TRUE(any_present);
   1220   EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum);
   1221 }
   1222 
   1223 TEST(WideStringView, EmptyReverseIterator) {
   1224   WideStringView empty;
   1225   auto iter = empty.rbegin();
   1226   EXPECT_TRUE(iter == empty.rend());
   1227   EXPECT_FALSE(iter != empty.rend());
   1228   EXPECT_FALSE(iter < empty.rend());
   1229 }
   1230 
   1231 TEST(WideStringView, OneCharReverseIterator) {
   1232   WideStringView one_str(L"a");
   1233   auto iter = one_str.rbegin();
   1234   EXPECT_FALSE(iter == one_str.rend());
   1235   EXPECT_TRUE(iter != one_str.rend());
   1236   EXPECT_TRUE(iter < one_str.rend());
   1237 
   1238   char ch = *iter++;
   1239   EXPECT_EQ('a', ch);
   1240   EXPECT_TRUE(iter == one_str.rend());
   1241   EXPECT_FALSE(iter != one_str.rend());
   1242   EXPECT_FALSE(iter < one_str.rend());
   1243 }
   1244 
   1245 TEST(WideStringView, MultiCharReverseIterator) {
   1246   WideStringView multi_str(L"abcd");
   1247   auto iter = multi_str.rbegin();
   1248   EXPECT_FALSE(iter == multi_str.rend());
   1249 
   1250   char ch = *iter++;
   1251   EXPECT_EQ('d', ch);
   1252   EXPECT_EQ('c', *iter);
   1253   EXPECT_FALSE(iter == multi_str.rend());
   1254 
   1255   ch = *(++iter);
   1256   EXPECT_EQ('b', ch);
   1257   EXPECT_EQ('b', *iter);
   1258   EXPECT_FALSE(iter == multi_str.rend());
   1259 
   1260   ch = *iter++;
   1261   EXPECT_EQ('b', ch);
   1262   EXPECT_EQ('a', *iter);
   1263   EXPECT_FALSE(iter == multi_str.rend());
   1264 
   1265   ch = *iter++;
   1266   EXPECT_EQ('a', ch);
   1267   EXPECT_TRUE(iter == multi_str.rend());
   1268 
   1269   ch = *(--iter);
   1270   EXPECT_EQ('a', ch);
   1271   EXPECT_EQ('a', *iter);
   1272   EXPECT_FALSE(iter == multi_str.rend());
   1273 
   1274   ch = *iter--;
   1275   EXPECT_EQ('a', ch);
   1276   EXPECT_EQ('b', *iter);
   1277   EXPECT_FALSE(iter == multi_str.rend());
   1278 
   1279   ch = *iter--;
   1280   EXPECT_EQ('b', ch);
   1281   EXPECT_EQ('c', *iter);
   1282   EXPECT_FALSE(iter == multi_str.rend());
   1283 
   1284   ch = *(--iter);
   1285   EXPECT_EQ('d', ch);
   1286   EXPECT_EQ('d', *iter);
   1287   EXPECT_TRUE(iter == multi_str.rbegin());
   1288 }
   1289 
   1290 TEST(WideStringView, AnyAllNoneOf) {
   1291   WideStringView str(L"aaaaaaaaaaaaaaaaab");
   1292   EXPECT_FALSE(std::all_of(str.begin(), str.end(),
   1293                            [](const wchar_t& c) { return c == L'a'; }));
   1294 
   1295   EXPECT_FALSE(std::none_of(str.begin(), str.end(),
   1296                             [](const wchar_t& c) { return c == L'a'; }));
   1297 
   1298   EXPECT_TRUE(std::any_of(str.begin(), str.end(),
   1299                           [](const wchar_t& c) { return c == L'a'; }));
   1300 
   1301   EXPECT_TRUE(pdfium::ContainsValue(str, L'a'));
   1302   EXPECT_TRUE(pdfium::ContainsValue(str, L'b'));
   1303   EXPECT_FALSE(pdfium::ContainsValue(str, L'z'));
   1304 }
   1305 
   1306 TEST(WideStringView, TrimmedRight) {
   1307   WideStringView fred(L"FRED");
   1308   EXPECT_EQ(L"FRED", fred.TrimmedRight(L'E'));
   1309   EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D'));
   1310   WideStringView fredd(L"FREDD");
   1311   EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D'));
   1312 }
   1313 
   1314 TEST(WideString, FormatWidth) {
   1315   EXPECT_EQ(L"    1", WideString::Format(L"%5d", 1));
   1316   EXPECT_EQ(L"1", WideString::Format(L"%d", 1));
   1317   EXPECT_EQ(L"    1", WideString::Format(L"%*d", 5, 1));
   1318   EXPECT_EQ(L"1", WideString::Format(L"%-1d", 1));
   1319   EXPECT_EQ(L"1", WideString::Format(L"%0d", 1));
   1320   EXPECT_EQ(L"", WideString::Format(L"%1048576d", 1));
   1321 }
   1322 
   1323 TEST(WideString, FormatPrecision) {
   1324   EXPECT_EQ(L"1.12", WideString::Format(L"%.2f", 1.12345));
   1325   EXPECT_EQ(L"1.123", WideString::Format(L"%.*f", 3, 1.12345));
   1326   EXPECT_EQ(L"1.123450", WideString::Format(L"%f", 1.12345));
   1327   EXPECT_EQ(L"1.123450", WideString::Format(L"%-1f", 1.12345));
   1328   EXPECT_EQ(L"1.123450", WideString::Format(L"%0f", 1.12345));
   1329   EXPECT_EQ(L"", WideString::Format(L"%.1048576f", 1.2));
   1330 }
   1331 
   1332 TEST(WideString, FormatOutOfRangeChar) {
   1333   EXPECT_NE(L"", WideString::Format(L"unsupported char '%c'", 0x00FF00FF));
   1334 }
   1335 
   1336 TEST(WideString, Empty) {
   1337   WideString empty_str;
   1338   EXPECT_TRUE(empty_str.IsEmpty());
   1339   EXPECT_EQ(0u, empty_str.GetLength());
   1340   const wchar_t* cstr = empty_str.c_str();
   1341   EXPECT_EQ(0u, wcslen(cstr));
   1342 }
   1343 
   1344 TEST(CFX_WidString, InitializerList) {
   1345   WideString many_str({L"clams", L" and ", L"oysters"});
   1346   EXPECT_EQ(L"clams and oysters", many_str);
   1347   many_str = {L"fish", L" and ", L"chips", L" and ", L"soda"};
   1348   EXPECT_EQ(L"fish and chips and soda", many_str);
   1349 }
   1350 
   1351 TEST(WideString, NullIterator) {
   1352   WideString null_str;
   1353   int32_t sum = 0;
   1354   bool any_present = false;
   1355   for (const auto& c : null_str) {
   1356     sum += c;  // Avoid unused arg warnings.
   1357     any_present = true;
   1358   }
   1359   EXPECT_FALSE(any_present);
   1360   EXPECT_EQ(0, sum);
   1361 }
   1362 
   1363 TEST(WideString, EmptyIterator) {
   1364   WideString empty_str(L"");
   1365   int32_t sum = 0;
   1366   bool any_present = false;
   1367   for (const auto& c : empty_str) {
   1368     any_present = true;
   1369     sum += c;  // Avoid unused arg warnings.
   1370   }
   1371   EXPECT_FALSE(any_present);
   1372   EXPECT_EQ(0, sum);
   1373 }
   1374 
   1375 TEST(WideString, OneCharIterator) {
   1376   WideString one_str(L"a");
   1377   int32_t sum = 0;
   1378   bool any_present = false;
   1379   for (const auto& c : one_str) {
   1380     any_present = true;
   1381     sum += c;  // Avoid unused arg warnings.
   1382   }
   1383   EXPECT_TRUE(any_present);
   1384   EXPECT_EQ(static_cast<int32_t>(L'a'), sum);
   1385 }
   1386 
   1387 TEST(WideString, MultiCharIterator) {
   1388   WideString one_str(L"abc");
   1389   int32_t sum = 0;
   1390   bool any_present = false;
   1391   for (const auto& c : one_str) {
   1392     any_present = true;
   1393     sum += c;  // Avoid unused arg warnings.
   1394   }
   1395   EXPECT_TRUE(any_present);
   1396   EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum);
   1397 }
   1398 
   1399 TEST(WideString, AnyAllNoneOf) {
   1400   WideString str(L"aaaaaaaaaaaaaaaaab");
   1401   EXPECT_FALSE(std::all_of(str.begin(), str.end(),
   1402                            [](const wchar_t& c) { return c == L'a'; }));
   1403 
   1404   EXPECT_FALSE(std::none_of(str.begin(), str.end(),
   1405                             [](const wchar_t& c) { return c == L'a'; }));
   1406 
   1407   EXPECT_TRUE(std::any_of(str.begin(), str.end(),
   1408                           [](const wchar_t& c) { return c == L'a'; }));
   1409 
   1410   EXPECT_TRUE(pdfium::ContainsValue(str, L'a'));
   1411   EXPECT_TRUE(pdfium::ContainsValue(str, L'b'));
   1412   EXPECT_FALSE(pdfium::ContainsValue(str, L'z'));
   1413 }
   1414 
   1415 TEST(WideString, OStreamOverload) {
   1416   std::ostringstream stream;
   1417 
   1418   // Basic case, empty string
   1419   WideString str;
   1420   stream << str;
   1421   EXPECT_EQ("", stream.str());
   1422 
   1423   // Basic case, wide character
   1424   str = L"\u20AC";
   1425   stream << str;
   1426   EXPECT_EQ("\u20AC", stream.str());
   1427 
   1428   // Basic case, non-empty string
   1429   str = L"def";
   1430   stream.str("");
   1431   stream << "abc" << str << "ghi";
   1432   EXPECT_EQ("abcdefghi", stream.str());
   1433 
   1434   // Changing the WideString does not change the stream it was written to.
   1435   str = L"123";
   1436   EXPECT_EQ("abcdefghi", stream.str());
   1437 
   1438   // Writing it again to the stream will use the latest value.
   1439   stream.str("");
   1440   stream << "abc" << str << "ghi";
   1441   EXPECT_EQ("abc123ghi", stream.str());
   1442 
   1443   wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1444 
   1445   // Writing a WideString with nulls and no specified length treats it as
   1446   // a C-style null-terminated string.
   1447   str = WideString(stringWithNulls);
   1448   EXPECT_EQ(2u, str.GetLength());
   1449   stream.str("");
   1450   stream << str;
   1451   EXPECT_EQ(2u, stream.tellp());
   1452 
   1453   // Writing a WideString with nulls but specifying its length treats it as
   1454   // a C++-style string.
   1455   str = WideString(stringWithNulls, 4);
   1456   EXPECT_EQ(4u, str.GetLength());
   1457   stream.str("");
   1458   stream << str;
   1459   EXPECT_EQ(4u, stream.tellp());
   1460 
   1461   // << operators can be chained.
   1462   WideString str1(L"abc");
   1463   WideString str2(L"def");
   1464   stream.str("");
   1465   stream << str1 << str2;
   1466   EXPECT_EQ("abcdef", stream.str());
   1467 }
   1468 
   1469 TEST(WideString, WideOStreamOverload) {
   1470   std::wostringstream stream;
   1471 
   1472   // Basic case, empty string
   1473   WideString str;
   1474   stream << str;
   1475   EXPECT_EQ(L"", stream.str());
   1476 
   1477   // Basic case, wide character
   1478   str = L"\u20AC";
   1479   stream << str;
   1480   EXPECT_EQ(L"\u20AC", stream.str());
   1481 
   1482   // Basic case, non-empty string
   1483   str = L"def";
   1484   stream.str(L"");
   1485   stream << L"abc" << str << L"ghi";
   1486   EXPECT_EQ(L"abcdefghi", stream.str());
   1487 
   1488   // Changing the WideString does not change the stream it was written to.
   1489   str = L"123";
   1490   EXPECT_EQ(L"abcdefghi", stream.str());
   1491 
   1492   // Writing it again to the stream will use the latest value.
   1493   stream.str(L"");
   1494   stream << L"abc" << str << L"ghi";
   1495   EXPECT_EQ(L"abc123ghi", stream.str());
   1496 
   1497   wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1498 
   1499   // Writing a WideString with nulls and no specified length treats it as
   1500   // a C-style null-terminated string.
   1501   str = WideString(stringWithNulls);
   1502   EXPECT_EQ(2u, str.GetLength());
   1503   stream.str(L"");
   1504   stream << str;
   1505   EXPECT_EQ(2u, stream.tellp());
   1506 
   1507   // Writing a WideString with nulls but specifying its length treats it as
   1508   // a C++-style string.
   1509   str = WideString(stringWithNulls, 4);
   1510   EXPECT_EQ(4u, str.GetLength());
   1511   stream.str(L"");
   1512   stream << str;
   1513   EXPECT_EQ(4u, stream.tellp());
   1514 
   1515   // << operators can be chained.
   1516   WideString str1(L"abc");
   1517   WideString str2(L"def");
   1518   stream.str(L"");
   1519   stream << str1 << str2;
   1520   EXPECT_EQ(L"abcdef", stream.str());
   1521 }
   1522 
   1523 TEST(WideStringView, OStreamOverload) {
   1524   // Basic case, empty string
   1525   {
   1526     std::ostringstream stream;
   1527     WideStringView str;
   1528     stream << str;
   1529     EXPECT_EQ("", stream.str());
   1530   }
   1531 
   1532   // Basic case, non-empty string
   1533   {
   1534     std::ostringstream stream;
   1535     WideStringView str(L"def");
   1536     stream << "abc" << str << "ghi";
   1537     EXPECT_EQ("abcdefghi", stream.str());
   1538   }
   1539 
   1540   // Basic case, wide character
   1541   {
   1542     std::ostringstream stream;
   1543     WideStringView str(L"\u20AC");
   1544     stream << str;
   1545     EXPECT_EQ("\u20AC", stream.str());
   1546   }
   1547 
   1548   // Changing the WideStringView does not change the stream it was written to.
   1549   {
   1550     std::ostringstream stream;
   1551     WideStringView str(L"abc");
   1552     stream << str;
   1553     str = L"123";
   1554     EXPECT_EQ("abc", stream.str());
   1555   }
   1556 
   1557   // Writing it again to the stream will use the latest value.
   1558   {
   1559     std::ostringstream stream;
   1560     WideStringView str(L"abc");
   1561     stream << str;
   1562     stream.str("");
   1563     str = L"123";
   1564     stream << str;
   1565     EXPECT_EQ("123", stream.str());
   1566   }
   1567 
   1568   // Writing a WideStringView with nulls and no specified length treats it as
   1569   // a C-style null-terminated string.
   1570   {
   1571     wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1572     std::ostringstream stream;
   1573     WideStringView str(stringWithNulls);
   1574     EXPECT_EQ(2u, str.GetLength());
   1575     stream << str;
   1576     EXPECT_EQ(2u, stream.tellp());
   1577     str = L"";
   1578   }
   1579 
   1580   // Writing a WideStringView with nulls but specifying its length treats it as
   1581   // a C++-style string.
   1582   {
   1583     wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1584     std::ostringstream stream;
   1585     WideStringView str(stringWithNulls, 4);
   1586     EXPECT_EQ(4u, str.GetLength());
   1587     stream << str;
   1588     EXPECT_EQ(4u, stream.tellp());
   1589     str = L"";
   1590   }
   1591 
   1592   // << operators can be chained.
   1593   {
   1594     std::ostringstream stream;
   1595     WideStringView str1(L"abc");
   1596     WideStringView str2(L"def");
   1597     stream << str1 << str2;
   1598     EXPECT_EQ("abcdef", stream.str());
   1599   }
   1600 }
   1601 
   1602 TEST(WideStringView, WideOStreamOverload) {
   1603   // Basic case, empty string
   1604   {
   1605     std::wostringstream stream;
   1606     WideStringView str;
   1607     stream << str;
   1608     EXPECT_EQ(L"", stream.str());
   1609   }
   1610 
   1611   // Basic case, non-empty string
   1612   {
   1613     std::wostringstream stream;
   1614     WideStringView str(L"def");
   1615     stream << "abc" << str << "ghi";
   1616     EXPECT_EQ(L"abcdefghi", stream.str());
   1617   }
   1618 
   1619   // Basic case, wide character
   1620   {
   1621     std::wostringstream stream;
   1622     WideStringView str(L"\u20AC");
   1623     stream << str;
   1624     EXPECT_EQ(L"\u20AC", stream.str());
   1625   }
   1626 
   1627   // Changing the WideStringView does not change the stream it was written to.
   1628   {
   1629     std::wostringstream stream;
   1630     WideStringView str(L"abc");
   1631     stream << str;
   1632     str = L"123";
   1633     EXPECT_EQ(L"abc", stream.str());
   1634   }
   1635 
   1636   // Writing it again to the stream will use the latest value.
   1637   {
   1638     std::wostringstream stream;
   1639     WideStringView str(L"abc");
   1640     stream << str;
   1641     stream.str(L"");
   1642     str = L"123";
   1643     stream << str;
   1644     EXPECT_EQ(L"123", stream.str());
   1645   }
   1646 
   1647   // Writing a WideStringView with nulls and no specified length treats it as
   1648   // a C-style null-terminated string.
   1649   {
   1650     wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1651     std::wostringstream stream;
   1652     WideStringView str(stringWithNulls);
   1653     EXPECT_EQ(2u, str.GetLength());
   1654     stream << str;
   1655     EXPECT_EQ(2u, stream.tellp());
   1656   }
   1657 
   1658   // Writing a WideStringView with nulls but specifying its length treats it as
   1659   // a C++-style string.
   1660   {
   1661     wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
   1662     std::wostringstream stream;
   1663     WideStringView str(stringWithNulls, 4);
   1664     EXPECT_EQ(4u, str.GetLength());
   1665     stream << str;
   1666     EXPECT_EQ(4u, stream.tellp());
   1667   }
   1668 
   1669   // << operators can be chained.
   1670   {
   1671     std::wostringstream stream;
   1672     WideStringView str1(L"abc");
   1673     WideStringView str2(L"def");
   1674     stream << str1 << str2;
   1675     EXPECT_EQ(L"abcdef", stream.str());
   1676   }
   1677 }
   1678 
   1679 }  // namespace fxcrt
   1680