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 "xfa/fde/css/cfde_cssvaluelistparser.h" 8 9CFDE_CSSValueListParser::CFDE_CSSValueListParser(const FX_WCHAR* psz, 10 int32_t iLen, 11 FX_WCHAR separator) 12 : m_Separator(separator), m_pCur(psz), m_pEnd(psz + iLen) { 13 ASSERT(psz && iLen > 0); 14} 15 16bool CFDE_CSSValueListParser::NextValue(FDE_CSSPrimitiveType& eType, 17 const FX_WCHAR*& pStart, 18 int32_t& iLength) { 19 while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) 20 ++m_pCur; 21 22 if (m_pCur >= m_pEnd) 23 return false; 24 25 eType = FDE_CSSPrimitiveType::Unknown; 26 pStart = m_pCur; 27 iLength = 0; 28 FX_WCHAR wch = *m_pCur; 29 if (wch == '#') { 30 iLength = SkipTo(' ', false, false); 31 if (iLength == 4 || iLength == 7) 32 eType = FDE_CSSPrimitiveType::RGB; 33 } else if ((wch >= '0' && wch <= '9') || wch == '.' || wch == '-' || 34 wch == '+') { 35 while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) 36 ++m_pCur; 37 38 iLength = m_pCur - pStart; 39 eType = FDE_CSSPrimitiveType::Number; 40 } else if (wch == '\"' || wch == '\'') { 41 pStart++; 42 m_pCur++; 43 iLength = SkipTo(wch, false, false); 44 m_pCur++; 45 eType = FDE_CSSPrimitiveType::String; 46 } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') { 47 if (FXSYS_wcsnicmp(L"rgb", m_pCur, 3) == 0) { 48 iLength = SkipTo(')', false, false) + 1; 49 m_pCur++; 50 eType = FDE_CSSPrimitiveType::RGB; 51 } 52 } else { 53 iLength = SkipTo(m_Separator, true, true); 54 eType = FDE_CSSPrimitiveType::String; 55 } 56 return m_pCur <= m_pEnd && iLength > 0; 57} 58 59int32_t CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, 60 bool breakOnSpace, 61 bool matchBrackets) { 62 const FX_WCHAR* pStart = m_pCur; 63 int32_t bracketCount = 0; 64 while (m_pCur < m_pEnd && *m_pCur != wch) { 65 if (breakOnSpace && *m_pCur <= ' ') 66 break; 67 if (!matchBrackets) { 68 m_pCur++; 69 continue; 70 } 71 72 if (*m_pCur == '(') 73 bracketCount++; 74 else if (*m_pCur == ')') 75 bracketCount--; 76 77 m_pCur++; 78 } 79 80 while (bracketCount > 0 && m_pCur < m_pEnd) { 81 if (*m_pCur == ')') 82 bracketCount--; 83 m_pCur++; 84 } 85 return m_pCur - pStart; 86} 87