Add ability to append narrow strings to CFX_WideTextBuf.

Precursor to removing a bunch of wide string literals.
Add unit test while we're at it.

Change-Id: Icdd5e843149f0760c6c873e19b822e6b1b007805
Reviewed-on: https://pdfium-review.googlesource.com/c/46290
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index d489dea..6ef7bd7 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -151,6 +151,7 @@
     "autorestorer_unittest.cpp",
     "bytestring_unittest.cpp",
     "cfx_bitstream_unittest.cpp",
+    "cfx_widetextbuf_unittest.cpp",
     "fx_bidi_unittest.cpp",
     "fx_coordinates_unittest.cpp",
     "fx_extension_unittest.cpp",
diff --git a/core/fxcrt/cfx_widetextbuf.cpp b/core/fxcrt/cfx_widetextbuf.cpp
index a9b59b5..13208d1 100644
--- a/core/fxcrt/cfx_widetextbuf.cpp
+++ b/core/fxcrt/cfx_widetextbuf.cpp
@@ -16,6 +16,13 @@
   m_DataSize += sizeof(wchar_t);
 }
 
+CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const ByteStringView& ascii) {
+  // TODO(tsepez): avoid a malloc/copy here.
+  WideString temp = WideString::FromASCII(ascii);
+  AppendBlock(temp.c_str(), temp.GetLength() * sizeof(wchar_t));
+  return *this;
+}
+
 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const WideStringView& str) {
   AppendBlock(str.unterminated_c_str(), str.GetLength() * sizeof(wchar_t));
   return *this;
diff --git a/core/fxcrt/cfx_widetextbuf.h b/core/fxcrt/cfx_widetextbuf.h
index 483f75d..c4de5d3 100644
--- a/core/fxcrt/cfx_widetextbuf.h
+++ b/core/fxcrt/cfx_widetextbuf.h
@@ -35,6 +35,7 @@
 
   CFX_WideTextBuf& operator<<(int i);
   CFX_WideTextBuf& operator<<(double f);
+  CFX_WideTextBuf& operator<<(const ByteStringView& ascii);
   CFX_WideTextBuf& operator<<(const wchar_t* lpsz);
   CFX_WideTextBuf& operator<<(const WideStringView& str);
   CFX_WideTextBuf& operator<<(const WideString& str);
diff --git a/core/fxcrt/cfx_widetextbuf_unittest.cpp b/core/fxcrt/cfx_widetextbuf_unittest.cpp
new file mode 100644
index 0000000..ddca23f
--- /dev/null
+++ b/core/fxcrt/cfx_widetextbuf_unittest.cpp
@@ -0,0 +1,45 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcrt/cfx_widetextbuf.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace fxcrt {
+
+TEST(WideTextBuf, EmptyBuf) {
+  CFX_WideTextBuf wtb;
+  EXPECT_EQ(nullptr, wtb.GetBuffer());
+  EXPECT_TRUE(wtb.AsStringView().IsEmpty());
+  EXPECT_TRUE(wtb.MakeString().IsEmpty());
+}
+
+TEST(WideTextBuf, OperatorLtLt) {
+  CFX_WideTextBuf wtb;
+  wtb << 42 << 3.14 << "clams" << L"\u208c\u208e";
+  EXPECT_TRUE(wtb.MakeString() == L"423.14clams\u208c\u208e");
+}
+
+TEST(WideTextBuf, Deletion) {
+  CFX_WideTextBuf wtb;
+  wtb << L"ABCDEFG";
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII("ABCDEFG"));
+
+  wtb.Delete(1, 3);
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII("AEFG"));
+
+  wtb.Delete(1, 0);
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII("AEFG"));
+
+  wtb.Delete(0, 2);
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII("FG"));
+
+  wtb.Delete(0, 2);
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII(""));
+
+  wtb.Delete(0, 0);
+  EXPECT_TRUE(wtb.AsStringView().EqualsASCII(""));
+}
+
+}  // namespace fxcrt