Encapsulate some public static methods in CFXJSE_FormCalcContext.

They are only used inside CFXJSE_FormCalcContext. Move into an anonymous
namespace.

Change-Id: Ib8a0ff9b90cf951459c04655bedada3bdb1979a4
Reviewed-on: https://pdfium-review.googlesource.com/39090
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/fxjs/cfxjse_formcalc_context.cpp b/fxjs/cfxjse_formcalc_context.cpp
index 2b3db83..b2fa970 100644
--- a/fxjs/cfxjse_formcalc_context.cpp
+++ b/fxjs/cfxjse_formcalc_context.cpp
@@ -622,6 +622,925 @@
   return dValue;
 }
 
+bool IsIsoDateFormat(const char* pData,
+                     int32_t iLength,
+                     int32_t& iStyle,
+                     int32_t& iYear,
+                     int32_t& iMonth,
+                     int32_t& iDay) {
+  iYear = 0;
+  iMonth = 1;
+  iDay = 1;
+
+  if (iLength < 4)
+    return false;
+
+  char strYear[5];
+  strYear[4] = '\0';
+  for (int32_t i = 0; i < 4; ++i) {
+    if (!std::isdigit(pData[i]))
+      return false;
+
+    strYear[i] = pData[i];
+  }
+  iYear = FXSYS_atoi(strYear);
+  iStyle = 0;
+  if (iLength == 4)
+    return true;
+
+  iStyle = pData[4] == '-' ? 1 : 0;
+
+  char strTemp[3];
+  strTemp[2] = '\0';
+  int32_t iPosOff = iStyle == 0 ? 4 : 5;
+  if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
+    return false;
+
+  strTemp[0] = pData[iPosOff];
+  strTemp[1] = pData[iPosOff + 1];
+  iMonth = FXSYS_atoi(strTemp);
+  if (iMonth > 12 || iMonth < 1)
+    return false;
+
+  if (iStyle == 0) {
+    iPosOff += 2;
+    if (iLength == 6)
+      return true;
+  } else {
+    iPosOff += 3;
+    if (iLength == 7)
+      return true;
+  }
+  if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
+    return false;
+
+  strTemp[0] = pData[iPosOff];
+  strTemp[1] = pData[iPosOff + 1];
+  iDay = FXSYS_atoi(strTemp);
+  if (iPosOff + 2 < iLength)
+    return false;
+
+  if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
+    if (iMonth == 2 && iDay > 29)
+      return false;
+  } else {
+    if (iMonth == 2 && iDay > 28)
+      return false;
+  }
+  if (iMonth != 2) {
+    if (iMonth < 8) {
+      if (iDay > (iMonth % 2 == 0 ? 30 : 31))
+        return false;
+    } else if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool IsIsoTimeFormat(const char* pData,
+                     int32_t iLength,
+                     int32_t& iHour,
+                     int32_t& iMinute,
+                     int32_t& iSecond,
+                     int32_t& iMilliSecond,
+                     int32_t& iZoneHour,
+                     int32_t& iZoneMinute) {
+  iHour = 0;
+  iMinute = 0;
+  iSecond = 0;
+  iMilliSecond = 0;
+  iZoneHour = 0;
+  iZoneMinute = 0;
+  if (!pData)
+    return false;
+
+  char strTemp[3];
+  strTemp[2] = '\0';
+  int32_t iZone = 0;
+  int32_t i = 0;
+  while (i < iLength) {
+    if (!std::isdigit(pData[i]) && pData[i] != ':') {
+      iZone = i;
+      break;
+    }
+    ++i;
+  }
+  if (i == iLength)
+    iZone = iLength;
+
+  int32_t iPos = 0;
+  int32_t iIndex = 0;
+  while (iIndex < iZone) {
+    if (!std::isdigit(pData[iIndex]))
+      return false;
+
+    strTemp[0] = pData[iIndex];
+    if (!std::isdigit(pData[iIndex + 1]))
+      return false;
+
+    strTemp[1] = pData[iIndex + 1];
+    if (FXSYS_atoi(strTemp) > 60)
+      return false;
+
+    if (pData[2] == ':') {
+      if (iPos == 0) {
+        iHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else {
+        iSecond = FXSYS_atoi(strTemp);
+      }
+      iIndex += 3;
+    } else {
+      if (iPos == 0) {
+        iHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 2) {
+        iSecond = FXSYS_atoi(strTemp);
+        ++iPos;
+      }
+      iIndex += 2;
+    }
+  }
+
+  if (iIndex < iLength && pData[iIndex] == '.') {
+    constexpr int kSubSecondLength = 3;
+    if (iIndex + kSubSecondLength >= iLength)
+      return false;
+
+    ++iIndex;
+    char strSec[kSubSecondLength + 1];
+    for (int i = 0; i < kSubSecondLength; ++i) {
+      char c = pData[iIndex + i];
+      if (!std::isdigit(c))
+        return false;
+      strSec[i] = c;
+    }
+    strSec[kSubSecondLength] = '\0';
+
+    iMilliSecond = FXSYS_atoi(strSec);
+    if (iMilliSecond > 100) {
+      iMilliSecond = 0;
+      return false;
+    }
+    iIndex += kSubSecondLength;
+  }
+
+  if (iIndex < iLength && FXSYS_towlower(pData[iIndex]) == 'z')
+    return true;
+
+  int32_t iSign = 1;
+  if (iIndex < iLength) {
+    if (pData[iIndex] == '+') {
+      ++iIndex;
+    } else if (pData[iIndex] == '-') {
+      iSign = -1;
+      ++iIndex;
+    }
+  }
+  iPos = 0;
+  while (iIndex < iLength) {
+    if (!std::isdigit(pData[iIndex]))
+      return false;
+
+    strTemp[0] = pData[iIndex];
+    if (!std::isdigit(pData[iIndex + 1]))
+      return false;
+
+    strTemp[1] = pData[iIndex + 1];
+    if (FXSYS_atoi(strTemp) > 60)
+      return false;
+
+    if (pData[2] == ':') {
+      if (iPos == 0) {
+        iZoneHour = FXSYS_atoi(strTemp);
+      } else if (iPos == 1) {
+        iZoneMinute = FXSYS_atoi(strTemp);
+      }
+      iIndex += 3;
+    } else {
+      if (!iPos) {
+        iZoneHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iZoneMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      }
+      iIndex += 2;
+    }
+  }
+  if (iIndex < iLength)
+    return false;
+
+  iZoneHour *= iSign;
+  return true;
+}
+
+bool IsIsoDateTimeFormat(const char* pData,
+                         int32_t iLength,
+                         int32_t& iYear,
+                         int32_t& iMonth,
+                         int32_t& iDay,
+                         int32_t& iHour,
+                         int32_t& iMinute,
+                         int32_t& iSecond,
+                         int32_t& iMillionSecond,
+                         int32_t& iZoneHour,
+                         int32_t& iZoneMinute) {
+  iYear = 0;
+  iMonth = 0;
+  iDay = 0;
+  iHour = 0;
+  iMinute = 0;
+  iSecond = 0;
+  if (!pData)
+    return false;
+
+  int32_t iIndex = 0;
+  while (pData[iIndex] != 'T' && pData[iIndex] != 't') {
+    if (iIndex >= iLength)
+      return false;
+    ++iIndex;
+  }
+  if (iIndex != 8 && iIndex != 10)
+    return false;
+
+  int32_t iStyle = -1;
+  if (!IsIsoDateFormat(pData, iIndex, iStyle, iYear, iMonth, iDay))
+    return false;
+  if (pData[iIndex] != 'T' && pData[iIndex] != 't')
+    return true;
+
+  ++iIndex;
+  if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) &&
+      (iLength - iIndex != 15)) {
+    return true;
+  }
+  return IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute,
+                         iSecond, iMillionSecond, iZoneHour, iZoneMinute);
+}
+
+int32_t DateString2Num(const ByteStringView& szDateString) {
+  int32_t iLength = szDateString.GetLength();
+  int32_t iYear = 0;
+  int32_t iMonth = 0;
+  int32_t iDay = 0;
+  if (iLength <= 10) {
+    int32_t iStyle = -1;
+    if (!IsIsoDateFormat(szDateString.unterminated_c_str(), iLength, iStyle,
+                         iYear, iMonth, iDay)) {
+      return 0;
+    }
+  } else {
+    int32_t iHour = 0;
+    int32_t iMinute = 0;
+    int32_t iSecond = 0;
+    int32_t iMilliSecond = 0;
+    int32_t iZoneHour = 0;
+    int32_t iZoneMinute = 0;
+    if (!IsIsoDateTimeFormat(szDateString.unterminated_c_str(), iLength, iYear,
+                             iMonth, iDay, iHour, iMinute, iSecond,
+                             iMilliSecond, iZoneHour, iZoneMinute)) {
+      return 0;
+    }
+  }
+
+  float dDays = 0;
+  int32_t i = 1;
+  if (iYear < 1900)
+    return 0;
+
+  while (iYear - i >= 1900) {
+    dDays +=
+        ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400))
+            ? 366
+            : 365;
+    ++i;
+  }
+  i = 1;
+  while (i < iMonth) {
+    if (i == 2)
+      dDays += ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) ? 29 : 28;
+    else if (i <= 7)
+      dDays += (i % 2 == 0) ? 30 : 31;
+    else
+      dDays += (i % 2 == 0) ? 31 : 30;
+
+    ++i;
+  }
+  i = 0;
+  while (iDay - i > 0) {
+    dDays += 1;
+    ++i;
+  }
+  return (int32_t)dDays;
+}
+
+void GetLocalTimeZone(int32_t& iHour, int32_t& iMin, int32_t& iSec) {
+  time_t now;
+  time(&now);
+
+  struct tm* pGmt = gmtime(&now);
+  struct tm* pLocal = localtime(&now);
+  iHour = pLocal->tm_hour - pGmt->tm_hour;
+  iMin = pLocal->tm_min - pGmt->tm_min;
+  iSec = pLocal->tm_sec - pGmt->tm_sec;
+}
+
+bool HTMLSTR2Code(const WideStringView& pData, uint32_t* iCode) {
+  auto cmpFunc = [](const XFA_FMHtmlReserveCode& iter,
+                    const WideStringView& val) {
+    // TODO(tsepez): check usage of c_str() below.
+    return wcscmp(val.unterminated_c_str(), iter.m_htmlReserve) > 0;
+  };
+  const XFA_FMHtmlReserveCode* result =
+      std::lower_bound(std::begin(kReservesForDecode),
+                       std::end(kReservesForDecode), pData, cmpFunc);
+  if (result != std::end(kReservesForEncode) &&
+      !wcscmp(pData.unterminated_c_str(), result->m_htmlReserve)) {
+    *iCode = result->m_uCode;
+    return true;
+  }
+  return false;
+}
+
+bool HTMLCode2STR(uint32_t iCode, WideString* wsHTMLReserve) {
+  auto cmpFunc = [](const XFA_FMHtmlReserveCode iter, const uint32_t& val) {
+    return iter.m_uCode < val;
+  };
+  const XFA_FMHtmlReserveCode* result =
+      std::lower_bound(std::begin(kReservesForEncode),
+                       std::end(kReservesForEncode), iCode, cmpFunc);
+  if (result != std::end(kReservesForEncode) && result->m_uCode == iCode) {
+    *wsHTMLReserve = result->m_htmlReserve;
+    return true;
+  }
+  return false;
+}
+
+WideString DecodeURL(const WideString& wsURLString) {
+  const wchar_t* pData = wsURLString.c_str();
+  size_t i = 0;
+  CFX_WideTextBuf wsResultBuf;
+  while (i < wsURLString.GetLength()) {
+    wchar_t ch = pData[i];
+    if ('%' != ch) {
+      wsResultBuf.AppendChar(ch);
+      ++i;
+      continue;
+    }
+
+    wchar_t chTemp = 0;
+    int32_t iCount = 0;
+    while (iCount < 2) {
+      ++i;
+      ch = pData[i];
+      if (ch <= '9' && ch >= '0') {
+        // TODO(dsinclair): Premultiply and add rather then scale.
+        chTemp += (ch - '0') * (!iCount ? 16 : 1);
+      } else if (ch <= 'F' && ch >= 'A') {
+        chTemp += (ch - 'A' + 10) * (!iCount ? 16 : 1);
+      } else if (ch <= 'f' && ch >= 'a') {
+        chTemp += (ch - 'a' + 10) * (!iCount ? 16 : 1);
+      } else {
+        return WideString();
+      }
+      ++iCount;
+    }
+    wsResultBuf.AppendChar(chTemp);
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+  return wsResultBuf.MakeString();
+}
+
+WideString DecodeHTML(const WideString& wsHTMLString) {
+  wchar_t strString[9];
+  size_t iStrIndex = 0;
+  size_t iLen = wsHTMLString.GetLength();
+  size_t i = 0;
+  int32_t iCode = 0;
+  const wchar_t* pData = wsHTMLString.c_str();
+  CFX_WideTextBuf wsResultBuf;
+  while (i < iLen) {
+    wchar_t ch = pData[i];
+    if (ch != '&') {
+      wsResultBuf.AppendChar(ch);
+      ++i;
+      continue;
+    }
+
+    ++i;
+    ch = pData[i];
+    if (ch == '#') {
+      ++i;
+      ch = pData[i];
+      if (ch != 'x' && ch != 'X') {
+        return WideString();
+      }
+
+      ++i;
+      ch = pData[i];
+      if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
+          (ch <= 'F' && ch >= 'A')) {
+        while (ch != ';' && i < iLen) {
+          if (ch >= '0' && ch <= '9') {
+            iCode += ch - '0';
+          } else if (ch <= 'f' && ch >= 'a') {
+            iCode += ch - 'a' + 10;
+          } else if (ch <= 'F' && ch >= 'A') {
+            iCode += ch - 'A' + 10;
+          } else {
+            return WideString();
+          }
+          ++i;
+          // TODO(dsinclair): Postmultiply seems wrong, start at zero
+          //   and pre-multiply then can remove the post divide.
+          iCode *= 16;
+          ch = pData[i];
+        }
+        iCode /= 16;
+      }
+    } else {
+      while (ch != ';' && i < iLen) {
+        strString[iStrIndex++] = ch;
+        ++i;
+        ch = pData[i];
+      }
+      strString[iStrIndex] = 0;
+    }
+    uint32_t iData = 0;
+    if (HTMLSTR2Code(strString, &iData)) {
+      wsResultBuf.AppendChar((wchar_t)iData);
+    } else {
+      wsResultBuf.AppendChar(iCode);
+    }
+    iStrIndex = 0;
+    strString[iStrIndex] = 0;
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+
+  return wsResultBuf.MakeString();
+}
+
+WideString DecodeXML(const WideString& wsXMLString) {
+  wchar_t strString[9];
+  int32_t iStrIndex = 0;
+  int32_t iLen = wsXMLString.GetLength();
+  int32_t i = 0;
+  int32_t iCode = 0;
+  wchar_t ch = 0;
+  const wchar_t* pData = wsXMLString.c_str();
+  CFX_WideTextBuf wsResultBuf;
+  while (i < iLen) {
+    ch = pData[i];
+    if (ch != '&') {
+      wsResultBuf.AppendChar(ch);
+      ++i;
+      continue;
+    }
+
+    // TODO(dsinclair): This is very similar to DecodeHTML, can they be
+    //   combined?
+    ++i;
+    ch = pData[i];
+    if (ch == '#') {
+      ++i;
+      ch = pData[i];
+      if (ch != 'x' && ch != 'X') {
+        return WideString();
+      }
+
+      ++i;
+      ch = pData[i];
+      if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
+          (ch <= 'F' && ch >= 'A')) {
+        while (ch != ';') {
+          if (ch >= '0' && ch <= '9') {
+            iCode += ch - '0';
+          } else if (ch <= 'f' && ch >= 'a') {
+            iCode += ch - 'a' + 10;
+          } else if (ch <= 'F' && ch >= 'A') {
+            iCode += ch - 'A' + 10;
+          } else {
+            return WideString();
+          }
+          ++i;
+          iCode *= 16;
+          ch = pData[i];
+        }
+        iCode /= 16;
+      }
+    } else {
+      while (ch != ';' && i < iLen) {
+        strString[iStrIndex++] = ch;
+        ++i;
+        ch = pData[i];
+      }
+      strString[iStrIndex] = 0;
+    }
+
+    const wchar_t* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
+    int32_t iIndex = 0;
+    while (iIndex < 5) {
+      if (memcmp(strString, strName[iIndex], wcslen(strName[iIndex])) == 0) {
+        break;
+      }
+      ++iIndex;
+    }
+    switch (iIndex) {
+      case 0:
+        wsResultBuf.AppendChar('"');
+        break;
+      case 1:
+        wsResultBuf.AppendChar('&');
+        break;
+      case 2:
+        wsResultBuf.AppendChar('\'');
+        break;
+      case 3:
+        wsResultBuf.AppendChar('<');
+        break;
+      case 4:
+        wsResultBuf.AppendChar('>');
+        break;
+      default:
+        wsResultBuf.AppendChar(iCode);
+        break;
+    }
+    iStrIndex = 0;
+    strString[iStrIndex] = 0;
+    ++i;
+    iCode = 0;
+  }
+  wsResultBuf.AppendChar(0);
+  return wsResultBuf.MakeString();
+}
+
+WideString EncodeURL(const ByteString& szURLString) {
+  WideString wsURLString = WideString::FromUTF8(szURLString.AsStringView());
+  CFX_WideTextBuf wsResultBuf;
+  wchar_t strEncode[4];
+  strEncode[0] = '%';
+  strEncode[3] = 0;
+  wchar_t strUnsafe[] = {' ', '<',  '>', '"', '#', '%', '{', '}',
+                         '|', '\\', '^', '~', '[', ']', '`'};
+  wchar_t strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
+  wchar_t strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
+  const wchar_t* strCode = L"0123456789abcdef";
+  for (auto ch : wsURLString) {
+    int32_t i = 0;
+    int32_t iCount = FX_ArraySize(strUnsafe);
+    while (i < iCount) {
+      if (ch == strUnsafe[i]) {
+        int32_t iIndex = ch / 16;
+        strEncode[1] = strCode[iIndex];
+        strEncode[2] = strCode[ch - iIndex * 16];
+        wsResultBuf << strEncode;
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount)
+      continue;
+
+    i = 0;
+    iCount = FX_ArraySize(strReserved);
+    while (i < iCount) {
+      if (ch == strReserved[i]) {
+        int32_t iIndex = ch / 16;
+        strEncode[1] = strCode[iIndex];
+        strEncode[2] = strCode[ch - iIndex * 16];
+        wsResultBuf << strEncode;
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount)
+      continue;
+
+    i = 0;
+    iCount = FX_ArraySize(strSpecial);
+    while (i < iCount) {
+      if (ch == strSpecial[i]) {
+        wsResultBuf.AppendChar(ch);
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount)
+      continue;
+
+    if ((ch >= 0x80 && ch <= 0xff) || ch <= 0x1f || ch == 0x7f) {
+      int32_t iIndex = ch / 16;
+      strEncode[1] = strCode[iIndex];
+      strEncode[2] = strCode[ch - iIndex * 16];
+      wsResultBuf << strEncode;
+    } else if (ch >= 0x20 && ch <= 0x7e) {
+      wsResultBuf.AppendChar(ch);
+    } else {
+      const wchar_t iRadix = 16;
+      WideString strTmp;
+      while (ch >= iRadix) {
+        wchar_t tmp = strCode[ch % iRadix];
+        ch /= iRadix;
+        strTmp += tmp;
+      }
+      strTmp += strCode[ch];
+      int32_t iLen = strTmp.GetLength();
+      if (iLen < 2)
+        break;
+
+      int32_t iIndex = 0;
+      if (iLen % 2 != 0) {
+        strEncode[1] = '0';
+        strEncode[2] = strTmp[iLen - 1];
+        iIndex = iLen - 2;
+      } else {
+        strEncode[1] = strTmp[iLen - 1];
+        strEncode[2] = strTmp[iLen - 2];
+        iIndex = iLen - 3;
+      }
+      wsResultBuf << strEncode;
+      while (iIndex > 0) {
+        strEncode[1] = strTmp[iIndex];
+        strEncode[2] = strTmp[iIndex - 1];
+        iIndex -= 2;
+        wsResultBuf << strEncode;
+      }
+    }
+  }
+  wsResultBuf.AppendChar(0);
+  return wsResultBuf.MakeString();
+}
+
+WideString EncodeHTML(const ByteString& szHTMLString) {
+  WideString wsHTMLString = WideString::FromUTF8(szHTMLString.AsStringView());
+  const wchar_t* strCode = L"0123456789abcdef";
+  wchar_t strEncode[9];
+  strEncode[0] = '&';
+  strEncode[1] = '#';
+  strEncode[2] = 'x';
+  strEncode[5] = ';';
+  strEncode[6] = 0;
+  strEncode[7] = ';';
+  strEncode[8] = 0;
+  CFX_WideTextBuf wsResultBuf;
+  int32_t iLen = wsHTMLString.GetLength();
+  int32_t i = 0;
+  const wchar_t* pData = wsHTMLString.c_str();
+  while (i < iLen) {
+    uint32_t ch = pData[i];
+    WideString htmlReserve;
+    if (HTMLCode2STR(ch, &htmlReserve)) {
+      wsResultBuf.AppendChar(L'&');
+      wsResultBuf << htmlReserve;
+      wsResultBuf.AppendChar(L';');
+    } else if (ch >= 32 && ch <= 126) {
+      wsResultBuf.AppendChar((wchar_t)ch);
+    } else if (ch < 256) {
+      int32_t iIndex = ch / 16;
+      strEncode[3] = strCode[iIndex];
+      strEncode[4] = strCode[ch - iIndex * 16];
+      strEncode[5] = ';';
+      strEncode[6] = 0;
+      wsResultBuf << strEncode;
+    } else {
+      int32_t iBigByte = ch / 256;
+      int32_t iLittleByte = ch % 256;
+      strEncode[3] = strCode[iBigByte / 16];
+      strEncode[4] = strCode[iBigByte % 16];
+      strEncode[5] = strCode[iLittleByte / 16];
+      strEncode[6] = strCode[iLittleByte % 16];
+      wsResultBuf << strEncode;
+    }
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+  return wsResultBuf.MakeString();
+}
+
+WideString EncodeXML(const ByteString& szXMLString) {
+  WideString wsXMLString = WideString::FromUTF8(szXMLString.AsStringView());
+  CFX_WideTextBuf wsResultBuf;
+  wchar_t strEncode[9];
+  strEncode[0] = '&';
+  strEncode[1] = '#';
+  strEncode[2] = 'x';
+  strEncode[5] = ';';
+  strEncode[6] = 0;
+  strEncode[7] = ';';
+  strEncode[8] = 0;
+  const wchar_t* strCode = L"0123456789abcdef";
+  for (const auto& ch : wsXMLString) {
+    switch (ch) {
+      case '"':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << WideStringView(L"quot");
+        wsResultBuf.AppendChar(';');
+        break;
+      case '&':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << WideStringView(L"amp");
+        wsResultBuf.AppendChar(';');
+        break;
+      case '\'':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << WideStringView(L"apos");
+        wsResultBuf.AppendChar(';');
+        break;
+      case '<':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << WideStringView(L"lt");
+        wsResultBuf.AppendChar(';');
+        break;
+      case '>':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << WideStringView(L"gt");
+        wsResultBuf.AppendChar(';');
+        break;
+      default: {
+        if (ch >= 32 && ch <= 126) {
+          wsResultBuf.AppendChar(ch);
+        } else if (ch < 256) {
+          int32_t iIndex = ch / 16;
+          strEncode[3] = strCode[iIndex];
+          strEncode[4] = strCode[ch - iIndex * 16];
+          strEncode[5] = ';';
+          strEncode[6] = 0;
+          wsResultBuf << strEncode;
+        } else {
+          int32_t iBigByte = ch / 256;
+          int32_t iLittleByte = ch % 256;
+          strEncode[3] = strCode[iBigByte / 16];
+          strEncode[4] = strCode[iBigByte % 16];
+          strEncode[5] = strCode[iLittleByte / 16];
+          strEncode[6] = strCode[iLittleByte % 16];
+          wsResultBuf << strEncode;
+        }
+        break;
+      }
+    }
+  }
+  wsResultBuf.AppendChar(0);
+  return wsResultBuf.MakeString();
+}
+
+ByteString TrillionUS(const ByteStringView& szData) {
+  std::ostringstream strBuf;
+  ByteStringView pUnits[] = {"zero", "one", "two",   "three", "four",
+                             "five", "six", "seven", "eight", "nine"};
+  ByteStringView pCapUnits[] = {"Zero", "One", "Two",   "Three", "Four",
+                                "Five", "Six", "Seven", "Eight", "Nine"};
+  ByteStringView pTens[] = {"Ten",      "Eleven",  "Twelve",  "Thirteen",
+                            "Fourteen", "Fifteen", "Sixteen", "Seventeen",
+                            "Eighteen", "Nineteen"};
+  ByteStringView pLastTens[] = {"Twenty", "Thirty",  "Forty",  "Fifty",
+                                "Sixty",  "Seventy", "Eighty", "Ninety"};
+  ByteStringView pComm[] = {" Hundred ", " Thousand ", " Million ", " Billion ",
+                            "Trillion"};
+  const char* pData = szData.unterminated_c_str();
+  int32_t iLength = szData.GetLength();
+  int32_t iComm = 0;
+  if (iLength > 12)
+    iComm = 4;
+  else if (iLength > 9)
+    iComm = 3;
+  else if (iLength > 6)
+    iComm = 2;
+  else if (iLength > 3)
+    iComm = 1;
+
+  int32_t iFirstCount = iLength % 3;
+  if (iFirstCount == 0)
+    iFirstCount = 3;
+
+  int32_t iIndex = 0;
+  if (iFirstCount == 3) {
+    if (pData[iIndex] != '0') {
+      strBuf << pCapUnits[pData[iIndex] - '0'];
+      strBuf << pComm[0];
+    }
+    if (pData[iIndex + 1] == '0') {
+      strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+    } else {
+      if (pData[iIndex + 1] > '1') {
+        strBuf << pLastTens[pData[iIndex + 1] - '2'];
+        strBuf << "-";
+        strBuf << pUnits[pData[iIndex + 2] - '0'];
+      } else if (pData[iIndex + 1] == '1') {
+        strBuf << pTens[pData[iIndex + 2] - '0'];
+      } else if (pData[iIndex + 1] == '0') {
+        strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+      }
+    }
+    iIndex += 3;
+  } else if (iFirstCount == 2) {
+    if (pData[iIndex] == '0') {
+      strBuf << pCapUnits[pData[iIndex + 1] - '0'];
+    } else {
+      if (pData[iIndex] > '1') {
+        strBuf << pLastTens[pData[iIndex] - '2'];
+        strBuf << "-";
+        strBuf << pUnits[pData[iIndex + 1] - '0'];
+      } else if (pData[iIndex] == '1') {
+        strBuf << pTens[pData[iIndex + 1] - '0'];
+      } else if (pData[iIndex] == '0') {
+        strBuf << pCapUnits[pData[iIndex + 1] - '0'];
+      }
+    }
+    iIndex += 2;
+  } else if (iFirstCount == 1) {
+    strBuf << pCapUnits[pData[iIndex] - '0'];
+    iIndex += 1;
+  }
+  if (iLength > 3 && iFirstCount > 0) {
+    strBuf << pComm[iComm];
+    --iComm;
+  }
+  while (iIndex < iLength) {
+    if (pData[iIndex] != '0') {
+      strBuf << pCapUnits[pData[iIndex] - '0'];
+      strBuf << pComm[0];
+    }
+    if (pData[iIndex + 1] == '0') {
+      strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+    } else {
+      if (pData[iIndex + 1] > '1') {
+        strBuf << pLastTens[pData[iIndex + 1] - '2'];
+        strBuf << "-";
+        strBuf << pUnits[pData[iIndex + 2] - '0'];
+      } else if (pData[iIndex + 1] == '1') {
+        strBuf << pTens[pData[iIndex + 2] - '0'];
+      } else if (pData[iIndex + 1] == '0') {
+        strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+      }
+    }
+    if (iIndex < iLength - 3) {
+      strBuf << pComm[iComm];
+      --iComm;
+    }
+    iIndex += 3;
+  }
+  return ByteString(strBuf);
+}
+
+ByteString WordUS(const ByteString& szData, int32_t iStyle) {
+  const char* pData = szData.c_str();
+  int32_t iLength = szData.GetLength();
+  if (iStyle < 0 || iStyle > 2) {
+    return ByteString();
+  }
+
+  std::ostringstream strBuf;
+
+  int32_t iIndex = 0;
+  while (iIndex < iLength) {
+    if (pData[iIndex] == '.')
+      break;
+    ++iIndex;
+  }
+  int32_t iInteger = iIndex;
+  iIndex = 0;
+  while (iIndex < iInteger) {
+    int32_t iCount = (iInteger - iIndex) % 12;
+    if (!iCount && iInteger - iIndex > 0)
+      iCount = 12;
+
+    strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
+    iIndex += iCount;
+    if (iIndex < iInteger)
+      strBuf << " Trillion ";
+  }
+
+  if (iStyle > 0)
+    strBuf << " Dollars";
+
+  if (iStyle > 1 && iInteger < iLength) {
+    strBuf << " And ";
+    iIndex = iInteger + 1;
+    while (iIndex < iLength) {
+      int32_t iCount = (iLength - iIndex) % 12;
+      if (!iCount && iLength - iIndex > 0)
+        iCount = 12;
+
+      strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
+      iIndex += iCount;
+      if (iIndex < iLength)
+        strBuf << " Trillion ";
+    }
+    strBuf << " Cents";
+  }
+  return ByteString(strBuf);
+}
+
 }  // namespace
 
 const FXJSE_CLASS_DESCRIPTOR kFormCalcFM2JSDescriptor = {
@@ -1738,273 +2657,6 @@
 }
 
 // static
-bool CFXJSE_FormCalcContext::IsIsoDateFormat(const char* pData,
-                                             int32_t iLength,
-                                             int32_t& iStyle,
-                                             int32_t& iYear,
-                                             int32_t& iMonth,
-                                             int32_t& iDay) {
-  iYear = 0;
-  iMonth = 1;
-  iDay = 1;
-
-  if (iLength < 4)
-    return false;
-
-  char strYear[5];
-  strYear[4] = '\0';
-  for (int32_t i = 0; i < 4; ++i) {
-    if (!std::isdigit(pData[i]))
-      return false;
-
-    strYear[i] = pData[i];
-  }
-  iYear = FXSYS_atoi(strYear);
-  iStyle = 0;
-  if (iLength == 4)
-    return true;
-
-  iStyle = pData[4] == '-' ? 1 : 0;
-
-  char strTemp[3];
-  strTemp[2] = '\0';
-  int32_t iPosOff = iStyle == 0 ? 4 : 5;
-  if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
-    return false;
-
-  strTemp[0] = pData[iPosOff];
-  strTemp[1] = pData[iPosOff + 1];
-  iMonth = FXSYS_atoi(strTemp);
-  if (iMonth > 12 || iMonth < 1)
-    return false;
-
-  if (iStyle == 0) {
-    iPosOff += 2;
-    if (iLength == 6)
-      return true;
-  } else {
-    iPosOff += 3;
-    if (iLength == 7)
-      return true;
-  }
-  if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
-    return false;
-
-  strTemp[0] = pData[iPosOff];
-  strTemp[1] = pData[iPosOff + 1];
-  iDay = FXSYS_atoi(strTemp);
-  if (iPosOff + 2 < iLength)
-    return false;
-
-  if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
-    if (iMonth == 2 && iDay > 29)
-      return false;
-  } else {
-    if (iMonth == 2 && iDay > 28)
-      return false;
-  }
-  if (iMonth != 2) {
-    if (iMonth < 8) {
-      if (iDay > (iMonth % 2 == 0 ? 30 : 31))
-        return false;
-    } else if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// static
-bool CFXJSE_FormCalcContext::IsIsoTimeFormat(const char* pData,
-                                             int32_t iLength,
-                                             int32_t& iHour,
-                                             int32_t& iMinute,
-                                             int32_t& iSecond,
-                                             int32_t& iMilliSecond,
-                                             int32_t& iZoneHour,
-                                             int32_t& iZoneMinute) {
-  iHour = 0;
-  iMinute = 0;
-  iSecond = 0;
-  iMilliSecond = 0;
-  iZoneHour = 0;
-  iZoneMinute = 0;
-  if (!pData)
-    return false;
-
-  char strTemp[3];
-  strTemp[2] = '\0';
-  int32_t iZone = 0;
-  int32_t i = 0;
-  while (i < iLength) {
-    if (!std::isdigit(pData[i]) && pData[i] != ':') {
-      iZone = i;
-      break;
-    }
-    ++i;
-  }
-  if (i == iLength)
-    iZone = iLength;
-
-  int32_t iPos = 0;
-  int32_t iIndex = 0;
-  while (iIndex < iZone) {
-    if (!std::isdigit(pData[iIndex]))
-      return false;
-
-    strTemp[0] = pData[iIndex];
-    if (!std::isdigit(pData[iIndex + 1]))
-      return false;
-
-    strTemp[1] = pData[iIndex + 1];
-    if (FXSYS_atoi(strTemp) > 60)
-      return false;
-
-    if (pData[2] == ':') {
-      if (iPos == 0) {
-        iHour = FXSYS_atoi(strTemp);
-        ++iPos;
-      } else if (iPos == 1) {
-        iMinute = FXSYS_atoi(strTemp);
-        ++iPos;
-      } else {
-        iSecond = FXSYS_atoi(strTemp);
-      }
-      iIndex += 3;
-    } else {
-      if (iPos == 0) {
-        iHour = FXSYS_atoi(strTemp);
-        ++iPos;
-      } else if (iPos == 1) {
-        iMinute = FXSYS_atoi(strTemp);
-        ++iPos;
-      } else if (iPos == 2) {
-        iSecond = FXSYS_atoi(strTemp);
-        ++iPos;
-      }
-      iIndex += 2;
-    }
-  }
-
-  if (iIndex < iLength && pData[iIndex] == '.') {
-    constexpr int kSubSecondLength = 3;
-    if (iIndex + kSubSecondLength >= iLength)
-      return false;
-
-    ++iIndex;
-    char strSec[kSubSecondLength + 1];
-    for (int i = 0; i < kSubSecondLength; ++i) {
-      char c = pData[iIndex + i];
-      if (!std::isdigit(c))
-        return false;
-      strSec[i] = c;
-    }
-    strSec[kSubSecondLength] = '\0';
-
-    iMilliSecond = FXSYS_atoi(strSec);
-    if (iMilliSecond > 100) {
-      iMilliSecond = 0;
-      return false;
-    }
-    iIndex += kSubSecondLength;
-  }
-
-  if (iIndex < iLength && FXSYS_towlower(pData[iIndex]) == 'z')
-    return true;
-
-  int32_t iSign = 1;
-  if (iIndex < iLength) {
-    if (pData[iIndex] == '+') {
-      ++iIndex;
-    } else if (pData[iIndex] == '-') {
-      iSign = -1;
-      ++iIndex;
-    }
-  }
-  iPos = 0;
-  while (iIndex < iLength) {
-    if (!std::isdigit(pData[iIndex]))
-      return false;
-
-    strTemp[0] = pData[iIndex];
-    if (!std::isdigit(pData[iIndex + 1]))
-      return false;
-
-    strTemp[1] = pData[iIndex + 1];
-    if (FXSYS_atoi(strTemp) > 60)
-      return false;
-
-    if (pData[2] == ':') {
-      if (iPos == 0) {
-        iZoneHour = FXSYS_atoi(strTemp);
-      } else if (iPos == 1) {
-        iZoneMinute = FXSYS_atoi(strTemp);
-      }
-      iIndex += 3;
-    } else {
-      if (!iPos) {
-        iZoneHour = FXSYS_atoi(strTemp);
-        ++iPos;
-      } else if (iPos == 1) {
-        iZoneMinute = FXSYS_atoi(strTemp);
-        ++iPos;
-      }
-      iIndex += 2;
-    }
-  }
-  if (iIndex < iLength)
-    return false;
-
-  iZoneHour *= iSign;
-  return true;
-}
-
-// static
-bool CFXJSE_FormCalcContext::IsIsoDateTimeFormat(const char* pData,
-                                                 int32_t iLength,
-                                                 int32_t& iYear,
-                                                 int32_t& iMonth,
-                                                 int32_t& iDay,
-                                                 int32_t& iHour,
-                                                 int32_t& iMinute,
-                                                 int32_t& iSecond,
-                                                 int32_t& iMillionSecond,
-                                                 int32_t& iZoneHour,
-                                                 int32_t& iZoneMinute) {
-  iYear = 0;
-  iMonth = 0;
-  iDay = 0;
-  iHour = 0;
-  iMinute = 0;
-  iSecond = 0;
-  if (!pData)
-    return false;
-
-  int32_t iIndex = 0;
-  while (pData[iIndex] != 'T' && pData[iIndex] != 't') {
-    if (iIndex >= iLength)
-      return false;
-    ++iIndex;
-  }
-  if (iIndex != 8 && iIndex != 10)
-    return false;
-
-  int32_t iStyle = -1;
-  if (!IsIsoDateFormat(pData, iIndex, iStyle, iYear, iMonth, iDay))
-    return false;
-  if (pData[iIndex] != 'T' && pData[iIndex] != 't')
-    return true;
-
-  ++iIndex;
-  if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) &&
-      (iLength - iIndex != 15)) {
-    return true;
-  }
-  return IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute,
-                         iSecond, iMillionSecond, iZoneHour, iZoneMinute);
-}
-
-// static
 ByteString CFXJSE_FormCalcContext::Local2IsoDate(
     CFXJSE_Value* pThis,
     const ByteStringView& szDate,
@@ -2075,64 +2727,6 @@
 }
 
 // static
-int32_t CFXJSE_FormCalcContext::DateString2Num(
-    const ByteStringView& szDateString) {
-  int32_t iLength = szDateString.GetLength();
-  int32_t iYear = 0;
-  int32_t iMonth = 0;
-  int32_t iDay = 0;
-  if (iLength <= 10) {
-    int32_t iStyle = -1;
-    if (!IsIsoDateFormat(szDateString.unterminated_c_str(), iLength, iStyle,
-                         iYear, iMonth, iDay)) {
-      return 0;
-    }
-  } else {
-    int32_t iHour = 0;
-    int32_t iMinute = 0;
-    int32_t iSecond = 0;
-    int32_t iMilliSecond = 0;
-    int32_t iZoneHour = 0;
-    int32_t iZoneMinute = 0;
-    if (!IsIsoDateTimeFormat(szDateString.unterminated_c_str(), iLength, iYear,
-                             iMonth, iDay, iHour, iMinute, iSecond,
-                             iMilliSecond, iZoneHour, iZoneMinute)) {
-      return 0;
-    }
-  }
-
-  float dDays = 0;
-  int32_t i = 1;
-  if (iYear < 1900)
-    return 0;
-
-  while (iYear - i >= 1900) {
-    dDays +=
-        ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400))
-            ? 366
-            : 365;
-    ++i;
-  }
-  i = 1;
-  while (i < iMonth) {
-    if (i == 2)
-      dDays += ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) ? 29 : 28;
-    else if (i <= 7)
-      dDays += (i % 2 == 0) ? 30 : 31;
-    else
-      dDays += (i % 2 == 0) ? 31 : 30;
-
-    ++i;
-  }
-  i = 0;
-  while (iDay - i > 0) {
-    dDays += 1;
-    ++i;
-  }
-  return (int32_t)dDays;
-}
-
-// static
 ByteString CFXJSE_FormCalcContext::GetLocalDateFormat(
     CFXJSE_Value* pThis,
     int32_t iStyle,
@@ -2206,20 +2800,6 @@
 }
 
 // static
