Home | History | Annotate | Download | only in css
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcrt/css/cfx_cssvaluelistparser.h"
      8 
      9 #include "core/fxcrt/fx_extension.h"
     10 
     11 CFX_CSSValueListParser::CFX_CSSValueListParser(const wchar_t* psz,
     12                                                int32_t iLen,
     13                                                wchar_t separator)
     14     : m_Separator(separator), m_pCur(psz), m_pEnd(psz + iLen) {
     15   ASSERT(psz && iLen > 0);
     16 }
     17 
     18 bool CFX_CSSValueListParser::NextValue(CFX_CSSPrimitiveType* eType,
     19                                        const wchar_t** pStart,
     20                                        int32_t* iLength) {
     21   while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator))
     22     ++m_pCur;
     23 
     24   if (m_pCur >= m_pEnd)
     25     return false;
     26 
     27   *eType = CFX_CSSPrimitiveType::Unknown;
     28   *pStart = m_pCur;
     29   *iLength = 0;
     30   wchar_t wch = *m_pCur;
     31   if (wch == '#') {
     32     *iLength = SkipTo(' ', false, false);
     33     if (*iLength == 4 || *iLength == 7)
     34       *eType = CFX_CSSPrimitiveType::RGB;
     35   } else if (std::iswdigit(wch) || wch == '.' || wch == '-' || wch == '+') {
     36     while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator))
     37       ++m_pCur;
     38 
     39     *iLength = m_pCur - *pStart;
     40     *eType = CFX_CSSPrimitiveType::Number;
     41   } else if (wch == '\"' || wch == '\'') {
     42     ++(*pStart);
     43     m_pCur++;
     44     *iLength = SkipTo(wch, false, false);
     45     m_pCur++;
     46     *eType = CFX_CSSPrimitiveType::String;
     47   } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') {
     48     if (FXSYS_wcsnicmp(L"rgb", m_pCur, 3) == 0) {
     49       *iLength = SkipTo(')', false, false) + 1;
     50       m_pCur++;
     51       *eType = CFX_CSSPrimitiveType::RGB;
     52     }
     53   } else {
     54     *iLength = SkipTo(m_Separator, true, true);
     55     *eType = CFX_CSSPrimitiveType::String;
     56   }
     57   return m_pCur <= m_pEnd && *iLength > 0;
     58 }
     59 
     60 int32_t CFX_CSSValueListParser::SkipTo(wchar_t wch,
     61                                        bool breakOnSpace,
     62                                        bool matchBrackets) {
     63   const wchar_t* pStart = m_pCur;
     64   int32_t bracketCount = 0;
     65   while (m_pCur < m_pEnd && *m_pCur != wch) {
     66     if (breakOnSpace && *m_pCur <= ' ')
     67       break;
     68     if (!matchBrackets) {
     69       m_pCur++;
     70       continue;
     71     }
     72 
     73     if (*m_pCur == '(')
     74       bracketCount++;
     75     else if (*m_pCur == ')')
     76       bracketCount--;
     77 
     78     m_pCur++;
     79   }
     80 
     81   while (bracketCount > 0 && m_pCur < m_pEnd) {
     82     if (*m_pCur == ')')
     83       bracketCount--;
     84     m_pCur++;
     85   }
     86   return m_pCur - pStart;
     87 }
     88