Cleanup CFX_CSSTextBuf.

Split off from https://pdfium-review.googlesource.com/c/pdfium/+/66571

- Use a vector to hold contents.
- Move blank handling logic from parser into this class.
- Replace length method with IsEmpty() since that's all
  caller needs to know.

Change-Id: I23a5c079a81534b08f60dc3ceb3de228875077c3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67390
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/css/cfx_csssyntaxparser.cpp b/core/fxcrt/css/cfx_csssyntaxparser.cpp
index ab03e8c..869da99 100644
--- a/core/fxcrt/css/cfx_csssyntaxparser.cpp
+++ b/core/fxcrt/css/cfx_csssyntaxparser.cpp
@@ -27,7 +27,6 @@
 CFX_CSSSyntaxParser::CFX_CSSSyntaxParser(const wchar_t* pBuffer,
                                          int32_t iBufferSize) {
   ASSERT(pBuffer);
-  m_Output.InitWithSize(32);
   m_Input.AttachBuffer(pBuffer, iBufferSize);
 }
 
@@ -75,27 +74,25 @@
           case ',':
             m_Input.MoveNext();
             SwitchMode(SyntaxMode::kSelector);
-            if (m_Output.GetLength() > 0)
+            if (!m_Output.IsEmpty())
               return CFX_CSSSyntaxStatus::kSelector;
             break;
           case '{':
-            if (m_Output.GetLength() > 0) {
-              SaveTextData();
+            if (!m_Output.IsEmpty())
               return CFX_CSSSyntaxStatus::kSelector;
-            }
             m_Input.MoveNext();
             m_ModeStack.push(SyntaxMode::kRuleSet);
             SwitchMode(SyntaxMode::kPropertyName);
             return CFX_CSSSyntaxStatus::kDeclOpen;
           case '/':
             if (m_Input.GetNextChar() == '*') {
-              if (SwitchToComment() > 0)
+              if (SwitchToComment())
                 return CFX_CSSSyntaxStatus::kSelector;
               break;
             }
             FALLTHROUGH;
           default:
-            AppendCharIfNotLeadingBlank(wch);
+            m_Output.AppendCharIfNotLeadingBlank(wch);
             m_Input.MoveNext();
             break;
         }
@@ -115,13 +112,13 @@
             return CFX_CSSSyntaxStatus::kError;
           case '/':
             if (m_Input.GetNextChar() == '*') {
-              if (SwitchToComment() > 0)
+              if (SwitchToComment())
                 return CFX_CSSSyntaxStatus::kPropertyName;
               break;
             }
             FALLTHROUGH;
           default:
-            AppendCharIfNotLeadingBlank(wch);
+            m_Output.AppendCharIfNotLeadingBlank(wch);
             m_Input.MoveNext();
             break;
         }
@@ -136,13 +133,13 @@
             return CFX_CSSSyntaxStatus::kPropertyValue;
           case '/':
             if (m_Input.GetNextChar() == '*') {
-              if (SwitchToComment() > 0)
+              if (SwitchToComment())
                 return CFX_CSSSyntaxStatus::kPropertyValue;
               break;
             }
             FALLTHROUGH;
           default:
-            AppendCharIfNotLeadingBlank(wch);
+            m_Output.AppendCharIfNotLeadingBlank(wch);
             m_Input.MoveNext();
             break;
         }
@@ -159,32 +156,21 @@
         break;
     }
   }
-  if (m_eMode == SyntaxMode::kPropertyValue && m_Output.GetLength() > 0) {
-    SaveTextData();
+  if (m_eMode == SyntaxMode::kPropertyValue && !m_Output.IsEmpty())
     return CFX_CSSSyntaxStatus::kPropertyValue;
-  }
+
   return CFX_CSSSyntaxStatus::kEOS;
 }
 
-void CFX_CSSSyntaxParser::AppendCharIfNotLeadingBlank(wchar_t wch) {
-  if (m_Output.GetLength() > 0 || wch > ' ')
-    m_Output.AppendChar(wch);
-}
-
-void CFX_CSSSyntaxParser::SaveTextData() {
-  m_Output.TrimEnd();
-}
-
 void CFX_CSSSyntaxParser::SwitchMode(SyntaxMode eMode) {
   m_eMode = eMode;
-  SaveTextData();
 }
 
-int32_t CFX_CSSSyntaxParser::SwitchToComment() {
-  int32_t iLength = m_Output.GetLength();
+bool CFX_CSSSyntaxParser::SwitchToComment() {
+  const bool bEmpty = m_Output.IsEmpty();
   m_ModeStack.push(m_eMode);
   SwitchMode(SyntaxMode::kComment);
-  return iLength;
+  return !bEmpty;
 }
 
 bool CFX_CSSSyntaxParser::RestoreMode() {
@@ -197,5 +183,5 @@
 }
 
 WideStringView CFX_CSSSyntaxParser::GetCurrentString() const {
-  return WideStringView(m_Output.GetBuffer(), m_Output.GetLength());
+  return m_Output.GetTrailingBlankTrimmedString();
 }
diff --git a/core/fxcrt/css/cfx_csssyntaxparser.h b/core/fxcrt/css/cfx_csssyntaxparser.h
index 33f3361..361f4ca 100644
--- a/core/fxcrt/css/cfx_csssyntaxparser.h
+++ b/core/fxcrt/css/cfx_csssyntaxparser.h
@@ -47,11 +47,8 @@
   };
 
   void SwitchMode(SyntaxMode eMode);