-void CFXJSE_FormCalcContext::GetLocalTimeZone(int32_t& iHour,
-                                              int32_t& iMin,
-                                              int32_t& iSec) {
-  time_t now;
-  time(&now);
-
-  struct tm* pGmt = gmtime(&now);
-  struct tm* pLocal = localtime(&now);
-  iHour = pLocal->tm_hour - pGmt->tm_hour;
-  iMin = pLocal->tm_min - pGmt->tm_min;
-  iSec = pLocal->tm_sec - pGmt->tm_sec;
-}
-
-// static
 void CFXJSE_FormCalcContext::Apr(CFXJSE_Value* pThis,
                                  const ByteStringView& szFuncName,
                                  CFXJSE_Arguments& args) {
@@ -3253,209 +3833,6 @@
 }
 
 // static
-WideString CFXJSE_FormCalcContext::DecodeURL(const WideString& wsURLString) {
-  const wchar_t* pData = wsURLString.c_str();
-  size_t i = 0;
-  CFX_WideTextBuf wsResultBuf;
-  while (i < wsURLString.GetLength()) {
-    wchar_t ch = pData[i];
-    if ('%' != ch) {
-      wsResultBuf.AppendChar(ch);
-      ++i;
-      continue;
-    }
-
-    wchar_t chTemp = 0;
-    int32_t iCount = 0;
-    while (iCount < 2) {
-      ++i;
-      ch = pData[i];
-      if (ch <= '9' && ch >= '0') {
-        // TODO(dsinclair): Premultiply and add rather then scale.
-        chTemp += (ch - '0') * (!iCount ? 16 : 1);
-      } else if (ch <= 'F' && ch >= 'A') {
-        chTemp += (ch - 'A' + 10) * (!iCount ? 16 : 1);
-      } else if (ch <= 'f' && ch >= 'a') {
-        chTemp += (ch - 'a' + 10) * (!iCount ? 16 : 1);
-      } else {
-        return WideString();
-      }
-      ++iCount;
-    }
-    wsResultBuf.AppendChar(chTemp);
-    ++i;
-  }
-  wsResultBuf.AppendChar(0);
-  return wsResultBuf.MakeString();
-}
-
-// static
-WideString CFXJSE_FormCalcContext::DecodeHTML(const WideString& wsHTMLString) {
-  wchar_t strString[9];
-  size_t iStrIndex = 0;
-  size_t iLen = wsHTMLString.GetLength();
-  size_t i = 0;
-  int32_t iCode = 0;
-  const wchar_t* pData = wsHTMLString.c_str();
-  CFX_WideTextBuf wsResultBuf;
-  while (i < iLen) {
-    wchar_t ch = pData[i];
-    if (ch != '&') {
-      wsResultBuf.AppendChar(ch);
-      ++i;
-      continue;
-    }
-
-    ++i;
-    ch = pData[i];
-    if (ch == '#') {
-      ++i;
-      ch = pData[i];
-      if (ch != 'x' && ch != 'X') {
-        return WideString();
-      }
-
-      ++i;
-      ch = pData[i];
-      if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
-          (ch <= 'F' && ch >= 'A')) {
-        while (ch != ';' && i < iLen) {
-          if (ch >= '0' && ch <= '9') {
-            iCode += ch - '0';
-          } else if (ch <= 'f' && ch >= 'a') {
-            iCode += ch - 'a' + 10;
-          } else if (ch <= 'F' && ch >= 'A') {
-            iCode += ch - 'A' + 10;
-          } else {
-            return WideString();
-          }
-          ++i;
-          // TODO(dsinclair): Postmultiply seems wrong, start at zero
-          //   and pre-multiply then can remove the post divide.
-          iCode *= 16;
-          ch = pData[i];
-        }
-        iCode /= 16;
-      }
-    } else {
-      while (ch != ';' && i < iLen) {
-        strString[iStrIndex++] = ch;
-        ++i;
-        ch = pData[i];
-      }
-      strString[iStrIndex] = 0;
-    }
-    uint32_t iData = 0;
-    if (HTMLSTR2Code(strString, &iData)) {
-      wsResultBuf.AppendChar((wchar_t)iData);
-    } else {
-      wsResultBuf.AppendChar(iCode);
-    }
-    iStrIndex = 0;
-    strString[iStrIndex] = 0;
-    ++i;
-  }
-  wsResultBuf.AppendChar(0);
-
-  return wsResultBuf.MakeString();
-}
-
-// static
-WideString CFXJSE_FormCalcContext::DecodeXML(const WideString& wsXMLString) {
-  wchar_t strString[9];
-  int32_t iStrIndex = 0;
-  int32_t iLen = wsXMLString.GetLength();
-  int32_t i = 0;
-  int32_t iCode = 0;
-  wchar_t ch = 0;
-  const wchar_t* pData = wsXMLString.c_str();
-  CFX_WideTextBuf wsResultBuf;
-  while (i < iLen) {
-    ch = pData[i];
-    if (ch != '&') {
-      wsResultBuf.AppendChar(ch);
-      ++i;
-      continue;
-    }
-
-    // TODO(dsinclair): This is very similar to DecodeHTML, can they be
-    //   combined?
-    ++i;
-    ch = pData[i];
-    if (ch == '#') {
-      ++i;
-      ch = pData[i];
-      if (ch != 'x' && ch != 'X') {
-        return WideString();
-      }
-
-      ++i;
-      ch = pData[i];
-      if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
-          (ch <= 'F' && ch >= 'A')) {
-        while (ch != ';') {
-          if (ch >= '0' && ch <= '9') {
-            iCode += ch - '0';
-          } else if (ch <= 'f' && ch >= 'a') {
-            iCode += ch - 'a' + 10;
-          } else if (ch <= 'F' && ch >= 'A') {
-            iCode += ch - 'A' + 10;
-          } else {
-            return WideString();
-          }
-          ++i;
-          iCode *= 16;
-          ch = pData[i];
-        }
-        iCode /= 16;
-      }
-    } else {
-      while (ch != ';' && i < iLen) {
-        strString[iStrIndex++] = ch;
-        ++i;
-        ch = pData[i];
-      }
-      strString[iStrIndex] = 0;
-    }
-
-    const wchar_t* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
-    int32_t iIndex = 0;
-    while (iIndex < 5) {
-      if (memcmp(strString, strName[iIndex], wcslen(strName[iIndex])) == 0) {
-        break;
-      }
-      ++iIndex;
-    }
-    switch (iIndex) {
-      case 0:
-        wsResultBuf.AppendChar('"');
-        break;
-      case 1:
-        wsResultBuf.AppendChar('&');
-        break;
-      case 2:
-        wsResultBuf.AppendChar('\'');
-        break;
-      case 3:
-        wsResultBuf.AppendChar('<');
-        break;
-      case 4:
-        wsResultBuf.AppendChar('>');
-        break;
-      default:
-        wsResultBuf.AppendChar(iCode);
-        break;
-    }
-    iStrIndex = 0;
-    strString[iStrIndex] = 0;
-    ++i;
-    iCode = 0;
-  }
-  wsResultBuf.AppendChar(0);
-  return wsResultBuf.MakeString();
-}
-
-// static
 void CFXJSE_FormCalcContext::Encode(CFXJSE_Value* pThis,
                                     const ByteStringView& szFuncName,
                                     CFXJSE_Arguments& args) {
@@ -3500,253 +3877,6 @@
 }
 
 // static
