Index: xfa/src/fxfa/src/parser/xfa_localevalue.cpp |
diff --git a/xfa/src/fxfa/src/parser/xfa_localevalue.cpp b/xfa/src/fxfa/src/parser/xfa_localevalue.cpp |
index 24731b06683b301edf04fb843495d1954f36d238..75f7023d260d277fac5707b529a660e1795639f8 100644 |
--- a/xfa/src/fxfa/src/parser/xfa_localevalue.cpp |
+++ b/xfa/src/fxfa/src/parser/xfa_localevalue.cpp |
@@ -1,1001 +1,1001 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
- |
-#include "xfa/src/foxitlib.h" |
-#include "xfa/src/fxfa/src/common/xfa_utils.h" |
-#include "xfa/src/fxfa/src/common/xfa_object.h" |
-#include "xfa/src/fxfa/src/common/xfa_document.h" |
-#include "xfa/src/fxfa/src/common/xfa_parser.h" |
-#include "xfa/src/fxfa/src/common/xfa_script.h" |
-#include "xfa/src/fxfa/src/common/xfa_docdata.h" |
-#include "xfa/src/fxfa/src/common/xfa_doclayout.h" |
-#include "xfa/src/fxfa/src/common/xfa_localemgr.h" |
-#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" |
-static const FX_DOUBLE fraction_scales[] = {0.1, |
- 0.01, |
- 0.001, |
- 0.0001, |
- 0.00001, |
- 0.000001, |
- 0.0000001, |
- 0.00000001, |
- 0.000000001, |
- 0.0000000001, |
- 0.00000000001, |
- 0.000000000001, |
- 0.0000000000001, |
- 0.00000000000001, |
- 0.000000000000001, |
- 0.0000000000000001}; |
-CXFA_LocaleValue::CXFA_LocaleValue() { |
- m_dwType = XFA_VT_NULL; |
- m_bValid = TRUE; |
- m_pLocaleMgr = NULL; |
-} |
-CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) { |
- m_dwType = XFA_VT_NULL; |
- m_bValid = TRUE; |
- m_pLocaleMgr = NULL; |
- *this = value; |
-} |
-CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, |
- CXFA_LocaleMgr* pLocaleMgr) { |
- m_dwType = dwType; |
- m_bValid = (m_dwType != XFA_VT_NULL); |
- m_pLocaleMgr = pLocaleMgr; |
-} |
-CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, |
- const CFX_WideString& wsValue, |
- CXFA_LocaleMgr* pLocaleMgr) { |
- m_wsValue = wsValue; |
- m_dwType = dwType; |
- m_pLocaleMgr = pLocaleMgr; |
- m_bValid = ValidateCanonicalValue(wsValue, dwType); |
-} |
-CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD 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_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) { |
- m_wsValue = value.m_wsValue; |
- m_dwType = value.m_dwType; |
- m_bValid = value.m_bValid; |
- m_pLocaleMgr = value.m_pLocaleMgr; |
- return *this; |
-} |
-CXFA_LocaleValue::~CXFA_LocaleValue() {} |
-static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory, |
- FX_DWORD 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; |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, |
- const CFX_WideString& wsPattern, |
- IFX_Locale* pLocale, |
- CFX_WideString* pMatchFormat) { |
- CFX_WideString wsOutput; |
- IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(pLocale); |
- } |
- IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
- CFX_WideStringArray wsPatterns; |
- pFormat->SplitFormatString(wsPattern, wsPatterns); |
- FX_BOOL bRet = FALSE; |
- int32_t iCount = wsPatterns.GetSize(); |
- 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) { |
- case FX_LOCALECATEGORY_Null: |
- bRet = pFormat->ParseNull(wsValue, wsFormat); |
- if (!bRet) { |
- bRet = wsValue.IsEmpty(); |
- } |
- break; |
- case FX_LOCALECATEGORY_Zero: |
- bRet = pFormat->ParseZero(wsValue, wsFormat); |
- if (!bRet) { |
- bRet = wsValue == FX_WSTRC(L"0"); |
- } |
- break; |
- case FX_LOCALECATEGORY_Num: { |
- CFX_WideString fNum; |
- bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); |
- if (!bRet) { |
- bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput); |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_Text: |
- bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput); |
- wsOutput.Empty(); |
- if (!bRet) { |
- bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput); |
- } |
- break; |
- case FX_LOCALECATEGORY_Date: { |
- CFX_Unitime dt; |
- bRet = ValidateCanonicalDate(wsValue, dt); |
- if (!bRet) { |
- bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, |
- dt); |
- if (!bRet) { |
- bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
- FX_DATETIMETYPE_Date); |
- } |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_Time: { |
- CFX_Unitime dt; |
- bRet = |
- pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt); |
- if (!bRet) { |
- bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
- FX_DATETIMETYPE_Time); |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_DateTime: { |
- CFX_Unitime dt; |
- bRet = pFormat->ParseDateTime(wsValue, wsFormat, |
- FX_DATETIMETYPE_DateTime, dt); |
- if (!bRet) { |
- bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
- FX_DATETIMETYPE_DateTime); |
- } |
- break; |
- } |
- default: |
- bRet = FALSE; |
- break; |
- } |
- } |
- if (bRet && pMatchFormat) { |
- *pMatchFormat = wsPatterns[i - 1]; |
- } |
- pFormat->Release(); |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(locale); |
- } |
- return bRet; |
-} |
-CFX_WideString CXFA_LocaleValue::GetValue() const { |
- return m_wsValue; |
-} |
-FX_DWORD CXFA_LocaleValue::GetType() const { |
- return m_dwType; |
-} |
-void CXFA_LocaleValue::SetValue(const CFX_WideString& wsValue, |
- FX_DWORD dwType) { |
- m_wsValue = wsValue; |
- m_dwType = dwType; |
-} |
-CFX_WideString CXFA_LocaleValue::GetText() const { |
- if (m_bValid && m_dwType == XFA_VT_TEXT) { |
- return m_wsValue; |
- } |
- return CFX_WideString(); |
-} |
-FX_FLOAT CXFA_LocaleValue::GetNum() const { |
- if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER || |
- m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) { |
- int64_t nIntegral = 0; |
- FX_DWORD dwFractional = 0; |
- int32_t nExponent = 0; |
- int cc = 0; |
- FX_BOOL bNegative = FALSE, bExpSign = FALSE; |
- const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue; |
- int len = m_wsValue.GetLength(); |
- while (XFA_IsSpace(str[cc]) && cc < len) { |
- cc++; |
- } |
- if (cc >= len) { |
- return 0; |
- } |
- if (str[0] == '+') { |
- cc++; |
- } else if (str[0] == '-') { |
- bNegative = TRUE; |
- cc++; |
- } |
- int nIntegralLen = 0; |
- while (cc < len) { |
- if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) { |
- break; |
- } |
- nIntegral = nIntegral * 10 + str[cc] - '0'; |
- cc++; |
- nIntegralLen++; |
- } |
- nIntegral = bNegative ? -nIntegral : nIntegral; |
- int scale = 0; |
- double fraction = 0.0; |
- if (cc < len && str[cc] == '.') { |
- cc++; |
- while (cc < len) { |
- fraction += fraction_scales[scale] * (str[cc] - '0'); |
- scale++; |
- cc++; |
- if (scale == sizeof fraction_scales / sizeof(double) || |
- !XFA_IsDigit(str[cc])) { |
- break; |
- } |
- } |
- dwFractional = (FX_DWORD)(fraction * 4294967296.0); |
- } |
- if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) { |
- cc++; |
- if (cc < len) { |
- if (str[cc] == '+') { |
- cc++; |
- } else if (str[cc] == '-') { |
- bExpSign = TRUE; |
- cc++; |
- } |
- } |
- while (cc < len) { |
- if (str[cc] == '.' || !XFA_IsDigit(str[cc])) { |
- break; |
- } |
- nExponent = nExponent * 10 + str[cc] - '0'; |
- cc++; |
- } |
- nExponent = bExpSign ? -nExponent : nExponent; |
- } |
- FX_FLOAT fValue = (FX_FLOAT)(dwFractional / 4294967296.0); |
- fValue = nIntegral + (nIntegral >= 0 ? fValue : -fValue); |
- if (nExponent != 0) { |
- fValue *= FXSYS_pow(10, (FX_FLOAT)nExponent); |
- } |
- return fValue; |
- } |
- return 0; |
-} |
-FX_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)) { |
- int64_t nIntegral = 0; |
- FX_DWORD dwFractional = 0; |
- int32_t nExponent = 0; |
- int32_t cc = 0; |
- FX_BOOL bNegative = FALSE, bExpSign = FALSE; |
- const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue; |
- int len = m_wsValue.GetLength(); |
- while (XFA_IsSpace(str[cc]) && cc < len) { |
- cc++; |
- } |
- if (cc >= len) { |
- return 0; |
- } |
- if (str[0] == '+') { |
- cc++; |
- } else if (str[0] == '-') { |
- bNegative = TRUE; |
- cc++; |
- } |
- int32_t nIntegralLen = 0; |
- while (cc < len) { |
- if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) { |
- break; |
- } |
- nIntegral = nIntegral * 10 + str[cc] - '0'; |
- cc++; |
- nIntegralLen++; |
- } |
- nIntegral = bNegative ? -nIntegral : nIntegral; |
- int32_t scale = 0; |
- FX_DOUBLE fraction = 0.0; |
- if (cc < len && str[cc] == '.') { |
- cc++; |
- while (cc < len) { |
- fraction += fraction_scales[scale] * (str[cc] - '0'); |
- scale++; |
- cc++; |
- if (scale == sizeof fraction_scales / sizeof(FX_DOUBLE) || |
- !XFA_IsDigit(str[cc])) { |
- break; |
- } |
- } |
- dwFractional = (FX_DWORD)(fraction * 4294967296.0); |
- } |
- if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) { |
- cc++; |
- if (cc < len) { |
- if (str[cc] == '+') { |
- cc++; |
- } else if (str[cc] == '-') { |
- bExpSign = TRUE; |
- cc++; |
- } |
- } |
- while (cc < len) { |
- if (str[cc] == '.' || !XFA_IsDigit(str[cc])) { |
- break; |
- } |
- nExponent = nExponent * 10 + str[cc] - '0'; |
- cc++; |
- } |
- nExponent = bExpSign ? -nExponent : nExponent; |
- } |
- FX_DOUBLE dValue = (dwFractional / 4294967296.0); |
- dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue); |
- if (nExponent != 0) { |
- dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent); |
- } |
- return dValue; |
- } |
- return 0; |
-} |
-CFX_Unitime CXFA_LocaleValue::GetDate() const { |
- if (m_bValid && m_dwType == XFA_VT_DATE) { |
- CFX_Unitime dt; |
- FX_DateFromCanonical(m_wsValue, dt); |
- return dt; |
- } |
- return CFX_Unitime(); |
-} |
-CFX_Unitime CXFA_LocaleValue::GetTime() const { |
- if (m_bValid && m_dwType == XFA_VT_TIME) { |
- CFX_Unitime dt(0); |
- FXSYS_assert(m_pLocaleMgr); |
- FX_TimeFromCanonical(m_wsValue, dt, m_pLocaleMgr->GetDefLocale()); |
- return dt; |
- } |
- return CFX_Unitime(); |
-} |
-CFX_Unitime CXFA_LocaleValue::GetDateTime() const { |
- if (m_bValid && m_dwType == XFA_VT_DATETIME) { |
- int32_t index = m_wsValue.Find('T'); |
- CFX_Unitime dt; |
- FX_DateFromCanonical(m_wsValue.Left(index), dt); |
- FXSYS_assert(m_pLocaleMgr); |
- FX_TimeFromCanonical(m_wsValue.Right(m_wsValue.GetLength() - index - 1), dt, |
- m_pLocaleMgr->GetDefLocale()); |
- return dt; |
- } |
- return CFX_Unitime(); |
-} |
-FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText) { |
- m_dwType = XFA_VT_TEXT; |
- m_wsValue = wsText; |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale) { |
- m_dwType = XFA_VT_TEXT; |
- return m_bValid = ParsePatternValue(wsText, wsFormat, pLocale); |
-} |
-FX_BOOL CXFA_LocaleValue::SetNum(FX_FLOAT fNum) { |
- m_dwType = XFA_VT_FLOAT; |
- m_wsValue.Format(L"%.8g", (FX_DOUBLE)fNum); |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::SetNum(const CFX_WideString& wsNum, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale) { |
- m_dwType = XFA_VT_FLOAT; |
- return m_bValid = ParsePatternValue(wsNum, wsFormat, pLocale); |
-} |
-FX_BOOL CXFA_LocaleValue::SetDate(const CFX_Unitime& d) { |
- m_dwType = XFA_VT_DATE; |
- m_wsValue.Format(L"%04d-%02d-%02d", d.GetYear(), d.GetMonth(), d.GetDay()); |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::SetDate(const CFX_WideString& wsDate, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale) { |
- m_dwType = XFA_VT_DATE; |
- return m_bValid = ParsePatternValue(wsDate, wsFormat, pLocale); |
-} |
-FX_BOOL CXFA_LocaleValue::SetTime(const CFX_Unitime& t) { |
- m_dwType = XFA_VT_TIME; |
- m_wsValue.Format(L"%02d:%02d:%02d", t.GetHour(), t.GetMinute(), |
- t.GetSecond()); |
- if (t.GetMillisecond() > 0) { |
- CFX_WideString wsTemp; |
- wsTemp.Format(L"%:03d", t.GetMillisecond()); |
- m_wsValue += wsTemp; |
- } |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::SetTime(const CFX_WideString& wsTime, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale) { |
- m_dwType = XFA_VT_TIME; |
- return m_bValid = ParsePatternValue(wsTime, wsFormat, pLocale); |
-} |
-FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_Unitime& dt) { |
- m_dwType = XFA_VT_DATETIME; |
- m_wsValue.Format(L"%04d-%02d-%02dT%02d:%02d:%02d", dt.GetYear(), |
- dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute(), |
- dt.GetSecond()); |
- if (dt.GetMillisecond() > 0) { |
- CFX_WideString wsTemp; |
- wsTemp.Format(L"%:03d", dt.GetMillisecond()); |
- m_wsValue += wsTemp; |
- } |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_WideString& wsDateTime, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale) { |
- m_dwType = XFA_VT_DATETIME; |
- return m_bValid = ParsePatternValue(wsDateTime, wsFormat, pLocale); |
-} |
-FX_BOOL CXFA_LocaleValue::FormatPatterns(CFX_WideString& wsResult, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale, |
- XFA_VALUEPICTURE eValueType) const { |
- wsResult.Empty(); |
- FX_BOOL bRet = FALSE; |
- IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
- CFX_WideStringArray wsPatterns; |
- pFormat->SplitFormatString(wsFormat, wsPatterns); |
- int32_t iCount = wsPatterns.GetSize(); |
- for (int32_t i = 0; i < iCount; i++) { |
- bRet = FormatSinglePattern(wsResult, wsPatterns[i], pLocale, eValueType); |
- if (bRet) { |
- break; |
- } |
- } |
- pFormat->Release(); |
- return bRet; |
-} |
-FX_BOOL CXFA_LocaleValue::FormatSinglePattern( |
- CFX_WideString& wsResult, |
- const CFX_WideString& wsFormat, |
- IFX_Locale* pLocale, |
- XFA_VALUEPICTURE eValueType) const { |
- IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(pLocale); |
- } |
- wsResult.Empty(); |
- FX_BOOL bRet = FALSE; |
- IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
- FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat); |
- eCategory = XFA_ValugeCategory(eCategory, m_dwType); |
- switch (eCategory) { |
- case FX_LOCALECATEGORY_Null: |
- if (m_wsValue.IsEmpty()) { |
- bRet = pFormat->FormatNull(wsFormat, wsResult); |
- } |
- break; |
- case FX_LOCALECATEGORY_Zero: |
- if (m_wsValue == FX_WSTRC(L"0")) { |
- bRet = pFormat->FormatZero(wsFormat, wsResult); |
- } |
- break; |
- case FX_LOCALECATEGORY_Num: |
- bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult); |
- break; |
- case FX_LOCALECATEGORY_Text: |
- bRet = pFormat->FormatText(m_wsValue, wsFormat, wsResult); |
- break; |
- case FX_LOCALECATEGORY_Date: |
- bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
- FX_DATETIMETYPE_Date); |
- break; |
- case FX_LOCALECATEGORY_Time: |
- bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
- FX_DATETIMETYPE_Time); |
- break; |
- case FX_LOCALECATEGORY_DateTime: |
- bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
- FX_DATETIMETYPE_DateTime); |
- break; |
- default: |
- wsResult = m_wsValue; |
- bRet = TRUE; |
- } |
- pFormat->Release(); |
- if (!bRet && (eCategory != FX_LOCALECATEGORY_Num || |
- eValueType != XFA_VALUEPICTURE_Display)) { |
- wsResult = m_wsValue; |
- } |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(locale); |
- } |
- return bRet; |
-} |
-static FX_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; |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, |
- FX_DWORD dwVType) { |
- if (wsValue.IsEmpty()) { |
- return TRUE; |
- } |
- CFX_Unitime dt; |
- switch (dwVType) { |
- case XFA_VT_DATE: { |
- if (ValidateCanonicalDate(wsValue, dt)) { |
- return TRUE; |
- } |
- CFX_WideString wsDate, wsTime; |
- if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
- ValidateCanonicalDate(wsDate, dt)) { |
- return TRUE; |
- } |
- return FALSE; |
- } |
- case XFA_VT_TIME: { |
- if (ValidateCanonicalTime(wsValue)) { |
- return TRUE; |
- } |
- CFX_WideString wsDate, wsTime; |
- if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
- ValidateCanonicalTime(wsTime)) { |
- return TRUE; |
- } |
- return FALSE; |
- } |
- case XFA_VT_DATETIME: { |
- CFX_WideString wsDate, wsTime; |
- if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
- ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime)) { |
- return TRUE; |
- } |
- } break; |
- } |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate, |
- CFX_Unitime& unDate) { |
- const FX_WORD LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
- const FX_WORD wCountY = 4, wCountM = 2, wCountD = 2; |
- int nLen = wsDate.GetLength(); |
- if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) { |
- return FALSE; |
- } |
- FX_BOOL bSymbol = (wsDate.Find(0x2D) == -1) ? FALSE : TRUE; |
- FX_WORD wYear = 0, wMonth = 0, wDay = 0; |
- const FX_WCHAR* pDate = (const FX_WCHAR*)wsDate; |
- int nIndex = 0, nStart = 0; |
- while (pDate[nIndex] != '\0' && nIndex < wCountY) { |
- if (!XFA_IsDigit(pDate[nIndex])) { |
- return FALSE; |
- } |
- wYear = (pDate[nIndex] - '0') + wYear * 10; |
- nIndex++; |
- } |
- if (bSymbol) { |
- if (pDate[nIndex] != 0x2D) { |
- return FALSE; |
- } |
- nIndex++; |
- } |
- nStart = nIndex; |
- while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) { |
- if (!XFA_IsDigit(pDate[nIndex])) { |
- return FALSE; |
- } |
- wMonth = (pDate[nIndex] - '0') + wMonth * 10; |
- nIndex++; |
- } |
- if (bSymbol) { |
- if (pDate[nIndex] != 0x2D) { |
- return FALSE; |
- } |
- nIndex++; |
- } |
- nStart = nIndex; |
- while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) { |
- if (!XFA_IsDigit(pDate[nIndex])) { |
- return FALSE; |
- } |
- wDay = (pDate[nIndex] - '0') + wDay * 10; |
- nIndex++; |
- } |
- if (nIndex != nLen) { |
- return FALSE; |
- } |
- if (wYear < 1900 || wYear > 2029) { |
- return FALSE; |
- } |
- if (wMonth < 1 || wMonth > 12) { |
- if (wMonth == 0 && nLen == wCountY) { |
- return TRUE; |
- } |
- return FALSE; |
- } |
- if (wDay < 1) { |
- 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) { |
- return FALSE; |
- } |
- } |
- } else if (wDay > LastDay[wMonth - 1]) { |
- return FALSE; |
- } |
- CFX_Unitime ut; |
- ut.Set(wYear, static_cast<uint8_t>(wMonth), static_cast<uint8_t>(wDay)); |
- unDate = unDate + ut; |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) { |
- int nLen = wsTime.GetLength(); |
- if (nLen < 2) { |
- return FALSE; |
- } |
- const FX_WORD wCountH = 2, wCountM = 2, wCountS = 2, wCountF = 3; |
- FX_BOOL bSymbol = (wsTime.Find(':') == -1) ? FALSE : TRUE; |
- FX_WORD wHour = 0, wMinute = 0, wSecond = 0, wFraction = 0; |
- const FX_WCHAR* pTime = (const FX_WCHAR*)wsTime; |
- int nIndex = 0, nStart = 0; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- wHour = (pTime[nIndex] - '0') + wHour * 10; |
- nIndex++; |
- } |
- if (bSymbol) { |
- if (nIndex < nLen && pTime[nIndex] != ':') { |
- return FALSE; |
- } |
- nIndex++; |
- } |
- nStart = nIndex; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- wMinute = (pTime[nIndex] - '0') + wMinute * 10; |
- nIndex++; |
- } |
- if (bSymbol) { |
- if (nIndex < nLen && pTime[nIndex] != ':') { |
- return FALSE; |
- } |
- nIndex++; |
- } |
- nStart = nIndex; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountS && nIndex < nLen) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- wSecond = (pTime[nIndex] - '0') + wSecond * 10; |
- nIndex++; |
- } |
- if (wsTime.Find('.') > 0) { |
- if (pTime[nIndex] != '.') { |
- return FALSE; |
- } |
- nIndex++; |
- nStart = nIndex; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountF && |
- nIndex < nLen) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- wFraction = (pTime[nIndex] - '0') + wFraction * 10; |
- nIndex++; |
- } |
- } |
- if (nIndex < nLen) { |
- if (pTime[nIndex] == 'Z') { |
- nIndex++; |
- } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') { |
- int16_t nOffsetH = 0, nOffsetM = 0; |
- nIndex++; |
- nStart = nIndex; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH && |
- nIndex < nLen) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- nOffsetH = (pTime[nIndex] - '0') + nOffsetH * 10; |
- nIndex++; |
- } |
- if (bSymbol) { |
- if (nIndex < nLen && pTime[nIndex] != ':') { |
- return FALSE; |
- } |
- nIndex++; |
- } |
- nStart = nIndex; |
- while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && |
- nIndex < nLen) { |
- if (!XFA_IsDigit(pTime[nIndex])) { |
- return FALSE; |
- } |
- nOffsetM = (pTime[nIndex] - '0') + nOffsetM * 10; |
- nIndex++; |
- } |
- if (nOffsetH > 12) { |
- return FALSE; |
- } |
- if (nOffsetM >= 60) { |
- return FALSE; |
- } |
- } |
- } |
- if (nIndex != nLen) { |
- return FALSE; |
- } |
- if (wHour >= 24) { |
- return FALSE; |
- } |
- if (wMinute >= 60) { |
- return FALSE; |
- } |
- if (wSecond >= 60) { |
- return FALSE; |
- } |
- if (wFraction > 999) { |
- return FALSE; |
- } |
- return TRUE; |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateCanonicalDateTime( |
- const CFX_WideString& wsDateTime) { |
- CFX_WideString wsDate, wsTime; |
- 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); |
- CFX_Unitime dt; |
- return ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime); |
-} |
-FX_BOOL CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, |
- const CFX_WideString& wsPattern, |
- IFX_Locale* pLocale) { |
- IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(pLocale); |
- } |
- IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
- CFX_WideStringArray wsPatterns; |
- pFormat->SplitFormatString(wsPattern, wsPatterns); |
- FX_BOOL bRet = FALSE; |
- int32_t iCount = wsPatterns.GetSize(); |
- 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) { |
- case FX_LOCALECATEGORY_Null: |
- bRet = pFormat->ParseNull(wsValue, wsFormat); |
- if (bRet) { |
- m_wsValue.Empty(); |
- } |
- break; |
- case FX_LOCALECATEGORY_Zero: |
- bRet = pFormat->ParseZero(wsValue, wsFormat); |
- if (bRet) { |
- m_wsValue = FX_WSTRC(L"0"); |
- } |
- break; |
- case FX_LOCALECATEGORY_Num: { |
- CFX_WideString fNum; |
- bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); |
- if (bRet) { |
- m_wsValue = fNum; |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_Text: |
- bRet = pFormat->ParseText(wsValue, wsFormat, m_wsValue); |
- break; |
- case FX_LOCALECATEGORY_Date: { |
- CFX_Unitime dt; |
- bRet = ValidateCanonicalDate(wsValue, dt); |
- if (!bRet) { |
- bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, |
- dt); |
- } |
- if (bRet) { |
- SetDate(dt); |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_Time: { |
- CFX_Unitime dt; |
- bRet = |
- pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt); |
- if (bRet) { |
- SetTime(dt); |
- } |
- break; |
- } |
- case FX_LOCALECATEGORY_DateTime: { |
- CFX_Unitime dt; |
- bRet = pFormat->ParseDateTime(wsValue, wsFormat, |
- FX_DATETIMETYPE_DateTime, dt); |
- if (bRet) { |
- SetDateTime(dt); |
- } |
- break; |
- } |
- default: |
- m_wsValue = wsValue; |
- bRet = TRUE; |
- break; |
- } |
- } |
- if (!bRet) { |
- m_wsValue = wsValue; |
- } |
- pFormat->Release(); |
- if (pLocale) { |
- m_pLocaleMgr->SetDefLocale(locale); |
- } |
- return bRet; |
-} |
-void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat, |
- int32_t nIntLen, |
- int32_t nDecLen, |
- FX_BOOL bSign) { |
- FXSYS_assert(wsFormat.IsEmpty()); |
- FXSYS_assert(nIntLen >= -1 && nDecLen >= -1); |
- int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + (bSign ? 1 : 0) + |
- (nDecLen >= 0 ? nDecLen : 2) + (nDecLen == 0 ? 0 : 1); |
- FX_WCHAR* lpBuf = wsFormat.GetBuffer(nTotalLen); |
- int32_t nPos = 0; |
- if (bSign) { |
- lpBuf[nPos++] = L's'; |
- } |
- if (nIntLen == -1) { |
- lpBuf[nPos++] = L'z'; |
- lpBuf[nPos++] = L'*'; |
- } else { |
- while (nIntLen) { |
- lpBuf[nPos++] = L'z'; |
- nIntLen--; |
- } |
- } |
- if (nDecLen != 0) { |
- lpBuf[nPos++] = L'.'; |
- } |
- if (nDecLen == -1) { |
- lpBuf[nPos++] = L'z'; |
- lpBuf[nPos++] = L'*'; |
- } else { |
- while (nDecLen) { |
- lpBuf[nPos++] = L'z'; |
- nDecLen--; |
- } |
- } |
- wsFormat.ReleaseBuffer(nTotalLen); |
-} |
-FX_BOOL CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, |
- CFX_WideString& wsFormat, |
- IFX_Locale* pLocale, |
- int32_t* pos) { |
- if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) { |
- return TRUE; |
- } |
- const FX_WCHAR* pNum = wsNumeric.c_str(); |
- const FX_WCHAR* pFmt = wsFormat.c_str(); |
- int32_t n = 0, nf = 0; |
- FX_WCHAR c = pNum[n]; |
- FX_WCHAR cf = pFmt[nf]; |
- if (cf == L's') { |
- if (c == L'-' || c == L'+') { |
- ++n; |
- } |
- ++nf; |
- } |
- FX_BOOL bLimit = TRUE; |
- int32_t nCount = wsNumeric.GetLength(); |
- int32_t nCountFmt = wsFormat.GetLength(); |
- while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && |
- XFA_IsDigit(c = pNum[n])) { |
- if (bLimit == TRUE) { |
- if ((cf = pFmt[nf]) == L'*') { |
- bLimit = FALSE; |
- } else if (cf == L'z') { |
- nf++; |
- } else { |
- return FALSE; |
- } |
- } |
- n++; |
- } |
- if (n == nCount) { |
- return TRUE; |
- } |
- if (nf == nCountFmt) { |
- return FALSE; |
- } |
- while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') { |
- FXSYS_assert(cf == L'z' || cf == L'*'); |
- ++nf; |
- } |
- CFX_WideString wsDecimalSymbol; |
- if (pLocale) { |
- pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol); |
- } else { |
- wsDecimalSymbol = CFX_WideString(L'.'); |
- } |
- if (pFmt[nf] != L'.') { |
- return FALSE; |
- } |
- if (wsDecimalSymbol != CFX_WideStringC(c) && c != L'.') { |
- return FALSE; |
- } |
- ++nf; |
- ++n; |
- bLimit = TRUE; |
- while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && |
- XFA_IsDigit(c = pNum[n])) { |
- if (bLimit == TRUE) { |
- if ((cf = pFmt[nf]) == L'*') { |
- bLimit = FALSE; |
- } else if (cf == L'z') { |
- nf++; |
- } else { |
- return FALSE; |
- } |
- } |
- n++; |
- } |
- return n == nCount; |
-} |
+// Copyright 2014 PDFium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+ |
+#include "xfa/src/foxitlib.h" |
+#include "xfa/src/fxfa/src/common/xfa_utils.h" |
+#include "xfa/src/fxfa/src/common/xfa_object.h" |
+#include "xfa/src/fxfa/src/common/xfa_document.h" |
+#include "xfa/src/fxfa/src/common/xfa_parser.h" |
+#include "xfa/src/fxfa/src/common/xfa_script.h" |
+#include "xfa/src/fxfa/src/common/xfa_docdata.h" |
+#include "xfa/src/fxfa/src/common/xfa_doclayout.h" |
+#include "xfa/src/fxfa/src/common/xfa_localemgr.h" |
+#include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" |
+static const FX_DOUBLE fraction_scales[] = {0.1, |
+ 0.01, |
+ 0.001, |
+ 0.0001, |
+ 0.00001, |
+ 0.000001, |
+ 0.0000001, |
+ 0.00000001, |
+ 0.000000001, |
+ 0.0000000001, |
+ 0.00000000001, |
+ 0.000000000001, |
+ 0.0000000000001, |
+ 0.00000000000001, |
+ 0.000000000000001, |
+ 0.0000000000000001}; |
+CXFA_LocaleValue::CXFA_LocaleValue() { |
+ m_dwType = XFA_VT_NULL; |
+ m_bValid = TRUE; |
+ m_pLocaleMgr = NULL; |
+} |
+CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) { |
+ m_dwType = XFA_VT_NULL; |
+ m_bValid = TRUE; |
+ m_pLocaleMgr = NULL; |
+ *this = value; |
+} |
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, |
+ CXFA_LocaleMgr* pLocaleMgr) { |
+ m_dwType = dwType; |
+ m_bValid = (m_dwType != XFA_VT_NULL); |
+ m_pLocaleMgr = pLocaleMgr; |
+} |
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, |
+ const CFX_WideString& wsValue, |
+ CXFA_LocaleMgr* pLocaleMgr) { |
+ m_wsValue = wsValue; |
+ m_dwType = dwType; |
+ m_pLocaleMgr = pLocaleMgr; |
+ m_bValid = ValidateCanonicalValue(wsValue, dwType); |
+} |
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD 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_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) { |
+ m_wsValue = value.m_wsValue; |
+ m_dwType = value.m_dwType; |
+ m_bValid = value.m_bValid; |
+ m_pLocaleMgr = value.m_pLocaleMgr; |
+ return *this; |
+} |
+CXFA_LocaleValue::~CXFA_LocaleValue() {} |
+static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory, |
+ FX_DWORD 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; |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, |
+ const CFX_WideString& wsPattern, |
+ IFX_Locale* pLocale, |
+ CFX_WideString* pMatchFormat) { |
+ CFX_WideString wsOutput; |
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(pLocale); |
+ } |
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
+ CFX_WideStringArray wsPatterns; |
+ pFormat->SplitFormatString(wsPattern, wsPatterns); |
+ FX_BOOL bRet = FALSE; |
+ int32_t iCount = wsPatterns.GetSize(); |
+ 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) { |
+ case FX_LOCALECATEGORY_Null: |
+ bRet = pFormat->ParseNull(wsValue, wsFormat); |
+ if (!bRet) { |
+ bRet = wsValue.IsEmpty(); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Zero: |
+ bRet = pFormat->ParseZero(wsValue, wsFormat); |
+ if (!bRet) { |
+ bRet = wsValue == FX_WSTRC(L"0"); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Num: { |
+ CFX_WideString fNum; |
+ bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); |
+ if (!bRet) { |
+ bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput); |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_Text: |
+ bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput); |
+ wsOutput.Empty(); |
+ if (!bRet) { |
+ bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Date: { |
+ CFX_Unitime dt; |
+ bRet = ValidateCanonicalDate(wsValue, dt); |
+ if (!bRet) { |
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, |
+ dt); |
+ if (!bRet) { |
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
+ FX_DATETIMETYPE_Date); |
+ } |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_Time: { |
+ CFX_Unitime dt; |
+ bRet = |
+ pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt); |
+ if (!bRet) { |
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
+ FX_DATETIMETYPE_Time); |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_DateTime: { |
+ CFX_Unitime dt; |
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, |
+ FX_DATETIMETYPE_DateTime, dt); |
+ if (!bRet) { |
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, |
+ FX_DATETIMETYPE_DateTime); |
+ } |
+ break; |
+ } |
+ default: |
+ bRet = FALSE; |
+ break; |
+ } |
+ } |
+ if (bRet && pMatchFormat) { |
+ *pMatchFormat = wsPatterns[i - 1]; |
+ } |
+ pFormat->Release(); |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(locale); |
+ } |
+ return bRet; |
+} |
+CFX_WideString CXFA_LocaleValue::GetValue() const { |
+ return m_wsValue; |
+} |
+FX_DWORD CXFA_LocaleValue::GetType() const { |
+ return m_dwType; |
+} |
+void CXFA_LocaleValue::SetValue(const CFX_WideString& wsValue, |
+ FX_DWORD dwType) { |
+ m_wsValue = wsValue; |
+ m_dwType = dwType; |
+} |
+CFX_WideString CXFA_LocaleValue::GetText() const { |
+ if (m_bValid && m_dwType == XFA_VT_TEXT) { |
+ return m_wsValue; |
+ } |
+ return CFX_WideString(); |
+} |
+FX_FLOAT CXFA_LocaleValue::GetNum() const { |
+ if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER || |
+ m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) { |
+ int64_t nIntegral = 0; |
+ FX_DWORD dwFractional = 0; |
+ int32_t nExponent = 0; |
+ int cc = 0; |
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE; |
+ const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue; |
+ int len = m_wsValue.GetLength(); |
+ while (XFA_IsSpace(str[cc]) && cc < len) { |
+ cc++; |
+ } |
+ if (cc >= len) { |
+ return 0; |
+ } |
+ if (str[0] == '+') { |
+ cc++; |
+ } else if (str[0] == '-') { |
+ bNegative = TRUE; |
+ cc++; |
+ } |
+ int nIntegralLen = 0; |
+ while (cc < len) { |
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) { |
+ break; |
+ } |
+ nIntegral = nIntegral * 10 + str[cc] - '0'; |
+ cc++; |
+ nIntegralLen++; |
+ } |
+ nIntegral = bNegative ? -nIntegral : nIntegral; |
+ int scale = 0; |
+ double fraction = 0.0; |
+ if (cc < len && str[cc] == '.') { |
+ cc++; |
+ while (cc < len) { |
+ fraction += fraction_scales[scale] * (str[cc] - '0'); |
+ scale++; |
+ cc++; |
+ if (scale == sizeof fraction_scales / sizeof(double) || |
+ !XFA_IsDigit(str[cc])) { |
+ break; |
+ } |
+ } |
+ dwFractional = (FX_DWORD)(fraction * 4294967296.0); |
+ } |
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) { |
+ cc++; |
+ if (cc < len) { |
+ if (str[cc] == '+') { |
+ cc++; |
+ } else if (str[cc] == '-') { |
+ bExpSign = TRUE; |
+ cc++; |
+ } |
+ } |
+ while (cc < len) { |
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc])) { |
+ break; |
+ } |
+ nExponent = nExponent * 10 + str[cc] - '0'; |
+ cc++; |
+ } |
+ nExponent = bExpSign ? -nExponent : nExponent; |
+ } |
+ FX_FLOAT fValue = (FX_FLOAT)(dwFractional / 4294967296.0); |
+ fValue = nIntegral + (nIntegral >= 0 ? fValue : -fValue); |
+ if (nExponent != 0) { |
+ fValue *= FXSYS_pow(10, (FX_FLOAT)nExponent); |
+ } |
+ return fValue; |
+ } |
+ return 0; |
+} |
+FX_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)) { |
+ int64_t nIntegral = 0; |
+ FX_DWORD dwFractional = 0; |
+ int32_t nExponent = 0; |
+ int32_t cc = 0; |
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE; |
+ const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue; |
+ int len = m_wsValue.GetLength(); |
+ while (XFA_IsSpace(str[cc]) && cc < len) { |
+ cc++; |
+ } |
+ if (cc >= len) { |
+ return 0; |
+ } |
+ if (str[0] == '+') { |
+ cc++; |
+ } else if (str[0] == '-') { |
+ bNegative = TRUE; |
+ cc++; |
+ } |
+ int32_t nIntegralLen = 0; |
+ while (cc < len) { |
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) { |
+ break; |
+ } |
+ nIntegral = nIntegral * 10 + str[cc] - '0'; |
+ cc++; |
+ nIntegralLen++; |
+ } |
+ nIntegral = bNegative ? -nIntegral : nIntegral; |
+ int32_t scale = 0; |
+ FX_DOUBLE fraction = 0.0; |
+ if (cc < len && str[cc] == '.') { |
+ cc++; |
+ while (cc < len) { |
+ fraction += fraction_scales[scale] * (str[cc] - '0'); |
+ scale++; |
+ cc++; |
+ if (scale == sizeof fraction_scales / sizeof(FX_DOUBLE) || |
+ !XFA_IsDigit(str[cc])) { |
+ break; |
+ } |
+ } |
+ dwFractional = (FX_DWORD)(fraction * 4294967296.0); |
+ } |
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) { |
+ cc++; |
+ if (cc < len) { |
+ if (str[cc] == '+') { |
+ cc++; |
+ } else if (str[cc] == '-') { |
+ bExpSign = TRUE; |
+ cc++; |
+ } |
+ } |
+ while (cc < len) { |
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc])) { |
+ break; |
+ } |
+ nExponent = nExponent * 10 + str[cc] - '0'; |
+ cc++; |
+ } |
+ nExponent = bExpSign ? -nExponent : nExponent; |
+ } |
+ FX_DOUBLE dValue = (dwFractional / 4294967296.0); |
+ dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue); |
+ if (nExponent != 0) { |
+ dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent); |
+ } |
+ return dValue; |
+ } |
+ return 0; |
+} |
+CFX_Unitime CXFA_LocaleValue::GetDate() const { |
+ if (m_bValid && m_dwType == XFA_VT_DATE) { |
+ CFX_Unitime dt; |
+ FX_DateFromCanonical(m_wsValue, dt); |
+ return dt; |
+ } |
+ return CFX_Unitime(); |
+} |
+CFX_Unitime CXFA_LocaleValue::GetTime() const { |
+ if (m_bValid && m_dwType == XFA_VT_TIME) { |
+ CFX_Unitime dt(0); |
+ FXSYS_assert(m_pLocaleMgr); |
+ FX_TimeFromCanonical(m_wsValue, dt, m_pLocaleMgr->GetDefLocale()); |
+ return dt; |
+ } |
+ return CFX_Unitime(); |
+} |
+CFX_Unitime CXFA_LocaleValue::GetDateTime() const { |
+ if (m_bValid && m_dwType == XFA_VT_DATETIME) { |
+ int32_t index = m_wsValue.Find('T'); |
+ CFX_Unitime dt; |
+ FX_DateFromCanonical(m_wsValue.Left(index), dt); |
+ FXSYS_assert(m_pLocaleMgr); |
+ FX_TimeFromCanonical(m_wsValue.Right(m_wsValue.GetLength() - index - 1), dt, |
+ m_pLocaleMgr->GetDefLocale()); |
+ return dt; |
+ } |
+ return CFX_Unitime(); |
+} |
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText) { |
+ m_dwType = XFA_VT_TEXT; |
+ m_wsValue = wsText; |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale) { |
+ m_dwType = XFA_VT_TEXT; |
+ return m_bValid = ParsePatternValue(wsText, wsFormat, pLocale); |
+} |
+FX_BOOL CXFA_LocaleValue::SetNum(FX_FLOAT fNum) { |
+ m_dwType = XFA_VT_FLOAT; |
+ m_wsValue.Format(L"%.8g", (FX_DOUBLE)fNum); |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::SetNum(const CFX_WideString& wsNum, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale) { |
+ m_dwType = XFA_VT_FLOAT; |
+ return m_bValid = ParsePatternValue(wsNum, wsFormat, pLocale); |
+} |
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_Unitime& d) { |
+ m_dwType = XFA_VT_DATE; |
+ m_wsValue.Format(L"%04d-%02d-%02d", d.GetYear(), d.GetMonth(), d.GetDay()); |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_WideString& wsDate, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale) { |
+ m_dwType = XFA_VT_DATE; |
+ return m_bValid = ParsePatternValue(wsDate, wsFormat, pLocale); |
+} |
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_Unitime& t) { |
+ m_dwType = XFA_VT_TIME; |
+ m_wsValue.Format(L"%02d:%02d:%02d", t.GetHour(), t.GetMinute(), |
+ t.GetSecond()); |
+ if (t.GetMillisecond() > 0) { |
+ CFX_WideString wsTemp; |
+ wsTemp.Format(L"%:03d", t.GetMillisecond()); |
+ m_wsValue += wsTemp; |
+ } |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_WideString& wsTime, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale) { |
+ m_dwType = XFA_VT_TIME; |
+ return m_bValid = ParsePatternValue(wsTime, wsFormat, pLocale); |
+} |
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_Unitime& dt) { |
+ m_dwType = XFA_VT_DATETIME; |
+ m_wsValue.Format(L"%04d-%02d-%02dT%02d:%02d:%02d", dt.GetYear(), |
+ dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute(), |
+ dt.GetSecond()); |
+ if (dt.GetMillisecond() > 0) { |
+ CFX_WideString wsTemp; |
+ wsTemp.Format(L"%:03d", dt.GetMillisecond()); |
+ m_wsValue += wsTemp; |
+ } |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_WideString& wsDateTime, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale) { |
+ m_dwType = XFA_VT_DATETIME; |
+ return m_bValid = ParsePatternValue(wsDateTime, wsFormat, pLocale); |
+} |
+FX_BOOL CXFA_LocaleValue::FormatPatterns(CFX_WideString& wsResult, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale, |
+ XFA_VALUEPICTURE eValueType) const { |
+ wsResult.Empty(); |
+ FX_BOOL bRet = FALSE; |
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
+ CFX_WideStringArray wsPatterns; |
+ pFormat->SplitFormatString(wsFormat, wsPatterns); |
+ int32_t iCount = wsPatterns.GetSize(); |
+ for (int32_t i = 0; i < iCount; i++) { |
+ bRet = FormatSinglePattern(wsResult, wsPatterns[i], pLocale, eValueType); |
+ if (bRet) { |
+ break; |
+ } |
+ } |
+ pFormat->Release(); |
+ return bRet; |
+} |
+FX_BOOL CXFA_LocaleValue::FormatSinglePattern( |
+ CFX_WideString& wsResult, |
+ const CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale, |
+ XFA_VALUEPICTURE eValueType) const { |
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(pLocale); |
+ } |
+ wsResult.Empty(); |
+ FX_BOOL bRet = FALSE; |
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
+ FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat); |
+ eCategory = XFA_ValugeCategory(eCategory, m_dwType); |
+ switch (eCategory) { |
+ case FX_LOCALECATEGORY_Null: |
+ if (m_wsValue.IsEmpty()) { |
+ bRet = pFormat->FormatNull(wsFormat, wsResult); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Zero: |
+ if (m_wsValue == FX_WSTRC(L"0")) { |
+ bRet = pFormat->FormatZero(wsFormat, wsResult); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Num: |
+ bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult); |
+ break; |
+ case FX_LOCALECATEGORY_Text: |
+ bRet = pFormat->FormatText(m_wsValue, wsFormat, wsResult); |
+ break; |
+ case FX_LOCALECATEGORY_Date: |
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
+ FX_DATETIMETYPE_Date); |
+ break; |
+ case FX_LOCALECATEGORY_Time: |
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
+ FX_DATETIMETYPE_Time); |
+ break; |
+ case FX_LOCALECATEGORY_DateTime: |
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, |
+ FX_DATETIMETYPE_DateTime); |
+ break; |
+ default: |
+ wsResult = m_wsValue; |
+ bRet = TRUE; |
+ } |
+ pFormat->Release(); |
+ if (!bRet && (eCategory != FX_LOCALECATEGORY_Num || |
+ eValueType != XFA_VALUEPICTURE_Display)) { |
+ wsResult = m_wsValue; |
+ } |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(locale); |
+ } |
+ return bRet; |
+} |
+static FX_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; |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, |
+ FX_DWORD dwVType) { |
+ if (wsValue.IsEmpty()) { |
+ return TRUE; |
+ } |
+ CFX_Unitime dt; |
+ switch (dwVType) { |
+ case XFA_VT_DATE: { |
+ if (ValidateCanonicalDate(wsValue, dt)) { |
+ return TRUE; |
+ } |
+ CFX_WideString wsDate, wsTime; |
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
+ ValidateCanonicalDate(wsDate, dt)) { |
+ return TRUE; |
+ } |
+ return FALSE; |
+ } |
+ case XFA_VT_TIME: { |
+ if (ValidateCanonicalTime(wsValue)) { |
+ return TRUE; |
+ } |
+ CFX_WideString wsDate, wsTime; |
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
+ ValidateCanonicalTime(wsTime)) { |
+ return TRUE; |
+ } |
+ return FALSE; |
+ } |
+ case XFA_VT_DATETIME: { |
+ CFX_WideString wsDate, wsTime; |
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && |
+ ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime)) { |
+ return TRUE; |
+ } |
+ } break; |
+ } |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate, |
+ CFX_Unitime& unDate) { |
+ const FX_WORD LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
+ const FX_WORD wCountY = 4, wCountM = 2, wCountD = 2; |
+ int nLen = wsDate.GetLength(); |
+ if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) { |
+ return FALSE; |
+ } |
+ FX_BOOL bSymbol = (wsDate.Find(0x2D) == -1) ? FALSE : TRUE; |
+ FX_WORD wYear = 0, wMonth = 0, wDay = 0; |
+ const FX_WCHAR* pDate = (const FX_WCHAR*)wsDate; |
+ int nIndex = 0, nStart = 0; |
+ while (pDate[nIndex] != '\0' && nIndex < wCountY) { |
+ if (!XFA_IsDigit(pDate[nIndex])) { |
+ return FALSE; |
+ } |
+ wYear = (pDate[nIndex] - '0') + wYear * 10; |
+ nIndex++; |
+ } |
+ if (bSymbol) { |
+ if (pDate[nIndex] != 0x2D) { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ } |
+ nStart = nIndex; |
+ while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) { |
+ if (!XFA_IsDigit(pDate[nIndex])) { |
+ return FALSE; |
+ } |
+ wMonth = (pDate[nIndex] - '0') + wMonth * 10; |
+ nIndex++; |
+ } |
+ if (bSymbol) { |
+ if (pDate[nIndex] != 0x2D) { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ } |
+ nStart = nIndex; |
+ while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) { |
+ if (!XFA_IsDigit(pDate[nIndex])) { |
+ return FALSE; |
+ } |
+ wDay = (pDate[nIndex] - '0') + wDay * 10; |
+ nIndex++; |
+ } |
+ if (nIndex != nLen) { |
+ return FALSE; |
+ } |
+ if (wYear < 1900 || wYear > 2029) { |
+ return FALSE; |
+ } |
+ if (wMonth < 1 || wMonth > 12) { |
+ if (wMonth == 0 && nLen == wCountY) { |
+ return TRUE; |
+ } |
+ return FALSE; |
+ } |
+ if (wDay < 1) { |
+ 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) { |
+ return FALSE; |
+ } |
+ } |
+ } else if (wDay > LastDay[wMonth - 1]) { |
+ return FALSE; |
+ } |
+ CFX_Unitime ut; |
+ ut.Set(wYear, static_cast<uint8_t>(wMonth), static_cast<uint8_t>(wDay)); |
+ unDate = unDate + ut; |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) { |
+ int nLen = wsTime.GetLength(); |
+ if (nLen < 2) { |
+ return FALSE; |
+ } |
+ const FX_WORD wCountH = 2, wCountM = 2, wCountS = 2, wCountF = 3; |
+ FX_BOOL bSymbol = (wsTime.Find(':') == -1) ? FALSE : TRUE; |
+ FX_WORD wHour = 0, wMinute = 0, wSecond = 0, wFraction = 0; |
+ const FX_WCHAR* pTime = (const FX_WCHAR*)wsTime; |
+ int nIndex = 0, nStart = 0; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ wHour = (pTime[nIndex] - '0') + wHour * 10; |
+ nIndex++; |
+ } |
+ if (bSymbol) { |
+ if (nIndex < nLen && pTime[nIndex] != ':') { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ } |
+ nStart = nIndex; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ wMinute = (pTime[nIndex] - '0') + wMinute * 10; |
+ nIndex++; |
+ } |
+ if (bSymbol) { |
+ if (nIndex < nLen && pTime[nIndex] != ':') { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ } |
+ nStart = nIndex; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountS && nIndex < nLen) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ wSecond = (pTime[nIndex] - '0') + wSecond * 10; |
+ nIndex++; |
+ } |
+ if (wsTime.Find('.') > 0) { |
+ if (pTime[nIndex] != '.') { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ nStart = nIndex; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountF && |
+ nIndex < nLen) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ wFraction = (pTime[nIndex] - '0') + wFraction * 10; |
+ nIndex++; |
+ } |
+ } |
+ if (nIndex < nLen) { |
+ if (pTime[nIndex] == 'Z') { |
+ nIndex++; |
+ } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') { |
+ int16_t nOffsetH = 0, nOffsetM = 0; |
+ nIndex++; |
+ nStart = nIndex; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH && |
+ nIndex < nLen) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ nOffsetH = (pTime[nIndex] - '0') + nOffsetH * 10; |
+ nIndex++; |
+ } |
+ if (bSymbol) { |
+ if (nIndex < nLen && pTime[nIndex] != ':') { |
+ return FALSE; |
+ } |
+ nIndex++; |
+ } |
+ nStart = nIndex; |
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && |
+ nIndex < nLen) { |
+ if (!XFA_IsDigit(pTime[nIndex])) { |
+ return FALSE; |
+ } |
+ nOffsetM = (pTime[nIndex] - '0') + nOffsetM * 10; |
+ nIndex++; |
+ } |
+ if (nOffsetH > 12) { |
+ return FALSE; |
+ } |
+ if (nOffsetM >= 60) { |
+ return FALSE; |
+ } |
+ } |
+ } |
+ if (nIndex != nLen) { |
+ return FALSE; |
+ } |
+ if (wHour >= 24) { |
+ return FALSE; |
+ } |
+ if (wMinute >= 60) { |
+ return FALSE; |
+ } |
+ if (wSecond >= 60) { |
+ return FALSE; |
+ } |
+ if (wFraction > 999) { |
+ return FALSE; |
+ } |
+ return TRUE; |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDateTime( |
+ const CFX_WideString& wsDateTime) { |
+ CFX_WideString wsDate, wsTime; |
+ 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); |
+ CFX_Unitime dt; |
+ return ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime); |
+} |
+FX_BOOL CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, |
+ const CFX_WideString& wsPattern, |
+ IFX_Locale* pLocale) { |
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale(); |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(pLocale); |
+ } |
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE); |
+ CFX_WideStringArray wsPatterns; |
+ pFormat->SplitFormatString(wsPattern, wsPatterns); |
+ FX_BOOL bRet = FALSE; |
+ int32_t iCount = wsPatterns.GetSize(); |
+ 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) { |
+ case FX_LOCALECATEGORY_Null: |
+ bRet = pFormat->ParseNull(wsValue, wsFormat); |
+ if (bRet) { |
+ m_wsValue.Empty(); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Zero: |
+ bRet = pFormat->ParseZero(wsValue, wsFormat); |
+ if (bRet) { |
+ m_wsValue = FX_WSTRC(L"0"); |
+ } |
+ break; |
+ case FX_LOCALECATEGORY_Num: { |
+ CFX_WideString fNum; |
+ bRet = pFormat->ParseNum(wsValue, wsFormat, fNum); |
+ if (bRet) { |
+ m_wsValue = fNum; |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_Text: |
+ bRet = pFormat->ParseText(wsValue, wsFormat, m_wsValue); |
+ break; |
+ case FX_LOCALECATEGORY_Date: { |
+ CFX_Unitime dt; |
+ bRet = ValidateCanonicalDate(wsValue, dt); |
+ if (!bRet) { |
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, |
+ dt); |
+ } |
+ if (bRet) { |
+ SetDate(dt); |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_Time: { |
+ CFX_Unitime dt; |
+ bRet = |
+ pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt); |
+ if (bRet) { |
+ SetTime(dt); |
+ } |
+ break; |
+ } |
+ case FX_LOCALECATEGORY_DateTime: { |
+ CFX_Unitime dt; |
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, |
+ FX_DATETIMETYPE_DateTime, dt); |
+ if (bRet) { |
+ SetDateTime(dt); |
+ } |
+ break; |
+ } |
+ default: |
+ m_wsValue = wsValue; |
+ bRet = TRUE; |
+ break; |
+ } |
+ } |
+ if (!bRet) { |
+ m_wsValue = wsValue; |
+ } |
+ pFormat->Release(); |
+ if (pLocale) { |
+ m_pLocaleMgr->SetDefLocale(locale); |
+ } |
+ return bRet; |
+} |
+void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat, |
+ int32_t nIntLen, |
+ int32_t nDecLen, |
+ FX_BOOL bSign) { |
+ FXSYS_assert(wsFormat.IsEmpty()); |
+ FXSYS_assert(nIntLen >= -1 && nDecLen >= -1); |
+ int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + (bSign ? 1 : 0) + |
+ (nDecLen >= 0 ? nDecLen : 2) + (nDecLen == 0 ? 0 : 1); |
+ FX_WCHAR* lpBuf = wsFormat.GetBuffer(nTotalLen); |
+ int32_t nPos = 0; |
+ if (bSign) { |
+ lpBuf[nPos++] = L's'; |
+ } |
+ if (nIntLen == -1) { |
+ lpBuf[nPos++] = L'z'; |
+ lpBuf[nPos++] = L'*'; |
+ } else { |
+ while (nIntLen) { |
+ lpBuf[nPos++] = L'z'; |
+ nIntLen--; |
+ } |
+ } |
+ if (nDecLen != 0) { |
+ lpBuf[nPos++] = L'.'; |
+ } |
+ if (nDecLen == -1) { |
+ lpBuf[nPos++] = L'z'; |
+ lpBuf[nPos++] = L'*'; |
+ } else { |
+ while (nDecLen) { |
+ lpBuf[nPos++] = L'z'; |
+ nDecLen--; |
+ } |
+ } |
+ wsFormat.ReleaseBuffer(nTotalLen); |
+} |
+FX_BOOL CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, |
+ CFX_WideString& wsFormat, |
+ IFX_Locale* pLocale, |
+ int32_t* pos) { |
+ if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) { |
+ return TRUE; |
+ } |
+ const FX_WCHAR* pNum = wsNumeric.c_str(); |
+ const FX_WCHAR* pFmt = wsFormat.c_str(); |
+ int32_t n = 0, nf = 0; |
+ FX_WCHAR c = pNum[n]; |
+ FX_WCHAR cf = pFmt[nf]; |
+ if (cf == L's') { |
+ if (c == L'-' || c == L'+') { |
+ ++n; |
+ } |
+ ++nf; |
+ } |
+ FX_BOOL bLimit = TRUE; |
+ int32_t nCount = wsNumeric.GetLength(); |
+ int32_t nCountFmt = wsFormat.GetLength(); |
+ while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && |
+ XFA_IsDigit(c = pNum[n])) { |
+ if (bLimit == TRUE) { |
+ if ((cf = pFmt[nf]) == L'*') { |
+ bLimit = FALSE; |
+ } else if (cf == L'z') { |
+ nf++; |
+ } else { |
+ return FALSE; |
+ } |
+ } |
+ n++; |
+ } |
+ if (n == nCount) { |
+ return TRUE; |
+ } |
+ if (nf == nCountFmt) { |
+ return FALSE; |
+ } |
+ while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') { |
+ FXSYS_assert(cf == L'z' || cf == L'*'); |
+ ++nf; |
+ } |
+ CFX_WideString wsDecimalSymbol; |
+ if (pLocale) { |
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol); |
+ } else { |
+ wsDecimalSymbol = CFX_WideString(L'.'); |
+ } |
+ if (pFmt[nf] != L'.') { |
+ return FALSE; |
+ } |
+ if (wsDecimalSymbol != CFX_WideStringC(c) && c != L'.') { |
+ return FALSE; |
+ } |
+ ++nf; |
+ ++n; |
+ bLimit = TRUE; |
+ while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && |
+ XFA_IsDigit(c = pNum[n])) { |
+ if (bLimit == TRUE) { |
+ if ((cf = pFmt[nf]) == L'*') { |
+ bLimit = FALSE; |
+ } else if (cf == L'z') { |
+ nf++; |
+ } else { |
+ return FALSE; |
+ } |
+ } |
+ n++; |
+ } |
+ return n == nCount; |
+} |