Cache pattern span in xfa/fgas/crt/cfgas_stringformatter.h

Change-Id: I3e6bba3f480372d9592cd81ea32106e68a38a5f8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/51950
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fgas/crt/cfgas_stringformatter.cpp b/xfa/fgas/crt/cfgas_stringformatter.cpp
index de91740..3115df5 100644
--- a/xfa/fgas/crt/cfgas_stringformatter.cpp
+++ b/xfa/fgas/crt/cfgas_stringformatter.cpp
@@ -822,7 +822,9 @@
 
 CFGAS_StringFormatter::CFGAS_StringFormatter(LocaleMgrIface* pLocaleMgr,
                                              const WideString& wsPattern)
-    : m_pLocaleMgr(pLocaleMgr), m_wsPattern(wsPattern) {}
+    : m_pLocaleMgr(pLocaleMgr),
+      m_wsPattern(wsPattern),
+      m_spPattern(m_wsPattern.AsSpan()) {}
 
 CFGAS_StringFormatter::~CFGAS_StringFormatter() = default;
 
@@ -848,26 +850,25 @@
 
 FX_LOCALECATEGORY CFGAS_StringFormatter::GetCategory() const {
   FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
-  pdfium::span<const wchar_t> spPattern = m_wsPattern.AsSpan();
   size_t ccf = 0;
   bool bBraceOpen = false;
   WideStringView wsConstChars(gs_wsConstChars);
-  while (ccf < spPattern.size()) {
-    if (spPattern[ccf] == '\'') {
-      GetLiteralText(spPattern, &ccf);
-    } else if (!bBraceOpen && !wsConstChars.Contains(spPattern[ccf])) {
-      WideString wsCategory(spPattern[ccf]);
+  while (ccf < m_spPattern.size()) {
+    if (m_spPattern[ccf] == '\'') {
+      GetLiteralText(m_spPattern, &ccf);
+    } else if (!bBraceOpen && !wsConstChars.Contains(m_spPattern[ccf])) {
+      WideString wsCategory(m_spPattern[ccf]);
       ccf++;
       while (true) {
-        if (ccf == spPattern.size())
+        if (ccf == m_spPattern.size())
           return eCategory;
-        if (spPattern[ccf] == '.' || spPattern[ccf] == '(')
+        if (m_spPattern[ccf] == '.' || m_spPattern[ccf] == '(')
           break;
-        if (spPattern[ccf] == '{') {
+        if (m_spPattern[ccf] == '{') {
           bBraceOpen = true;
           break;
         }
-        wsCategory += spPattern[ccf];
+        wsCategory += m_spPattern[ccf];
         ccf++;
       }
 
@@ -891,7 +892,7 @@
           return FX_LOCALECATEGORY_DateTime;
         eCategory = FX_LOCALECATEGORY_Time;
       }
-    } else if (spPattern[ccf] == '}') {
+    } else if (m_spPattern[ccf] == '}') {
       bBraceOpen = false;
     }
     ccf++;
@@ -902,41 +903,40 @@
 WideString CFGAS_StringFormatter::GetTextFormat(
     WideStringView wsCategory) const {
   size_t ccf = 0;
-  pdfium::span<const wchar_t> spPattern = m_wsPattern.AsSpan();
   bool bBrackOpen = false;
   WideStringView wsConstChars(gs_wsConstChars);
   WideString wsPurgePattern;
-  while (ccf < spPattern.size()) {
-    if (spPattern[ccf] == '\'') {
+  while (ccf < m_spPattern.size()) {
+    if (m_spPattern[ccf] == '\'') {
       int32_t iCurChar = ccf;
-      GetLiteralText(spPattern, &ccf);
+      GetLiteralText(m_spPattern, &ccf);
       wsPurgePattern +=
-          WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
-    } else if (!bBrackOpen && !wsConstChars.Contains(spPattern[ccf])) {
-      WideString wsSearchCategory(spPattern[ccf]);
+          WideStringView(m_spPattern.data() + iCurChar, ccf - iCurChar + 1);
+    } else if (!bBrackOpen && !wsConstChars.Contains(m_spPattern[ccf])) {
+      WideString wsSearchCategory(m_spPattern[ccf]);
       ccf++;
-      while (ccf < spPattern.size() && spPattern[ccf] != '{' &&
-             spPattern[ccf] != '.' && spPattern[ccf] != '(') {
-        wsSearchCategory += spPattern[ccf];
+      while (ccf < m_spPattern.size() && m_spPattern[ccf] != '{' &&
+             m_spPattern[ccf] != '.' && m_spPattern[ccf] != '(') {
+        wsSearchCategory += m_spPattern[ccf];
         ccf++;
       }
       if (wsSearchCategory != wsCategory)
         continue;
 
-      while (ccf < spPattern.size()) {
-        if (spPattern[ccf] == '(') {
+      while (ccf < m_spPattern.size()) {
+        if (m_spPattern[ccf] == '(') {
           ccf++;
           // Skip over the encoding name.
-          while (ccf < spPattern.size() && spPattern[ccf] != ')')
+          while (ccf < m_spPattern.size() && m_spPattern[ccf] != ')')
             ccf++;
-        } else if (spPattern[ccf] == '{') {
+        } else if (m_spPattern[ccf] == '{') {
           bBrackOpen = true;
           break;
         }
         ccf++;
       }
-    } else if (spPattern[ccf] != '}') {
-      wsPurgePattern += spPattern[ccf];
+    } else if (m_spPattern[ccf] != '}') {
+      wsPurgePattern += m_spPattern[ccf];
     }
     ccf++;
   }
@@ -955,20 +955,19 @@
   size_t ccf = 0;
   bool bFindDot = false;
   bool bBrackOpen = false;
-  pdfium::span<const wchar_t> spPattern = m_wsPattern.AsSpan();
   WideStringView wsConstChars(gs_wsConstChars);
-  while (ccf < spPattern.size()) {
-    if (spPattern[ccf] == '\'') {
+  while (ccf < m_spPattern.size()) {
+    if (m_spPattern[ccf] == '\'') {
       int32_t iCurChar = ccf;
-      GetLiteralText(spPattern, &ccf);
+      GetLiteralText(m_spPattern, &ccf);
       *wsPurgePattern +=
-          WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
-    } else if (!bBrackOpen && !wsConstChars.Contains(spPattern[ccf])) {
-      WideString wsCategory(spPattern[ccf]);
+          WideStringView(m_spPattern.data() + iCurChar, ccf - iCurChar + 1);
+    } else if (!bBrackOpen && !wsConstChars.Contains(m_spPattern[ccf])) {
+      WideString wsCategory(m_spPattern[ccf]);
       ccf++;
-      while (ccf < spPattern.size() && spPattern[ccf] != '{' &&
-             spPattern[ccf] != '.' && spPattern[ccf] != '(') {
-        wsCategory += spPattern[ccf];
+      while (ccf < m_spPattern.size() && m_spPattern[ccf] != '{' &&
+             m_spPattern[ccf] != '.' && m_spPattern[ccf] != '(') {
+        wsCategory += m_spPattern[ccf];
         ccf++;
       }
       if (!wsCategory.EqualsASCII("num")) {
@@ -976,24 +975,24 @@
         ccf = 0;
         continue;
       }
-      while (ccf < spPattern.size()) {
-        if (spPattern[ccf] == '{') {
+      while (ccf < m_spPattern.size()) {
+        if (m_spPattern[ccf] == '{') {
           bBrackOpen = true;
           break;
         }
-        if (spPattern[ccf] == '(') {
+        if (m_spPattern[ccf] == '(') {
           ccf++;
           WideString wsLCID;
-          while (ccf < spPattern.size() && spPattern[ccf] != ')')
-            wsLCID += spPattern[ccf++];
+          while (ccf < m_spPattern.size() && m_spPattern[ccf] != ')')
+            wsLCID += m_spPattern[ccf++];
 
           pLocale = m_pLocaleMgr->GetLocaleByName(wsLCID);
-        } else if (spPattern[ccf] == '.') {
+        } else if (m_spPattern[ccf] == '.') {
           WideString wsSubCategory;
           ccf++;
-          while (ccf < spPattern.size() && spPattern[ccf] != '(' &&
-                 spPattern[ccf] != '{') {
-            wsSubCategory += spPattern[ccf++];
+          while (ccf < m_spPattern.size() && m_spPattern[ccf] != '(' &&
+                 m_spPattern[ccf] != '{') {
+            wsSubCategory += m_spPattern[ccf++];
           }
           uint32_t dwSubHash =
               FX_HashCode_GetW(wsSubCategory.AsStringView(), false);
@@ -1025,18 +1024,18 @@
         }
         ccf++;
       }
-    } else if (spPattern[ccf] == 'E') {
+    } else if (m_spPattern[ccf] == 'E') {
       *dwStyle |= FX_NUMSTYLE_Exponent;
-      *wsPurgePattern += spPattern[ccf];
-    } else if (spPattern[ccf] == '%') {
+      *wsPurgePattern += m_spPattern[ccf];
+    } else if (m_spPattern[ccf] == '%') {
       *dwStyle |= FX_NUMSTYLE_Percent;
-      *wsPurgePattern += spPattern[ccf];
-    } else if (spPattern[ccf] != '}') {
-      *wsPurgePattern += spPattern[ccf];
+      *wsPurgePattern += m_spPattern[ccf];
+    } else if (m_spPattern[ccf] != '}') {
+      *wsPurgePattern += m_spPattern[ccf];
     }
-    if (!bFindDot && ccf < spPattern.size() &&
-        (spPattern[ccf] == '.' || spPattern[ccf] == 'V' ||
-         spPattern[ccf] == 'v')) {
+    if (!bFindDot && ccf < m_spPattern.size() &&
+        (m_spPattern[ccf] == '.' || m_spPattern[ccf] == 'V' ||
+         m_spPattern[ccf] == 'v')) {
       bFindDot = true;
       *iDotIndex = wsPurgePattern->GetLength() - 1;
       *dwStyle |= FX_NUMSTYLE_DotVorv;
@@ -1542,23 +1541,22 @@
   WideString wsTempPattern;
   FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
   size_t ccf = 0;
-  pdfium::span<const wchar_t> spPattern = m_wsPattern.AsSpan();
   int32_t iFindCategory = 0;
   bool bBraceOpen = false;
   WideStringView wsConstChars(gs_wsConstChars);
-  while (ccf < spPattern.size()) {
-    if (spPattern[ccf] == '\'') {
+  while (ccf < m_spPattern.size()) {
+    if (m_spPattern[ccf] == '\'') {
       int32_t iCurChar = ccf;
-      GetLiteralText(spPattern, &ccf);
+      GetLiteralText(m_spPattern, &ccf);
       wsTempPattern +=
-          WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
+          WideStringView(m_spPattern.data() + iCurChar, ccf - iCurChar + 1);
     } else if (!bBraceOpen && iFindCategory != 3 &&
-               !wsConstChars.Contains(spPattern[ccf])) {
-      WideString wsCategory(spPattern[ccf]);
+               !wsConstChars.Contains(m_spPattern[ccf])) {
+      WideString wsCategory(m_spPattern[ccf]);
       ccf++;
-      while (ccf < spPattern.size() && spPattern[ccf] != '{' &&
-             spPattern[ccf] != '.' && spPattern[ccf] != '(') {
-        if (spPattern[ccf] == 'T') {
+      while (ccf < m_spPattern.size() && m_spPattern[ccf] != '{' &&
+             m_spPattern[ccf] != '.' && m_spPattern[ccf] != '(') {
+        if (m_spPattern[ccf] == 'T') {
           *wsDatePattern = m_wsPattern.Left(ccf);
           *wsTimePattern = m_wsPattern.Right(m_wsPattern.GetLength() - ccf);
           wsTimePattern->SetAt(0, ' ');
@@ -1567,7 +1565,7 @@
 
           return FX_DATETIMETYPE_DateTime;
         }
-        wsCategory += spPattern[ccf];
+        wsCategory += m_spPattern[ccf];
         ccf++;
       }
       if (!(iFindCategory & 1) && wsCategory.EqualsASCII("date")) {
@@ -1584,24 +1582,24 @@
       } else {
         continue;
       }
-      while (ccf < spPattern.size()) {
-        if (spPattern[ccf] == '{') {
+      while (ccf < m_spPattern.size()) {
+        if (m_spPattern[ccf] == '{') {
           bBraceOpen = true;
           break;
         }
-        if (spPattern[ccf] == '(') {
+        if (m_spPattern[ccf] == '(') {
           ccf++;
           WideString wsLCID;
-          while (ccf < spPattern.size() && spPattern[ccf] != ')')
-            wsLCID += spPattern[ccf++];
+          while (ccf < m_spPattern.size() && m_spPattern[ccf] != ')')
+            wsLCID += m_spPattern[ccf++];
 
           *pLocale = m_pLocaleMgr->GetLocaleByName(wsLCID);
-        } else if (spPattern[ccf] == '.') {
+        } else if (m_spPattern[ccf] == '.') {
           WideString wsSubCategory;
           ccf++;
-          while (ccf < spPattern.size() && spPattern[ccf] != '(' &&
-                 spPattern[ccf] != '{')
-            wsSubCategory += spPattern[ccf++];
+          while (ccf < m_spPattern.size() && m_spPattern[ccf] != '(' &&
+                 m_spPattern[ccf] != '{')
+            wsSubCategory += m_spPattern[ccf++];
 
           uint32_t dwSubHash =
               FX_HashCode_GetW(wsSubCategory.AsStringView(), false);
@@ -1639,7 +1637,7 @@
         }
         ccf++;
       }
-    } else if (spPattern[ccf] == '}') {
+    } else if (m_spPattern[ccf] == '}') {
       bBraceOpen = false;
       if (!wsTempPattern.IsEmpty()) {
         if (eCategory == FX_LOCALECATEGORY_Time)
@@ -1650,7 +1648,7 @@
           wsTempPattern.clear();
       }
     } else {
-      wsTempPattern += spPattern[ccf];
+      wsTempPattern += m_spPattern[ccf];
     }
     ccf++;
   }
diff --git a/xfa/fgas/crt/cfgas_stringformatter.h b/xfa/fgas/crt/cfgas_stringformatter.h
index 538a783..afdeeb9 100644
--- a/xfa/fgas/crt/cfgas_stringformatter.h
+++ b/xfa/fgas/crt/cfgas_stringformatter.h
@@ -60,7 +60,8 @@
                                     WideString* wsTimePattern) const;
 
   UnownedPtr<LocaleMgrIface> const m_pLocaleMgr;
-  const WideString m_wsPattern;
+  const WideString m_wsPattern;                   // keep pattern string alive.
+  const pdfium::span<const wchar_t> m_spPattern;  // span into |m_wsPattern|.
 };
 
 #endif  // XFA_FGAS_CRT_CFGAS_STRINGFORMATTER_H_