Add missing move operators for CFX_BinaryBuf

Otherwise, returning Optional<CFX_WideStringBuf> won't be possible
because the embedded unique_ptr<> prevents a copy from working.

Change-Id: I68e950af90045fe2cda88c1b1d090b62799c17f8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73510
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/cfx_binarybuf.cpp b/core/fxcrt/cfx_binarybuf.cpp
index e24590c..576f6f1 100644
--- a/core/fxcrt/cfx_binarybuf.cpp
+++ b/core/fxcrt/cfx_binarybuf.cpp
@@ -13,8 +13,33 @@
 
 CFX_BinaryBuf::CFX_BinaryBuf() = default;
 
+CFX_BinaryBuf::CFX_BinaryBuf(CFX_BinaryBuf&& that) noexcept
+    : m_AllocStep(that.m_AllocStep),
+      m_AllocSize(that.m_AllocSize),
+      m_DataSize(that.m_DataSize),
+      m_pBuffer(std::move(that.m_pBuffer)) {
+  // Can't just default, need to leave |that| in a valid state, which means
+  // that the size members reflect the (null) moved-from buffer.
+  that.m_AllocStep = 0;
+  that.m_AllocSize = 0;
+  that.m_DataSize = 0;
+}
+
 CFX_BinaryBuf::~CFX_BinaryBuf() = default;
 
+CFX_BinaryBuf& CFX_BinaryBuf::operator=(CFX_BinaryBuf&& that) noexcept {
+  // Can't just default, need to leave |that| in a valid state, which means
+  // that the size members reflect the (null) moved-from buffer.
+  m_AllocStep = that.m_AllocStep;
+  m_AllocSize = that.m_AllocSize;
+  m_DataSize = that.m_DataSize;
+  m_pBuffer = std::move(that.m_pBuffer);
+  that.m_AllocStep = 0;
+  that.m_AllocSize = 0;
+  that.m_DataSize = 0;
+  return *this;
+}
+
 void CFX_BinaryBuf::Delete(size_t start_index, size_t count) {
   if (!m_pBuffer || count > m_DataSize || start_index > m_DataSize - count)
     return;
diff --git a/core/fxcrt/cfx_binarybuf.h b/core/fxcrt/cfx_binarybuf.h
index b757c9a..44a07f9 100644
--- a/core/fxcrt/cfx_binarybuf.h
+++ b/core/fxcrt/cfx_binarybuf.h
@@ -17,8 +17,12 @@
 class CFX_BinaryBuf {
  public:
   CFX_BinaryBuf();
+  CFX_BinaryBuf(CFX_BinaryBuf&& that) noexcept;
   virtual ~CFX_BinaryBuf();
 
+  // Moved-from value will be left empty.
+  CFX_BinaryBuf& operator=(CFX_BinaryBuf&& that) noexcept;
+
   pdfium::span<uint8_t> GetSpan();
   pdfium::span<const uint8_t> GetSpan() const;
   uint8_t* GetBuffer() const { return m_pBuffer.get(); }
diff --git a/core/fxcrt/cfx_widetextbuf_unittest.cpp b/core/fxcrt/cfx_widetextbuf_unittest.cpp
index c8160ee..3dfba5d 100644
--- a/core/fxcrt/cfx_widetextbuf_unittest.cpp
+++ b/core/fxcrt/cfx_widetextbuf_unittest.cpp
@@ -18,7 +18,7 @@
 TEST(WideTextBuf, OperatorLtLt) {
   CFX_WideTextBuf wtb;
   wtb << 42 << 3.14 << "clams" << L"\u208c\u208e";
-  EXPECT_TRUE(wtb.MakeString() == L"423.14clams\u208c\u208e");
+  EXPECT_EQ(wtb.MakeString(), L"423.14clams\u208c\u208e");
 }
 
 TEST(WideTextBuf, Deletion) {
@@ -42,4 +42,19 @@
   EXPECT_TRUE(wtb.AsStringView().EqualsASCII(""));
 }
 
+TEST(WideTextBuf, Move) {
+  CFX_WideTextBuf wtb;
+  wtb << "clams";
+  EXPECT_EQ(wtb.MakeString(), L"clams");
+
+  CFX_WideTextBuf wtb2(std::move(wtb));
+  EXPECT_EQ(wtb.MakeString(), L"");
+  EXPECT_EQ(wtb2.MakeString(), L"clams");
+
+  CFX_WideTextBuf wtb3;
+  wtb3 = std::move(wtb2);
+  EXPECT_EQ(wtb2.MakeString(), L"");
+  EXPECT_EQ(wtb3.MakeString(), L"clams");
+}
+
 }  // namespace fxcrt