Remove CFX_RTFPieceArray and use std::vector

This CL removes the CFX_RTFPieceArray typedef and updates the code to
use a std::vector.

Change-Id: I885038d432e700830958e37b8c03c5beceff012f
Reviewed-on: https://pdfium-review.googlesource.com/2936
Reviewed-by: Nicolás Peña <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp
index 774d78f..50fda35 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.cpp
+++ b/xfa/fgas/layout/fgas_rtfbreak.cpp
@@ -41,9 +41,7 @@
   m_bPagination = !!(m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination);
 }
 
-CFX_RTFBreak::~CFX_RTFBreak() {
-  Reset();
-}
+CFX_RTFBreak::~CFX_RTFBreak() {}
 
 void CFX_RTFBreak::SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) {
   if (fLineStart > fLineEnd)
@@ -381,32 +379,22 @@
   ASSERT(dwStatus != CFX_RTFBreakType::None);
 
   ++m_dwIdentity;
-  const CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces;
-  int32_t iCount = pCurPieces->GetSize();
-  if (iCount > 0) {
-    CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount);
+  if (!m_pCurLine->m_LinePieces.empty()) {
     if (dwStatus != CFX_RTFBreakType::Piece)
-      pLastPiece->m_dwStatus = dwStatus;
-    else
-      dwStatus = pLastPiece->m_dwStatus;
-    return dwStatus;
+      m_pCurLine->m_LinePieces.back().m_dwStatus = dwStatus;
+    return m_pCurLine->m_LinePieces.back().m_dwStatus;
   }
 
   if (HasRTFLine()) {
-    pCurPieces = &m_RTFLine[m_iReady].m_LinePieces;
-    iCount = pCurPieces->GetSize();
-    if (iCount-- > 0) {
-      CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(iCount);
+    if (!m_RTFLine[m_iReady].m_LinePieces.empty()) {
       if (dwStatus != CFX_RTFBreakType::Piece)
-        pLastPiece->m_dwStatus = dwStatus;
-      else
-        dwStatus = pLastPiece->m_dwStatus;
-      return dwStatus;
+        m_RTFLine[m_iReady].m_LinePieces.back().m_dwStatus = dwStatus;
+      return m_RTFLine[m_iReady].m_LinePieces.back().m_dwStatus;
     }
     return CFX_RTFBreakType::None;
   }
 
-  iCount = m_pCurLine->CountChars();
+  int32_t iCount = m_pCurLine->CountChars();
   if (iCount < 1)
     return CFX_RTFBreakType::None;
 
@@ -494,7 +482,7 @@
         tp.m_iChars += 1;
         ++i;
       }
-      m_pCurLine->m_LinePieces.Add(tp);
+      m_pCurLine->m_LinePieces.push_back(tp);
       bNew = true;
     } else {
       tp.m_iWidth += pTC->m_iCharWidth;
@@ -560,7 +548,8 @@
     } else if (iBidiLevel != pTC->m_iBidiLevel ||
                pTC->m_dwIdentity != dwIdentity) {
       tp.m_iChars = i - tp.m_iStartChar;
-      m_pCurLine->m_LinePieces.Add(tp);
+      m_pCurLine->m_LinePieces.push_back(tp);
+
       tp.m_iStartPos += tp.m_iWidth;
       tp.m_iStartChar = i;
       tpo.index = j++;
@@ -578,7 +567,8 @@
   if (i > tp.m_iStartChar) {
     tp.m_dwStatus = dwStatus;
     tp.m_iChars = i - tp.m_iStartChar;
-    m_pCurLine->m_LinePieces.Add(tp);
+    m_pCurLine->m_LinePieces.push_back(tp);
+
     tpo.index = j;
     tpo.pos = tp.m_iBidiPos;
     tpos->push_back(tpo);
@@ -587,7 +577,7 @@
   std::sort(tpos->begin(), tpos->end());
   int32_t iStartPos = m_pCurLine->m_iStart;
   for (const auto& it : *tpos) {
-    CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces.GetAt(it.index);
+    CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces[it.index];
     ttp.m_iStartPos = iStartPos;
     iStartPos += ttp.m_iWidth;
   }
@@ -598,10 +588,9 @@
                                       CFX_RTFBreakType dwStatus) {
   int32_t iNetWidth = m_pCurLine->m_iWidth;
   int32_t iGapChars = 0;
-  int32_t iCount = m_pCurLine->m_LinePieces.GetSize();
   bool bFind = false;
-  for (int32_t i = iCount - 1; i > -1; --i) {
-    CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces.GetAt(tpos[i].index);
+  for (auto it = tpos.rbegin(); it != tpos.rend(); it++) {
+    CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces[it->index];
     if (!bFind)
       iNetWidth = ttp.GetEndPos();
 
@@ -638,8 +627,8 @@
                         (m_iAlignment == CFX_RTFLineAlignment::Justified &&
                          dwStatus != CFX_RTFBreakType::Paragraph))) {
     int32_t iStart = -1;
-    for (int32_t i = 0; i < iCount; ++i) {
-      CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces.GetAt(tpos[i].index);
+    for (const auto& tpo : tpos) {
+      CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces[tpo.index];
       if (iStart < 0)
         iStart = ttp.m_iStartPos;
       else
@@ -665,10 +654,8 @@
     if (m_iAlignment == CFX_RTFLineAlignment::Center)
       iOffset /= 2;
     if (iOffset > 0) {
-      for (int32_t i = 0; i < iCount; ++i) {
-        CFX_RTFPiece& ttp = m_pCurLine->m_LinePieces.GetAt(i);
+      for (auto& ttp : m_pCurLine->m_LinePieces)
         ttp.m_iStartPos += iOffset;
-      }
     }
   }
 }
@@ -784,7 +771,7 @@
 
   ++iCharPos;
   if (iCharPos >= iCount) {
-    pNextLine->RemoveAll(true);
+    pNextLine->Clear();
     curChars[iCharPos - 1].m_nBreakType = FX_LBT_UNKNOWN;
     return;
   }
@@ -807,30 +794,33 @@
 }
 
 int32_t CFX_RTFBreak::CountBreakPieces() const {
-  return HasRTFLine() ? m_RTFLine[m_iReady].m_LinePieces.GetSize() : 0;
+  return HasRTFLine()
+             ? pdfium::CollectionSize<int32_t>(m_RTFLine[m_iReady].m_LinePieces)
+             : 0;
 }
 
-const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(int32_t index) const {
+const CFX_RTFPiece* CFX_RTFBreak::GetBreakPieceUnstable(int32_t index) const {
   if (!HasRTFLine())
     return nullptr;
 
-  const CFX_RTFPieceArray* pRTFPieces = &m_RTFLine[m_iReady].m_LinePieces;
-  if (index < 0 || index >= pRTFPieces->GetSize())
+  const std::vector<CFX_RTFPiece>& pRTFPieces =
+      m_RTFLine[m_iReady].m_LinePieces;
+  if (index < 0 || index >= pdfium::CollectionSize<int32_t>(pRTFPieces))
     return nullptr;
-  return pRTFPieces->GetPtrAt(index);
+  return &pRTFPieces[index];
 }
 
 void CFX_RTFBreak::ClearBreakPieces() {
   if (HasRTFLine())
-    m_RTFLine[m_iReady].RemoveAll(true);
+    m_RTFLine[m_iReady].Clear();
 
   m_iReady = -1;
 }
 
 void CFX_RTFBreak::Reset() {
   m_eCharType = FX_CHARTYPE_Unknown;
-  m_RTFLine[0].RemoveAll(true);
-  m_RTFLine[1].RemoveAll(true);
+  m_RTFLine[0].Clear();
+  m_RTFLine[1].Clear();
 }
 
 int32_t CFX_RTFBreak::GetDisplayPos(const FX_RTFTEXTOBJ* pText,
@@ -963,16 +953,13 @@
       m_pChars(nullptr),
       m_pUserData(nullptr) {}
 
-CFX_RTFPiece::~CFX_RTFPiece() {
-  Reset();
-}
+CFX_RTFPiece::CFX_RTFPiece(const CFX_RTFPiece& other) = default;
 
-CFX_RTFLine::CFX_RTFLine()
-    : m_LinePieces(16), m_iStart(0), m_iWidth(0), m_iArabicChars(0) {}
+CFX_RTFPiece::~CFX_RTFPiece() {}
 
-CFX_RTFLine::~CFX_RTFLine() {
-  RemoveAll(false);
-}
+CFX_RTFLine::CFX_RTFLine() : m_iStart(0), m_iWidth(0), m_iArabicChars(0) {}
+
+CFX_RTFLine::~CFX_RTFLine() {}
 
 FX_RTFTEXTOBJ::FX_RTFTEXTOBJ()
     : pFont(nullptr),
diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h
index 835430e..125b06f 100644
--- a/xfa/fgas/layout/fgas_rtfbreak.h
+++ b/xfa/fgas/layout/fgas_rtfbreak.h
@@ -48,6 +48,7 @@
 class CFX_RTFPiece {
  public:
   CFX_RTFPiece();
+  CFX_RTFPiece(const CFX_RTFPiece& other);
   ~CFX_RTFPiece();
 
   int32_t GetEndPos() const {
@@ -75,20 +76,6 @@
     return ret;
   }
 
-  void Reset() {
-    m_dwStatus = CFX_RTFBreakType::Piece;
-    if (m_iWidth > -1)
-      m_iStartPos += m_iWidth;
-
-    m_iWidth = -1;
-    m_iStartChar += m_iChars;
-    m_iChars = 0;
-    m_iBidiLevel = 0;
-    m_iBidiPos = 0;
-    m_iHorizontalScale = 100;
-    m_iVerticalScale = 100;
-  }
-
   CFX_RTFBreakType m_dwStatus;
   int32_t m_iStartPos;
   int32_t m_iWidth;
@@ -105,8 +92,6 @@
   CFX_RetainPtr<CFX_Retainable> m_pUserData;
 };
 
-typedef CFX_BaseArrayTemplate<CFX_RTFPiece> CFX_RTFPieceArray;
-
 class CFX_RTFLine {
  public:
   CFX_RTFLine();
@@ -122,15 +107,15 @@
   }
 
   int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
-  void RemoveAll(bool bLeaveMemory) {
+  void Clear() {
     m_LineChars.clear();
-    m_LinePieces.RemoveAll(bLeaveMemory);
+    m_LinePieces.clear();
     m_iWidth = 0;
     m_iArabicChars = 0;
   }
 
   std::vector<CFX_RTFChar> m_LineChars;
-  CFX_RTFPieceArray m_LinePieces;
+  std::vector<CFX_RTFPiece> m_LinePieces;
   int32_t m_iStart;
   int32_t m_iWidth;
   int32_t m_iArabicChars;
@@ -157,7 +142,7 @@
 
   CFX_RTFBreakType EndBreak(CFX_RTFBreakType dwStatus);
   int32_t CountBreakPieces() const;
-  const CFX_RTFPiece* GetBreakPiece(int32_t index) const;
+  const CFX_RTFPiece* GetBreakPieceUnstable(int32_t index) const;
   void ClearBreakPieces();
 
   void Reset();
diff --git a/xfa/fgas/layout/fgas_rtfbreak_unittest.cpp b/xfa/fgas/layout/fgas_rtfbreak_unittest.cpp
index aba440a..bbac9d5 100644
--- a/xfa/fgas/layout/fgas_rtfbreak_unittest.cpp
+++ b/xfa/fgas/layout/fgas_rtfbreak_unittest.cpp
@@ -58,7 +58,7 @@
 
   EXPECT_EQ(CFX_RTFBreakType::Paragraph, b->AppendChar(L'\n'));
   ASSERT_EQ(1, b->CountBreakPieces());
-  EXPECT_EQ(str + L"\n", b->GetBreakPiece(0)->GetString());
+  EXPECT_EQ(str + L"\n", b->GetBreakPieceUnstable(0)->GetString());
 
   b->ClearBreakPieces();
   b->Reset();
@@ -71,7 +71,7 @@
   // Force the end of the break at the end of the string.
   b->EndBreak(CFX_RTFBreakType::Paragraph);
   ASSERT_EQ(1, b->CountBreakPieces());
-  EXPECT_EQ(str, b->GetBreakPiece(0)->GetString());
+  EXPECT_EQ(str, b->GetBreakPieceUnstable(0)->GetString());
 }
 
 TEST_F(RTFBreakTest, ControlCharacters) {
@@ -83,5 +83,5 @@
   EXPECT_EQ(CFX_RTFBreakType::Paragraph, b->AppendChar(L'\n'));
 
   ASSERT_EQ(1, b->CountBreakPieces());
-  EXPECT_EQ(L"\v", b->GetBreakPiece(0)->GetString());
+  EXPECT_EQ(L"\v", b->GetBreakPieceUnstable(0)->GetString());
 }
diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp
index 06cbfe0..676aded 100644
--- a/xfa/fxfa/app/cxfa_textlayout.cpp
+++ b/xfa/fxfa/app/cxfa_textlayout.cpp
@@ -1033,7 +1033,7 @@
     FX_FLOAT fLineStep = 0, fBaseLine = 0;
     int32_t i = 0;
     for (i = 0; i < iPieces; i++) {
-      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
+      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i);
       CXFA_TextUserData* pUserData =
           static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get());
       if (pUserData)
@@ -1088,7 +1088,7 @@
     FX_FLOAT fLineStep = 0;
     FX_FLOAT fLineWidth = 0;
     for (int32_t i = 0; i < iPieces; i++) {
-      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
+      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i);
       CXFA_TextUserData* pUserData =
           static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get());
       if (pUserData)