Example #1
0
// Static.
FX_ARGB CXFA_Data::ToColor(const CFX_WideStringC& wsValue) {
  uint8_t r = 0, g = 0, b = 0;
  if (wsValue.GetLength() == 0)
    return 0xff000000;

  int cc = 0;
  const FX_WCHAR* str = wsValue.c_str();
  int len = wsValue.GetLength();
  while (FXSYS_iswspace(str[cc]) && cc < len)
    cc++;

  if (cc >= len)
    return 0xff000000;

  while (cc < len) {
    if (str[cc] == ',' || !FXSYS_isDecimalDigit(str[cc]))
      break;

    r = r * 10 + str[cc] - '0';
    cc++;
  }
  if (cc < len && str[cc] == ',') {
    cc++;
    while (FXSYS_iswspace(str[cc]) && cc < len)
      cc++;

    while (cc < len) {
      if (str[cc] == ',' || !FXSYS_isDecimalDigit(str[cc]))
        break;

      g = g * 10 + str[cc] - '0';
      cc++;
    }
    if (cc < len && str[cc] == ',') {
      cc++;
      while (FXSYS_iswspace(str[cc]) && cc < len)
        cc++;

      while (cc < len) {
        if (str[cc] == ',' || !FXSYS_isDecimalDigit(str[cc]))
          break;

        b = b * 10 + str[cc] - '0';
        cc++;
      }
    }
  }
  return (0xff << 24) | (r << 16) | (g << 8) | b;
}
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) &&
         FXSYS_isDecimalDigit(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'.') {
    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) &&
         FXSYS_isDecimalDigit(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;
}
FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate,
                                                CFX_Unitime& 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;
  int nLen = wsDate.GetLength();
  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 FX_WCHAR* pDate = wsDate.c_str();
  int nIndex = 0, nStart = 0;
  while (pDate[nIndex] != '\0' && nIndex < wCountY) {
    if (!FXSYS_isDecimalDigit(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 (!FXSYS_isDecimalDigit(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 (!FXSYS_isDecimalDigit(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 uint16_t wCountH = 2;
  const uint16_t wCountM = 2;
  const uint16_t wCountS = 2;
  const uint16_t wCountF = 3;
  const bool bSymbol = wsTime.Find(':') != -1;
  uint16_t wHour = 0;
  uint16_t wMinute = 0;
  uint16_t wSecond = 0;
  uint16_t wFraction = 0;
  const FX_WCHAR* pTime = wsTime.c_str();
  int nIndex = 0;
  int nStart = 0;
  while (nIndex - nStart < wCountH && pTime[nIndex]) {
    if (!FXSYS_isDecimalDigit(pTime[nIndex]))
      return FALSE;
    wHour = pTime[nIndex] - '0' + wHour * 10;
    nIndex++;
  }
  if (bSymbol) {
    if (nIndex < nLen && pTime[nIndex] != ':')
      return FALSE;
    nIndex++;
  }
  nStart = nIndex;
  while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
    if (!FXSYS_isDecimalDigit(pTime[nIndex]))
      return FALSE;
    wMinute = pTime[nIndex] - '0' + wMinute * 10;
    nIndex++;
  }
  if (bSymbol) {
    if (nIndex < nLen && pTime[nIndex] != ':')
      return FALSE;
    nIndex++;
  }
  nStart = nIndex;
  while (nIndex - nStart < wCountS && nIndex < nLen && pTime[nIndex]) {
    if (!FXSYS_isDecimalDigit(pTime[nIndex]))
      return FALSE;
    wSecond = pTime[nIndex] - '0' + wSecond * 10;
    nIndex++;
  }
  if (wsTime.Find('.') > 0) {
    if (pTime[nIndex] != '.')
      return FALSE;
    nIndex++;
    nStart = nIndex;
    while (nIndex - nStart < wCountF && nIndex < nLen && pTime[nIndex]) {
      if (!FXSYS_isDecimalDigit(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;
      int16_t nOffsetM = 0;
      nIndex++;
      nStart = nIndex;
      while (nIndex - nStart < wCountH && nIndex < nLen && pTime[nIndex]) {
        if (!FXSYS_isDecimalDigit(pTime[nIndex]))
          return FALSE;
        nOffsetH = pTime[nIndex] - '0' + nOffsetH * 10;
        nIndex++;
      }
      if (bSymbol) {
        if (nIndex < nLen && pTime[nIndex] != ':')
          return FALSE;
        nIndex++;
      }
      nStart = nIndex;
      while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
        if (!FXSYS_isDecimalDigit(pTime[nIndex]))
          return FALSE;
        nOffsetM = pTime[nIndex] - '0' + nOffsetM * 10;
        nIndex++;
      }
      if (nOffsetH > 12 || nOffsetM >= 60)
        return FALSE;
    }
  }
  return nIndex == nLen && wHour < 24 && wMinute < 60 && wSecond < 60 &&
         wFraction <= 999;
}
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;
    uint32_t dwFractional = 0;
    int32_t nExponent = 0;
    int32_t cc = 0;
    FX_BOOL bNegative = FALSE, bExpSign = FALSE;
    const FX_WCHAR* str = m_wsValue.c_str();
    int len = m_wsValue.GetLength();
    while (FXSYS_iswspace(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] == '.' || !FXSYS_isDecimalDigit(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) ||
            !FXSYS_isDecimalDigit(str[cc])) {
          break;
        }
      }
      dwFractional = (uint32_t)(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] == '.' || !FXSYS_isDecimalDigit(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;
}