-WideString CFXJSE_FormCalcContext::EncodeURL(const ByteString& szURLString) {
-  WideString wsURLString = WideString::FromUTF8(szURLString.AsStringView());
-  CFX_WideTextBuf wsResultBuf;
-  wchar_t strEncode[4];
-  strEncode[0] = '%';
-  strEncode[3] = 0;
-  wchar_t strUnsafe[] = {' ', '<',  '>', '"', '#', '%', '{', '}',
-                         '|', '\\', '^', '~', '[', ']', '`'};
-  wchar_t strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
-  wchar_t strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
-  const wchar_t* strCode = L"0123456789abcdef";
-  for (auto ch : wsURLString) {
-    int32_t i = 0;
-    int32_t iCount = FX_ArraySize(strUnsafe);
-    while (i < iCount) {
-      if (ch == strUnsafe[i]) {
-        int32_t iIndex = ch / 16;
-        strEncode[1] = strCode[iIndex];
-        strEncode[2] = strCode[ch - iIndex * 16];
-        wsResultBuf << strEncode;
-        break;
-      }
-      ++i;
-    }
-    if (i < iCount)
-      continue;
-
-    i = 0;
-    iCount = FX_ArraySize(strReserved);
-    while (i < iCount) {
-      if (ch == strReserved[i]) {
-        int32_t iIndex = ch / 16;
-        strEncode[1] = strCode[iIndex];
-        strEncode[2] = strCode[ch - iIndex * 16];
-        wsResultBuf << strEncode;
-        break;
-      }
-      ++i;
-    }
-    if (i < iCount)
-      continue;
-
-    i = 0;
-    iCount = FX_ArraySize(strSpecial);
-    while (i < iCount) {
-      if (ch == strSpecial[i]) {
-        wsResultBuf.AppendChar(ch);
-        break;
-      }
-      ++i;
-    }
-    if (i < iCount)
-      continue;
-
-    if ((ch >= 0x80 && ch <= 0xff) || ch <= 0x1f || ch == 0x7f) {
-      int32_t iIndex = ch / 16;
-      strEncode[1] = strCode[iIndex];
-      strEncode[2] = strCode[ch - iIndex * 16];
-      wsResultBuf << strEncode;
-    } else if (ch >= 0x20 && ch <= 0x7e) {
-      wsResultBuf.AppendChar(ch);
-    } else {
-      const wchar_t iRadix = 16;
-      WideString strTmp;
-      while (ch >= iRadix) {
-        wchar_t tmp = strCode[ch % iRadix];
-        ch /= iRadix;
-        strTmp += tmp;
-      }
-      strTmp += strCode[ch];
-      int32_t iLen = strTmp.GetLength();
-      if (iLen < 2)
-        break;
-
-      int32_t iIndex = 0;
-      if (iLen % 2 != 0) {
-        strEncode[1] = '0';
-        strEncode[2] = strTmp[iLen - 1];
-        iIndex = iLen - 2;
-      } else {
-        strEncode[1] = strTmp[iLen - 1];
-        strEncode[2] = strTmp[iLen - 2];
-        iIndex = iLen - 3;
-      }
-      wsResultBuf << strEncode;
-      while (iIndex > 0) {
-        strEncode[1] = strTmp[iIndex];
-        strEncode[2] = strTmp[iIndex - 1];
-        iIndex -= 2;
-        wsResultBuf << strEncode;
-      }
-    }
-  }
-  wsResultBuf.AppendChar(0);
-  return wsResultBuf.MakeString();
-}
-
-// static
-WideString CFXJSE_FormCalcContext::EncodeHTML(const ByteString& szHTMLString) {
-  WideString wsHTMLString = WideString::FromUTF8(szHTMLString.AsStringView());
-  const wchar_t* strCode = L"0123456789abcdef";
-  wchar_t strEncode[9];
-  strEncode[0] = '&';
-  strEncode[1] = '#';
-  strEncode[2] = 'x';
-  strEncode[5] = ';';
-  strEncode[6] = 0;
-  strEncode[7] = ';';
-  strEncode[8] = 0;
-  CFX_WideTextBuf wsResultBuf;
-  int32_t iLen = wsHTMLString.GetLength();
-  int32_t i = 0;
-  const wchar_t* pData = wsHTMLString.c_str();
-  while (i < iLen) {
-    uint32_t ch = pData[i];
-    WideString htmlReserve;
-    if (HTMLCode2STR(ch, &htmlReserve)) {
-      wsResultBuf.AppendChar(L'&');
-      wsResultBuf << htmlReserve;
-      wsResultBuf.AppendChar(L';');
-    } else if (ch >= 32 && ch <= 126) {
-      wsResultBuf.AppendChar((wchar_t)ch);
-    } else if (ch < 256) {
-      int32_t iIndex = ch / 16;
-      strEncode[3] = strCode[iIndex];
-      strEncode[4] = strCode[ch - iIndex * 16];
-      strEncode[5] = ';';
-      strEncode[6] = 0;
-      wsResultBuf << strEncode;
-    } else {
-      int32_t iBigByte = ch / 256;
-      int32_t iLittleByte = ch % 256;
-      strEncode[3] = strCode[iBigByte / 16];
-      strEncode[4] = strCode[iBigByte % 16];
-      strEncode[5] = strCode[iLittleByte / 16];
-      strEncode[6] = strCode[iLittleByte % 16];
-      wsResultBuf << strEncode;
-    }
-    ++i;
-  }
-  wsResultBuf.AppendChar(0);
-  return wsResultBuf.MakeString();
-}
-
-// static
-WideString CFXJSE_FormCalcContext::EncodeXML(const ByteString& szXMLString) {
-  WideString wsXMLString = WideString::FromUTF8(szXMLString.AsStringView());
-  CFX_WideTextBuf wsResultBuf;
-  wchar_t strEncode[9];
-  strEncode[0] = '&';
-  strEncode[1] = '#';
-  strEncode[2] = 'x';
-  strEncode[5] = ';';
-  strEncode[6] = 0;
-  strEncode[7] = ';';
-  strEncode[8] = 0;
-  const wchar_t* strCode = L"0123456789abcdef";
-  for (const auto& ch : wsXMLString) {
-    switch (ch) {
-      case '"':
-        wsResultBuf.AppendChar('&');
-        wsResultBuf << WideStringView(L"quot");
-        wsResultBuf.AppendChar(';');
-        break;
-      case '&':
-        wsResultBuf.AppendChar('&');
-        wsResultBuf << WideStringView(L"amp");
-        wsResultBuf.AppendChar(';');
-        break;
-      case '\'':
-        wsResultBuf.AppendChar('&');
-        wsResultBuf << WideStringView(L"apos");
-        wsResultBuf.AppendChar(';');
-        break;
-      case '<':
-        wsResultBuf.AppendChar('&');
-        wsResultBuf << WideStringView(L"lt");
-        wsResultBuf.AppendChar(';');
-        break;
-      case '>':
-        wsResultBuf.AppendChar('&');
-        wsResultBuf << WideStringView(L"gt");
-        wsResultBuf.AppendChar(';');
-        break;
-      default: {
-        if (ch >= 32 && ch <= 126) {
-          wsResultBuf.AppendChar(ch);
-        } else if (ch < 256) {
-          int32_t iIndex = ch / 16;
-          strEncode[3] = strCode[iIndex];
-          strEncode[4] = strCode[ch - iIndex * 16];
-          strEncode[5] = ';';
-          strEncode[6] = 0;
-          wsResultBuf << strEncode;
-        } else {
-          int32_t iBigByte = ch / 256;
-          int32_t iLittleByte = ch % 256;
-          strEncode[3] = strCode[iBigByte / 16];
-          strEncode[4] = strCode[iBigByte % 16];
-          strEncode[5] = strCode[iLittleByte / 16];
-          strEncode[6] = strCode[iLittleByte % 16];
-          wsResultBuf << strEncode;
-        }
-        break;
-      }
-    }
-  }
-  wsResultBuf.AppendChar(0);
-  return wsResultBuf.MakeString();
-}
-
-// static
-bool CFXJSE_FormCalcContext::HTMLSTR2Code(const WideStringView& pData,
-                                          uint32_t* iCode) {
-  auto cmpFunc = [](const XFA_FMHtmlReserveCode& iter,
-                    const WideStringView& val) {
-    // TODO(tsepez): check usage of c_str() below.
-    return wcscmp(val.unterminated_c_str(), iter.m_htmlReserve) > 0;
-  };
-  const XFA_FMHtmlReserveCode* result =
-      std::lower_bound(std::begin(kReservesForDecode),
-                       std::end(kReservesForDecode), pData, cmpFunc);
-  if (result != std::end(kReservesForEncode) &&
-      !wcscmp(pData.unterminated_c_str(), result->m_htmlReserve)) {
-    *iCode = result->m_uCode;
-    return true;
-  }
-  return false;
-}
-
-// static
-bool CFXJSE_FormCalcContext::HTMLCode2STR(uint32_t iCode,
-                                          WideString* wsHTMLReserve) {
-  auto cmpFunc = [](const XFA_FMHtmlReserveCode iter, const uint32_t& val) {
-    return iter.m_uCode < val;
-  };
-  const XFA_FMHtmlReserveCode* result =
-      std::lower_bound(std::begin(kReservesForEncode),
-                       std::end(kReservesForEncode), iCode, cmpFunc);
-  if (result != std::end(kReservesForEncode) && result->m_uCode == iCode) {
-    *wsHTMLReserve = result->m_htmlReserve;
-    return true;
-  }
-  return false;
-}
-
-// static
 void CFXJSE_FormCalcContext::Format(CFXJSE_Value* pThis,
                                     const ByteStringView& szFuncName,
                                     CFXJSE_Arguments& args) {
@@ -4493,157 +4623,6 @@
 }
 
 // static
