• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_cssselector.h"
8 
9 #include <utility>
10 
11 #include "third_party/base/ptr_util.h"
12 
13 namespace {
14 
IsCSSChar(FX_WCHAR wch)15 bool IsCSSChar(FX_WCHAR wch) {
16   return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z');
17 }
18 
GetCSSNameLen(const FX_WCHAR * psz,const FX_WCHAR * pEnd)19 int32_t GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) {
20   const FX_WCHAR* pStart = psz;
21   while (psz < pEnd) {
22     FX_WCHAR wch = *psz;
23     if (IsCSSChar(wch) || (wch >= '0' && wch <= '9') || wch == '_' ||
24         wch == '-') {
25       ++psz;
26     } else {
27       break;
28     }
29   }
30   return psz - pStart;
31 }
32 
33 }  // namespace
34 
CFDE_CSSSelector(FDE_CSSSelectorType eType,const FX_WCHAR * psz,int32_t iLen,bool bIgnoreCase)35 CFDE_CSSSelector::CFDE_CSSSelector(FDE_CSSSelectorType eType,
36                                    const FX_WCHAR* psz,
37                                    int32_t iLen,
38                                    bool bIgnoreCase)
39     : m_eType(eType),
40       m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {}
41 
~CFDE_CSSSelector()42 CFDE_CSSSelector::~CFDE_CSSSelector() {}
43 
GetType() const44 FDE_CSSSelectorType CFDE_CSSSelector::GetType() const {
45   return m_eType;
46 }
47 
GetNameHash() const48 uint32_t CFDE_CSSSelector::GetNameHash() const {
49   return m_dwHash;
50 }
51 
GetNextSelector() const52 CFDE_CSSSelector* CFDE_CSSSelector::GetNextSelector() const {
53   return m_pNext.get();
54 }
55 
56 // static.
FromString(const CFX_WideStringC & str)57 std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString(
58     const CFX_WideStringC& str) {
59   ASSERT(!str.IsEmpty());
60 
61   const FX_WCHAR* psz = str.c_str();
62   const FX_WCHAR* pStart = psz;
63   const FX_WCHAR* pEnd = psz + str.GetLength();
64   for (; psz < pEnd; ++psz) {
65     switch (*psz) {
66       case '>':
67       case '[':
68       case '+':
69         return nullptr;
70     }
71   }
72 
73   std::unique_ptr<CFDE_CSSSelector> pFirst = nullptr;
74   for (psz = pStart; psz < pEnd;) {
75     FX_WCHAR wch = *psz;
76     if (IsCSSChar(wch) || wch == '*') {
77       int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd);
78       auto p = pdfium::MakeUnique<CFDE_CSSSelector>(
79           FDE_CSSSelectorType::Element, psz, iNameLen, true);
80       if (pFirst) {
81         pFirst->SetType(FDE_CSSSelectorType::Descendant);
82         p->SetNext(std::move(pFirst));
83       }
84       pFirst = std::move(p);
85       psz += iNameLen;
86     } else if (wch == ' ') {
87       psz++;
88     } else {
89       return nullptr;
90     }
91   }
92   return pFirst;
93 }
94