-  int32_t SwitchToComment();
-
+  bool SwitchToComment();
   bool RestoreMode();
-  void AppendCharIfNotLeadingBlank(wchar_t wch);
-  void SaveTextData();
 
   bool m_bError = false;
   SyntaxMode m_eMode = SyntaxMode::kRuleSet;
diff --git a/core/fxcrt/css/cfx_csstextbuf.cpp b/core/fxcrt/css/cfx_csstextbuf.cpp
index f2f3b94..f907f94 100644
--- a/core/fxcrt/css/cfx_csstextbuf.cpp
+++ b/core/fxcrt/css/cfx_csstextbuf.cpp
@@ -6,44 +6,23 @@
 
 #include "core/fxcrt/css/cfx_csstextbuf.h"
 
-#include "core/fxcrt/fx_memory.h"
-
-CFX_CSSTextBuf::CFX_CSSTextBuf()
-    : m_pBuffer(nullptr), m_iBufLen(0), m_iDatLen(0) {}
-
-CFX_CSSTextBuf::~CFX_CSSTextBuf() {
-  FX_Free(m_pBuffer);
-  m_pBuffer = nullptr;
-  m_iDatLen = m_iBufLen;
+CFX_CSSTextBuf::CFX_CSSTextBuf() {
+  m_Buffer.reserve(32);
 }
 
-void CFX_CSSTextBuf::InitWithSize(int32_t iAllocSize) {
-  ExpandBuf(iAllocSize);
-}
+CFX_CSSTextBuf::~CFX_CSSTextBuf() = default;
 
-void CFX_CSSTextBuf::AppendChar(wchar_t wch) {
-  if (m_iDatLen >= m_iBufLen)
-    ExpandBuf(m_iBufLen * 2);
-
-  m_pBuffer[m_iDatLen++] = wch;
-}
-
-int32_t CFX_CSSTextBuf::TrimEnd() {
-  while (m_iDatLen > 0 && m_pBuffer[m_iDatLen - 1] <= ' ')
-    --m_iDatLen;
-  AppendChar(0);
-  return --m_iDatLen;
-}
-
-void CFX_CSSTextBuf::ExpandBuf(int32_t iDesiredSize) {
-  ASSERT(iDesiredSize > 0);
-  if (m_pBuffer && m_iBufLen == iDesiredSize)
+void CFX_CSSTextBuf::AppendCharIfNotLeadingBlank(wchar_t wch) {
+  if (m_Buffer.empty() && wch <= ' ')
     return;
 
-  if (m_pBuffer)
-    m_pBuffer = FX_Realloc(wchar_t, m_pBuffer, iDesiredSize);
-  else
-    m_pBuffer = FX_Alloc(wchar_t, iDesiredSize);
+  m_Buffer.push_back(wch);
+}
 
-  m_iBufLen = iDesiredSize;
+WideStringView CFX_CSSTextBuf::GetTrailingBlankTrimmedString() const {
+  WideStringView result(m_Buffer);
+  while (!result.IsEmpty() && result.Back() <= ' ')
+    result = result.First(result.GetLength() - 1);
+
+  return result;
 }
diff --git a/core/fxcrt/css/cfx_csstextbuf.h b/core/fxcrt/css/cfx_csstextbuf.h
index e1b9c64..c504fa7 100644
--- a/core/fxcrt/css/cfx_csstextbuf.h
+++ b/core/fxcrt/css/cfx_csstextbuf.h
@@ -7,29 +7,22 @@
 #ifndef CORE_FXCRT_CSS_CFX_CSSTEXTBUF_H_
 #define CORE_FXCRT_CSS_CFX_CSSTEXTBUF_H_
 
-#include "core/fxcrt/fx_system.h"
+#include <vector>
+
+#include "core/fxcrt/fx_string.h"
 
 class CFX_CSSTextBuf {
  public:
   CFX_CSSTextBuf();
   ~CFX_CSSTextBuf();
 
-  void InitWithSize(int32_t iAllocSize);
-  void AppendChar(wchar_t wch);
-
-  void Clear() { m_iDatLen = 0; }
-
-  int32_t TrimEnd();
-
-  int32_t GetLength() const { return m_iDatLen; }
-  const wchar_t* GetBuffer() const { return m_pBuffer; }
+  void Clear() { m_Buffer.clear(); }
+  bool IsEmpty() const { return m_Buffer.empty(); }
+  void AppendCharIfNotLeadingBlank(wchar_t wch);
+  WideStringView GetTrailingBlankTrimmedString() const;
 
  protected:
-  void ExpandBuf(int32_t iDesiredSize);
-
-  wchar_t* m_pBuffer;
-  int32_t m_iBufLen;
-  int32_t m_iDatLen;
+  std::vector<wchar_t> m_Buffer;
 };
 
 #endif  // CORE_FXCRT_CSS_CFX_CSSTEXTBUF_H_