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
CFDE_CSSValueListParser(const FX_WCHAR * psz,int32_t iLen,FX_WCHAR separator)9 CFDE_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
NextValue(FDE_CSSPrimitiveType & eType,const FX_WCHAR * & pStart,int32_t & iLength)16 bool 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
SkipTo(FX_WCHAR wch,bool breakOnSpace,bool matchBrackets)59 int32_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