diff options
Diffstat (limited to 'xfa/fxfa/parser/cxfa_localevalue.cpp')
-rw-r--r-- | xfa/fxfa/parser/cxfa_localevalue.cpp | 334 |
1 files changed, 159 insertions, 175 deletions
diff --git a/xfa/fxfa/parser/cxfa_localevalue.cpp b/xfa/fxfa/parser/cxfa_localevalue.cpp index c563f44082..113c8cc46e 100644 --- a/xfa/fxfa/parser/cxfa_localevalue.cpp +++ b/xfa/fxfa/parser/cxfa_localevalue.cpp @@ -16,41 +16,83 @@ #include "xfa/fxfa/parser/cxfa_localemgr.h" #include "xfa/fxfa/parser/xfa_utils.h" -CXFA_LocaleValue::CXFA_LocaleValue() { - m_dwType = XFA_VT_NULL; - m_bValid = true; - m_pLocaleMgr = nullptr; +namespace { + +FX_LOCALECATEGORY ValueCategory(FX_LOCALECATEGORY eCategory, + uint32_t dwValueType) { + if (eCategory != FX_LOCALECATEGORY_Unknown) + return eCategory; + + switch (dwValueType) { + case XFA_VT_BOOLEAN: + case XFA_VT_INTEGER: + case XFA_VT_DECIMAL: + case XFA_VT_FLOAT: + return FX_LOCALECATEGORY_Num; + case XFA_VT_TEXT: + return FX_LOCALECATEGORY_Text; + case XFA_VT_DATE: + return FX_LOCALECATEGORY_Date; + case XFA_VT_TIME: + return FX_LOCALECATEGORY_Time; + case XFA_VT_DATETIME: + return FX_LOCALECATEGORY_DateTime; + } + return FX_LOCALECATEGORY_Unknown; } -CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) { - m_dwType = XFA_VT_NULL; - m_bValid = true; - m_pLocaleMgr = nullptr; - *this = value; -} -CXFA_LocaleValue::CXFA_LocaleValue(uint32_t dwType, - CXFA_LocaleMgr* pLocaleMgr) { - m_dwType = dwType; - m_bValid = (m_dwType != XFA_VT_NULL); - m_pLocaleMgr = pLocaleMgr; + +bool ValueSplitDateTime(const CFX_WideString& wsDateTime, + CFX_WideString& wsDate, + CFX_WideString& wsTime) { + wsDate = L""; + wsTime = L""; + if (wsDateTime.IsEmpty()) + return false; + + int nSplitIndex = wsDateTime.Find('T'); + if (nSplitIndex < 0) + nSplitIndex = wsDateTime.Find(' '); + if (nSplitIndex < 0) + return false; + + wsDate = wsDateTime.Left(nSplitIndex); + wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1); + return true; } + +} // namespace + +CXFA_LocaleValue::CXFA_LocaleValue() + : m_pLocaleMgr(nullptr), m_dwType(XFA_VT_NULL), m_bValid(true) {} + +CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) + : m_pLocaleMgr(value.m_pLocaleMgr), + m_wsValue(value.m_wsValue), + m_dwType(value.m_dwType), + m_bValid(value.m_bValid) {} + +CXFA_LocaleValue::CXFA_LocaleValue(uint32_t dwType, CXFA_LocaleMgr* pLocaleMgr) + : m_pLocaleMgr(pLocaleMgr), + m_dwType(dwType), + m_bValid(m_dwType != XFA_VT_NULL) {} + CXFA_LocaleValue::CXFA_LocaleValue(uint32_t dwType, const CFX_WideString& wsValue, - CXFA_LocaleMgr* pLocaleMgr) { - m_wsValue = wsValue; - m_dwType = dwType; - m_pLocaleMgr = pLocaleMgr; - m_bValid = ValidateCanonicalValue(wsValue, dwType); -} + CXFA_LocaleMgr* pLocaleMgr) + : m_pLocaleMgr(pLocaleMgr), + m_wsValue(wsValue), + m_dwType(dwType), + m_bValid(ValidateCanonicalValue(wsValue, dwType)) {} + CXFA_LocaleValue::CXFA_LocaleValue(uint32_t dwType, const CFX_WideString& wsValue, const CFX_WideString& wsFormat, IFX_Locale* pLocale, - CXFA_LocaleMgr* pLocaleMgr) { - m_pLocaleMgr = pLocaleMgr; - m_bValid = true; - m_dwType = dwType; - m_bValid = ParsePatternValue(wsValue, wsFormat, pLocale); -} + CXFA_LocaleMgr* pLocaleMgr) + : m_pLocaleMgr(pLocaleMgr), + m_dwType(dwType), + m_bValid(ParsePatternValue(wsValue, wsFormat, pLocale)) {} + CXFA_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) { m_wsValue = value.m_wsValue; m_dwType = value.m_dwType; @@ -58,28 +100,8 @@ CXFA_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) { m_pLocaleMgr = value.m_pLocaleMgr; return *this; } + CXFA_LocaleValue::~CXFA_LocaleValue() {} -static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory, - uint32_t dwValueType) { - if (eCategory == FX_LOCALECATEGORY_Unknown) { - switch (dwValueType) { - case XFA_VT_BOOLEAN: - case XFA_VT_INTEGER: - case XFA_VT_DECIMAL: - case XFA_VT_FLOAT: - return FX_LOCALECATEGORY_Num; - case XFA_VT_TEXT: - return FX_LOCALECATEGORY_Text; - case XFA_VT_DATE: - return FX_LOCALECATEGORY_Date; - case XFA_VT_TIME: - return FX_LOCALECATEGORY_Time; - case XFA_VT_DATETIME: - return FX_LOCALECATEGORY_DateTime; - } - } - return eCategory; -} bool CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, const CFX_WideString& wsPattern, @@ -99,35 +121,29 @@ bool CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, int32_t i = 0; for (; i < iCount && !bRet; i++) { CFX_WideString wsFormat = wsPatterns[i]; - FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat); - eCategory = XFA_ValugeCategory(eCategory, m_dwType); - switch (eCategory) { + switch (ValueCategory(pFormat->GetCategory(wsFormat), m_dwType)) { case FX_LOCALECATEGORY_Null: bRet = pFormat->ParseNull(wsValue, wsFormat); - if (!bRet) { + if (!bRet) bRet = wsValue.IsEmpty(); - } break; case FX_LOCALECATEGORY_Zero: bRet = pFormat->ParseZero(wsValue, wsFormat); - if (!bRet) { + if (!bRet) bRet = wsValue == L"0"; - } break; case FX_LOCALECATEGORY_Num: { CFX_WideString fNum; bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); - if (!bRet) { + if (!bRet) bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput); - } break; } case FX_LOCALECATEGORY_Text: bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput); wsOutput.clear(); - if (!bRet) { + if (!bRet) bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput); - } break; case FX_LOCALECATEGORY_Date: { CFX_DateTime dt; @@ -169,19 +185,12 @@ bool CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, } if (bRet && pMatchFormat) *pMatchFormat = wsPatterns[i - 1]; - if (pLocale) m_pLocaleMgr->SetDefLocale(locale); return bRet; } -CFX_WideString CXFA_LocaleValue::GetValue() const { - return m_wsValue; -} -uint32_t CXFA_LocaleValue::GetType() const { - return m_dwType; -} double CXFA_LocaleValue::GetDoubleNum() const { if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER || m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) { @@ -189,7 +198,8 @@ double CXFA_LocaleValue::GetDoubleNum() const { uint32_t dwFractional = 0; int32_t nExponent = 0; int32_t cc = 0; - bool bNegative = false, bExpSign = false; + bool bNegative = false; + bool bExpSign = false; const wchar_t* str = m_wsValue.c_str(); int len = m_wsValue.GetLength(); while (FXSYS_iswspace(str[cc]) && cc < len) @@ -214,6 +224,7 @@ double CXFA_LocaleValue::GetDoubleNum() const { cc++; nIntegralLen++; } + nIntegral = bNegative ? -nIntegral : nIntegral; int32_t scale = 0; double fraction = 0.0; @@ -261,24 +272,22 @@ double CXFA_LocaleValue::GetDoubleNum() const { } CFX_DateTime CXFA_LocaleValue::GetDate() const { - if (m_bValid && m_dwType == XFA_VT_DATE) { - CFX_DateTime dt; - FX_DateFromCanonical(m_wsValue, &dt); - return dt; - } - return CFX_DateTime(); + if (!m_bValid || m_dwType != XFA_VT_DATE) + return CFX_DateTime(); + + CFX_DateTime dt; + FX_DateFromCanonical(m_wsValue, &dt); + return dt; } CFX_DateTime CXFA_LocaleValue::GetTime() const { - if (m_bValid && m_dwType == XFA_VT_TIME) { - ASSERT(m_pLocaleMgr); + if (!m_bValid || m_dwType != XFA_VT_TIME) + return CFX_DateTime(); - CFX_DateTime dt; - FX_TimeFromCanonical(m_wsValue.AsStringC(), &dt, - m_pLocaleMgr->GetDefLocale()); - return dt; - } - return CFX_DateTime(); + CFX_DateTime dt; + FX_TimeFromCanonical(m_wsValue.AsStringC(), &dt, + m_pLocaleMgr->GetDefLocale()); + return dt; } bool CXFA_LocaleValue::SetDate(const CFX_DateTime& d) { @@ -339,18 +348,16 @@ bool CXFA_LocaleValue::FormatSinglePattern(CFX_WideString& wsResult, wsResult.clear(); bool bRet = false; auto pFormat = pdfium::MakeUnique<CFGAS_FormatString>(m_pLocaleMgr); - FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat); - eCategory = XFA_ValugeCategory(eCategory, m_dwType); + FX_LOCALECATEGORY eCategory = + ValueCategory(pFormat->GetCategory(wsFormat), m_dwType); switch (eCategory) { case FX_LOCALECATEGORY_Null: - if (m_wsValue.IsEmpty()) { + if (m_wsValue.IsEmpty()) bRet = pFormat->FormatNull(wsFormat, wsResult); - } break; case FX_LOCALECATEGORY_Zero: - if (m_wsValue == L"0") { + if (m_wsValue == L"0") bRet = pFormat->FormatZero(wsFormat, wsResult); - } break; case FX_LOCALECATEGORY_Num: bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult); @@ -384,39 +391,20 @@ bool CXFA_LocaleValue::FormatSinglePattern(CFX_WideString& wsResult, return bRet; } -static bool XFA_ValueSplitDateTime(const CFX_WideString& wsDateTime, - CFX_WideString& wsDate, - CFX_WideString& wsTime) { - wsDate = L""; - wsTime = L""; - if (wsDateTime.IsEmpty()) { - return false; - } - int nSplitIndex = -1; - nSplitIndex = wsDateTime.Find('T'); - if (nSplitIndex < 0) { - nSplitIndex = wsDateTime.Find(' '); - } - if (nSplitIndex < 0) { - return false; - } - wsDate = wsDateTime.Left(nSplitIndex); - wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1); - return true; -} bool CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, uint32_t dwVType) { - if (wsValue.IsEmpty()) { + if (wsValue.IsEmpty()) return true; - } + CFX_DateTime dt; switch (dwVType) { case XFA_VT_DATE: { if (ValidateCanonicalDate(wsValue, &dt)) return true; - CFX_WideString wsDate, wsTime; - if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && + CFX_WideString wsDate; + CFX_WideString wsTime; + if (ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalDate(wsDate, &dt)) { return true; } @@ -426,8 +414,9 @@ bool CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, if (ValidateCanonicalTime(wsValue)) return true; - CFX_WideString wsDate, wsTime; - if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && + CFX_WideString wsDate; + CFX_WideString wsTime; + if (ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalTime(wsTime)) { return true; } @@ -435,7 +424,7 @@ bool CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, } case XFA_VT_DATETIME: { CFX_WideString wsDate, wsTime; - if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && + if (ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalDate(wsDate, &dt) && ValidateCanonicalTime(wsTime)) { return true; } @@ -443,82 +432,80 @@ bool CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, } return true; } + bool CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate, CFX_DateTime* unDate) { - const uint16_t LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - const uint16_t wCountY = 4, wCountM = 2, wCountD = 2; + static const uint16_t LastDay[12] = {31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31}; + static const uint16_t wCountY = 4; + static const uint16_t wCountM = 2; + static const uint16_t wCountD = 2; int nLen = wsDate.GetLength(); - if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) { + if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) return false; - } + const bool bSymbol = wsDate.Find(0x2D) != -1; uint16_t wYear = 0; uint16_t wMonth = 0; uint16_t wDay = 0; const wchar_t* pDate = wsDate.c_str(); - int nIndex = 0, nStart = 0; + int nIndex = 0; + int nStart = 0; while (pDate[nIndex] != '\0' && nIndex < wCountY) { - if (!FXSYS_isDecimalDigit(pDate[nIndex])) { + if (!FXSYS_isDecimalDigit(pDate[nIndex])) return false; - } + wYear = (pDate[nIndex] - '0') + wYear * 10; nIndex++; } if (bSymbol) { - if (pDate[nIndex] != 0x2D) { + if (pDate[nIndex] != 0x2D) return false; - } nIndex++; } + nStart = nIndex; while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) { - if (!FXSYS_isDecimalDigit(pDate[nIndex])) { + if (!FXSYS_isDecimalDigit(pDate[nIndex])) return false; - } + wMonth = (pDate[nIndex] - '0') + wMonth * 10; nIndex++; } if (bSymbol) { - if (pDate[nIndex] != 0x2D) { + if (pDate[nIndex] != 0x2D) return false; - } nIndex++; } + nStart = nIndex; while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) { - if (!FXSYS_isDecimalDigit(pDate[nIndex])) { + if (!FXSYS_isDecimalDigit(pDate[nIndex])) return false; - } + wDay = (pDate[nIndex] - '0') + wDay * 10; nIndex++; } - if (nIndex != nLen) { + if (nIndex != nLen) return false; - } - if (wYear < 1900 || wYear > 2029) { + if (wYear < 1900 || wYear > 2029) return false; - } if (wMonth < 1 || wMonth > 12) { - if (wMonth == 0 && nLen == wCountY) { + if (wMonth == 0 && nLen == wCountY) return true; - } return false; } if (wDay < 1) { - if (wDay == 0 && (nLen == wCountY + wCountM)) { + if (wDay == 0 && (nLen == wCountY + wCountM)) return true; - } return false; } if (wMonth == 2) { if (wYear % 400 == 0 || (wYear % 100 != 0 && wYear % 4 == 0)) { - if (wDay > 29) { - return false; - } - } else { - if (wDay > 28) { + if (wDay > 29) return false; - } + } else if (wDay > 28) { + return false; } } else if (wDay > LastDay[wMonth - 1]) { return false; @@ -533,6 +520,7 @@ bool CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) { int nLen = wsTime.GetLength(); if (nLen < 2) return false; + const uint16_t wCountH = 2; const uint16_t wCountM = 2; const uint16_t wCountS = 2; @@ -556,6 +544,7 @@ bool CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) { return false; nIndex++; } + nStart = nIndex; while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) { if (!FXSYS_isDecimalDigit(pTime[nIndex])) @@ -635,14 +624,11 @@ bool CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, int32_t iCount = pdfium::CollectionSize<int32_t>(wsPatterns); for (int32_t i = 0; i < iCount && !bRet; i++) { CFX_WideString wsFormat = wsPatterns[i]; - FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat); - eCategory = XFA_ValugeCategory(eCategory, m_dwType); - switch (eCategory) { + switch (ValueCategory(pFormat->GetCategory(wsFormat), m_dwType)) { case FX_LOCALECATEGORY_Null: bRet = pFormat->ParseNull(wsValue, wsFormat); - if (bRet) { + if (bRet) m_wsValue.clear(); - } break; case FX_LOCALECATEGORY_Zero: bRet = pFormat->ParseZero(wsValue, wsFormat); @@ -652,9 +638,8 @@ bool CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, case FX_LOCALECATEGORY_Num: { CFX_WideString fNum; bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); - if (bRet) { + if (bRet) m_wsValue = fNum; - } break; } case FX_LOCALECATEGORY_Text: @@ -702,19 +687,18 @@ bool CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, return bRet; } -void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat, - int32_t nIntLen, - int32_t nDecLen, - bool bSign) { +void CXFA_LocaleValue::GetNumericFormat(CFX_WideString& wsFormat, + int32_t nIntLen, + int32_t nDecLen) { ASSERT(wsFormat.IsEmpty()); ASSERT(nIntLen >= -1 && nDecLen >= -1); - int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + (bSign ? 1 : 0) + + + int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + 1 + (nDecLen >= 0 ? nDecLen : 2) + (nDecLen == 0 ? 0 : 1); wchar_t* lpBuf = wsFormat.GetBuffer(nTotalLen); int32_t nPos = 0; - if (bSign) { - lpBuf[nPos++] = L's'; - } + lpBuf[nPos++] = L's'; + if (nIntLen == -1) { lpBuf[nPos++] = L'z'; lpBuf[nPos++] = L'*'; @@ -738,37 +722,37 @@ void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat, } wsFormat.ReleaseBuffer(nTotalLen); } -bool CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, - CFX_WideString& wsFormat, - IFX_Locale* pLocale, - int32_t* pos) { - if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) { + +bool CXFA_LocaleValue::ValidateNumericTemp(const CFX_WideString& wsNumeric, + const CFX_WideString& wsFormat, + IFX_Locale* pLocale) { + if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) return true; - } + const wchar_t* pNum = wsNumeric.c_str(); const wchar_t* pFmt = wsFormat.c_str(); - int32_t n = 0, nf = 0; + int32_t n = 0; + int32_t nf = 0; wchar_t c = pNum[n]; wchar_t cf = pFmt[nf]; if (cf == L's') { - if (c == L'-' || c == L'+') { + if (c == L'-' || c == L'+') ++n; - } ++nf; } + bool bLimit = true; int32_t nCount = wsNumeric.GetLength(); int32_t nCountFmt = wsFormat.GetLength(); while (n < nCount && (bLimit ? nf < nCountFmt : true) && FXSYS_isDecimalDigit(c = pNum[n])) { if (bLimit == true) { - if ((cf = pFmt[nf]) == L'*') { + if ((cf = pFmt[nf]) == L'*') bLimit = false; - } else if (cf == L'z') { + else if (cf == L'z') nf++; - } else { + else return false; - } } n++; } @@ -781,6 +765,7 @@ bool CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, ASSERT(cf == L'z' || cf == L'*'); ++nf; } + CFX_WideString wsDecimalSymbol; if (pLocale) wsDecimalSymbol = pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal); @@ -798,13 +783,12 @@ bool CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, while (n < nCount && (bLimit ? nf < nCountFmt : true) && FXSYS_isDecimalDigit(c = pNum[n])) { if (bLimit == true) { - if ((cf = pFmt[nf]) == L'*') { + if ((cf = pFmt[nf]) == L'*') bLimit = false; - } else if (cf == L'z') { + else if (cf == L'z') nf++; - } else { + else return false; - } } n++; } |