| // Copyright 2017 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/fde/css/cfde_cssvaluelistparser.h" |
| |
| CFDE_CSSValueListParser::CFDE_CSSValueListParser(const FX_WCHAR* psz, |
| int32_t iLen, |
| FX_WCHAR separator) |
| : m_Separator(separator), m_pCur(psz), m_pEnd(psz + iLen) { |
| ASSERT(psz && iLen > 0); |
| } |
| |
| bool CFDE_CSSValueListParser::NextValue(FDE_CSSPrimitiveType& eType, |
| const FX_WCHAR*& pStart, |
| int32_t& iLength) { |
| while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) { |
| ++m_pCur; |
| } |
| if (m_pCur >= m_pEnd) { |
| return false; |
| } |
| eType = FDE_CSSPrimitiveType::Unknown; |
| pStart = m_pCur; |
| iLength = 0; |
| FX_WCHAR wch = *m_pCur; |
| if (wch == '#') { |
| iLength = SkipTo(' '); |
| if (iLength == 4 || iLength == 7) { |
| eType = FDE_CSSPrimitiveType::RGB; |
| } |
| } else if ((wch >= '0' && wch <= '9') || wch == '.' || wch == '-' || |
| wch == '+') { |
| while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) { |
| ++m_pCur; |
| } |
| iLength = m_pCur - pStart; |
| if (iLength > 0) { |
| eType = FDE_CSSPrimitiveType::Number; |
| } |
| } else if (wch == '\"' || wch == '\'') { |
| pStart++; |
| iLength = SkipTo(wch) - 1; |
| m_pCur++; |
| eType = FDE_CSSPrimitiveType::String; |
| } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') { |
| if (FXSYS_wcsnicmp(L"url", m_pCur, 3) == 0) { |
| wch = m_pCur[4]; |
| if (wch == '\"' || wch == '\'') { |
| pStart += 5; |
| iLength = SkipTo(wch) - 6; |
| m_pCur += 2; |
| } else { |
| pStart += 4; |
| iLength = SkipTo(')') - 4; |
| m_pCur++; |
| } |
| eType = FDE_CSSPrimitiveType::String; |
| } else if (FXSYS_wcsnicmp(L"rgb", m_pCur, 3) == 0) { |
| iLength = SkipTo(')') + 1; |
| m_pCur++; |
| eType = FDE_CSSPrimitiveType::RGB; |
| } |
| } else { |
| iLength = SkipTo(m_Separator, true, true); |
| eType = FDE_CSSPrimitiveType::String; |
| } |
| return m_pCur <= m_pEnd && iLength > 0; |
| } |
| int32_t CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, |
| bool bWSSeparator, |
| bool bBrContinue) { |
| const FX_WCHAR* pStart = m_pCur; |
| if (!bBrContinue) { |
| if (bWSSeparator) { |
| while ((++m_pCur < m_pEnd) && (*m_pCur != wch) && (*m_pCur > ' ')) { |
| continue; |
| } |
| } else { |
| while (++m_pCur < m_pEnd && *m_pCur != wch) { |
| continue; |
| } |
| } |
| |
| } else { |
| int32_t iBracketCount = 0; |
| if (bWSSeparator) { |
| while ((m_pCur < m_pEnd) && (*m_pCur != wch) && (*m_pCur > ' ')) { |
| if (*m_pCur == '(') { |
| iBracketCount++; |
| } else if (*m_pCur == ')') { |
| iBracketCount--; |
| } |
| m_pCur++; |
| } |
| } else { |
| while (m_pCur < m_pEnd && *m_pCur != wch) { |
| if (*m_pCur == '(') { |
| iBracketCount++; |
| } else if (*m_pCur == ')') { |
| iBracketCount--; |
| } |
| m_pCur++; |
| } |
| } |
| while (iBracketCount > 0 && m_pCur < m_pEnd) { |
| if (*m_pCur == ')') { |
| iBracketCount--; |
| } |
| m_pCur++; |
| } |
| } |
| return m_pCur - pStart; |
| } |