-ByteString CFXJSE_FormCalcContext::TrillionUS(const ByteStringView& szData) {
-  std::ostringstream strBuf;
-  ByteStringView pUnits[] = {"zero", "one", "two",   "three", "four",
-                             "five", "six", "seven", "eight", "nine"};
-  ByteStringView pCapUnits[] = {"Zero", "One", "Two",   "Three", "Four",
-                                "Five", "Six", "Seven", "Eight", "Nine"};
-  ByteStringView pTens[] = {"Ten",      "Eleven",  "Twelve",  "Thirteen",
-                            "Fourteen", "Fifteen", "Sixteen", "Seventeen",
-                            "Eighteen", "Nineteen"};
-  ByteStringView pLastTens[] = {"Twenty", "Thirty",  "Forty",  "Fifty",
-                                "Sixty",  "Seventy", "Eighty", "Ninety"};
-  ByteStringView pComm[] = {" Hundred ", " Thousand ", " Million ", " Billion ",
-                            "Trillion"};
-  const char* pData = szData.unterminated_c_str();
-  int32_t iLength = szData.GetLength();
-  int32_t iComm = 0;
-  if (iLength > 12)
-    iComm = 4;
-  else if (iLength > 9)
-    iComm = 3;
-  else if (iLength > 6)
-    iComm = 2;
-  else if (iLength > 3)
-    iComm = 1;
-
-  int32_t iFirstCount = iLength % 3;
-  if (iFirstCount == 0)
-    iFirstCount = 3;
-
-  int32_t iIndex = 0;
-  if (iFirstCount == 3) {
-    if (pData[iIndex] != '0') {
-      strBuf << pCapUnits[pData[iIndex] - '0'];
-      strBuf << pComm[0];
-    }
-    if (pData[iIndex + 1] == '0') {
-      strBuf << pCapUnits[pData[iIndex + 2] - '0'];
-    } else {
-      if (pData[iIndex + 1] > '1') {
-        strBuf << pLastTens[pData[iIndex + 1] - '2'];
-        strBuf << "-";
-        strBuf << pUnits[pData[iIndex + 2] - '0'];
-      } else if (pData[iIndex + 1] == '1') {
-        strBuf << pTens[pData[iIndex + 2] - '0'];
-      } else if (pData[iIndex + 1] == '0') {
-        strBuf << pCapUnits[pData[iIndex + 2] - '0'];
-      }
-    }
-    iIndex += 3;
-  } else if (iFirstCount == 2) {
-    if (pData[iIndex] == '0') {
-      strBuf << pCapUnits[pData[iIndex + 1] - '0'];
-    } else {
-      if (pData[iIndex] > '1') {
-        strBuf << pLastTens[pData[iIndex] - '2'];
-        strBuf << "-";
-        strBuf << pUnits[pData[iIndex + 1] - '0'];
-      } else if (pData[iIndex] == '1') {
-        strBuf << pTens[pData[iIndex + 1] - '0'];
-      } else if (pData[iIndex] == '0') {
-        strBuf << pCapUnits[pData[iIndex + 1] - '0'];
-      }
-    }
-    iIndex += 2;
-  } else if (iFirstCount == 1) {
-    strBuf << pCapUnits[pData[iIndex] - '0'];
-    iIndex += 1;
-  }
-  if (iLength > 3 && iFirstCount > 0) {
-    strBuf << pComm[iComm];
-    --iComm;
-  }
-  while (iIndex < iLength) {
-    if (pData[iIndex] != '0') {
-      strBuf << pCapUnits[pData[iIndex] - '0'];
-      strBuf << pComm[0];
-    }
-    if (pData[iIndex + 1] == '0') {
-      strBuf << pCapUnits[pData[iIndex + 2] - '0'];
-    } else {
-      if (pData[iIndex + 1] > '1') {
-        strBuf << pLastTens[pData[iIndex + 1] - '2'];
-        strBuf << "-";
-        strBuf << pUnits[pData[iIndex + 2] - '0'];
-      } else if (pData[iIndex + 1] == '1') {
-        strBuf << pTens[pData[iIndex + 2] - '0'];
-      } else if (pData[iIndex + 1] == '0') {
-        strBuf << pCapUnits[pData[iIndex + 2] - '0'];
-      }
-    }
-    if (iIndex < iLength - 3) {
-      strBuf << pComm[iComm];
-      --iComm;
-    }
-    iIndex += 3;
-  }
-  return ByteString(strBuf);
-}
-
-// static
-ByteString CFXJSE_FormCalcContext::WordUS(const ByteString& szData,
-                                          int32_t iStyle) {
-  const char* pData = szData.c_str();
-  int32_t iLength = szData.GetLength();
-  if (iStyle < 0 || iStyle > 2) {
-    return ByteString();
-  }
-
-  std::ostringstream strBuf;
-
-  int32_t iIndex = 0;
-  while (iIndex < iLength) {
-    if (pData[iIndex] == '.')
-      break;
-    ++iIndex;
-  }
-  int32_t iInteger = iIndex;
-  iIndex = 0;
-  while (iIndex < iInteger) {
-    int32_t iCount = (iInteger - iIndex) % 12;
-    if (!iCount && iInteger - iIndex > 0)
-      iCount = 12;
-
-    strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
-    iIndex += iCount;
-    if (iIndex < iInteger)
-      strBuf << " Trillion ";
-  }
-
-  if (iStyle > 0)
-    strBuf << " Dollars";
-
-  if (iStyle > 1 && iInteger < iLength) {
-    strBuf << " And ";
-    iIndex = iInteger + 1;
-    while (iIndex < iLength) {
-      int32_t iCount = (iLength - iIndex) % 12;
-      if (!iCount && iLength - iIndex > 0)
-        iCount = 12;
-
-      strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
-      iIndex += iCount;
-      if (iIndex < iLength)
-        strBuf << " Trillion ";
-    }
-    strBuf << " Cents";
-  }
-  return ByteString(strBuf);
-}
-
-// static
 void CFXJSE_FormCalcContext::Get(CFXJSE_Value* pThis,
                                  const ByteStringView& szFuncName,
                                  CFXJSE_Arguments& args) {
diff --git a/fxjs/cfxjse_formcalc_context.h b/fxjs/cfxjse_formcalc_context.h
index 8a92d9b..f605603 100644
--- a/fxjs/cfxjse_formcalc_context.h
+++ b/fxjs/cfxjse_formcalc_context.h
@@ -98,31 +98,6 @@
                       const ByteStringView& szFuncName,
                       CFXJSE_Arguments& args);
 
