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