blob: 6ee81f561063c30416e1900cbf8157b6c28ba383 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "core/fxcrt/css/cfx_cssselector.h"
#include <utility>
#include "core/fxcrt/fx_extension.h"
#include "third_party/base/ptr_util.h"
namespace {
int32_t GetCSSNameLen(const wchar_t* psz, const wchar_t* pEnd) {
const wchar_t* pStart = psz;
while (psz < pEnd) {
wchar_t wch = *psz;
if (!FXSYS_iswalnum(wch) && wch != '_' && wch != '-')
break;
++psz;
}
return psz - pStart;
}
} // namespace
CFX_CSSSelector::CFX_CSSSelector(CFX_CSSSelectorType eType,
const wchar_t* psz,
int32_t iLen,
bool bIgnoreCase)
: m_eType(eType),
m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {}
CFX_CSSSelector::~CFX_CSSSelector() {}
CFX_CSSSelectorType CFX_CSSSelector::GetType() const {
return m_eType;
}
uint32_t CFX_CSSSelector::GetNameHash() const {
return m_dwHash;
}
CFX_CSSSelector* CFX_CSSSelector::GetNextSelector() const {
return m_pNext.get();
}
// static.
std::unique_ptr<CFX_CSSSelector> CFX_CSSSelector::FromString(
const CFX_WideStringC& str) {
ASSERT(!str.IsEmpty());
const wchar_t* psz = str.unterminated_c_str();
const wchar_t* pStart = psz;
const wchar_t* pEnd = psz + str.GetLength();
for (; psz < pEnd; ++psz) {
switch (*psz) {
case '>':
case '[':
case '+':
return nullptr;
}
}
std::unique_ptr<CFX_CSSSelector> pFirst = nullptr;
for (psz = pStart; psz < pEnd;) {
wchar_t wch = *psz;
if (FXSYS_iswalpha(wch) || wch == '*') {
int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd);
auto p = pdfium::MakeUnique<CFX_CSSSelector>(CFX_CSSSelectorType::Element,
psz, iNameLen, true);
if (pFirst) {
pFirst->SetType(CFX_CSSSelectorType::Descendant);
p->SetNext(std::move(pFirst));
}
pFirst = std::move(p);
psz += iNameLen;
} else if (wch == ' ') {
psz++;
} else {
return nullptr;
}
}
return pFirst;
}
|