-  static bool IsIsoDateFormat(const char* pData,
-                              int32_t iLength,
-                              int32_t& iStyle,
-                              int32_t& iYear,
-                              int32_t& iMonth,
-                              int32_t& iDay);
-  static bool IsIsoTimeFormat(const char* pData,
-                              int32_t iLength,
-                              int32_t& iHour,
-                              int32_t& iMinute,
-                              int32_t& iSecond,
-                              int32_t& iMilliSecond,
-                              int32_t& iZoneHour,
-                              int32_t& iZoneMinute);
-  static bool IsIsoDateTimeFormat(const char* pData,
-                                  int32_t iLength,
-                                  int32_t& iYear,
-                                  int32_t& iMonth,
-                                  int32_t& iDay,
-                                  int32_t& iHour,
-                                  int32_t& iMinute,
-                                  int32_t& iSecond,
-                                  int32_t& iMillionSecond,
-                                  int32_t& iZoneHour,
-                                  int32_t& iZoneMinute);
   static ByteString Local2IsoDate(CFXJSE_Value* pThis,
                                   const ByteStringView& szDate,
                                   const ByteStringView& szFormat,
@@ -135,7 +110,6 @@
                                   const ByteStringView& szTime,
                                   const ByteStringView& szFormat,
                                   const ByteStringView& szLocale);
