Replace some in/out parameters in cfgas_stringformatter.cpp
Doing so allows the optimizer to remove another bounds check
in GetLiteralText() since there is less aliasing possible.
- small logic tidy in FormatDateTime()
- consolidate FormatNull() and FormatZero() implementations.
Change-Id: If7b2e7acc1b01ccb64792510a64286016c623ad0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/51850
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fgas/crt/cfgas_stringformatter.cpp b/xfa/fgas/crt/cfgas_stringformatter.cpp
index ee8321f..2118b08 100644
--- a/xfa/fgas/crt/cfgas_stringformatter.cpp
+++ b/xfa/fgas/crt/cfgas_stringformatter.cpp
@@ -108,64 +108,67 @@
return iKeyValue;
}
-WideString GetLiteralText(pdfium::span<const wchar_t> pStrPattern,
- size_t* iPattern) {
+// Returns {next character position, literal text string}.
+std::pair<size_t, WideString> GetLiteralText(
+ pdfium::span<const wchar_t> pStrPattern,
+ size_t iPattern) {
WideString wsOutput;
- if (*iPattern >= pStrPattern.size() || pStrPattern[*iPattern] != '\'')
- return wsOutput;
+ if (iPattern >= pStrPattern.size() || pStrPattern[iPattern] != '\'')
+ return {iPattern, wsOutput};
- (*iPattern)++;
+ iPattern++;
int32_t iQuote = 1;
- while (*iPattern < pStrPattern.size()) {
- if (pStrPattern[*iPattern] == '\'') {
+ while (iPattern < pStrPattern.size()) {
+ if (pStrPattern[iPattern] == '\'') {
iQuote++;
- if ((*iPattern + 1 >= pStrPattern.size()) ||
- ((pStrPattern[*iPattern + 1] != '\'') && (iQuote % 2 == 0))) {
+ if (iPattern + 1 >= pStrPattern.size() ||
+ ((pStrPattern[iPattern + 1] != '\'') && (iQuote % 2 == 0))) {
break;
}
iQuote++;
- (*iPattern)++;
- } else if (pStrPattern[*iPattern] == '\\' &&
- (*iPattern + 1 < pStrPattern.size()) &&
- pStrPattern[*iPattern + 1] == 'u') {
+ iPattern++;
+ } else if (pStrPattern[iPattern] == '\\' &&
+ iPattern + 1 < pStrPattern.size() &&
+ pStrPattern[iPattern + 1] == 'u') {
int32_t iKeyValue = 0;
- *iPattern += 2;
- for (int32_t i = 0; *iPattern < pStrPattern.size() && i < 4; ++i) {
- wchar_t ch = pStrPattern[(*iPattern)++];
+ iPattern += 2;
+ for (size_t i = 0; iPattern < pStrPattern.size() && i < 4; ++i) {
+ wchar_t ch = pStrPattern[iPattern++];
iKeyValue = ConvertHex(iKeyValue, ch);
}
if (iKeyValue != 0)
wsOutput += static_cast<wchar_t>(iKeyValue & 0x0000FFFF);
-
continue;
}
- wsOutput += pStrPattern[(*iPattern)++];
+ wsOutput += pStrPattern[iPattern++];
}
- return wsOutput;
+ return {iPattern, wsOutput};
}
-WideString GetLiteralTextReverse(pdfium::span<const wchar_t> pStrPattern,
- size_t* iPattern) {
+// Returns {next character position, literal text string}.
+std::pair<size_t, WideString> GetLiteralTextReverse(
+ pdfium::span<const wchar_t> pStrPattern,
+ size_t iPattern) {
WideString wsOutput;
- if (*iPattern >= pStrPattern.size() || pStrPattern[*iPattern] != '\'')
- return wsOutput;
+ if (iPattern >= pStrPattern.size() || pStrPattern[iPattern] != '\'')
+ return {iPattern, wsOutput};
- (*iPattern)--;
+ iPattern--;
int32_t iQuote = 1;
- while (*iPattern < pStrPattern.size()) {
- if (pStrPattern[*iPattern] == '\'') {
+ while (iPattern < pStrPattern.size()) {
+ if (pStrPattern[iPattern] == '\'') {
iQuote++;
- if (*iPattern - 1 >= pStrPattern.size() ||
- ((pStrPattern[*iPattern - 1] != '\'') && (iQuote % 2 == 0))) {
+ if (iPattern - 1 >= pStrPattern.size() ||
+ ((pStrPattern[iPattern - 1] != '\'') && (iQuote % 2 == 0))) {
break;
}
iQuote++;
- (*iPattern)--;
- } else if (pStrPattern[*iPattern] == '\\' &&
- *iPattern + 1 < pStrPattern.size() &&
- pStrPattern[*iPattern + 1] == 'u') {
- (*iPattern)--;
+ iPattern--;
+ } else if (pStrPattern[iPattern] == '\\' &&
+ iPattern + 1 < pStrPattern.size() &&
+ pStrPattern[iPattern + 1] == 'u') {
+ iPattern--;
int32_t iKeyValue = 0;
int32_t iLen = wsOutput.GetLength();
int32_t i = 1;
@@ -179,9 +182,9 @@
}
continue;
}
- wsOutput = pStrPattern[(*iPattern)--] + wsOutput;
+ wsOutput = pStrPattern[iPattern--] + wsOutput;
}
- return wsOutput;
+ return {iPattern, wsOutput};
}
bool GetNumericDotIndex(const WideString& wsNum,
@@ -191,7 +194,7 @@
pdfium::span<const wchar_t> spDotSymbol = wsDotSymbol.AsSpan();
for (size_t ccf = 0; ccf < spNum.size(); ++ccf) {
if (spNum[ccf] == '\'') {
- GetLiteralText(spNum, &ccf);
+ ccf = GetLiteralText(spNum, ccf).first;
continue;
}
if (ccf + spDotSymbol.size() <= spNum.size() &&
@@ -241,7 +244,8 @@
WideStringView wsDateSymbols(gs_wsDateSymbols);
while (*cc < spDate.size() && ccf < spDatePattern.size()) {
if (spDatePattern[ccf] == '\'') {
- WideString wsLiteral = GetLiteralText(spDatePattern, &ccf);
+ WideString wsLiteral;
+ std::tie(ccf, wsLiteral) = GetLiteralText(spDatePattern, ccf);
int32_t iLiteralLen = wsLiteral.GetLength();
if (*cc + iLiteralLen > spDate.size() ||
wcsncmp(spDate.data() + *cc, wsLiteral.c_str(), iLiteralLen) != 0) {
@@ -364,8 +368,9 @@
WideStringView wsTimeSymbols(gs_wsTimeSymbols);
while (*cc < spTime.size() && ccf < spTimePattern.size()) {
if (spTimePattern[ccf] == '\'') {
- WideString wsLiteral = GetLiteralText(spTimePattern, &ccf);
- int32_t iLiteralLen = wsLiteral.GetLength();
+ WideString wsLiteral;
+ std::tie(ccf, wsLiteral) = GetLiteralText(spTimePattern, ccf);
+ size_t iLiteralLen = wsLiteral.GetLength();
if (*cc + iLiteralLen > spTime.size() ||
wcsncmp(spTime.data() + *cc, wsLiteral.c_str(), iLiteralLen) != 0) {
return false;
@@ -576,7 +581,9 @@
WideStringView wsDateSymbols(gs_wsDateSymbols);
while (ccf < spDatePattern.size()) {
if (spDatePattern[ccf] == '\'') {
- wsResult += GetLiteralText(spDatePattern, &ccf);
+ WideString wsPiece;
+ std::tie(ccf, wsPiece) = GetLiteralText(spDatePattern, ccf);
+ wsResult += wsPiece;
ccf++;
continue;
}
@@ -646,7 +653,9 @@
WideStringView wsTimeSymbols(gs_wsTimeSymbols);
while (ccf < spTimePattern.size()) {
if (spTimePattern[ccf] == '\'') {
- wsResult += GetLiteralText(spTimePattern, &ccf);
+ WideString wsPiece;
+ std::tie(ccf, wsPiece) = GetLiteralText(spTimePattern, ccf);
+ wsResult += wsPiece;
ccf++;
continue;
}
@@ -857,7 +866,7 @@
WideStringView wsConstChars(gs_wsConstChars);
while (ccf < spPattern.size()) {
if (spPattern[ccf] == '\'') {
- GetLiteralText(spPattern, &ccf);
+ ccf = GetLiteralText(spPattern, ccf).first;
} else if (!bBraceOpen && !wsConstChars.Contains(spPattern[ccf])) {
WideString wsCategory(spPattern[ccf]);
ccf++;
@@ -913,7 +922,7 @@
while (ccf < spPattern.size()) {
if (spPattern[ccf] == '\'') {
int32_t iCurChar = ccf;
- GetLiteralText(spPattern, &ccf);
+ ccf = GetLiteralText(spPattern, ccf).first;
wsPurgePattern +=
WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
} else if (!bBrackOpen && !wsConstChars.Contains(spPattern[ccf])) {
@@ -965,7 +974,7 @@
while (ccf < spPattern.size()) {
if (spPattern[ccf] == '\'') {
int32_t iCurChar = ccf;
- GetLiteralText(spPattern, &ccf);
+ ccf = GetLiteralText(spPattern, ccf).first;
*wsPurgePattern +=
WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
} else if (!bBrackOpen && !wsConstChars.Contains(spPattern[ccf])) {
@@ -1074,8 +1083,9 @@
while (iPattern < spTextFormat.size() && iText < spSrcText.size()) {
switch (spTextFormat[iPattern]) {
case '\'': {
- WideString wsLiteral = GetLiteralText(spTextFormat, &iPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
+ WideString wsLiteral;
+ std::tie(iPattern, wsLiteral) = GetLiteralText(spTextFormat, iPattern);
+ size_t iLiteralLen = wsLiteral.GetLength();
if (iText + iLiteralLen > spSrcText.size() ||
wcsncmp(spSrcText.data() + iText, wsLiteral.c_str(), iLiteralLen) !=
0) {
@@ -1176,7 +1186,8 @@
while (ccf < spNumFormat.size() && cc < spSrcNum.size()) {
switch (spNumFormat[ccf]) {
case '\'': {
- WideString wsLiteral = GetLiteralTextReverse(spNumFormat, &ccf);
+ WideString wsLiteral;
+ std::tie(ccf, wsLiteral) = GetLiteralTextReverse(spNumFormat, ccf);
int32_t iLiteralLen = wsLiteral.GetLength();
cc -= iLiteralLen - 1;
if (cc >= spSrcNum.size() ||
@@ -1366,8 +1377,9 @@
cc < spSrcNum.size() && ccf < spNumFormat.size(); ++ccf) {
switch (spNumFormat[ccf]) {
case '\'': {
- WideString wsLiteral = GetLiteralText(spNumFormat, &ccf);
- int32_t iLiteralLen = wsLiteral.GetLength();
+ WideString wsLiteral;
+ std::tie(ccf, wsLiteral) = GetLiteralText(spNumFormat, ccf);
+ size_t iLiteralLen = wsLiteral.GetLength();
if (cc + iLiteralLen > spSrcNum.size() ||
wcsncmp(spSrcNum.data() + cc, wsLiteral.c_str(), iLiteralLen) !=
0) {
@@ -1557,7 +1569,7 @@
while (ccf < spPattern.size()) {
if (spPattern[ccf] == '\'') {
int32_t iCurChar = ccf;
- GetLiteralText(spPattern, &ccf);
+ ccf = GetLiteralText(spPattern, ccf).first;
wsTempPattern +=
WideStringView(spPattern.data() + iCurChar, ccf - iCurChar + 1);
} else if (!bBraceOpen && iFindCategory != 3 &&
@@ -1733,8 +1745,9 @@
size_t iPattern = 0;
while (iPattern < spTextFormat.size() && iText < spSrcText.size()) {
if (spTextFormat[iPattern] == '\'') {
- WideString wsLiteral = GetLiteralText(spTextFormat, &iPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
+ WideString wsLiteral;
+ std::tie(iPattern, wsLiteral) = GetLiteralText(spTextFormat, iPattern);
+ size_t iLiteralLen = wsLiteral.GetLength();
if (iText + iLiteralLen > spSrcText.size() ||
wcsncmp(spSrcText.data() + iText, wsLiteral.c_str(), iLiteralLen)) {
return false;
@@ -1762,8 +1775,9 @@
size_t iPattern = 0;
while (iPattern < spTextFormat.size() && iText < spSrcText.size()) {
if (spTextFormat[iPattern] == '\'') {
- WideString wsLiteral = GetLiteralText(spTextFormat, &iPattern);
- int32_t iLiteralLen = wsLiteral.GetLength();
+ WideString wsLiteral;
+ std::tie(iPattern, wsLiteral) = GetLiteralText(spTextFormat, iPattern);
+ size_t iLiteralLen = wsLiteral.GetLength();
if (iText + iLiteralLen > spSrcText.size() ||
wcsncmp(spSrcText.data() + iText, wsLiteral.c_str(), iLiteralLen)) {
return false;
@@ -1796,7 +1810,9 @@
while (iPattern < spTextFormat.size()) {
switch (spTextFormat[iPattern]) {
case '\'': {
- *wsOutput += GetLiteralText(spTextFormat, &iPattern);
+ WideString wsPiece;
+ std::tie(iPattern, wsPiece) = GetLiteralText(spTextFormat, iPattern);
+ *wsOutput += wsPiece;
iPattern++;
break;
}
@@ -1872,7 +1888,7 @@
for (size_t ccf = 0; ccf < dot_index_f; ++ccf) {
switch (spNumFormat[ccf]) {
case '\'':
- GetLiteralText(spNumFormat, &ccf);
+ ccf = GetLiteralText(spNumFormat, ccf).first;
break;
case '9':
case 'z':
@@ -2040,9 +2056,12 @@
case ')':
wsOutput->InsertAtFront(bNeg ? L')' : L' ');
break;
- case '\'':
- *wsOutput = GetLiteralTextReverse(spNumFormat, &ccf) + *wsOutput;
+ case '\'': {
+ WideString wsPiece;
+ std::tie(ccf, wsPiece) = GetLiteralTextReverse(spNumFormat, ccf);
+ *wsOutput = wsPiece + *wsOutput;
break;
+ }
default:
wsOutput->InsertAtFront(spNumFormat[ccf]);
break;
@@ -2086,9 +2105,12 @@
cc = dot_index.value() + 1;
for (size_t ccf = dot_index_f + 1; ccf < spNumFormat.size(); ++ccf) {
switch (spNumFormat[ccf]) {
- case '\'':
- *wsOutput += GetLiteralText(spNumFormat, &ccf);
+ case '\'': {
+ WideString wsPiece;
+ std::tie(ccf, wsPiece) = GetLiteralText(spNumFormat, ccf);
+ *wsOutput += wsPiece;
break;
+ }
case '9':
if (cc < spSrcNum.size()) {
if (!FXSYS_IsDecimalDigit(spSrcNum[cc]))
@@ -2202,12 +2224,12 @@
return false;
if (eCategory == FX_DATETIMETYPE_Unknown) {
+ if (eDateTimeType == FX_DATETIMETYPE_Unknown)
+ return false;
+
if (eDateTimeType == FX_DATETIMETYPE_Time)
wsTimePattern = std::move(wsDatePattern);
-
eCategory = eDateTimeType;
- if (eCategory == FX_DATETIMETYPE_Unknown)
- return false;
}
CFX_DateTime dt;
@@ -2225,52 +2247,49 @@
pLocale);
return true;
}
- } else {
- pdfium::span<const wchar_t> wsSrcDate =
- wsSrcDateTime.AsSpan().first(iT.value());
- pdfium::span<const wchar_t> wsSrcTime =
- wsSrcDateTime.AsSpan().subspan(iT.value() + 1);
- if (wsSrcDate.empty() || wsSrcTime.empty())
- return false;
+ return false;
+ }
- if (FX_DateFromCanonical(wsSrcDate, &dt) &&
- FX_TimeFromCanonical(pLocale, wsSrcTime, &dt)) {
- *wsOutput = FormatDateTimeInternal(dt, wsDatePattern, wsTimePattern,
- eCategory != FX_DATETIMETYPE_TimeDate,
- pLocale);
- return true;
- }
+ pdfium::span<const wchar_t> wsSrcDate =
+ wsSrcDateTime.AsSpan().first(iT.value());
+ pdfium::span<const wchar_t> wsSrcTime =
+ wsSrcDateTime.AsSpan().subspan(iT.value() + 1);
+ if (wsSrcDate.empty() || wsSrcTime.empty())
+ return false;
+
+ if (FX_DateFromCanonical(wsSrcDate, &dt) &&
+ FX_TimeFromCanonical(pLocale, wsSrcTime, &dt)) {
+ *wsOutput =
+ FormatDateTimeInternal(dt, wsDatePattern, wsTimePattern,
+ eCategory != FX_DATETIMETYPE_TimeDate, pLocale);
+ return true;
}
return false;
}
bool CFGAS_StringFormatter::FormatZero(const WideString& wsPattern,
WideString* wsOutput) const {
- if (wsPattern.IsEmpty())
- return false;
-
- WideString wsTextFormat = GetTextFormat(wsPattern, L"zero");
- pdfium::span<const wchar_t> spTextFormat = wsTextFormat.AsSpan();
- for (size_t iPattern = 0; iPattern < spTextFormat.size(); ++iPattern) {
- if (spTextFormat[iPattern] == '\'') {
- *wsOutput += GetLiteralText(spTextFormat, &iPattern);
- continue;
- }
- *wsOutput += spTextFormat[iPattern];
- }
- return true;
+ return FormatZeroOrNull(L"zero", wsPattern, wsOutput);
}
bool CFGAS_StringFormatter::FormatNull(const WideString& wsPattern,
WideString* wsOutput) const {
+ return FormatZeroOrNull(L"null", wsPattern, wsOutput);
+}
+
+bool CFGAS_StringFormatter::FormatZeroOrNull(const wchar_t* what,
+ const WideString& wsPattern,
+ WideString* wsOutput) const {
if (wsPattern.IsEmpty())
return false;
- WideString wsTextFormat = GetTextFormat(wsPattern, L"null");
+ WideString wsTextFormat = GetTextFormat(wsPattern, what);
pdfium::span<const wchar_t> spTextFormat = wsTextFormat.AsSpan();
for (size_t iPattern = 0; iPattern < spTextFormat.size(); ++iPattern) {
if (spTextFormat[iPattern] == '\'') {
- *wsOutput += GetLiteralText(spTextFormat, &iPattern);
+ WideString wsPiece;
+ std::tie(iPattern, wsPiece) = GetLiteralText(spTextFormat, iPattern);
+ *wsOutput += wsPiece;
continue;
}
*wsOutput += spTextFormat[iPattern];
diff --git a/xfa/fgas/crt/cfgas_stringformatter.h b/xfa/fgas/crt/cfgas_stringformatter.h
index 9583724..cc534f4 100644
--- a/xfa/fgas/crt/cfgas_stringformatter.h
+++ b/xfa/fgas/crt/cfgas_stringformatter.h
@@ -67,6 +67,9 @@
LocaleIface** pLocale,
WideString* wsDatePattern,
WideString* wsTimePattern) const;
+ bool FormatZeroOrNull(const wchar_t* what,
+ const WideString& wsPattern,
+ WideString* wsOutput) const;
UnownedPtr<LocaleMgrIface> const m_pLocaleMgr;
};