-  static int32_t DateString2Num(const ByteStringView& szDateString);
   static ByteString GetLocalDateFormat(CFXJSE_Value* pThis,
                                        int32_t iStyle,
                                        const ByteStringView& szLocalStr,
@@ -155,7 +129,6 @@
                                 const ByteStringView& szFormat,
                                 const ByteStringView& szLocale,
                                 bool bGM);
-  static void GetLocalTimeZone(int32_t& iHour, int32_t& iMin, int32_t& iSec);
 
   static void Apr(CFXJSE_Value* pThis,
                   const ByteStringView& szFuncName,
@@ -227,17 +200,9 @@
   static void Decode(CFXJSE_Value* pThis,
                      const ByteStringView& szFuncName,
                      CFXJSE_Arguments& args);
-  static WideString DecodeURL(const WideString& wsURLString);
-  static WideString DecodeHTML(const WideString& wsHTMLString);
-  static WideString DecodeXML(const WideString& wsXMLString);
   static void Encode(CFXJSE_Value* pThis,
                      const ByteStringView& szFuncName,
                      CFXJSE_Arguments& args);
-  static WideString EncodeURL(const ByteString& szURLString);
-  static WideString EncodeHTML(const ByteString& szHTMLString);
-  static WideString EncodeXML(const ByteString& szXMLString);
-  static bool HTMLSTR2Code(const WideStringView& pData, uint32_t* iCode);
-  static bool HTMLCode2STR(uint32_t iCode, WideString* wsHTMLReserve);
   static void Format(CFXJSE_Value* pThis,
                      const ByteStringView& szFuncName,
                      CFXJSE_Arguments& args);
@@ -286,8 +251,6 @@
   static void WordNum(CFXJSE_Value* pThis,
                       const ByteStringView& szFuncName,
                       CFXJSE_Arguments& args);
-  static ByteString TrillionUS(const ByteStringView& szData);
-  static ByteString WordUS(const ByteString& szData, int32_t iStyle);
 
   static void Get(CFXJSE_Value* pThis,
                   const ByteStringView& szFuncName,